@payai/x402
Version:
PayAI-distributed wrapper for @x402/core v2
399 lines (396 loc) • 13.9 kB
text/typescript
import { x as x402ResourceServer, h as Price, N as Network, c as PaymentRequired, P as PaymentPayload, a as PaymentRequirements, S as SettleResponse } from './mechanisms-Q3XXOYVv.mjs';
/**
* Framework-agnostic HTTP adapter interface
* Implementations provide framework-specific HTTP operations
*/
interface HTTPAdapter {
getHeader(name: string): string | undefined;
getMethod(): string;
getPath(): string;
getUrl(): string;
getAcceptHeader(): string;
getUserAgent(): string;
/**
* Get query parameters from the request URL
*
* @returns Record of query parameter key-value pairs
*/
getQueryParams?(): Record<string, string | string[]>;
/**
* Get a specific query parameter by name
*
* @param name - The query parameter name
* @returns The query parameter value(s) or undefined
*/
getQueryParam?(name: string): string | string[] | undefined;
/**
* Get the parsed request body
* Framework adapters should parse JSON/form data appropriately
*
* @returns The parsed request body
*/
getBody?(): unknown;
}
/**
* Paywall configuration for HTML responses
*/
interface PaywallConfig {
appName?: string;
appLogo?: string;
sessionTokenEndpoint?: string;
currentUrl?: string;
testnet?: boolean;
}
/**
* Paywall provider interface for generating HTML
*/
interface PaywallProvider {
generateHtml(paymentRequired: PaymentRequired, config?: PaywallConfig): string;
}
/**
* Dynamic payTo function that receives HTTP request context
*/
type DynamicPayTo = (context: HTTPRequestContext) => string | Promise<string>;
/**
* Dynamic price function that receives HTTP request context
*/
type DynamicPrice = (context: HTTPRequestContext) => Price | Promise<Price>;
/**
* Result of the unpaid response callback containing content type and body.
*/
interface UnpaidResponseResult {
/**
* The content type for the response (e.g., 'application/json', 'text/plain').
*/
contentType: string;
/**
* The response body to include in the 402 response.
*/
body: unknown;
}
/**
* Dynamic function to generate a custom response for unpaid requests.
* Receives the HTTP request context and returns the content type and body to include in the 402 response.
*/
type UnpaidResponseBody = (context: HTTPRequestContext) => UnpaidResponseResult | Promise<UnpaidResponseResult>;
/**
* A single payment option for a route
* Represents one way a client can pay for access to the resource
*/
interface PaymentOption {
scheme: string;
payTo: string | DynamicPayTo;
price: Price | DynamicPrice;
network: Network;
maxTimeoutSeconds?: number;
extra?: Record<string, unknown>;
}
/**
* Route configuration for HTTP endpoints
*
* The 'accepts' field defines payment options for the route.
* Can be a single PaymentOption or an array of PaymentOptions for multiple payment methods.
*/
interface RouteConfig {
accepts: PaymentOption | PaymentOption[];
resource?: string;
description?: string;
mimeType?: string;
customPaywallHtml?: string;
/**
* Optional callback to generate a custom response for unpaid API requests.
* This allows servers to return preview data, error messages, or other content
* when a request lacks payment.
*
* For browser requests (Accept: text/html), the paywall HTML takes precedence.
* This callback is only used for API clients.
*
* If not provided, defaults to { contentType: 'application/json', body: {} }.
*
* @param context - The HTTP request context
* @returns An object containing both contentType and body for the 402 response
*/
unpaidResponseBody?: UnpaidResponseBody;
extensions?: Record<string, unknown>;
}
/**
* Routes configuration - maps path patterns to route configs
*/
type RoutesConfig = Record<string, RouteConfig> | RouteConfig;
/**
* Hook that runs on every request to a protected route, before payment processing.
* Can grant access without payment, deny the request, or continue to payment flow.
*
* @returns
* - `void` - Continue to payment processing (default behavior)
* - `{ grantAccess: true }` - Grant access without requiring payment
* - `{ abort: true; reason: string }` - Deny the request (returns 403)
*/
type ProtectedRequestHook = (context: HTTPRequestContext, routeConfig: RouteConfig) => Promise<void | {
grantAccess: true;
} | {
abort: true;
reason: string;
}>;
/**
* Compiled route for efficient matching
*/
interface CompiledRoute {
verb: string;
regex: RegExp;
config: RouteConfig;
}
/**
* HTTP request context that encapsulates all request data
*/
interface HTTPRequestContext {
adapter: HTTPAdapter;
path: string;
method: string;
paymentHeader?: string;
}
/**
* HTTP response instructions for the framework middleware
*/
interface HTTPResponseInstructions {
status: number;
headers: Record<string, string>;
body?: unknown;
isHtml?: boolean;
}
/**
* Result of processing an HTTP request for payment
*/
type HTTPProcessResult = {
type: "no-payment-required";
} | {
type: "payment-verified";
paymentPayload: PaymentPayload;
paymentRequirements: PaymentRequirements;
declaredExtensions?: Record<string, unknown>;
} | {
type: "payment-error";
response: HTTPResponseInstructions;
};
/**
* Result of processSettlement
*/
type ProcessSettleSuccessResponse = SettleResponse & {
success: true;
headers: Record<string, string>;
requirements: PaymentRequirements;
};
type ProcessSettleFailureResponse = SettleResponse & {
success: false;
errorReason: string;
errorMessage?: string;
};
type ProcessSettleResultResponse = ProcessSettleSuccessResponse | ProcessSettleFailureResponse;
/**
* Represents a validation error for a specific route's payment configuration.
*/
interface RouteValidationError {
/** The route pattern (e.g., "GET /api/weather") */
routePattern: string;
/** The payment scheme that failed validation */
scheme: string;
/** The network that failed validation */
network: Network;
/** The type of validation failure */
reason: "missing_scheme" | "missing_facilitator";
/** Human-readable error message */
message: string;
}
/**
* Error thrown when route configuration validation fails.
*/
declare class RouteConfigurationError extends Error {
/** The validation errors that caused this exception */
readonly errors: RouteValidationError[];
/**
* Creates a new RouteConfigurationError with the given validation errors.
*
* @param errors - The validation errors that caused this exception.
*/
constructor(errors: RouteValidationError[]);
}
/**
* HTTP-enhanced x402 resource server
* Provides framework-agnostic HTTP protocol handling
*/
declare class x402HTTPResourceServer {
private ResourceServer;
private compiledRoutes;
private routesConfig;
private paywallProvider?;
private protectedRequestHooks;
/**
* Creates a new x402HTTPResourceServer instance.
*
* @param ResourceServer - The core x402ResourceServer instance to use
* @param routes - Route configuration for payment-protected endpoints
*/
constructor(ResourceServer: x402ResourceServer, routes: RoutesConfig);
/**
* Get the underlying x402ResourceServer instance.
*
* @returns The underlying x402ResourceServer instance
*/
get server(): x402ResourceServer;
/**
* Get the routes configuration.
*
* @returns The routes configuration
*/
get routes(): RoutesConfig;
/**
* Initialize the HTTP resource server.
*
* This method initializes the underlying resource server (fetching facilitator support)
* and then validates that all route payment configurations have corresponding
* registered schemes and facilitator support.
*
* @throws RouteConfigurationError if any route's payment options don't have
* corresponding registered schemes or facilitator support
*
* @example
* ```typescript
* const httpServer = new x402HTTPResourceServer(server, routes);
* await httpServer.initialize();
* ```
*/
initialize(): Promise<void>;
/**
* Register a custom paywall provider for generating HTML
*
* @param provider - PaywallProvider instance
* @returns This service instance for chaining
*/
registerPaywallProvider(provider: PaywallProvider): this;
/**
* Register a hook that runs on every request to a protected route, before payment processing.
* Hooks are executed in order of registration. The first hook to return a non-void result wins.
*
* @param hook - The request hook function
* @returns The x402HTTPResourceServer instance for chaining
*/
onProtectedRequest(hook: ProtectedRequestHook): this;
/**
* Process HTTP request and return response instructions
* This is the main entry point for framework middleware
*
* @param context - HTTP request context
* @param paywallConfig - Optional paywall configuration
* @returns Process result indicating next action for middleware
*/
processHTTPRequest(context: HTTPRequestContext, paywallConfig?: PaywallConfig): Promise<HTTPProcessResult>;
/**
* Process settlement after successful response
*
* @param paymentPayload - The verified payment payload
* @param requirements - The matching payment requirements
* @param declaredExtensions - Optional declared extensions (for per-key enrichment)
* @returns ProcessSettleResultResponse - SettleResponse with headers if success or errorReason if failure
*/
processSettlement(paymentPayload: PaymentPayload, requirements: PaymentRequirements, declaredExtensions?: Record<string, unknown>): Promise<ProcessSettleResultResponse>;
/**
* Check if a request requires payment based on route configuration
*
* @param context - HTTP request context
* @returns True if the route requires payment, false otherwise
*/
requiresPayment(context: HTTPRequestContext): boolean;
/**
* Normalizes a RouteConfig's accepts field into an array of PaymentOptions
* Handles both single PaymentOption and array formats
*
* @param routeConfig - Route configuration
* @returns Array of payment options
*/
private normalizePaymentOptions;
/**
* Validates that all payment options in routes have corresponding registered schemes
* and facilitator support.
*
* @returns Array of validation errors (empty if all routes are valid)
*/
private validateRouteConfiguration;
/**
* Get route configuration for a request
*
* @param path - Request path
* @param method - HTTP method
* @returns Route configuration or undefined if no match
*/
private getRouteConfig;
/**
* Extract payment from HTTP headers (handles v1 and v2)
*
* @param adapter - HTTP adapter
* @returns Decoded payment payload or null
*/
private extractPayment;
/**
* Check if request is from a web browser
*
* @param adapter - HTTP adapter
* @returns True if request appears to be from a browser
*/
private isWebBrowser;
/**
* Create HTTP response instructions from payment required
*
* @param paymentRequired - Payment requirements
* @param isWebBrowser - Whether request is from browser
* @param paywallConfig - Paywall configuration
* @param customHtml - Custom HTML template
* @param unpaidResponse - Optional custom response (content type and body) for unpaid API requests
* @returns Response instructions
*/
private createHTTPResponse;
/**
* Create HTTP payment required response (v1 puts in body, v2 puts in header)
*
* @param paymentRequired - Payment required object
* @returns Headers and body for the HTTP response
*/
private createHTTPPaymentRequiredResponse;
/**
* Create settlement response headers
*
* @param settleResponse - Settlement response
* @returns Headers to add to response
*/
private createSettlementHeaders;
/**
* Parse route pattern into verb and regex
*
* @param pattern - Route pattern like "GET /api/*" or "/api/[id]"
* @returns Parsed pattern with verb and regex
*/
private parseRoutePattern;
/**
* Normalize path for matching
*
* @param path - Raw path from request
* @returns Normalized path
*/
private normalizePath;
/**
* Generate paywall HTML for browser requests
*
* @param paymentRequired - Payment required response
* @param paywallConfig - Optional paywall configuration
* @param customHtml - Optional custom HTML template
* @returns HTML string
*/
private generatePaywallHTML;
/**
* Extract display amount from payment requirements.
*
* @param paymentRequired - The payment required object
* @returns The display amount in decimal format
*/
private getDisplayAmount;
}
export { type CompiledRoute as C, type DynamicPayTo as D, type HTTPAdapter as H, type PaywallConfig as P, type RouteConfig as R, type UnpaidResponseBody as U, type HTTPRequestContext as a, type HTTPResponseInstructions as b, type HTTPProcessResult as c, type PaywallProvider as d, type PaymentOption as e, type RoutesConfig as f, type DynamicPrice as g, type UnpaidResponseResult as h, type ProcessSettleResultResponse as i, type ProcessSettleSuccessResponse as j, type ProcessSettleFailureResponse as k, type RouteValidationError as l, RouteConfigurationError as m, type ProtectedRequestHook as n, x402HTTPResourceServer as x };