/** * Express middleware for Nevermined payment protection using the x402 protocol. * * This middleware provides a simple way to protect Express routes with * Nevermined payment verification and settlement. * * ## x402 HTTP Transport Headers * * Following the x402 spec (https://github.com/coinbase/x402/blob/main/specs/transports-v2/http.md): * * - **Client → Server**: `payment-signature` header with base64-encoded token * - **Server → Client (402)**: `payment-required` header with base64-encoded PaymentRequired * - **Server → Client (success)**: `payment-response` header with settlement receipt * * @example * ```typescript * import express from 'express' * import { Payments } from '@nevermined-io/payments' * import { paymentMiddleware } from '@nevermined-io/payments/express' * * const app = express() * const payments = Payments.getInstance({ nvmApiKey: '...', environment: 'testing' }) * * // Protect routes with payment middleware * app.use(paymentMiddleware(payments, { * 'POST /ask': { planId: '123', credits: 1 }, * 'POST /generate': { planId: '123', credits: 5 }, * })) * * // Route handlers - no payment logic needed! * app.post('/ask', (req, res) => res.json({ answer: '...' })) * ``` * * @example Client usage * ```typescript * const token = await payments.x402.getX402AccessToken(planId) * * const response = await fetch('/ask', { * method: 'POST', * headers: { * 'Content-Type': 'application/json', * 'payment-signature': token.accessToken, // x402 header * }, * body: JSON.stringify({ query: 'Hello!' }), * }) * ``` */ import type { Request, Response, NextFunction } from 'express'; /** * Express middleware function type. * Using explicit signature instead of RequestHandler to avoid type resolution issues * when SDK's \@types/express version differs from consumer's. */ export type ExpressMiddleware = (req: Request, res: Response, next: NextFunction) => void; import type { Payments } from '../../payments.js'; import type { StartAgentRequest, X402SchemeType } from '../../common/types.js'; import { type X402PaymentRequired, type VerifyPermissionsResult } from '../facilitator-api.js'; /** * Configuration for a protected route */ export interface RouteConfig { /** The Nevermined plan ID that protects this route */ planId: string; /** Number of credits to charge for this route (default: 1) */ credits?: number | ((req: Request, res: Response) => number | Promise); /** Optional agent ID */ agentId?: string; /** Network identifier (default: auto-derived from scheme) */ network?: string; /** x402 scheme override (auto-detected from plan metadata if omitted) */ scheme?: X402SchemeType; /** Human-readable description of the protected resource */ description?: string; /** Expected response MIME type (e.g., "application/json") */ mimeType?: string; } /** * Route configuration map: "METHOD \/path" -> RouteConfig */ export type RouteConfigMap = Record; /** * x402 HTTP Transport header names (v2 spec) * @see https://github.com/coinbase/x402/blob/main/specs/transports-v2/http.md */ export declare const X402_HEADERS: { /** Client sends payment token in this header */ readonly PAYMENT_SIGNATURE: "payment-signature"; /** Server sends PaymentRequired in this header (base64-encoded) */ readonly PAYMENT_REQUIRED: "payment-required"; /** Server sends settlement receipt in this header (base64-encoded) */ readonly PAYMENT_RESPONSE: "payment-response"; }; /** * Payment context attached to the request after verification. * Available as `req.paymentContext` in route handlers. */ export interface PaymentContext { /** The x402 access token */ token: string; /** The payment required object */ paymentRequired: X402PaymentRequired; /** Number of credits to settle */ creditsToSettle: number; /** Whether verification was successful */ verified: boolean; /** Agent request context for observability (from verification response) */ agentRequest?: StartAgentRequest; /** Agent request ID for observability tracking */ agentRequestId?: string; } /** * Options for the payment middleware */ export interface PaymentMiddlewareOptions { /** * Header name(s) to check for the x402 access token. * Default: 'payment-signature' (x402 v2 compliant) */ tokenHeader?: string | string[]; /** Custom error handler for payment failures */ onPaymentError?: (error: Error, req: Request, res: Response) => void; /** Hook called before verification */ onBeforeVerify?: (req: Request, paymentRequired: X402PaymentRequired) => void | Promise; /** * Hook called after successful verification. * Use this to access agentRequest for observability configuration. */ onAfterVerify?: (req: Request, verification: VerifyPermissionsResult) => void | Promise; /** Hook called after successful settlement */ onAfterSettle?: (req: Request, creditsUsed: number, result: unknown) => void | Promise; } export declare function paymentMiddleware(payments: Payments, routes: RouteConfigMap, options?: PaymentMiddlewareOptions): ExpressMiddleware; export default paymentMiddleware; //# sourceMappingURL=middleware.d.ts.map