@alleyboss/micropay-solana-x402-paywall 1.0.1 → 2.0.1
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/README.md +100 -167
- package/dist/client/index.cjs +99 -0
- package/dist/client/index.cjs.map +1 -0
- package/dist/client/index.d.cts +112 -0
- package/dist/client/index.d.ts +112 -0
- package/dist/client/index.js +95 -0
- package/dist/client/index.js.map +1 -0
- package/dist/client-CSZHI8o8.d.ts +32 -0
- package/dist/client-vRr48m2x.d.cts +32 -0
- package/dist/index.cjs +696 -15
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +11 -3
- package/dist/index.d.ts +11 -3
- package/dist/index.js +674 -16
- package/dist/index.js.map +1 -1
- package/dist/memory-Daxkczti.d.cts +29 -0
- package/dist/memory-Daxkczti.d.ts +29 -0
- package/dist/middleware/index.cjs +261 -0
- package/dist/middleware/index.cjs.map +1 -0
- package/dist/middleware/index.d.cts +90 -0
- package/dist/middleware/index.d.ts +90 -0
- package/dist/middleware/index.js +255 -0
- package/dist/middleware/index.js.map +1 -0
- package/dist/nextjs-BK0pVb9Y.d.ts +78 -0
- package/dist/nextjs-Bm272Jkj.d.cts +78 -0
- package/dist/{client-kfCr7G-P.d.cts → payment-CTxdtqmc.d.cts} +23 -34
- package/dist/{client-kfCr7G-P.d.ts → payment-CTxdtqmc.d.ts} +23 -34
- package/dist/pricing/index.cjs +142 -0
- package/dist/pricing/index.cjs.map +1 -0
- package/dist/pricing/index.d.cts +111 -0
- package/dist/pricing/index.d.ts +111 -0
- package/dist/pricing/index.js +133 -0
- package/dist/pricing/index.js.map +1 -0
- package/dist/session/index.d.cts +29 -1
- package/dist/session/index.d.ts +29 -1
- package/dist/{index-uxMb72hH.d.cts → session-D2IoWAWV.d.cts} +1 -27
- package/dist/{index-uxMb72hH.d.ts → session-D2IoWAWV.d.ts} +1 -27
- package/dist/solana/index.cjs +193 -0
- package/dist/solana/index.cjs.map +1 -1
- package/dist/solana/index.d.cts +60 -3
- package/dist/solana/index.d.ts +60 -3
- package/dist/solana/index.js +190 -1
- package/dist/solana/index.js.map +1 -1
- package/dist/store/index.cjs +99 -0
- package/dist/store/index.cjs.map +1 -0
- package/dist/store/index.d.cts +38 -0
- package/dist/store/index.d.ts +38 -0
- package/dist/store/index.js +96 -0
- package/dist/store/index.js.map +1 -0
- package/dist/utils/index.cjs +68 -0
- package/dist/utils/index.cjs.map +1 -0
- package/dist/utils/index.d.cts +30 -0
- package/dist/utils/index.d.ts +30 -0
- package/dist/utils/index.js +65 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/x402/index.cjs +2 -1
- package/dist/x402/index.cjs.map +1 -1
- package/dist/x402/index.d.cts +2 -1
- package/dist/x402/index.d.ts +2 -1
- package/dist/x402/index.js +2 -1
- package/dist/x402/index.js.map +1 -1
- package/package.json +56 -3
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/solana/client.ts","../src/solana/verification.ts","../src/session/core.ts","../src/x402/config.ts","../src/x402/verification.ts"],"names":["clusterApiUrl","Connection","PublicKey","LAMPORTS_PER_SOL","uuidv4","SignJWT","jwtVerify","WALLET_REGEX","SIGNATURE_REGEX"],"mappings":"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","file":"index.cjs","sourcesContent":["// Solana RPC client with multi-provider support\nimport { Connection, clusterApiUrl, type Cluster } from '@solana/web3.js';\nimport type { SolanaNetwork } from '../types';\n\n/** Configuration for Solana client */\nexport interface SolanaClientConfig {\n /** Network to connect to */\n network: SolanaNetwork;\n /** Custom RPC URL (optional) */\n rpcUrl?: string;\n /** Tatum.io API key for RPC (optional) */\n tatumApiKey?: string;\n}\n\n// Singleton state\nlet cachedConnection: Connection | null = null;\nlet cachedNetwork: SolanaNetwork | null = null;\n\n/**\n * Build RPC URL based on configuration priority:\n * 1. Custom RPC URL\n * 2. Tatum.io with API key\n * 3. Public RPC (rate limited)\n */\nfunction buildRpcUrl(config: SolanaClientConfig): string {\n const { network, rpcUrl, tatumApiKey } = config;\n\n if (rpcUrl) {\n // If Tatum URL without key, append key if available\n if (rpcUrl.includes('tatum.io') && tatumApiKey && !rpcUrl.includes(tatumApiKey)) {\n return rpcUrl.endsWith('/') ? `${rpcUrl}${tatumApiKey}` : `${rpcUrl}/${tatumApiKey}`;\n }\n return rpcUrl;\n }\n\n if (tatumApiKey) {\n const baseUrl = network === 'mainnet-beta'\n ? 'https://solana-mainnet.gateway.tatum.io'\n : 'https://solana-devnet.gateway.tatum.io';\n return `${baseUrl}/${tatumApiKey}`;\n }\n\n // Fallback to public RPC\n return clusterApiUrl(network as Cluster);\n}\n\n/**\n * Get or create a Solana connection\n * Uses singleton pattern with network-aware caching\n */\nexport function getConnection(config: SolanaClientConfig): Connection {\n const { network } = config;\n\n // Return cached if same network\n if (cachedConnection && cachedNetwork === network) {\n return cachedConnection;\n }\n\n const rpcUrl = buildRpcUrl(config);\n\n cachedConnection = new Connection(rpcUrl, {\n commitment: 'confirmed',\n confirmTransactionInitialTimeout: 60000,\n });\n cachedNetwork = network;\n\n return cachedConnection;\n}\n\n/**\n * Reset the cached connection\n * Useful for testing or network switching\n */\nexport function resetConnection(): void {\n cachedConnection = null;\n cachedNetwork = null;\n}\n\n/**\n * Check if network is mainnet\n */\nexport function isMainnet(network: SolanaNetwork): boolean {\n return network === 'mainnet-beta';\n}\n\n/**\n * Convert Solana network to x402 network identifier\n */\nexport function toX402Network(network: SolanaNetwork): 'solana-devnet' | 'solana-mainnet' {\n return network === 'mainnet-beta' ? 'solana-mainnet' : 'solana-devnet';\n}\n","// Transaction verification for SOL payments\n// SECURITY: On-chain verification, signature validation, replay protection\nimport { PublicKey, LAMPORTS_PER_SOL, type ParsedTransactionWithMeta } from '@solana/web3.js';\nimport { getConnection, type SolanaClientConfig } from './client';\n\n/** Result of transaction verification */\nexport interface TransactionVerificationResult {\n /** Whether the transaction is valid for the payment */\n valid: boolean;\n /** Whether the transaction is confirmed on-chain */\n confirmed: boolean;\n /** Transaction signature */\n signature: string;\n /** Sender wallet address */\n from?: string;\n /** Recipient wallet address */\n to?: string;\n /** Amount transferred in lamports */\n amount?: bigint;\n /** Block time (Unix timestamp) */\n blockTime?: number;\n /** Slot number */\n slot?: number;\n /** Error message if verification failed */\n error?: string;\n}\n\n/** Parameters for verifying a payment */\nexport interface VerifyPaymentParams {\n /** Transaction signature to verify */\n signature: string;\n /** Expected recipient wallet address */\n expectedRecipient: string;\n /** Expected amount in lamports */\n expectedAmount: bigint;\n /** Maximum age of transaction in seconds (default: 300) */\n maxAgeSeconds?: number;\n /** Solana client configuration */\n clientConfig: SolanaClientConfig;\n}\n\n// Signature validation regex (base58, 87-88 chars)\nconst SIGNATURE_REGEX = /^[1-9A-HJ-NP-Za-km-z]{87,88}$/;\n\n// Wallet address validation regex\nconst WALLET_REGEX = /^[1-9A-HJ-NP-Za-km-z]{32,44}$/;\n\n/**\n * Validate transaction signature format\n * SECURITY: Prevents malformed signatures from reaching RPC\n */\nfunction isValidSignature(signature: string): boolean {\n if (!signature || typeof signature !== 'string') return false;\n return SIGNATURE_REGEX.test(signature);\n}\n\n/**\n * Validate wallet address format\n * SECURITY: Ensures valid base58 address\n */\nfunction isValidWalletAddress(address: string): boolean {\n if (!address || typeof address !== 'string') return false;\n return WALLET_REGEX.test(address);\n}\n\n/**\n * Parse SOL transfer details from a transaction\n */\nfunction parseSOLTransfer(\n transaction: ParsedTransactionWithMeta,\n expectedRecipient: string\n): { from: string; to: string; amount: bigint } | null {\n const instructions = transaction.transaction.message.instructions;\n\n // Check main instructions\n for (const ix of instructions) {\n if ('parsed' in ix && ix.program === 'system') {\n const parsed = ix.parsed as {\n type: string;\n info: { source: string; destination: string; lamports: number }\n };\n\n if (parsed.type === 'transfer' && parsed.info.destination === expectedRecipient) {\n return {\n from: parsed.info.source,\n to: parsed.info.destination,\n amount: BigInt(parsed.info.lamports),\n };\n }\n }\n }\n\n // Check inner instructions\n if (transaction.meta?.innerInstructions) {\n for (const inner of transaction.meta.innerInstructions) {\n for (const ix of inner.instructions) {\n if ('parsed' in ix && ix.program === 'system') {\n const parsed = ix.parsed as {\n type: string;\n info: { source: string; destination: string; lamports: number }\n };\n\n if (parsed.type === 'transfer' && parsed.info.destination === expectedRecipient) {\n return {\n from: parsed.info.source,\n to: parsed.info.destination,\n amount: BigInt(parsed.info.lamports),\n };\n }\n }\n }\n }\n }\n\n return null;\n}\n\n/**\n * Verify a SOL transfer transaction\n * SECURITY: Full on-chain verification with amount/recipient/age checks\n */\nexport async function verifyPayment(\n params: VerifyPaymentParams\n): Promise<TransactionVerificationResult> {\n const {\n signature,\n expectedRecipient,\n expectedAmount,\n maxAgeSeconds = 300,\n clientConfig\n } = params;\n\n // SECURITY: Validate signature format before RPC call\n if (!isValidSignature(signature)) {\n return { valid: false, confirmed: false, signature, error: 'Invalid signature format' };\n }\n\n // SECURITY: Validate recipient address format\n if (!isValidWalletAddress(expectedRecipient)) {\n return { valid: false, confirmed: false, signature, error: 'Invalid recipient address' };\n }\n\n // SECURITY: Validate expected amount is positive\n if (expectedAmount <= 0n) {\n return { valid: false, confirmed: false, signature, error: 'Invalid expected amount' };\n }\n\n // SECURITY: Enforce reasonable max age (prevent replay with very old transactions)\n const effectiveMaxAge = Math.min(Math.max(maxAgeSeconds, 60), 3600); // 1 min to 1 hour\n\n const connection = getConnection(clientConfig);\n\n try {\n const transaction = await connection.getParsedTransaction(signature, {\n commitment: 'confirmed',\n maxSupportedTransactionVersion: 0,\n });\n\n if (!transaction) {\n return { valid: false, confirmed: false, signature, error: 'Transaction not found' };\n }\n\n // Check for transaction errors\n if (transaction.meta?.err) {\n return {\n valid: false,\n confirmed: true,\n signature,\n error: 'Transaction failed on-chain',\n };\n }\n\n // SECURITY: Validate transaction age (replay protection)\n if (transaction.blockTime) {\n const now = Math.floor(Date.now() / 1000);\n if (now - transaction.blockTime > effectiveMaxAge) {\n return { valid: false, confirmed: true, signature, error: 'Transaction too old' };\n }\n // Also reject future-dated transactions (clock skew attack)\n if (transaction.blockTime > now + 60) {\n return { valid: false, confirmed: true, signature, error: 'Invalid transaction time' };\n }\n }\n\n // Parse transfer details\n const transferDetails = parseSOLTransfer(transaction, expectedRecipient);\n\n if (!transferDetails) {\n return {\n valid: false,\n confirmed: true,\n signature,\n error: 'No valid SOL transfer to recipient found',\n };\n }\n\n // SECURITY: Validate amount (must meet or exceed expected)\n if (transferDetails.amount < expectedAmount) {\n return {\n valid: false,\n confirmed: true,\n signature,\n from: transferDetails.from,\n to: transferDetails.to,\n amount: transferDetails.amount,\n error: 'Insufficient payment amount',\n };\n }\n\n return {\n valid: true,\n confirmed: true,\n signature,\n from: transferDetails.from,\n to: transferDetails.to,\n amount: transferDetails.amount,\n blockTime: transaction.blockTime ?? undefined,\n slot: transaction.slot,\n };\n } catch (error) {\n // SECURITY: Don't expose internal error details\n return {\n valid: false,\n confirmed: false,\n signature,\n error: 'Verification failed',\n };\n }\n}\n\n/**\n * Wait for transaction confirmation\n */\nexport async function waitForConfirmation(\n signature: string,\n clientConfig: SolanaClientConfig\n): Promise<{ confirmed: boolean; slot?: number; error?: string }> {\n if (!isValidSignature(signature)) {\n return { confirmed: false, error: 'Invalid signature format' };\n }\n\n const connection = getConnection(clientConfig);\n\n try {\n const confirmation = await connection.confirmTransaction(signature, 'confirmed');\n\n if (confirmation.value.err) {\n return { confirmed: false, error: 'Transaction failed' };\n }\n\n return { confirmed: true, slot: confirmation.context?.slot };\n } catch {\n return { confirmed: false, error: 'Confirmation timeout' };\n }\n}\n\n/**\n * Get recent transactions for a wallet\n */\nexport async function getWalletTransactions(\n walletAddress: string,\n clientConfig: SolanaClientConfig,\n limit: number = 20\n): Promise<Array<{ signature: string; blockTime?: number; slot: number }>> {\n if (!isValidWalletAddress(walletAddress)) {\n return [];\n }\n\n // SECURITY: Cap limit to prevent abuse\n const safeLimit = Math.min(Math.max(limit, 1), 100);\n\n const connection = getConnection(clientConfig);\n\n try {\n const pubkey = new PublicKey(walletAddress);\n const signatures = await connection.getSignaturesForAddress(pubkey, { limit: safeLimit });\n return signatures.map((sig) => ({\n signature: sig.signature,\n blockTime: sig.blockTime ?? undefined,\n slot: sig.slot,\n }));\n } catch {\n return [];\n }\n}\n\n/**\n * Convert lamports to SOL\n */\nexport function lamportsToSol(lamports: bigint | number): number {\n return Number(lamports) / LAMPORTS_PER_SOL;\n}\n\n/**\n * Convert SOL to lamports\n */\nexport function solToLamports(sol: number): bigint {\n if (!Number.isFinite(sol) || sol < 0) {\n throw new Error('Invalid SOL amount');\n }\n return BigInt(Math.floor(sol * LAMPORTS_PER_SOL));\n}\n","// Session management with JWT (framework-agnostic core)\n// SECURITY: Uses jose library with HS256, constant-time validation, input sanitization\nimport { SignJWT, jwtVerify } from 'jose';\nimport { v4 as uuidv4 } from 'uuid';\nimport type { SessionData, SessionConfig, SessionValidation, SessionJWTPayload } from '../types';\n\n// Maximum articles per session to prevent unbounded growth\nconst MAX_ARTICLES_PER_SESSION = 100;\n\n// Minimum secret length for security\nconst MIN_SECRET_LENGTH = 32;\n\n/**\n * Get the secret key for JWT signing\n * SECURITY: Enforces minimum secret length\n */\nfunction getSecretKey(secret: string): Uint8Array {\n if (!secret || typeof secret !== 'string') {\n throw new Error('Session secret is required');\n }\n if (secret.length < MIN_SECRET_LENGTH) {\n throw new Error(`Session secret must be at least ${MIN_SECRET_LENGTH} characters`);\n }\n return new TextEncoder().encode(secret);\n}\n\n/**\n * Validate wallet address format (base58, 32-44 chars)\n * SECURITY: Prevents injection via wallet address field\n */\nfunction validateWalletAddress(address: string): boolean {\n if (!address || typeof address !== 'string') return false;\n // Solana addresses are base58, typically 32-44 characters\n const base58Regex = /^[1-9A-HJ-NP-Za-km-z]{32,44}$/;\n return base58Regex.test(address);\n}\n\n/**\n * Validate article ID format\n * SECURITY: Prevents injection via articleId field\n */\nfunction validateArticleId(articleId: string): boolean {\n if (!articleId || typeof articleId !== 'string') return false;\n // Allow alphanumeric, hyphens, underscores, max 128 chars\n if (articleId.length > 128) return false;\n const safeIdRegex = /^[a-zA-Z0-9_-]+$/;\n return safeIdRegex.test(articleId);\n}\n\n/**\n * Create a new session after successful payment\n * SECURITY: Validates inputs, enforces limits\n */\nexport async function createSession(\n walletAddress: string,\n articleId: string,\n config: SessionConfig,\n siteWide: boolean = false\n): Promise<{ token: string; session: SessionData }> {\n // Input validation\n if (!validateWalletAddress(walletAddress)) {\n throw new Error('Invalid wallet address format');\n }\n if (!validateArticleId(articleId)) {\n throw new Error('Invalid article ID format');\n }\n if (!config.durationHours || config.durationHours <= 0 || config.durationHours > 720) {\n throw new Error('Session duration must be between 1 and 720 hours');\n }\n\n const sessionId = uuidv4();\n const now = Math.floor(Date.now() / 1000);\n const expiresAt = now + (config.durationHours * 3600);\n\n const session: SessionData = {\n id: sessionId,\n walletAddress,\n unlockedArticles: [articleId],\n siteWideUnlock: Boolean(siteWide),\n createdAt: now,\n expiresAt,\n };\n\n const payload: SessionJWTPayload = {\n sub: walletAddress,\n sid: sessionId,\n articles: session.unlockedArticles,\n siteWide: session.siteWideUnlock,\n iat: now,\n exp: expiresAt,\n };\n\n const token = await new SignJWT(payload as unknown as Record<string, unknown>)\n .setProtectedHeader({ alg: 'HS256' })\n .setIssuedAt()\n .setExpirationTime(`${config.durationHours}h`)\n .sign(getSecretKey(config.secret));\n\n return { token, session };\n}\n\n/**\n * Validate an existing session token\n * SECURITY: jose library handles timing-safe comparison internally\n */\nexport async function validateSession(\n token: string,\n secret: string\n): Promise<SessionValidation> {\n // Input validation\n if (!token || typeof token !== 'string') {\n return { valid: false, reason: 'Invalid token format' };\n }\n\n try {\n const { payload } = await jwtVerify(token, getSecretKey(secret));\n const sessionPayload = payload as unknown as SessionJWTPayload;\n\n // Validate required fields exist\n if (!sessionPayload.sub || !sessionPayload.sid || !sessionPayload.exp) {\n return { valid: false, reason: 'Malformed session payload' };\n }\n\n // Check expiration (jose already checks, but double-check)\n const now = Math.floor(Date.now() / 1000);\n if (sessionPayload.exp < now) {\n return { valid: false, reason: 'Session expired' };\n }\n\n // Validate wallet address format from token\n if (!validateWalletAddress(sessionPayload.sub)) {\n return { valid: false, reason: 'Invalid session data' };\n }\n\n const session: SessionData = {\n id: sessionPayload.sid,\n walletAddress: sessionPayload.sub,\n unlockedArticles: Array.isArray(sessionPayload.articles) ? sessionPayload.articles : [],\n siteWideUnlock: Boolean(sessionPayload.siteWide),\n createdAt: sessionPayload.iat ?? 0,\n expiresAt: sessionPayload.exp,\n };\n\n return { valid: true, session };\n } catch (error) {\n // SECURITY: Don't expose internal error details\n return { valid: false, reason: 'Invalid session' };\n }\n}\n\n/**\n * Add an article to an existing session\n * SECURITY: Enforces article limit to prevent token bloat\n */\nexport async function addArticleToSession(\n token: string,\n articleId: string,\n secret: string\n): Promise<{ token: string; session: SessionData } | null> {\n // Validate article ID\n if (!validateArticleId(articleId)) {\n return null;\n }\n\n const validation = await validateSession(token, secret);\n if (!validation.valid || !validation.session) {\n return null;\n }\n\n const session = validation.session;\n\n // Already unlocked\n if (session.unlockedArticles.includes(articleId)) {\n return { token, session };\n }\n\n // SECURITY: Enforce maximum articles per session\n if (session.unlockedArticles.length >= MAX_ARTICLES_PER_SESSION) {\n return null;\n }\n\n const updatedArticles = [...session.unlockedArticles, articleId];\n\n const payload: SessionJWTPayload = {\n sub: session.walletAddress,\n sid: session.id,\n articles: updatedArticles,\n siteWide: session.siteWideUnlock,\n iat: session.createdAt,\n exp: session.expiresAt,\n };\n\n const newToken = await new SignJWT(payload as unknown as Record<string, unknown>)\n .setProtectedHeader({ alg: 'HS256' })\n .sign(getSecretKey(secret));\n\n return {\n token: newToken,\n session: { ...session, unlockedArticles: updatedArticles },\n };\n}\n\n/**\n * Check if an article is unlocked for a session\n */\nexport async function isArticleUnlocked(\n token: string,\n articleId: string,\n secret: string\n): Promise<boolean> {\n if (!validateArticleId(articleId)) {\n return false;\n }\n\n const validation = await validateSession(token, secret);\n if (!validation.valid || !validation.session) {\n return false;\n }\n\n if (validation.session.siteWideUnlock) {\n return true;\n }\n\n return validation.session.unlockedArticles.includes(articleId);\n}\n","// x402 payment configuration and helpers\n// SECURITY: Input sanitization for payment requirements\nimport type { PaymentRequirement, X402Network, SolanaNetwork } from '../types';\nimport { toX402Network } from '../solana';\n\n// Wallet address validation regex\nconst WALLET_REGEX = /^[1-9A-HJ-NP-Za-km-z]{32,44}$/;\n\n/** Parameters for building a payment requirement */\nexport interface BuildPaymentParams {\n /** Unique article identifier */\n articleId: string;\n /** Article title for display */\n articleTitle: string;\n /** Price in lamports */\n priceInLamports: bigint;\n /** Creator wallet address */\n creatorWallet: string;\n /** Full URL of the protected resource */\n resourceUrl: string;\n /** Solana network */\n network: SolanaNetwork;\n /** Max time to complete payment (default: 300s) */\n maxTimeoutSeconds?: number;\n}\n\n/**\n * Sanitize string for safe display (prevent XSS in UIs)\n */\nfunction sanitizeDisplayString(str: string, maxLength: number = 200): string {\n if (!str || typeof str !== 'string') return '';\n return str.slice(0, maxLength).replace(/[<>\"'&]/g, '');\n}\n\n/**\n * Validate URL format\n */\nfunction isValidUrl(url: string): boolean {\n try {\n const parsed = new URL(url);\n return parsed.protocol === 'http:' || parsed.protocol === 'https:';\n } catch {\n return false;\n }\n}\n\n/**\n * Build a payment requirement for an article\n * SECURITY: Validates all inputs before building requirement\n */\nexport function buildPaymentRequirement(params: BuildPaymentParams): PaymentRequirement {\n // Validate wallet address\n if (!WALLET_REGEX.test(params.creatorWallet)) {\n throw new Error('Invalid creator wallet address');\n }\n\n // Validate price\n if (params.priceInLamports <= 0n) {\n throw new Error('Price must be positive');\n }\n\n // Validate URL\n if (!isValidUrl(params.resourceUrl)) {\n throw new Error('Invalid resource URL');\n }\n\n // Validate network\n if (params.network !== 'devnet' && params.network !== 'mainnet-beta') {\n throw new Error('Invalid network');\n }\n\n // Validate timeout\n const timeout = params.maxTimeoutSeconds ?? 300;\n if (timeout < 60 || timeout > 3600) {\n throw new Error('Timeout must be between 60 and 3600 seconds');\n }\n\n const x402Network = toX402Network(params.network);\n\n // Sanitize display strings\n const safeTitle = sanitizeDisplayString(params.articleTitle, 200);\n const safeArticleId = sanitizeDisplayString(params.articleId, 128);\n\n return {\n scheme: 'exact',\n network: x402Network,\n maxAmountRequired: params.priceInLamports.toString(),\n resource: params.resourceUrl,\n description: `Unlock: ${safeTitle}`,\n mimeType: 'text/html',\n payTo: params.creatorWallet,\n maxTimeoutSeconds: timeout,\n asset: 'native',\n extra: {\n name: safeTitle,\n articleId: safeArticleId,\n },\n };\n}\n\n/**\n * Encode payment requirement for x402 header\n */\nexport function encodePaymentRequired(requirement: PaymentRequirement): string {\n return Buffer.from(JSON.stringify(requirement)).toString('base64');\n}\n\n/**\n * Decode payment requirement from x402 header\n * SECURITY: Safe parsing with size limit\n */\nexport function decodePaymentRequired(encoded: string): PaymentRequirement {\n if (!encoded || typeof encoded !== 'string') {\n throw new Error('Invalid encoded requirement');\n }\n\n // SECURITY: Limit size to prevent DoS\n if (encoded.length > 10000) {\n throw new Error('Encoded requirement too large');\n }\n\n try {\n const decoded = Buffer.from(encoded, 'base64').toString('utf-8');\n return JSON.parse(decoded);\n } catch {\n throw new Error('Failed to decode payment requirement');\n }\n}\n\n/**\n * x402 response header names\n */\nexport const X402_HEADERS = {\n PAYMENT_REQUIRED: 'X-Payment-Required',\n PAYMENT: 'X-Payment',\n PAYMENT_RESPONSE: 'X-Payment-Response',\n} as const;\n\n/**\n * Create 402 Payment Required response body\n */\nexport function create402ResponseBody(requirement: PaymentRequirement): {\n error: string;\n message: string;\n price: { amount: string; asset: string; network: X402Network };\n} {\n return {\n error: 'Payment Required',\n message: requirement.description,\n price: {\n amount: requirement.maxAmountRequired,\n asset: requirement.asset,\n network: requirement.network,\n },\n };\n}\n\n/**\n * Create headers for 402 response\n */\nexport function create402Headers(requirement: PaymentRequirement): Record<string, string> {\n const encoded = encodePaymentRequired(requirement);\n return {\n 'Content-Type': 'application/json',\n [X402_HEADERS.PAYMENT_REQUIRED]: encoded,\n 'Access-Control-Expose-Headers': X402_HEADERS.PAYMENT_REQUIRED,\n };\n}\n","// x402 payment verification service\n// SECURITY: Input validation, network verification, on-chain settlement check\nimport { verifyPayment, type SolanaClientConfig } from '../solana';\nimport type { PaymentPayload, PaymentRequirement, VerificationResponse } from '../types';\n\n// Signature validation regex (base58, 87-88 chars)\nconst SIGNATURE_REGEX = /^[1-9A-HJ-NP-Za-km-z]{87,88}$/;\n\n/**\n * Verify a payment payload against requirements\n * SECURITY: Full validation chain - format, network, on-chain\n */\nexport async function verifyX402Payment(\n payload: PaymentPayload,\n requirement: PaymentRequirement,\n clientConfig: SolanaClientConfig\n): Promise<VerificationResponse> {\n // SECURITY: Validate payload exists\n if (!payload || typeof payload !== 'object') {\n return { valid: false, invalidReason: 'Invalid payload' };\n }\n\n // SECURITY: Validate signature exists and format\n const signature = payload.payload?.signature;\n if (!signature || typeof signature !== 'string') {\n return { valid: false, invalidReason: 'Missing transaction signature' };\n }\n if (!SIGNATURE_REGEX.test(signature)) {\n return { valid: false, invalidReason: 'Invalid signature format' };\n }\n\n // SECURITY: Validate x402 version\n if (payload.x402Version !== 1) {\n return { valid: false, invalidReason: 'Unsupported x402 version' };\n }\n\n // SECURITY: Validate scheme\n if (payload.scheme !== 'exact') {\n return { valid: false, invalidReason: 'Unsupported payment scheme' };\n }\n\n // SECURITY: Validate network matches exactly\n if (payload.network !== requirement.network) {\n return {\n valid: false,\n invalidReason: `Network mismatch: expected ${requirement.network}`,\n };\n }\n\n // SECURITY: Validate requirement has valid payTo address\n const walletRegex = /^[1-9A-HJ-NP-Za-km-z]{32,44}$/;\n if (!walletRegex.test(requirement.payTo)) {\n return { valid: false, invalidReason: 'Invalid recipient configuration' };\n }\n\n // SECURITY: Validate amount is positive\n let expectedAmount: bigint;\n try {\n expectedAmount = BigInt(requirement.maxAmountRequired);\n if (expectedAmount <= 0n) {\n return { valid: false, invalidReason: 'Invalid payment amount' };\n }\n } catch {\n return { valid: false, invalidReason: 'Invalid payment amount format' };\n }\n\n // Verify on-chain\n const verification = await verifyPayment({\n signature,\n expectedRecipient: requirement.payTo,\n expectedAmount,\n maxAgeSeconds: requirement.maxTimeoutSeconds,\n clientConfig,\n });\n\n if (!verification.valid) {\n return {\n valid: false,\n invalidReason: verification.error || 'Transaction verification failed',\n };\n }\n\n return {\n valid: true,\n settled: verification.confirmed,\n transaction: {\n signature: verification.signature,\n blockTime: verification.blockTime,\n slot: verification.slot,\n },\n };\n}\n\n/**\n * Parse payment payload from x402 header\n * SECURITY: Safe JSON parsing with try-catch\n */\nexport function parsePaymentHeader(header: string): PaymentPayload | null {\n if (!header || typeof header !== 'string') {\n return null;\n }\n\n // SECURITY: Limit header size to prevent DoS\n if (header.length > 10000) {\n return null;\n }\n\n try {\n const decoded = Buffer.from(header, 'base64').toString('utf-8');\n const parsed = JSON.parse(decoded);\n\n // Basic structure validation\n if (!parsed || typeof parsed !== 'object') {\n return null;\n }\n\n return parsed as PaymentPayload;\n } catch {\n return null;\n }\n}\n\n/**\n * Encode payment response for header\n */\nexport function encodePaymentResponse(response: VerificationResponse): string {\n return Buffer.from(JSON.stringify(response)).toString('base64');\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/types/payment.ts","../src/solana/client.ts","../src/solana/verification.ts","../src/solana/spl.ts","../src/session/core.ts","../src/x402/config.ts","../src/x402/verification.ts","../src/store/memory.ts","../src/store/redis.ts","../src/middleware/nextjs.ts","../src/utils/retry.ts","../src/client/payment.ts","../src/pricing/index.ts"],"names":["config","clusterApiUrl","Connection","PublicKey","LAMPORTS_PER_SOL","SIGNATURE_REGEX","WALLET_REGEX","uuidv4","SignJWT","jwtVerify"],"mappings":"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","file":"index.cjs","sourcesContent":["// Payment-related TypeScript types for x402 protocol\n\n/** x402 network identifiers for Solana */\nexport type X402Network = 'solana-devnet' | 'solana-mainnet';\n\n/** Solana network types */\nexport type SolanaNetwork = 'devnet' | 'mainnet-beta';\n\n/** SPL Token asset specification */\nexport interface SPLTokenAsset {\n /** Token mint address */\n mint: string;\n /** Token decimals (default: 6 for USDC/USDT) */\n decimals?: number;\n}\n\n/** Asset types for payments */\nexport type PaymentAsset = 'native' | 'usdc' | 'usdt' | SPLTokenAsset;\n\n/** Known SPL token mint addresses */\nexport const TOKEN_MINTS = {\n /** USDC on mainnet */\n USDC_MAINNET: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',\n /** USDC on devnet */\n USDC_DEVNET: '4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU',\n /** USDT on mainnet */\n USDT_MAINNET: 'Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB',\n} as const;\n\n/** Payment requirement for x402 protocol */\nexport interface PaymentRequirement {\n /** Payment scheme - currently only 'exact' is supported */\n scheme: 'exact';\n /** Network identifier for x402 */\n network: X402Network;\n /** Amount in smallest unit as string (lamports for SOL, base units for tokens) */\n maxAmountRequired: string;\n /** URL of the protected resource */\n resource: string;\n /** Human-readable description */\n description: string;\n /** MIME type of the resource */\n mimeType?: string;\n /** Recipient wallet address */\n payTo: string;\n /** Maximum time in seconds to complete payment */\n maxTimeoutSeconds: number;\n /** Asset type - 'native' for SOL, 'usdc', 'usdt', or custom mint */\n asset: PaymentAsset;\n /** Additional metadata */\n extra?: {\n name?: string;\n articleId?: string;\n [key: string]: unknown;\n };\n}\n\n/** Payment payload sent by client after transaction */\nexport interface PaymentPayload {\n /** x402 protocol version */\n x402Version: number;\n /** Payment scheme */\n scheme: 'exact';\n /** Network identifier */\n network: X402Network;\n /** Transaction details */\n payload: {\n /** Transaction signature (base58) */\n signature: string;\n /** Base64 encoded transaction (optional) */\n transaction?: string;\n };\n}\n\n/** Request to verify a payment */\nexport interface VerificationRequest {\n paymentPayload: PaymentPayload;\n paymentRequirements: PaymentRequirement;\n}\n\n/** Response from payment verification */\nexport interface VerificationResponse {\n /** Whether the payment is valid */\n valid: boolean;\n /** Reason for invalid payment */\n invalidReason?: string;\n /** Whether the transaction is settled on-chain */\n settled?: boolean;\n /** Transaction details */\n transaction?: {\n signature: string;\n blockTime?: number;\n slot?: number;\n };\n}\n\n/** Payment status for tracking */\nexport interface PaymentStatus {\n status: 'pending' | 'confirmed' | 'failed' | 'expired';\n signature?: string;\n confirmations?: number;\n error?: string;\n}\n\n/** x402 HTTP header constants */\nexport const X402_HEADERS = {\n PAYMENT_REQUIRED: 'x-payment-required',\n PAYMENT: 'x-payment',\n PAYMENT_RESPONSE: 'x-payment-response',\n} as const;\n\n/** Configuration for article pricing */\nexport interface ArticlePaymentConfig {\n articleId: string;\n priceInLamports: bigint;\n title: string;\n description?: string;\n}\n","// Solana RPC client with multi-provider support\nimport { Connection, clusterApiUrl, type Cluster } from '@solana/web3.js';\nimport type { SolanaNetwork } from '../types';\n\n/** Configuration for Solana client */\nexport interface SolanaClientConfig {\n /** Network to connect to */\n network: SolanaNetwork;\n /** Custom RPC URL (optional) */\n rpcUrl?: string;\n /** Tatum.io API key for RPC (optional) */\n tatumApiKey?: string;\n}\n\n// Singleton state\nlet cachedConnection: Connection | null = null;\nlet cachedNetwork: SolanaNetwork | null = null;\n\n/**\n * Build RPC URL based on configuration priority:\n * 1. Custom RPC URL\n * 2. Tatum.io with API key\n * 3. Public RPC (rate limited)\n */\nfunction buildRpcUrl(config: SolanaClientConfig): string {\n const { network, rpcUrl, tatumApiKey } = config;\n\n if (rpcUrl) {\n // If Tatum URL without key, append key if available\n if (rpcUrl.includes('tatum.io') && tatumApiKey && !rpcUrl.includes(tatumApiKey)) {\n return rpcUrl.endsWith('/') ? `${rpcUrl}${tatumApiKey}` : `${rpcUrl}/${tatumApiKey}`;\n }\n return rpcUrl;\n }\n\n if (tatumApiKey) {\n const baseUrl = network === 'mainnet-beta'\n ? 'https://solana-mainnet.gateway.tatum.io'\n : 'https://solana-devnet.gateway.tatum.io';\n return `${baseUrl}/${tatumApiKey}`;\n }\n\n // Fallback to public RPC\n return clusterApiUrl(network as Cluster);\n}\n\n/**\n * Get or create a Solana connection\n * Uses singleton pattern with network-aware caching\n */\nexport function getConnection(config: SolanaClientConfig): Connection {\n const { network } = config;\n\n // Return cached if same network\n if (cachedConnection && cachedNetwork === network) {\n return cachedConnection;\n }\n\n const rpcUrl = buildRpcUrl(config);\n\n cachedConnection = new Connection(rpcUrl, {\n commitment: 'confirmed',\n confirmTransactionInitialTimeout: 60000,\n });\n cachedNetwork = network;\n\n return cachedConnection;\n}\n\n/**\n * Reset the cached connection\n * Useful for testing or network switching\n */\nexport function resetConnection(): void {\n cachedConnection = null;\n cachedNetwork = null;\n}\n\n/**\n * Check if network is mainnet\n */\nexport function isMainnet(network: SolanaNetwork): boolean {\n return network === 'mainnet-beta';\n}\n\n/**\n * Convert Solana network to x402 network identifier\n */\nexport function toX402Network(network: SolanaNetwork): 'solana-devnet' | 'solana-mainnet' {\n return network === 'mainnet-beta' ? 'solana-mainnet' : 'solana-devnet';\n}\n","// Transaction verification for SOL payments\n// SECURITY: On-chain verification, signature validation, replay protection\nimport { PublicKey, LAMPORTS_PER_SOL, type ParsedTransactionWithMeta } from '@solana/web3.js';\nimport { getConnection, type SolanaClientConfig } from './client';\n\n/** Result of transaction verification */\nexport interface TransactionVerificationResult {\n /** Whether the transaction is valid for the payment */\n valid: boolean;\n /** Whether the transaction is confirmed on-chain */\n confirmed: boolean;\n /** Transaction signature */\n signature: string;\n /** Sender wallet address */\n from?: string;\n /** Recipient wallet address */\n to?: string;\n /** Amount transferred in lamports */\n amount?: bigint;\n /** Block time (Unix timestamp) */\n blockTime?: number;\n /** Slot number */\n slot?: number;\n /** Error message if verification failed */\n error?: string;\n}\n\n/** Parameters for verifying a payment */\nexport interface VerifyPaymentParams {\n /** Transaction signature to verify */\n signature: string;\n /** Expected recipient wallet address */\n expectedRecipient: string;\n /** Expected amount in lamports */\n expectedAmount: bigint;\n /** Maximum age of transaction in seconds (default: 300) */\n maxAgeSeconds?: number;\n /** Solana client configuration */\n clientConfig: SolanaClientConfig;\n}\n\n// Signature validation regex (base58, 87-88 chars)\nconst SIGNATURE_REGEX = /^[1-9A-HJ-NP-Za-km-z]{87,88}$/;\n\n// Wallet address validation regex\nconst WALLET_REGEX = /^[1-9A-HJ-NP-Za-km-z]{32,44}$/;\n\n/**\n * Validate transaction signature format\n * SECURITY: Prevents malformed signatures from reaching RPC\n */\nfunction isValidSignature(signature: string): boolean {\n if (!signature || typeof signature !== 'string') return false;\n return SIGNATURE_REGEX.test(signature);\n}\n\n/**\n * Validate wallet address format\n * SECURITY: Ensures valid base58 address\n */\nfunction isValidWalletAddress(address: string): boolean {\n if (!address || typeof address !== 'string') return false;\n return WALLET_REGEX.test(address);\n}\n\n/**\n * Parse SOL transfer details from a transaction\n */\nfunction parseSOLTransfer(\n transaction: ParsedTransactionWithMeta,\n expectedRecipient: string\n): { from: string; to: string; amount: bigint } | null {\n const instructions = transaction.transaction.message.instructions;\n\n // Check main instructions\n for (const ix of instructions) {\n if ('parsed' in ix && ix.program === 'system') {\n const parsed = ix.parsed as {\n type: string;\n info: { source: string; destination: string; lamports: number }\n };\n\n if (parsed.type === 'transfer' && parsed.info.destination === expectedRecipient) {\n return {\n from: parsed.info.source,\n to: parsed.info.destination,\n amount: BigInt(parsed.info.lamports),\n };\n }\n }\n }\n\n // Check inner instructions\n if (transaction.meta?.innerInstructions) {\n for (const inner of transaction.meta.innerInstructions) {\n for (const ix of inner.instructions) {\n if ('parsed' in ix && ix.program === 'system') {\n const parsed = ix.parsed as {\n type: string;\n info: { source: string; destination: string; lamports: number }\n };\n\n if (parsed.type === 'transfer' && parsed.info.destination === expectedRecipient) {\n return {\n from: parsed.info.source,\n to: parsed.info.destination,\n amount: BigInt(parsed.info.lamports),\n };\n }\n }\n }\n }\n }\n\n return null;\n}\n\n/**\n * Verify a SOL transfer transaction\n * SECURITY: Full on-chain verification with amount/recipient/age checks\n */\nexport async function verifyPayment(\n params: VerifyPaymentParams\n): Promise<TransactionVerificationResult> {\n const {\n signature,\n expectedRecipient,\n expectedAmount,\n maxAgeSeconds = 300,\n clientConfig\n } = params;\n\n // SECURITY: Validate signature format before RPC call\n if (!isValidSignature(signature)) {\n return { valid: false, confirmed: false, signature, error: 'Invalid signature format' };\n }\n\n // SECURITY: Validate recipient address format\n if (!isValidWalletAddress(expectedRecipient)) {\n return { valid: false, confirmed: false, signature, error: 'Invalid recipient address' };\n }\n\n // SECURITY: Validate expected amount is positive\n if (expectedAmount <= 0n) {\n return { valid: false, confirmed: false, signature, error: 'Invalid expected amount' };\n }\n\n // SECURITY: Enforce reasonable max age (prevent replay with very old transactions)\n const effectiveMaxAge = Math.min(Math.max(maxAgeSeconds, 60), 3600); // 1 min to 1 hour\n\n const connection = getConnection(clientConfig);\n\n try {\n const transaction = await connection.getParsedTransaction(signature, {\n commitment: 'confirmed',\n maxSupportedTransactionVersion: 0,\n });\n\n if (!transaction) {\n return { valid: false, confirmed: false, signature, error: 'Transaction not found' };\n }\n\n // Check for transaction errors\n if (transaction.meta?.err) {\n return {\n valid: false,\n confirmed: true,\n signature,\n error: 'Transaction failed on-chain',\n };\n }\n\n // SECURITY: Validate transaction age (replay protection)\n if (transaction.blockTime) {\n const now = Math.floor(Date.now() / 1000);\n if (now - transaction.blockTime > effectiveMaxAge) {\n return { valid: false, confirmed: true, signature, error: 'Transaction too old' };\n }\n // Also reject future-dated transactions (clock skew attack)\n if (transaction.blockTime > now + 60) {\n return { valid: false, confirmed: true, signature, error: 'Invalid transaction time' };\n }\n }\n\n // Parse transfer details\n const transferDetails = parseSOLTransfer(transaction, expectedRecipient);\n\n if (!transferDetails) {\n return {\n valid: false,\n confirmed: true,\n signature,\n error: 'No valid SOL transfer to recipient found',\n };\n }\n\n // SECURITY: Validate amount (must meet or exceed expected)\n if (transferDetails.amount < expectedAmount) {\n return {\n valid: false,\n confirmed: true,\n signature,\n from: transferDetails.from,\n to: transferDetails.to,\n amount: transferDetails.amount,\n error: 'Insufficient payment amount',\n };\n }\n\n return {\n valid: true,\n confirmed: true,\n signature,\n from: transferDetails.from,\n to: transferDetails.to,\n amount: transferDetails.amount,\n blockTime: transaction.blockTime ?? undefined,\n slot: transaction.slot,\n };\n } catch (error) {\n // SECURITY: Don't expose internal error details\n return {\n valid: false,\n confirmed: false,\n signature,\n error: 'Verification failed',\n };\n }\n}\n\n/**\n * Wait for transaction confirmation\n */\nexport async function waitForConfirmation(\n signature: string,\n clientConfig: SolanaClientConfig\n): Promise<{ confirmed: boolean; slot?: number; error?: string }> {\n if (!isValidSignature(signature)) {\n return { confirmed: false, error: 'Invalid signature format' };\n }\n\n const connection = getConnection(clientConfig);\n\n try {\n const confirmation = await connection.confirmTransaction(signature, 'confirmed');\n\n if (confirmation.value.err) {\n return { confirmed: false, error: 'Transaction failed' };\n }\n\n return { confirmed: true, slot: confirmation.context?.slot };\n } catch {\n return { confirmed: false, error: 'Confirmation timeout' };\n }\n}\n\n/**\n * Get recent transactions for a wallet\n */\nexport async function getWalletTransactions(\n walletAddress: string,\n clientConfig: SolanaClientConfig,\n limit: number = 20\n): Promise<Array<{ signature: string; blockTime?: number; slot: number }>> {\n if (!isValidWalletAddress(walletAddress)) {\n return [];\n }\n\n // SECURITY: Cap limit to prevent abuse\n const safeLimit = Math.min(Math.max(limit, 1), 100);\n\n const connection = getConnection(clientConfig);\n\n try {\n const pubkey = new PublicKey(walletAddress);\n const signatures = await connection.getSignaturesForAddress(pubkey, { limit: safeLimit });\n return signatures.map((sig) => ({\n signature: sig.signature,\n blockTime: sig.blockTime ?? undefined,\n slot: sig.slot,\n }));\n } catch {\n return [];\n }\n}\n\n/**\n * Convert lamports to SOL\n */\nexport function lamportsToSol(lamports: bigint | number): number {\n return Number(lamports) / LAMPORTS_PER_SOL;\n}\n\n/**\n * Convert SOL to lamports\n */\nexport function solToLamports(sol: number): bigint {\n if (!Number.isFinite(sol) || sol < 0) {\n throw new Error('Invalid SOL amount');\n }\n return BigInt(Math.floor(sol * LAMPORTS_PER_SOL));\n}\n","// SPL Token payment verification\n// SECURITY: On-chain verification for SPL token transfers (USDC, USDT, custom)\nimport { type ParsedTransactionWithMeta } from '@solana/web3.js';\nimport { getConnection, type SolanaClientConfig } from './client';\nimport { TOKEN_MINTS, type PaymentAsset } from '../types';\n\n/** Result of SPL token transfer verification */\nexport interface SPLVerificationResult {\n /** Whether the transfer is valid */\n valid: boolean;\n /** Whether transaction is confirmed */\n confirmed: boolean;\n /** Transaction signature */\n signature: string;\n /** Sender wallet address */\n from?: string;\n /** Recipient wallet address */\n to?: string;\n /** Token mint address */\n mint?: string;\n /** Amount transferred (in token's smallest unit) */\n amount?: bigint;\n /** Block time */\n blockTime?: number;\n /** Slot number */\n slot?: number;\n /** Error message */\n error?: string;\n}\n\n/** Parameters for SPL payment verification */\nexport interface VerifySPLPaymentParams {\n /** Transaction signature */\n signature: string;\n /** Expected recipient wallet */\n expectedRecipient: string;\n /** Expected amount in token's smallest unit */\n expectedAmount: bigint;\n /** Asset specification */\n asset: PaymentAsset;\n /** Solana network config */\n clientConfig: SolanaClientConfig;\n /** Maximum transaction age in seconds */\n maxAgeSeconds?: number;\n}\n\n// Signature validation regex\nconst SIGNATURE_REGEX = /^[1-9A-HJ-NP-Za-km-z]{87,88}$/;\nconst WALLET_REGEX = /^[1-9A-HJ-NP-Za-km-z]{32,44}$/;\n\n/**\n * Resolve asset to mint address\n */\nexport function resolveMintAddress(asset: PaymentAsset, network: 'devnet' | 'mainnet-beta'): string | null {\n if (asset === 'native') return null;\n\n if (asset === 'usdc') {\n return network === 'mainnet-beta' ? TOKEN_MINTS.USDC_MAINNET : TOKEN_MINTS.USDC_DEVNET;\n }\n\n if (asset === 'usdt') {\n return TOKEN_MINTS.USDT_MAINNET; // USDT only on mainnet\n }\n\n if (typeof asset === 'object' && 'mint' in asset) {\n return asset.mint;\n }\n\n return null;\n}\n\n/**\n * Get token decimals for an asset\n */\nexport function getTokenDecimals(asset: PaymentAsset): number {\n if (asset === 'native') return 9; // SOL\n if (asset === 'usdc' || asset === 'usdt') return 6;\n if (typeof asset === 'object' && 'decimals' in asset) {\n return asset.decimals ?? 6;\n }\n return 6; // Default for SPL tokens\n}\n\n/**\n * Parse SPL token transfer from transaction\n * Handles Token Program transfers to the expected recipient\n */\nfunction parseSPLTransfer(\n transaction: ParsedTransactionWithMeta,\n expectedRecipient: string,\n expectedMint: string\n): { from: string; to: string; amount: bigint; mint: string } | null {\n const instructions = transaction.transaction.message.instructions;\n\n // Check main instructions for Token Program transfers\n for (const ix of instructions) {\n if ('parsed' in ix && (ix.program === 'spl-token' || ix.program === 'spl-token-2022')) {\n const parsed = ix.parsed as {\n type: string;\n info: {\n source?: string;\n destination?: string;\n authority?: string;\n amount?: string;\n tokenAmount?: { amount: string; decimals: number };\n mint?: string;\n };\n };\n\n // Handle 'transfer' and 'transferChecked' instructions\n if (parsed.type === 'transfer' || parsed.type === 'transferChecked') {\n const amount = parsed.info.amount || parsed.info.tokenAmount?.amount;\n\n if (amount && parsed.info.destination) {\n // We need to resolve the token account to the owner wallet\n // For now, accept if destination matches expected recipient's token account\n return {\n from: parsed.info.authority || parsed.info.source || '',\n to: parsed.info.destination,\n amount: BigInt(amount),\n mint: parsed.info.mint || expectedMint,\n };\n }\n }\n }\n }\n\n // Check inner instructions\n if (transaction.meta?.innerInstructions) {\n for (const inner of transaction.meta.innerInstructions) {\n for (const ix of inner.instructions) {\n if ('parsed' in ix && (ix.program === 'spl-token' || ix.program === 'spl-token-2022')) {\n const parsed = ix.parsed as {\n type: string;\n info: {\n source?: string;\n destination?: string;\n authority?: string;\n amount?: string;\n tokenAmount?: { amount: string };\n mint?: string;\n };\n };\n\n if (parsed.type === 'transfer' || parsed.type === 'transferChecked') {\n const amount = parsed.info.amount || parsed.info.tokenAmount?.amount;\n if (amount) {\n return {\n from: parsed.info.authority || parsed.info.source || '',\n to: parsed.info.destination || '',\n amount: BigInt(amount),\n mint: parsed.info.mint || expectedMint,\n };\n }\n }\n }\n }\n }\n }\n\n // Check post token balances for transfers\n if (transaction.meta?.postTokenBalances && transaction.meta?.preTokenBalances) {\n const preBalances = transaction.meta.preTokenBalances;\n const postBalances = transaction.meta.postTokenBalances;\n\n for (const post of postBalances) {\n if (post.mint === expectedMint && post.owner === expectedRecipient) {\n const pre = preBalances.find(\n (p) => p.accountIndex === post.accountIndex\n );\n const preAmount = BigInt(pre?.uiTokenAmount?.amount || '0');\n const postAmount = BigInt(post.uiTokenAmount?.amount || '0');\n const transferred = postAmount - preAmount;\n\n if (transferred > 0n) {\n return {\n from: '', // Can't determine from balance changes\n to: expectedRecipient,\n amount: transferred,\n mint: expectedMint,\n };\n }\n }\n }\n }\n\n return null;\n}\n\n/**\n * Verify an SPL token transfer\n * SECURITY: Full on-chain verification with amount/recipient/mint checks\n */\nexport async function verifySPLPayment(\n params: VerifySPLPaymentParams\n): Promise<SPLVerificationResult> {\n const {\n signature,\n expectedRecipient,\n expectedAmount,\n asset,\n clientConfig,\n maxAgeSeconds = 300,\n } = params;\n\n // Validate signature format\n if (!SIGNATURE_REGEX.test(signature)) {\n return { valid: false, confirmed: false, signature, error: 'Invalid signature format' };\n }\n\n // Validate recipient\n if (!WALLET_REGEX.test(expectedRecipient)) {\n return { valid: false, confirmed: false, signature, error: 'Invalid recipient address' };\n }\n\n // Resolve mint address\n const mintAddress = resolveMintAddress(asset, clientConfig.network);\n if (!mintAddress) {\n return { valid: false, confirmed: false, signature, error: 'Invalid asset configuration' };\n }\n\n // Validate amount\n if (expectedAmount <= 0n) {\n return { valid: false, confirmed: false, signature, error: 'Invalid expected amount' };\n }\n\n const effectiveMaxAge = Math.min(Math.max(maxAgeSeconds, 60), 3600);\n const connection = getConnection(clientConfig);\n\n try {\n const transaction = await connection.getParsedTransaction(signature, {\n commitment: 'confirmed',\n maxSupportedTransactionVersion: 0,\n });\n\n if (!transaction) {\n return { valid: false, confirmed: false, signature, error: 'Transaction not found' };\n }\n\n if (transaction.meta?.err) {\n return { valid: false, confirmed: true, signature, error: 'Transaction failed on-chain' };\n }\n\n // Validate age\n if (transaction.blockTime) {\n const now = Math.floor(Date.now() / 1000);\n if (now - transaction.blockTime > effectiveMaxAge) {\n return { valid: false, confirmed: true, signature, error: 'Transaction too old' };\n }\n if (transaction.blockTime > now + 60) {\n return { valid: false, confirmed: true, signature, error: 'Invalid transaction time' };\n }\n }\n\n // Parse transfer\n const transfer = parseSPLTransfer(transaction, expectedRecipient, mintAddress);\n if (!transfer) {\n return {\n valid: false,\n confirmed: true,\n signature,\n error: 'No valid token transfer to recipient found',\n };\n }\n\n // Validate mint matches\n if (transfer.mint !== mintAddress) {\n return {\n valid: false,\n confirmed: true,\n signature,\n error: 'Token mint mismatch',\n };\n }\n\n // Validate amount\n if (transfer.amount < expectedAmount) {\n return {\n valid: false,\n confirmed: true,\n signature,\n from: transfer.from,\n to: transfer.to,\n mint: transfer.mint,\n amount: transfer.amount,\n error: 'Insufficient payment amount',\n };\n }\n\n return {\n valid: true,\n confirmed: true,\n signature,\n from: transfer.from,\n to: transfer.to,\n mint: transfer.mint,\n amount: transfer.amount,\n blockTime: transaction.blockTime ?? undefined,\n slot: transaction.slot,\n };\n } catch {\n return { valid: false, confirmed: false, signature, error: 'Verification failed' };\n }\n}\n\n/**\n * Check if asset is native SOL\n */\nexport function isNativeAsset(asset: PaymentAsset): asset is 'native' {\n return asset === 'native';\n}\n","// Session management with JWT (framework-agnostic core)\n// SECURITY: Uses jose library with HS256, constant-time validation, input sanitization\nimport { SignJWT, jwtVerify } from 'jose';\nimport { v4 as uuidv4 } from 'uuid';\nimport type { SessionData, SessionConfig, SessionValidation, SessionJWTPayload } from '../types';\n\n// Maximum articles per session to prevent unbounded growth\nconst MAX_ARTICLES_PER_SESSION = 100;\n\n// Minimum secret length for security\nconst MIN_SECRET_LENGTH = 32;\n\n/**\n * Get the secret key for JWT signing\n * SECURITY: Enforces minimum secret length\n */\nfunction getSecretKey(secret: string): Uint8Array {\n if (!secret || typeof secret !== 'string') {\n throw new Error('Session secret is required');\n }\n if (secret.length < MIN_SECRET_LENGTH) {\n throw new Error(`Session secret must be at least ${MIN_SECRET_LENGTH} characters`);\n }\n return new TextEncoder().encode(secret);\n}\n\n/**\n * Validate wallet address format (base58, 32-44 chars)\n * SECURITY: Prevents injection via wallet address field\n */\nfunction validateWalletAddress(address: string): boolean {\n if (!address || typeof address !== 'string') return false;\n // Solana addresses are base58, typically 32-44 characters\n const base58Regex = /^[1-9A-HJ-NP-Za-km-z]{32,44}$/;\n return base58Regex.test(address);\n}\n\n/**\n * Validate article ID format\n * SECURITY: Prevents injection via articleId field\n */\nfunction validateArticleId(articleId: string): boolean {\n if (!articleId || typeof articleId !== 'string') return false;\n // Allow alphanumeric, hyphens, underscores, max 128 chars\n if (articleId.length > 128) return false;\n const safeIdRegex = /^[a-zA-Z0-9_-]+$/;\n return safeIdRegex.test(articleId);\n}\n\n/**\n * Create a new session after successful payment\n * SECURITY: Validates inputs, enforces limits\n */\nexport async function createSession(\n walletAddress: string,\n articleId: string,\n config: SessionConfig,\n siteWide: boolean = false\n): Promise<{ token: string; session: SessionData }> {\n // Input validation\n if (!validateWalletAddress(walletAddress)) {\n throw new Error('Invalid wallet address format');\n }\n if (!validateArticleId(articleId)) {\n throw new Error('Invalid article ID format');\n }\n if (!config.durationHours || config.durationHours <= 0 || config.durationHours > 720) {\n throw new Error('Session duration must be between 1 and 720 hours');\n }\n\n const sessionId = uuidv4();\n const now = Math.floor(Date.now() / 1000);\n const expiresAt = now + (config.durationHours * 3600);\n\n const session: SessionData = {\n id: sessionId,\n walletAddress,\n unlockedArticles: [articleId],\n siteWideUnlock: Boolean(siteWide),\n createdAt: now,\n expiresAt,\n };\n\n const payload: SessionJWTPayload = {\n sub: walletAddress,\n sid: sessionId,\n articles: session.unlockedArticles,\n siteWide: session.siteWideUnlock,\n iat: now,\n exp: expiresAt,\n };\n\n const token = await new SignJWT(payload as unknown as Record<string, unknown>)\n .setProtectedHeader({ alg: 'HS256' })\n .setIssuedAt()\n .setExpirationTime(`${config.durationHours}h`)\n .sign(getSecretKey(config.secret));\n\n return { token, session };\n}\n\n/**\n * Validate an existing session token\n * SECURITY: jose library handles timing-safe comparison internally\n */\nexport async function validateSession(\n token: string,\n secret: string\n): Promise<SessionValidation> {\n // Input validation\n if (!token || typeof token !== 'string') {\n return { valid: false, reason: 'Invalid token format' };\n }\n\n try {\n const { payload } = await jwtVerify(token, getSecretKey(secret));\n const sessionPayload = payload as unknown as SessionJWTPayload;\n\n // Validate required fields exist\n if (!sessionPayload.sub || !sessionPayload.sid || !sessionPayload.exp) {\n return { valid: false, reason: 'Malformed session payload' };\n }\n\n // Check expiration (jose already checks, but double-check)\n const now = Math.floor(Date.now() / 1000);\n if (sessionPayload.exp < now) {\n return { valid: false, reason: 'Session expired' };\n }\n\n // Validate wallet address format from token\n if (!validateWalletAddress(sessionPayload.sub)) {\n return { valid: false, reason: 'Invalid session data' };\n }\n\n const session: SessionData = {\n id: sessionPayload.sid,\n walletAddress: sessionPayload.sub,\n unlockedArticles: Array.isArray(sessionPayload.articles) ? sessionPayload.articles : [],\n siteWideUnlock: Boolean(sessionPayload.siteWide),\n createdAt: sessionPayload.iat ?? 0,\n expiresAt: sessionPayload.exp,\n };\n\n return { valid: true, session };\n } catch (error) {\n // SECURITY: Don't expose internal error details\n return { valid: false, reason: 'Invalid session' };\n }\n}\n\n/**\n * Add an article to an existing session\n * SECURITY: Enforces article limit to prevent token bloat\n */\nexport async function addArticleToSession(\n token: string,\n articleId: string,\n secret: string\n): Promise<{ token: string; session: SessionData } | null> {\n // Validate article ID\n if (!validateArticleId(articleId)) {\n return null;\n }\n\n const validation = await validateSession(token, secret);\n if (!validation.valid || !validation.session) {\n return null;\n }\n\n const session = validation.session;\n\n // Already unlocked\n if (session.unlockedArticles.includes(articleId)) {\n return { token, session };\n }\n\n // SECURITY: Enforce maximum articles per session\n if (session.unlockedArticles.length >= MAX_ARTICLES_PER_SESSION) {\n return null;\n }\n\n const updatedArticles = [...session.unlockedArticles, articleId];\n\n const payload: SessionJWTPayload = {\n sub: session.walletAddress,\n sid: session.id,\n articles: updatedArticles,\n siteWide: session.siteWideUnlock,\n iat: session.createdAt,\n exp: session.expiresAt,\n };\n\n const newToken = await new SignJWT(payload as unknown as Record<string, unknown>)\n .setProtectedHeader({ alg: 'HS256' })\n .sign(getSecretKey(secret));\n\n return {\n token: newToken,\n session: { ...session, unlockedArticles: updatedArticles },\n };\n}\n\n/**\n * Check if an article is unlocked for a session\n */\nexport async function isArticleUnlocked(\n token: string,\n articleId: string,\n secret: string\n): Promise<boolean> {\n if (!validateArticleId(articleId)) {\n return false;\n }\n\n const validation = await validateSession(token, secret);\n if (!validation.valid || !validation.session) {\n return false;\n }\n\n if (validation.session.siteWideUnlock) {\n return true;\n }\n\n return validation.session.unlockedArticles.includes(articleId);\n}\n","// x402 payment configuration and helpers\n// SECURITY: Input sanitization for payment requirements\nimport type { PaymentRequirement, X402Network, SolanaNetwork } from '../types';\nimport { toX402Network } from '../solana';\n\n// Wallet address validation regex\nconst WALLET_REGEX = /^[1-9A-HJ-NP-Za-km-z]{32,44}$/;\n\n/** Parameters for building a payment requirement */\nexport interface BuildPaymentParams {\n /** Unique article identifier */\n articleId: string;\n /** Article title for display */\n articleTitle: string;\n /** Price in lamports */\n priceInLamports: bigint;\n /** Creator wallet address */\n creatorWallet: string;\n /** Full URL of the protected resource */\n resourceUrl: string;\n /** Solana network */\n network: SolanaNetwork;\n /** Max time to complete payment (default: 300s) */\n maxTimeoutSeconds?: number;\n}\n\n/**\n * Sanitize string for safe display (prevent XSS in UIs)\n */\nfunction sanitizeDisplayString(str: string, maxLength: number = 200): string {\n if (!str || typeof str !== 'string') return '';\n return str.slice(0, maxLength).replace(/[<>\"'&]/g, '');\n}\n\n/**\n * Validate URL format\n */\nfunction isValidUrl(url: string): boolean {\n try {\n const parsed = new URL(url);\n return parsed.protocol === 'http:' || parsed.protocol === 'https:';\n } catch {\n return false;\n }\n}\n\n/**\n * Build a payment requirement for an article\n * SECURITY: Validates all inputs before building requirement\n */\nexport function buildPaymentRequirement(params: BuildPaymentParams): PaymentRequirement {\n // Validate wallet address\n if (!WALLET_REGEX.test(params.creatorWallet)) {\n throw new Error('Invalid creator wallet address');\n }\n\n // Validate price\n if (params.priceInLamports <= 0n) {\n throw new Error('Price must be positive');\n }\n\n // Validate URL\n if (!isValidUrl(params.resourceUrl)) {\n throw new Error('Invalid resource URL');\n }\n\n // Validate network\n if (params.network !== 'devnet' && params.network !== 'mainnet-beta') {\n throw new Error('Invalid network');\n }\n\n // Validate timeout\n const timeout = params.maxTimeoutSeconds ?? 300;\n if (timeout < 60 || timeout > 3600) {\n throw new Error('Timeout must be between 60 and 3600 seconds');\n }\n\n const x402Network = toX402Network(params.network);\n\n // Sanitize display strings\n const safeTitle = sanitizeDisplayString(params.articleTitle, 200);\n const safeArticleId = sanitizeDisplayString(params.articleId, 128);\n\n return {\n scheme: 'exact',\n network: x402Network,\n maxAmountRequired: params.priceInLamports.toString(),\n resource: params.resourceUrl,\n description: `Unlock: ${safeTitle}`,\n mimeType: 'text/html',\n payTo: params.creatorWallet,\n maxTimeoutSeconds: timeout,\n asset: 'native',\n extra: {\n name: safeTitle,\n articleId: safeArticleId,\n },\n };\n}\n\n/**\n * Encode payment requirement for x402 header\n */\nexport function encodePaymentRequired(requirement: PaymentRequirement): string {\n return Buffer.from(JSON.stringify(requirement)).toString('base64');\n}\n\n/**\n * Decode payment requirement from x402 header\n * SECURITY: Safe parsing with size limit\n */\nexport function decodePaymentRequired(encoded: string): PaymentRequirement {\n if (!encoded || typeof encoded !== 'string') {\n throw new Error('Invalid encoded requirement');\n }\n\n // SECURITY: Limit size to prevent DoS\n if (encoded.length > 10000) {\n throw new Error('Encoded requirement too large');\n }\n\n try {\n const decoded = Buffer.from(encoded, 'base64').toString('utf-8');\n return JSON.parse(decoded);\n } catch {\n throw new Error('Failed to decode payment requirement');\n }\n}\n\n/**\n * x402 response header names\n */\nexport const X402_HEADERS = {\n PAYMENT_REQUIRED: 'X-Payment-Required',\n PAYMENT: 'X-Payment',\n PAYMENT_RESPONSE: 'X-Payment-Response',\n} as const;\n\n/**\n * Create 402 Payment Required response body\n */\nexport function create402ResponseBody(requirement: PaymentRequirement): {\n error: string;\n message: string;\n price: { amount: string; asset: string; network: X402Network };\n} {\n // Convert asset to string for JSON serialization\n const assetStr = typeof requirement.asset === 'string'\n ? requirement.asset\n : requirement.asset.mint;\n\n return {\n error: 'Payment Required',\n message: requirement.description,\n price: {\n amount: requirement.maxAmountRequired,\n asset: assetStr,\n network: requirement.network,\n },\n };\n}\n\n/**\n * Create headers for 402 response\n */\nexport function create402Headers(requirement: PaymentRequirement): Record<string, string> {\n const encoded = encodePaymentRequired(requirement);\n return {\n 'Content-Type': 'application/json',\n [X402_HEADERS.PAYMENT_REQUIRED]: encoded,\n 'Access-Control-Expose-Headers': X402_HEADERS.PAYMENT_REQUIRED,\n };\n}\n","// x402 payment verification service\n// SECURITY: Input validation, network verification, on-chain settlement check\nimport { verifyPayment, type SolanaClientConfig } from '../solana';\nimport type { PaymentPayload, PaymentRequirement, VerificationResponse } from '../types';\n\n// Signature validation regex (base58, 87-88 chars)\nconst SIGNATURE_REGEX = /^[1-9A-HJ-NP-Za-km-z]{87,88}$/;\n\n/**\n * Verify a payment payload against requirements\n * SECURITY: Full validation chain - format, network, on-chain\n */\nexport async function verifyX402Payment(\n payload: PaymentPayload,\n requirement: PaymentRequirement,\n clientConfig: SolanaClientConfig\n): Promise<VerificationResponse> {\n // SECURITY: Validate payload exists\n if (!payload || typeof payload !== 'object') {\n return { valid: false, invalidReason: 'Invalid payload' };\n }\n\n // SECURITY: Validate signature exists and format\n const signature = payload.payload?.signature;\n if (!signature || typeof signature !== 'string') {\n return { valid: false, invalidReason: 'Missing transaction signature' };\n }\n if (!SIGNATURE_REGEX.test(signature)) {\n return { valid: false, invalidReason: 'Invalid signature format' };\n }\n\n // SECURITY: Validate x402 version\n if (payload.x402Version !== 1) {\n return { valid: false, invalidReason: 'Unsupported x402 version' };\n }\n\n // SECURITY: Validate scheme\n if (payload.scheme !== 'exact') {\n return { valid: false, invalidReason: 'Unsupported payment scheme' };\n }\n\n // SECURITY: Validate network matches exactly\n if (payload.network !== requirement.network) {\n return {\n valid: false,\n invalidReason: `Network mismatch: expected ${requirement.network}`,\n };\n }\n\n // SECURITY: Validate requirement has valid payTo address\n const walletRegex = /^[1-9A-HJ-NP-Za-km-z]{32,44}$/;\n if (!walletRegex.test(requirement.payTo)) {\n return { valid: false, invalidReason: 'Invalid recipient configuration' };\n }\n\n // SECURITY: Validate amount is positive\n let expectedAmount: bigint;\n try {\n expectedAmount = BigInt(requirement.maxAmountRequired);\n if (expectedAmount <= 0n) {\n return { valid: false, invalidReason: 'Invalid payment amount' };\n }\n } catch {\n return { valid: false, invalidReason: 'Invalid payment amount format' };\n }\n\n // Verify on-chain\n const verification = await verifyPayment({\n signature,\n expectedRecipient: requirement.payTo,\n expectedAmount,\n maxAgeSeconds: requirement.maxTimeoutSeconds,\n clientConfig,\n });\n\n if (!verification.valid) {\n return {\n valid: false,\n invalidReason: verification.error || 'Transaction verification failed',\n };\n }\n\n return {\n valid: true,\n settled: verification.confirmed,\n transaction: {\n signature: verification.signature,\n blockTime: verification.blockTime,\n slot: verification.slot,\n },\n };\n}\n\n/**\n * Parse payment payload from x402 header\n * SECURITY: Safe JSON parsing with try-catch\n */\nexport function parsePaymentHeader(header: string): PaymentPayload | null {\n if (!header || typeof header !== 'string') {\n return null;\n }\n\n // SECURITY: Limit header size to prevent DoS\n if (header.length > 10000) {\n return null;\n }\n\n try {\n const decoded = Buffer.from(header, 'base64').toString('utf-8');\n const parsed = JSON.parse(decoded);\n\n // Basic structure validation\n if (!parsed || typeof parsed !== 'object') {\n return null;\n }\n\n return parsed as PaymentPayload;\n } catch {\n return null;\n }\n}\n\n/**\n * Encode payment response for header\n */\nexport function encodePaymentResponse(response: VerificationResponse): string {\n return Buffer.from(JSON.stringify(response)).toString('base64');\n}\n","// In-Memory Signature Store\n// For development, testing, and single-instance deployments\n\n/** Signature usage record */\nexport interface SignatureUsage {\n signature: string;\n resourceId: string;\n usedAt: Date;\n expiresAt: Date;\n walletAddress?: string;\n}\n\n/** Interface for tracking payment signature usage */\nexport interface SignatureStore {\n hasBeenUsed(signature: string): Promise<boolean>;\n markAsUsed(signature: string, resourceId: string, expiresAt: Date): Promise<void>;\n getUsage?(signature: string): Promise<SignatureUsage | null>;\n}\n\nexport interface MemoryStoreOptions {\n /** Default TTL in seconds */\n defaultTTL?: number;\n /** Cleanup interval in ms (default: 60000) */\n cleanupInterval?: number;\n}\n\ninterface StoredRecord {\n resourceId: string;\n usedAt: number;\n expiresAt: number;\n walletAddress?: string;\n}\n\n/**\n * Create an in-memory signature store\n * ⚠️ Not suitable for multi-instance deployments (use Redis instead)\n */\nexport function createMemoryStore(options: MemoryStoreOptions = {}): SignatureStore & { close: () => void } {\n const { cleanupInterval = 60000 } = options;\n const store = new Map<string, StoredRecord>();\n\n // Periodic cleanup of expired entries\n const cleanupTimer = setInterval(() => {\n const now = Date.now();\n for (const [key, record] of store.entries()) {\n if (record.expiresAt < now) {\n store.delete(key);\n }\n }\n }, cleanupInterval);\n\n return {\n async hasBeenUsed(signature: string): Promise<boolean> {\n const record = store.get(signature);\n if (!record) return false;\n\n // Check if expired\n if (record.expiresAt < Date.now()) {\n store.delete(signature);\n return false;\n }\n\n return true;\n },\n\n async markAsUsed(signature: string, resourceId: string, expiresAt: Date): Promise<void> {\n store.set(signature, {\n resourceId,\n usedAt: Date.now(),\n expiresAt: expiresAt.getTime(),\n });\n },\n\n async getUsage(signature: string): Promise<SignatureUsage | null> {\n const record = store.get(signature);\n if (!record) return null;\n\n // Check expiration\n if (record.expiresAt < Date.now()) {\n store.delete(signature);\n return null;\n }\n\n return {\n signature,\n resourceId: record.resourceId,\n usedAt: new Date(record.usedAt),\n expiresAt: new Date(record.expiresAt),\n walletAddress: record.walletAddress,\n };\n },\n\n /** Stop cleanup timer (for graceful shutdown) */\n close(): void {\n clearInterval(cleanupTimer);\n store.clear();\n },\n };\n}\n","// Redis Signature Store Adapter\n// For production multi-instance deployments\n\nimport type { SignatureStore, SignatureUsage } from './memory';\n\n/**\n * Minimal Redis client interface\n * Compatible with ioredis, redis, and similar clients\n */\nexport interface RedisClient {\n get(key: string): Promise<string | null>;\n set(key: string, value: string, options?: { EX?: number }): Promise<string | null>;\n setex?(key: string, seconds: number, value: string): Promise<string>;\n exists(key: string): Promise<number>;\n del(key: string): Promise<number>;\n}\n\nexport interface RedisStoreOptions {\n /** Redis client instance */\n client: RedisClient;\n /** Key prefix */\n keyPrefix?: string;\n /** Default TTL in seconds */\n defaultTTL?: number;\n}\n\n/**\n * Create a Redis-backed signature store\n * Production-ready for distributed deployments\n */\nexport function createRedisStore(options: RedisStoreOptions): SignatureStore {\n const { client, keyPrefix = 'micropay:sig:' } = options;\n\n const buildKey = (signature: string) => `${keyPrefix}${signature}`;\n\n return {\n async hasBeenUsed(signature: string): Promise<boolean> {\n const exists = await client.exists(buildKey(signature));\n return exists > 0;\n },\n\n async markAsUsed(signature: string, resourceId: string, expiresAt: Date): Promise<void> {\n const key = buildKey(signature);\n const ttl = Math.max(1, Math.floor((expiresAt.getTime() - Date.now()) / 1000));\n\n const record: SignatureUsage = {\n signature,\n resourceId,\n usedAt: new Date(),\n expiresAt,\n };\n\n // Support both `setex` (ioredis) and `set` with EX (node-redis)\n if (client.setex) {\n await client.setex(key, ttl, JSON.stringify(record));\n } else {\n await client.set(key, JSON.stringify(record), { EX: ttl });\n }\n },\n\n async getUsage(signature: string): Promise<SignatureUsage | null> {\n const data = await client.get(buildKey(signature));\n if (!data) return null;\n\n try {\n const record = JSON.parse(data) as SignatureUsage;\n // Convert date strings back to Date objects\n return {\n ...record,\n usedAt: new Date(record.usedAt),\n expiresAt: new Date(record.expiresAt),\n };\n } catch {\n return null;\n }\n },\n };\n}\n","// Next.js Middleware for Paywall\n// Zero-boilerplate integration for protected routes\n\nimport type { SignatureStore } from '../store';\nimport type { SessionData } from '../types';\nimport { validateSession } from '../session';\n\n/**\n * Configuration for paywall middleware\n */\nexport interface PaywallMiddlewareConfig {\n /** Session secret for JWT validation */\n sessionSecret: string;\n /** Protected path patterns (glob-like) */\n protectedPaths: string[];\n /** Cookie name for session token */\n cookieName?: string;\n /** Optional signature store for anti-replay */\n signatureStore?: SignatureStore;\n /** Custom 402 response body */\n custom402Response?: (path: string) => object;\n}\n\n/**\n * Result of middleware check\n */\nexport interface MiddlewareResult {\n /** Whether access is allowed */\n allowed: boolean;\n /** Session data if valid */\n session?: SessionData;\n /** Reason for denial */\n reason?: string;\n /** Should respond with 402 */\n requiresPayment?: boolean;\n}\n\n/**\n * Check if path matches any protected pattern\n */\nfunction matchesProtectedPath(path: string, patterns: string[]): boolean {\n for (const pattern of patterns) {\n // Simple glob matching: * matches anything, ** matches path segments\n const regexPattern = pattern\n .replace(/\\*\\*/g, '{{DOUBLE_STAR}}')\n .replace(/\\*/g, '[^/]*')\n .replace(/{{DOUBLE_STAR}}/g, '.*');\n\n const regex = new RegExp(`^${regexPattern}$`);\n if (regex.test(path)) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * Check paywall access for a request\n * Framework-agnostic core logic\n */\nexport async function checkPaywallAccess(\n path: string,\n sessionToken: string | undefined,\n config: PaywallMiddlewareConfig\n): Promise<MiddlewareResult> {\n // Check if path is protected\n if (!matchesProtectedPath(path, config.protectedPaths)) {\n return { allowed: true };\n }\n\n // No session token\n if (!sessionToken) {\n return {\n allowed: false,\n reason: 'No session token',\n requiresPayment: true,\n };\n }\n\n // Validate session\n const validation = await validateSession(sessionToken, config.sessionSecret);\n\n if (!validation.valid || !validation.session) {\n return {\n allowed: false,\n reason: validation.reason || 'Invalid session',\n requiresPayment: true,\n };\n }\n\n return {\n allowed: true,\n session: validation.session,\n };\n}\n\n/**\n * Create Next.js middleware handler\n * \n * @example\n * ```typescript\n * // middleware.ts\n * import { createPaywallMiddleware } from '@alleyboss/micropay-solana-x402-paywall/middleware';\n * \n * export const middleware = createPaywallMiddleware({\n * sessionSecret: process.env.SESSION_SECRET!,\n * protectedPaths: ['/api/premium/*', '/api/content/*'],\n * });\n * \n * export const config = { matcher: ['/api/premium/:path*', '/api/content/:path*'] };\n * ```\n */\nexport function createPaywallMiddleware(config: PaywallMiddlewareConfig) {\n const { cookieName = 'x402_session' } = config;\n\n return async function middleware(request: Request): Promise<Response | null> {\n const url = new URL(request.url);\n const path = url.pathname;\n\n // Get session from cookie header\n const cookieHeader = request.headers.get('cookie') || '';\n const cookies = Object.fromEntries(\n cookieHeader.split(';').map(c => {\n const [key, ...vals] = c.trim().split('=');\n return [key, vals.join('=')];\n })\n );\n const sessionToken = cookies[cookieName];\n\n const result = await checkPaywallAccess(path, sessionToken, config);\n\n if (!result.allowed && result.requiresPayment) {\n // Return 402 Payment Required\n const body = config.custom402Response\n ? config.custom402Response(path)\n : {\n error: 'Payment Required',\n message: 'This resource requires payment to access',\n path,\n };\n\n return new Response(JSON.stringify(body), {\n status: 402,\n headers: {\n 'Content-Type': 'application/json',\n },\n });\n }\n\n // Allow request to continue\n return null;\n };\n}\n\n/**\n * API route wrapper for Next.js App Router\n * \n * @example\n * ```typescript\n * // app/api/premium/route.ts\n * import { withPaywall } from '@alleyboss/micropay-solana-x402-paywall/middleware';\n * \n * async function handler(request: Request, session: SessionData) {\n * return Response.json({ content: 'Premium content', wallet: session.walletAddress });\n * }\n * \n * export const GET = withPaywall(handler, {\n * sessionSecret: process.env.SESSION_SECRET!,\n * articleId: 'article-123', // Optional: check specific article unlock\n * });\n * ```\n */\nexport function withPaywall<T>(\n handler: (request: Request, session: SessionData) => Promise<T>,\n options: {\n sessionSecret: string;\n cookieName?: string;\n articleId?: string;\n }\n): (request: Request) => Promise<Response | T> {\n const { sessionSecret, cookieName = 'x402_session', articleId } = options;\n\n return async function protectedHandler(request: Request): Promise<Response | T> {\n // Extract session token from cookie\n const cookieHeader = request.headers.get('cookie') || '';\n const cookies = Object.fromEntries(\n cookieHeader.split(';').map(c => {\n const [key, ...vals] = c.trim().split('=');\n return [key, vals.join('=')];\n })\n );\n const sessionToken = cookies[cookieName];\n\n if (!sessionToken) {\n return new Response(\n JSON.stringify({ error: 'Payment Required', message: 'No session token' }),\n { status: 402, headers: { 'Content-Type': 'application/json' } }\n );\n }\n\n // Validate session\n const validation = await validateSession(sessionToken, sessionSecret);\n\n if (!validation.valid || !validation.session) {\n return new Response(\n JSON.stringify({ error: 'Payment Required', message: validation.reason }),\n { status: 402, headers: { 'Content-Type': 'application/json' } }\n );\n }\n\n // Check article-specific unlock if required\n if (articleId) {\n const { session } = validation;\n const hasAccess = session.siteWideUnlock || session.unlockedArticles.includes(articleId);\n\n if (!hasAccess) {\n return new Response(\n JSON.stringify({ error: 'Payment Required', message: 'Article not unlocked' }),\n { status: 402, headers: { 'Content-Type': 'application/json' } }\n );\n }\n }\n\n // Call the actual handler with session\n return handler(request, validation.session);\n };\n}\n","// Utility functions\n// Retry logic with exponential backoff for RPC resilience\n\nexport interface RetryOptions {\n /** Maximum number of attempts */\n maxAttempts?: number;\n /** Base delay in milliseconds */\n baseDelay?: number;\n /** Maximum delay in milliseconds */\n maxDelay?: number;\n /** Whether to add jitter to delay */\n jitter?: boolean;\n /** Errors to retry on (default: all) */\n retryOn?: (error: unknown) => boolean;\n}\n\n/**\n * Sleep for a given duration\n */\nfunction sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n}\n\n/**\n * Calculate delay with exponential backoff and optional jitter\n */\nfunction calculateDelay(attempt: number, options: Required<Omit<RetryOptions, 'retryOn'>>): number {\n const { baseDelay, maxDelay, jitter } = options;\n\n // Exponential backoff: baseDelay * 2^attempt\n let delay = baseDelay * Math.pow(2, attempt);\n\n // Cap at maxDelay\n delay = Math.min(delay, maxDelay);\n\n // Add jitter (±25%)\n if (jitter) {\n const jitterAmount = delay * 0.25;\n delay += (Math.random() * jitterAmount * 2) - jitterAmount;\n }\n\n return Math.floor(delay);\n}\n\n/**\n * Execute a function with retry logic and exponential backoff\n * \n * @example\n * ```typescript\n * const result = await withRetry(\n * () => connection.getBalance(publicKey),\n * { maxAttempts: 3, baseDelay: 500 }\n * );\n * ```\n */\nexport async function withRetry<T>(\n fn: () => Promise<T>,\n options: RetryOptions = {}\n): Promise<T> {\n const {\n maxAttempts = 3,\n baseDelay = 500,\n maxDelay = 10000,\n jitter = true,\n retryOn = () => true,\n } = options;\n\n let lastError: unknown;\n\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\n try {\n return await fn();\n } catch (error) {\n lastError = error;\n\n // Check if we should retry this error\n if (!retryOn(error)) {\n throw error;\n }\n\n // Don't sleep after the last attempt\n if (attempt < maxAttempts - 1) {\n const delay = calculateDelay(attempt, {\n maxAttempts,\n baseDelay,\n maxDelay,\n jitter\n });\n await sleep(delay);\n }\n }\n }\n\n throw lastError;\n}\n\n/**\n * Check if error is a transient RPC error that should be retried\n */\nexport function isRetryableRPCError(error: unknown): boolean {\n if (error instanceof Error) {\n const message = error.message.toLowerCase();\n\n // Rate limiting\n if (message.includes('429') || message.includes('rate limit')) {\n return true;\n }\n\n // Network errors\n if (message.includes('timeout') || message.includes('econnreset')) {\n return true;\n }\n\n // Server errors\n if (message.includes('503') || message.includes('502') || message.includes('500')) {\n return true;\n }\n\n // Solana-specific transient errors\n if (message.includes('blockhash not found') || message.includes('slot skipped')) {\n return true;\n }\n }\n\n return false;\n}\n","// Client-Side Payment Flow Helper\n// Headless payment flow for frontend integration (no Node.js dependencies)\n\nimport { TOKEN_MINTS, type PaymentAsset, type SolanaNetwork } from '../types';\n\n/**\n * Payment flow configuration\n */\nexport interface PaymentFlowConfig {\n /** Solana network */\n network: SolanaNetwork;\n /** Recipient wallet address */\n recipientWallet: string;\n /** Amount in smallest unit (lamports or token base units) */\n amount: bigint;\n /** Asset to pay with */\n asset?: PaymentAsset;\n /** Optional memo for the transaction */\n memo?: string;\n}\n\n/**\n * Solana Pay URL parameters\n */\nexport interface SolanaPayUrlParams {\n /** Recipient address */\n recipient: string;\n /** Amount in token's natural units (e.g., SOL, not lamports) */\n amount?: number;\n /** SPL token mint address */\n splToken?: string;\n /** Transaction reference */\n reference?: string;\n /** Label for the recipient */\n label?: string;\n /** Memo/message */\n message?: string;\n}\n\n/**\n * Build a Solana Pay URL for QR codes and deep linking\n * Compatible with Phantom, Solflare, and other Solana Pay wallets\n * \n * @example\n * ```typescript\n * const url = buildSolanaPayUrl({\n * recipient: 'CreatorWalletAddress',\n * amount: 0.01,\n * label: 'Article Unlock',\n * message: 'Premium Content Access',\n * });\n * // Returns: solana:CreatorWalletAddress?amount=0.01&label=Article%20Unlock&message=Premium%20Content%20Access\n * ```\n */\nexport function buildSolanaPayUrl(params: SolanaPayUrlParams): string {\n const { recipient, amount, splToken, reference, label, message } = params;\n\n const url = new URL(`solana:${recipient}`);\n\n if (amount !== undefined) {\n url.searchParams.set('amount', amount.toString());\n }\n\n if (splToken) {\n url.searchParams.set('spl-token', splToken);\n }\n\n if (reference) {\n url.searchParams.set('reference', reference);\n }\n\n if (label) {\n url.searchParams.set('label', label);\n }\n\n if (message) {\n url.searchParams.set('message', message);\n }\n\n return url.toString();\n}\n\n/**\n * Create a payment flow helper for frontend use\n * Provides utilities for building transactions and generating QR codes\n * \n * @example\n * ```typescript\n * const flow = createPaymentFlow({\n * network: 'devnet',\n * recipientWallet: 'CreatorAddress',\n * amount: 10000000n, // 0.01 SOL\n * });\n * \n * // Generate QR code URL\n * const qrUrl = flow.getSolanaPayUrl({ label: 'Unlock Article' });\n * \n * // Get transaction amount in natural units\n * const amountInSol = flow.getDisplayAmount();\n * ```\n */\nexport function createPaymentFlow(config: PaymentFlowConfig) {\n const { network, recipientWallet, amount, asset = 'native', memo } = config;\n\n // Determine decimals and mint\n let decimals = 9; // SOL default\n let mintAddress: string | undefined;\n\n if (asset === 'usdc') {\n decimals = 6;\n mintAddress = network === 'mainnet-beta' ? TOKEN_MINTS.USDC_MAINNET : TOKEN_MINTS.USDC_DEVNET;\n } else if (asset === 'usdt') {\n decimals = 6;\n mintAddress = TOKEN_MINTS.USDT_MAINNET;\n } else if (typeof asset === 'object' && 'mint' in asset) {\n decimals = asset.decimals ?? 6;\n mintAddress = asset.mint;\n }\n\n // Convert to natural units (from lamports/base units)\n const naturalAmount = Number(amount) / Math.pow(10, decimals);\n\n return {\n /** Get the payment configuration */\n getConfig: () => ({ ...config }),\n\n /** Get amount in natural display units (e.g., 0.01 SOL) */\n getDisplayAmount: () => naturalAmount,\n\n /** Get amount formatted with symbol */\n getFormattedAmount: () => {\n const symbol = asset === 'native' ? 'SOL'\n : asset === 'usdc' ? 'USDC'\n : asset === 'usdt' ? 'USDT'\n : 'tokens';\n return `${naturalAmount.toFixed(decimals > 6 ? 4 : 2)} ${symbol}`;\n },\n\n /** Generate Solana Pay URL for QR codes */\n getSolanaPayUrl: (options: { label?: string; reference?: string } = {}) => {\n return buildSolanaPayUrl({\n recipient: recipientWallet,\n amount: naturalAmount,\n splToken: mintAddress,\n label: options.label,\n reference: options.reference,\n message: memo,\n });\n },\n\n /** Get the token mint address (undefined for native SOL) */\n getMintAddress: () => mintAddress,\n\n /** Check if this is a native SOL payment */\n isNativePayment: () => asset === 'native',\n\n /** Get network information */\n getNetworkInfo: () => ({\n network,\n isMainnet: network === 'mainnet-beta',\n explorerUrl: network === 'mainnet-beta'\n ? 'https://explorer.solana.com'\n : 'https://explorer.solana.com?cluster=devnet',\n }),\n\n /** Build explorer URL for a transaction */\n getExplorerUrl: (signature: string) => {\n const baseUrl = 'https://explorer.solana.com/tx';\n const cluster = network === 'mainnet-beta' ? '' : '?cluster=devnet';\n return `${baseUrl}/${signature}${cluster}`;\n },\n };\n}\n\n/**\n * Create a unique reference for payment tracking\n * Uses crypto.randomUUID when available\n */\nexport function createPaymentReference(): string {\n if (typeof crypto !== 'undefined' && crypto.randomUUID) {\n return crypto.randomUUID();\n }\n // Fallback for environments without crypto.randomUUID\n return `${Date.now()}-${Math.random().toString(36).slice(2, 11)}`;\n}\n","// Price Conversion Helpers\n// Multi-provider SOL price fetching with fallback rotation\n\n/**\n * Price data from API\n */\nexport interface PriceData {\n /** SOL price in USD */\n solPrice: number;\n /** Timestamp of price fetch */\n fetchedAt: Date;\n /** Source of price data */\n source: string;\n}\n\n/**\n * Custom price provider function type\n */\nexport type CustomPriceProvider = () => Promise<number>;\n\n/**\n * Price provider configuration\n */\nexport interface PriceConfig {\n /** Custom price provider (if set, skips built-in providers) */\n customProvider?: CustomPriceProvider;\n /** Cache TTL in milliseconds (default: 60000) */\n cacheTTL?: number;\n /** Request timeout in milliseconds (default: 5000) */\n timeout?: number;\n}\n\n// Cached price data\nlet cachedPrice: PriceData | null = null;\nlet config: PriceConfig = {};\nlet lastProviderIndex = -1;\n\n/**\n * Configure price fetching\n * \n * @example\n * ```typescript\n * // Use custom API\n * configurePricing({\n * customProvider: async () => {\n * const res = await fetch('https://my-api.com/sol-price');\n * return (await res.json()).price;\n * },\n * });\n * \n * // Or just adjust cache TTL\n * configurePricing({ cacheTTL: 30000 }); // 30 seconds\n * ```\n */\nexport function configurePricing(newConfig: PriceConfig): void {\n config = { ...config, ...newConfig };\n cachedPrice = null; // Clear cache on config change\n}\n\n/**\n * Built-in price providers with reliability rotation\n */\nconst PROVIDERS = [\n {\n name: 'coincap',\n url: 'https://api.coincap.io/v2/assets/solana',\n parse: (data: { data?: { priceUsd?: string } }) => parseFloat(data.data?.priceUsd || '0'),\n },\n {\n name: 'binance',\n url: 'https://api.binance.com/api/v3/ticker/price?symbol=SOLUSDT',\n parse: (data: { price?: string }) => parseFloat(data.price || '0'),\n },\n {\n name: 'coingecko',\n url: 'https://api.coingecko.com/api/v3/simple/price?ids=solana&vs_currencies=usd',\n parse: (data: { solana?: { usd?: number } }) => data.solana?.usd || 0,\n },\n {\n name: 'kraken',\n url: 'https://api.kraken.com/0/public/Ticker?pair=SOLUSD',\n parse: (data: { result?: { SOLUSD?: { c?: string[] } } }) =>\n parseFloat(data.result?.SOLUSD?.c?.[0] || '0'),\n },\n];\n\n/**\n * Fetch price from a single provider\n */\nasync function fetchFromProvider(\n provider: typeof PROVIDERS[0],\n timeout: number\n): Promise<number> {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), timeout);\n\n try {\n const response = await fetch(provider.url, {\n headers: { 'Accept': 'application/json' },\n signal: controller.signal,\n });\n\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}`);\n }\n\n const data = await response.json() as Record<string, unknown>;\n const price = provider.parse(data as Parameters<typeof provider.parse>[0]);\n\n if (!price || price <= 0) {\n throw new Error('Invalid price');\n }\n\n return price;\n } finally {\n clearTimeout(timeoutId);\n }\n}\n\n/**\n * Get SOL price with multi-provider fallback\n * \n * Provider rotation order:\n * 1. CoinCap (primary)\n * 2. Binance (backup #1)\n * 3. CoinGecko (backup #2)\n * 4. Kraken (backup #3)\n * \n * @example\n * ```typescript\n * const { solPrice, source } = await getSolPrice();\n * console.log(`SOL is $${solPrice} (from ${source})`);\n * ```\n */\nexport async function getSolPrice(): Promise<PriceData> {\n const cacheTTL = config.cacheTTL ?? 60000;\n const timeout = config.timeout ?? 5000;\n\n // Return cached price if valid\n if (cachedPrice && Date.now() - cachedPrice.fetchedAt.getTime() < cacheTTL) {\n return cachedPrice;\n }\n\n // Try custom provider first if configured\n if (config.customProvider) {\n try {\n const price = await config.customProvider();\n if (price > 0) {\n cachedPrice = {\n solPrice: price,\n fetchedAt: new Date(),\n source: 'custom',\n };\n return cachedPrice;\n }\n } catch {\n // Fall through to built-in providers\n }\n }\n\n // Try providers in rotation, starting after the last successful one\n for (let i = 0; i < PROVIDERS.length; i++) {\n const idx = (lastProviderIndex + 1 + i) % PROVIDERS.length;\n const provider = PROVIDERS[idx];\n\n try {\n const price = await fetchFromProvider(provider, timeout);\n lastProviderIndex = idx;\n\n cachedPrice = {\n solPrice: price,\n fetchedAt: new Date(),\n source: provider.name,\n };\n return cachedPrice;\n } catch {\n // Try next provider\n continue;\n }\n }\n\n // All providers failed, use stale cache or fallback\n if (cachedPrice) {\n return cachedPrice;\n }\n\n // Last resort fallback\n return {\n solPrice: 150, // Reasonable fallback\n fetchedAt: new Date(),\n source: 'fallback',\n };\n}\n\n/**\n * Convert lamports to USD\n * \n * @example\n * ```typescript\n * const usd = await lamportsToUsd(10_000_000n); // 0.01 SOL\n * console.log(`$${usd.toFixed(2)}`);\n * ```\n */\nexport async function lamportsToUsd(lamports: bigint): Promise<number> {\n const { solPrice } = await getSolPrice();\n const sol = Number(lamports) / 1_000_000_000;\n return sol * solPrice;\n}\n\n/**\n * Convert USD to lamports\n * \n * @example\n * ```typescript\n * const lamports = await usdToLamports(1.50); // $1.50\n * console.log(`${lamports} lamports`);\n * ```\n */\nexport async function usdToLamports(usd: number): Promise<bigint> {\n const { solPrice } = await getSolPrice();\n const sol = usd / solPrice;\n return BigInt(Math.floor(sol * 1_000_000_000));\n}\n\n/**\n * Format a price for display with both SOL and USD\n * \n * @example\n * ```typescript\n * const display = await formatPriceDisplay(10_000_000n);\n * // Returns: \"0.0100 SOL (~$1.50)\"\n * ```\n */\nexport async function formatPriceDisplay(lamports: bigint): Promise<string> {\n const { solPrice } = await getSolPrice();\n const sol = Number(lamports) / 1_000_000_000;\n const usd = sol * solPrice;\n\n return `${sol.toFixed(4)} SOL (~$${usd.toFixed(2)})`;\n}\n\n/**\n * Synchronous price formatting (requires pre-fetched price)\n */\nexport function formatPriceSync(lamports: bigint, solPrice: number): {\n sol: number;\n usd: number;\n formatted: string;\n} {\n const sol = Number(lamports) / 1_000_000_000;\n const usd = sol * solPrice;\n\n return {\n sol,\n usd,\n formatted: `${sol.toFixed(4)} SOL (~$${usd.toFixed(2)})`,\n };\n}\n\n/**\n * Clear the price cache (for testing or manual refresh)\n */\nexport function clearPriceCache(): void {\n cachedPrice = null;\n lastProviderIndex = -1;\n}\n\n/**\n * Get list of available built-in providers\n */\nexport function getProviders(): { name: string; url: string }[] {\n return PROVIDERS.map(p => ({ name: p.name, url: p.url }));\n}\n"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
|
-
export { A as ArticlePaymentConfig, a as PaymentPayload, P as PaymentRequirement, c as PaymentStatus,
|
|
2
|
-
export { a as SessionConfig, S as SessionData, c as SessionJWTPayload, b as SessionValidation
|
|
3
|
-
export {
|
|
1
|
+
export { A as ArticlePaymentConfig, d as PaymentAsset, a as PaymentPayload, P as PaymentRequirement, c as PaymentStatus, e as SPLTokenAsset, S as SolanaNetwork, T as TOKEN_MINTS, V as VerificationRequest, b as VerificationResponse, X as X402Network } from './payment-CTxdtqmc.cjs';
|
|
2
|
+
export { a as SessionConfig, S as SessionData, c as SessionJWTPayload, b as SessionValidation } from './session-D2IoWAWV.cjs';
|
|
3
|
+
export { S as SolanaClientConfig, g as getConnection, i as isMainnet, r as resetConnection, t as toX402Network } from './client-vRr48m2x.cjs';
|
|
4
|
+
export { SPLVerificationResult, TransactionVerificationResult, VerifyPaymentParams, VerifySPLPaymentParams, getTokenDecimals, getWalletTransactions, isNativeAsset, lamportsToSol, resolveMintAddress, solToLamports, verifyPayment, verifySPLPayment, waitForConfirmation } from './solana/index.cjs';
|
|
5
|
+
export { addArticleToSession, createSession, isArticleUnlocked, validateSession } from './session/index.cjs';
|
|
4
6
|
export { BuildPaymentParams, X402_HEADERS, buildPaymentRequirement, create402Headers, create402ResponseBody, decodePaymentRequired, encodePaymentRequired, encodePaymentResponse, parsePaymentHeader, verifyX402Payment } from './x402/index.cjs';
|
|
7
|
+
export { StoreConfig, createRedisStore } from './store/index.cjs';
|
|
8
|
+
export { M as MiddlewareResult, P as PaywallMiddlewareConfig, a as checkPaywallAccess, c as createPaywallMiddleware, w as withPaywall } from './nextjs-Bm272Jkj.cjs';
|
|
9
|
+
export { RetryOptions, isRetryableRPCError, withRetry } from './utils/index.cjs';
|
|
10
|
+
export { PaymentFlowConfig, SolanaPayUrlParams, buildSolanaPayUrl, createPaymentFlow, createPaymentReference } from './client/index.cjs';
|
|
11
|
+
export { CustomPriceProvider, PriceConfig, PriceData, clearPriceCache, configurePricing, formatPriceDisplay, formatPriceSync, getProviders, getSolPrice, lamportsToUsd, usdToLamports } from './pricing/index.cjs';
|
|
12
|
+
export { S as SignatureStore, a as SignatureUsage, c as createMemoryStore } from './memory-Daxkczti.cjs';
|
|
5
13
|
import '@solana/web3.js';
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
|
-
export { A as ArticlePaymentConfig, a as PaymentPayload, P as PaymentRequirement, c as PaymentStatus,
|
|
2
|
-
export { a as SessionConfig, S as SessionData, c as SessionJWTPayload, b as SessionValidation
|
|
3
|
-
export {
|
|
1
|
+
export { A as ArticlePaymentConfig, d as PaymentAsset, a as PaymentPayload, P as PaymentRequirement, c as PaymentStatus, e as SPLTokenAsset, S as SolanaNetwork, T as TOKEN_MINTS, V as VerificationRequest, b as VerificationResponse, X as X402Network } from './payment-CTxdtqmc.js';
|
|
2
|
+
export { a as SessionConfig, S as SessionData, c as SessionJWTPayload, b as SessionValidation } from './session-D2IoWAWV.js';
|
|
3
|
+
export { S as SolanaClientConfig, g as getConnection, i as isMainnet, r as resetConnection, t as toX402Network } from './client-CSZHI8o8.js';
|
|
4
|
+
export { SPLVerificationResult, TransactionVerificationResult, VerifyPaymentParams, VerifySPLPaymentParams, getTokenDecimals, getWalletTransactions, isNativeAsset, lamportsToSol, resolveMintAddress, solToLamports, verifyPayment, verifySPLPayment, waitForConfirmation } from './solana/index.js';
|
|
5
|
+
export { addArticleToSession, createSession, isArticleUnlocked, validateSession } from './session/index.js';
|
|
4
6
|
export { BuildPaymentParams, X402_HEADERS, buildPaymentRequirement, create402Headers, create402ResponseBody, decodePaymentRequired, encodePaymentRequired, encodePaymentResponse, parsePaymentHeader, verifyX402Payment } from './x402/index.js';
|
|
7
|
+
export { StoreConfig, createRedisStore } from './store/index.js';
|
|
8
|
+
export { M as MiddlewareResult, P as PaywallMiddlewareConfig, a as checkPaywallAccess, c as createPaywallMiddleware, w as withPaywall } from './nextjs-BK0pVb9Y.js';
|
|
9
|
+
export { RetryOptions, isRetryableRPCError, withRetry } from './utils/index.js';
|
|
10
|
+
export { PaymentFlowConfig, SolanaPayUrlParams, buildSolanaPayUrl, createPaymentFlow, createPaymentReference } from './client/index.js';
|
|
11
|
+
export { CustomPriceProvider, PriceConfig, PriceData, clearPriceCache, configurePricing, formatPriceDisplay, formatPriceSync, getProviders, getSolPrice, lamportsToUsd, usdToLamports } from './pricing/index.js';
|
|
12
|
+
export { S as SignatureStore, a as SignatureUsage, c as createMemoryStore } from './memory-Daxkczti.js';
|
|
5
13
|
import '@solana/web3.js';
|