@okxweb3/app-x402-express 0.1.2 → 0.2.0

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.
@@ -72,6 +72,11 @@ declare class ExpressAdapter implements HTTPAdapter {
72
72
  * @returns The parsed request body
73
73
  */
74
74
  getBody(): unknown;
75
+ /**
76
+ * Return all request headers as a lowercase-keyed map.
77
+ * Multi-value headers are joined with ", ".
78
+ */
79
+ getHeaders(): Record<string, string>;
75
80
  }
76
81
 
77
82
  /**
package/dist/cjs/index.js CHANGED
@@ -120,6 +120,18 @@ var ExpressAdapter = class {
120
120
  getBody() {
121
121
  return this.req.body;
122
122
  }
123
+ /**
124
+ * Return all request headers as a lowercase-keyed map.
125
+ * Multi-value headers are joined with ", ".
126
+ */
127
+ getHeaders() {
128
+ const out = {};
129
+ for (const [k, v] of Object.entries(this.req.headers)) {
130
+ if (v == null) continue;
131
+ out[k.toLowerCase()] = Array.isArray(v) ? v.join(", ") : String(v);
132
+ }
133
+ return out;
134
+ }
123
135
  };
124
136
 
125
137
  // src/index.ts
@@ -153,6 +165,7 @@ function paymentMiddlewareFromHTTPServer(httpServer, paywallConfig, paywall, syn
153
165
  }
154
166
  }
155
167
  return async (req, res, next) => {
168
+ var _a, _b;
156
169
  const adapter = new ExpressAdapter(req);
157
170
  const context = {
158
171
  adapter,
@@ -321,6 +334,56 @@ function paymentMiddlewareFromHTTPServer(httpServer, paywallConfig, paywall, syn
321
334
  bufferedCalls = [];
322
335
  }
323
336
  return;
337
+ // ── period dispatch results ────────────────────────────────────────
338
+ case "payment-presettle": {
339
+ try {
340
+ const settleResult = await result.settle();
341
+ if (!settleResult.success) {
342
+ res.status(402).json({
343
+ error: settleResult.error ?? "subscription settle failed"
344
+ });
345
+ return;
346
+ }
347
+ if (settleResult.headers) {
348
+ for (const [k, v] of Object.entries(settleResult.headers)) {
349
+ res.setHeader(k, v);
350
+ }
351
+ }
352
+ req.x402 = {
353
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
354
+ ...req.x402,
355
+ subscription: (_a = settleResult.data) == null ? void 0 : _a.subscription,
356
+ subId: (_b = settleResult.data) == null ? void 0 : _b.subId,
357
+ paymentPayload: result.paymentPayload,
358
+ paymentRequirements: result.paymentRequirements,
359
+ settleResult
360
+ };
361
+ return next();
362
+ } catch (err) {
363
+ if (err instanceof import_server.FacilitatorResponseError) {
364
+ sendFacilitatorError(res, err);
365
+ return;
366
+ }
367
+ console.error("payment-presettle error:", err);
368
+ res.status(402).json({
369
+ error: err instanceof Error ? err.message : "subscription settle threw"
370
+ });
371
+ return;
372
+ }
373
+ }
374
+ case "access-verified": {
375
+ if (result.headers) {
376
+ for (const [k, v] of Object.entries(result.headers)) {
377
+ res.setHeader(k, v);
378
+ }
379
+ }
380
+ req.x402 = {
381
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
382
+ ...req.x402,
383
+ subscription: result.subscription
384
+ };
385
+ return next();
386
+ }
324
387
  }
325
388
  };
326
389
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/index.ts","../../src/adapter.ts"],"sourcesContent":["import {\n HTTPRequestContext,\n PaywallConfig,\n PaywallProvider,\n x402HTTPResourceServer,\n x402ResourceServer,\n RoutesConfig,\n FacilitatorClient,\n FacilitatorResponseError,\n getFacilitatorResponseError,\n SETTLEMENT_OVERRIDES_HEADER,\n SettlementOverrides,\n} from \"@okxweb3/app-x402-core/server\";\nimport { SchemeNetworkServer, Network } from \"@okxweb3/app-x402-core/types\";\nimport { NextFunction, Request, Response } from \"express\";\nimport { ExpressAdapter } from \"./adapter\";\n\n/**\n * Set settlement overrides on the response for partial settlement.\n * The middleware will extract these before settlement and strip the header from the client response.\n *\n * @param res - Express response object\n * @param overrides - Settlement overrides (e.g., { amount: \"500\" } for partial settlement)\n */\nexport function setSettlementOverrides(res: Response, overrides: SettlementOverrides): void {\n res.setHeader(SETTLEMENT_OVERRIDES_HEADER, JSON.stringify(overrides));\n}\n\n/**\n * Configuration for registering a payment scheme with a specific network\n */\nexport interface SchemeRegistration {\n /**\n * The network identifier (e.g., 'eip155:196', 'eip155:196')\n */\n network: Network;\n\n /**\n * The scheme server implementation for this network\n */\n server: SchemeNetworkServer;\n}\n\n/**\n * Sends a normalized 502 response for facilitator boundary failures.\n *\n * @param res - The Express response to write to\n * @param error - The facilitator response error to surface\n */\nfunction sendFacilitatorError(res: Response, error: FacilitatorResponseError): void {\n res.status(502).json({ error: error.message });\n}\n\n/**\n * Express payment middleware for x402 protocol (direct HTTP server instance).\n *\n * Use this when you need to configure HTTP-level hooks.\n *\n * @param httpServer - Pre-configured x402HTTPResourceServer instance\n * @param paywallConfig - Optional configuration for the built-in paywall UI\n * @param paywall - Optional custom paywall provider (overrides default)\n * @param syncFacilitatorOnStart - Whether to sync with the facilitator on startup (defaults to true)\n * @returns Express middleware handler\n *\n * @example\n * ```typescript\n * import { paymentMiddlewareFromHTTPServer, x402ResourceServer, x402HTTPResourceServer } from \"@okxweb3/app-x402-express\";\n *\n * const resourceServer = new x402ResourceServer(facilitatorClient)\n * .register(NETWORK, new ExactEvmScheme())\n *\n * const httpServer = new x402HTTPResourceServer(resourceServer, routes)\n * .onProtectedRequest(requestHook);\n *\n * app.use(paymentMiddlewareFromHTTPServer(httpServer));\n * ```\n */\nexport function paymentMiddlewareFromHTTPServer(\n httpServer: x402HTTPResourceServer,\n paywallConfig?: PaywallConfig,\n paywall?: PaywallProvider,\n syncFacilitatorOnStart: boolean = true,\n) {\n // Register custom paywall provider if provided\n if (paywall) {\n httpServer.registerPaywallProvider(paywall);\n }\n\n // Store initialization promise (not the result)\n // httpServer.initialize() fetches facilitator support and validates routes\n let initPromise: Promise<void> | null = syncFacilitatorOnStart ? httpServer.initialize() : null;\n let isInitialized = false;\n\n /**\n * Ensures facilitator initialization succeeds once, while allowing retries after failures.\n */\n async function initializeHttpServer(): Promise<void> {\n if (!syncFacilitatorOnStart || isInitialized) {\n return;\n }\n\n if (!initPromise) {\n initPromise = httpServer.initialize();\n }\n\n try {\n await initPromise;\n isInitialized = true;\n } catch (error) {\n initPromise = null;\n throw error;\n }\n }\n\n return async (req: Request, res: Response, next: NextFunction) => {\n // Create adapter and context\n const adapter = new ExpressAdapter(req);\n const context: HTTPRequestContext = {\n adapter,\n path: req.path,\n method: req.method,\n paymentHeader: adapter.getHeader(\"payment-signature\") || adapter.getHeader(\"x-payment\"),\n };\n\n // Check if route requires payment before initializing facilitator\n if (!httpServer.requiresPayment(context)) {\n return next();\n }\n\n // Only initialize when processing a protected route\n if (syncFacilitatorOnStart && !isInitialized) {\n try {\n await initializeHttpServer();\n } catch (error) {\n const facilitatorError = getFacilitatorResponseError(error);\n if (facilitatorError) {\n sendFacilitatorError(res, facilitatorError);\n return;\n }\n return next(error);\n }\n }\n\n // Process payment requirement check\n let result: Awaited<ReturnType<x402HTTPResourceServer[\"processHTTPRequest\"]>>;\n try {\n result = await httpServer.processHTTPRequest(context, paywallConfig);\n } catch (error) {\n if (error instanceof FacilitatorResponseError) {\n sendFacilitatorError(res, error);\n return;\n }\n return next(error);\n }\n\n // Handle the different result types\n switch (result.type) {\n case \"no-payment-required\":\n // No payment needed, proceed directly to the route handler\n return next();\n\n case \"payment-error\":\n // Payment required but not provided or invalid\n const { response } = result;\n res.status(response.status);\n Object.entries(response.headers).forEach(([key, value]) => {\n res.setHeader(key, value);\n });\n if (response.isHtml) {\n res.send(response.body);\n } else {\n res.json(response.body || {});\n }\n return;\n\n case \"payment-verified\":\n // Payment is valid, need to wrap response for settlement\n const { paymentPayload, paymentRequirements, declaredExtensions } = result;\n\n // Intercept and buffer all core methods that can commit response to client\n const originalWriteHead = res.writeHead.bind(res);\n const originalWrite = res.write.bind(res);\n const originalEnd = res.end.bind(res);\n const originalFlushHeaders = res.flushHeaders.bind(res);\n\n type BufferedCall =\n | [\"writeHead\", Parameters<typeof originalWriteHead>]\n | [\"write\", Parameters<typeof originalWrite>]\n | [\"end\", Parameters<typeof originalEnd>]\n | [\"flushHeaders\", []];\n let bufferedCalls: BufferedCall[] = [];\n let settled = false;\n\n // Create a promise that resolves when the handler finishes and calls res.end()\n let endCalled: () => void;\n const endPromise = new Promise<void>(resolve => {\n endCalled = resolve;\n });\n\n res.writeHead = function (...args: Parameters<typeof originalWriteHead>) {\n if (!settled) {\n bufferedCalls.push([\"writeHead\", args]);\n return res;\n }\n return originalWriteHead(...args);\n } as typeof originalWriteHead;\n\n res.write = function (...args: Parameters<typeof originalWrite>) {\n if (!settled) {\n bufferedCalls.push([\"write\", args]);\n return true;\n }\n return originalWrite(...args);\n } as typeof originalWrite;\n\n res.end = function (...args: Parameters<typeof originalEnd>) {\n if (!settled) {\n bufferedCalls.push([\"end\", args]);\n // Signal that the handler has finished\n endCalled();\n return res;\n }\n return originalEnd(...args);\n } as typeof originalEnd;\n\n res.flushHeaders = function () {\n if (!settled) {\n bufferedCalls.push([\"flushHeaders\", []]);\n return;\n }\n return originalFlushHeaders();\n };\n\n // Proceed to the next middleware or route handler\n next();\n\n // Wait for the handler to actually call res.end() before checking status\n await endPromise;\n\n // If the response from the protected route is >= 400, do not settle payment\n if (res.statusCode >= 400) {\n settled = true;\n res.writeHead = originalWriteHead;\n res.write = originalWrite;\n res.end = originalEnd;\n res.flushHeaders = originalFlushHeaders;\n // Replay all buffered calls in order\n for (const [method, args] of bufferedCalls) {\n if (method === \"writeHead\")\n originalWriteHead(...(args as Parameters<typeof originalWriteHead>));\n else if (method === \"write\")\n originalWrite(...(args as Parameters<typeof originalWrite>));\n else if (method === \"end\") originalEnd(...(args as Parameters<typeof originalEnd>));\n else if (method === \"flushHeaders\") originalFlushHeaders();\n }\n bufferedCalls = [];\n return;\n }\n\n try {\n // Build response body buffer from buffered write/end calls\n const responseBody = Buffer.concat(\n bufferedCalls.flatMap(([m, args]) =>\n (m === \"write\" || m === \"end\") && args[0] ? [Buffer.from(args[0])] : [],\n ),\n );\n\n // Extract settlement overrides from response header (set by route handler)\n const overridesHeaderValue = res.getHeader(SETTLEMENT_OVERRIDES_HEADER);\n const responseHeaders: Record<string, string> = {};\n if (overridesHeaderValue) {\n responseHeaders[SETTLEMENT_OVERRIDES_HEADER] = String(overridesHeaderValue);\n res.removeHeader(SETTLEMENT_OVERRIDES_HEADER);\n }\n\n const settleResult = await httpServer.processSettlement(\n paymentPayload,\n paymentRequirements,\n declaredExtensions,\n { request: context, responseBody, responseHeaders },\n );\n\n // If settlement fails, return an error and do not send the buffered response\n if (!settleResult.success) {\n bufferedCalls = [];\n const { response } = settleResult;\n Object.entries(response.headers).forEach(([key, value]) => {\n res.setHeader(key, value);\n });\n if (response.isHtml) {\n res.status(response.status).send(response.body);\n } else {\n res.status(response.status).json(response.body ?? {});\n }\n return;\n }\n\n // Settlement succeeded - add headers to response\n Object.entries(settleResult.headers).forEach(([key, value]) => {\n res.setHeader(key, value);\n });\n } catch (error) {\n if (error instanceof FacilitatorResponseError) {\n bufferedCalls = [];\n sendFacilitatorError(res, error);\n return;\n }\n console.error(error);\n // If settlement fails, don't send the buffered response\n bufferedCalls = [];\n res.status(402).json({});\n return;\n } finally {\n settled = true;\n res.writeHead = originalWriteHead;\n res.write = originalWrite;\n res.end = originalEnd;\n res.flushHeaders = originalFlushHeaders;\n\n // Replay all buffered calls in order\n for (const [method, args] of bufferedCalls) {\n if (method === \"writeHead\")\n originalWriteHead(...(args as Parameters<typeof originalWriteHead>));\n else if (method === \"write\")\n originalWrite(...(args as Parameters<typeof originalWrite>));\n else if (method === \"end\") originalEnd(...(args as Parameters<typeof originalEnd>));\n else if (method === \"flushHeaders\") originalFlushHeaders();\n }\n bufferedCalls = [];\n }\n return;\n }\n };\n}\n\n/**\n * Express payment middleware for x402 protocol (direct server instance).\n *\n * Use this when you want to pass a pre-configured x402ResourceServer instance.\n * This provides more flexibility for testing, custom configuration, and reusing\n * server instances across multiple middlewares.\n *\n * @param routes - Route configurations for protected endpoints\n * @param server - Pre-configured x402ResourceServer instance\n * @param paywallConfig - Optional configuration for the built-in paywall UI\n * @param paywall - Optional custom paywall provider (overrides default)\n * @param syncFacilitatorOnStart - Whether to sync with the facilitator on startup (defaults to true)\n * @returns Express middleware handler\n *\n * @example\n * ```typescript\n * import { paymentMiddleware } from \"@okxweb3/app-x402-express\";\n *\n * const server = new x402ResourceServer(myFacilitatorClient)\n * .register(NETWORK, new ExactEvmScheme());\n *\n * app.use(paymentMiddleware(routes, server, paywallConfig));\n * ```\n */\nexport function paymentMiddleware(\n routes: RoutesConfig,\n server: x402ResourceServer,\n paywallConfig?: PaywallConfig,\n paywall?: PaywallProvider,\n syncFacilitatorOnStart: boolean = true,\n) {\n // Create the x402 HTTP server instance with the resource server\n const httpServer = new x402HTTPResourceServer(server, routes);\n\n return paymentMiddlewareFromHTTPServer(\n httpServer,\n paywallConfig,\n paywall,\n syncFacilitatorOnStart,\n );\n}\n\n/**\n * Express payment middleware for x402 protocol (configuration-based).\n *\n * Use this when you want to quickly set up middleware with simple configuration.\n * This function creates and configures the x402ResourceServer internally.\n *\n * @param routes - Route configurations for protected endpoints\n * @param facilitatorClients - Optional facilitator client(s) for payment processing\n * @param schemes - Optional array of scheme registrations for server-side payment processing\n * @param paywallConfig - Optional configuration for the built-in paywall UI\n * @param paywall - Optional custom paywall provider (overrides default)\n * @param syncFacilitatorOnStart - Whether to sync with the facilitator on startup (defaults to true)\n * @returns Express middleware handler\n *\n * @example\n * ```typescript\n * import { paymentMiddlewareFromConfig } from \"@okxweb3/app-x402-express\";\n *\n * app.use(paymentMiddlewareFromConfig(\n * routes,\n * myFacilitatorClient,\n * [{ network: \"eip155:196\", server: evmSchemeServer }],\n * paywallConfig\n * ));\n * ```\n */\nexport function paymentMiddlewareFromConfig(\n routes: RoutesConfig,\n facilitatorClients?: FacilitatorClient | FacilitatorClient[],\n schemes?: SchemeRegistration[],\n paywallConfig?: PaywallConfig,\n paywall?: PaywallProvider,\n syncFacilitatorOnStart: boolean = true,\n) {\n const ResourceServer = new x402ResourceServer(facilitatorClients);\n\n if (schemes) {\n schemes.forEach(({ network, server: schemeServer }) => {\n ResourceServer.register(network, schemeServer);\n });\n }\n\n return paymentMiddleware(routes, ResourceServer, paywallConfig, paywall, syncFacilitatorOnStart);\n}\n\nexport { x402ResourceServer, x402HTTPResourceServer } from \"@okxweb3/app-x402-core/server\";\n\nexport type {\n PaymentRequired,\n PaymentRequirements,\n PaymentPayload,\n Network,\n SchemeNetworkServer,\n} from \"@okxweb3/app-x402-core/types\";\n\nexport type {\n PaywallProvider,\n PaywallConfig,\n SettlementOverrides,\n} from \"@okxweb3/app-x402-core/server\";\n\nexport { RouteConfigurationError, SETTLEMENT_OVERRIDES_HEADER } from \"@okxweb3/app-x402-core/server\";\n\nexport type { RouteValidationError } from \"@okxweb3/app-x402-core/server\";\n\nexport { ExpressAdapter } from \"./adapter\";\n","import { HTTPAdapter } from \"@okxweb3/app-x402-core/server\";\nimport { Request } from \"express\";\n\n/**\n * Express adapter implementation\n */\nexport class ExpressAdapter implements HTTPAdapter {\n /**\n * Creates a new ExpressAdapter instance.\n *\n * @param req - The Express request object\n */\n constructor(private req: Request) {}\n\n /**\n * Gets a header value from the request.\n *\n * @param name - The header name\n * @returns The header value or undefined\n */\n getHeader(name: string): string | undefined {\n const value = this.req.header(name);\n return Array.isArray(value) ? value[0] : value;\n }\n\n /**\n * Gets the HTTP method of the request.\n *\n * @returns The HTTP method\n */\n getMethod(): string {\n return this.req.method;\n }\n\n /**\n * Gets the path of the request.\n *\n * @returns The request path\n */\n getPath(): string {\n return this.req.path;\n }\n\n /**\n * Gets the full URL of the request.\n *\n * @returns The full request URL\n */\n getUrl(): string {\n return `${this.req.protocol}://${this.req.headers.host}${this.req.originalUrl}`;\n }\n\n /**\n * Gets the Accept header from the request.\n *\n * @returns The Accept header value or empty string\n */\n getAcceptHeader(): string {\n return this.req.header(\"Accept\") || \"\";\n }\n\n /**\n * Gets the User-Agent header from the request.\n *\n * @returns The User-Agent header value or empty string\n */\n getUserAgent(): string {\n return this.req.header(\"User-Agent\") || \"\";\n }\n\n /**\n * Gets all query parameters from the request URL.\n *\n * @returns Record of query parameter key-value pairs\n */\n getQueryParams(): Record<string, string | string[]> {\n return this.req.query as Record<string, string | string[]>;\n }\n\n /**\n * Gets a specific query parameter by name.\n *\n * @param name - The query parameter name\n * @returns The query parameter value(s) or undefined\n */\n getQueryParam(name: string): string | string[] | undefined {\n const value = this.req.query[name];\n return value as string | string[] | undefined;\n }\n\n /**\n * Gets the parsed request body.\n * Requires express.json() or express.urlencoded() middleware.\n *\n * @returns The parsed request body\n */\n getBody(): unknown {\n return this.req.body;\n }\n}\n"],"mappings":"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","names":["import_server","response"]}
1
+ {"version":3,"sources":["../../src/index.ts","../../src/adapter.ts"],"sourcesContent":["import {\n HTTPRequestContext,\n PaywallConfig,\n PaywallProvider,\n x402HTTPResourceServer,\n x402ResourceServer,\n RoutesConfig,\n FacilitatorClient,\n FacilitatorResponseError,\n getFacilitatorResponseError,\n SETTLEMENT_OVERRIDES_HEADER,\n SettlementOverrides,\n} from \"@okxweb3/app-x402-core/server\";\nimport { SchemeNetworkServer, Network } from \"@okxweb3/app-x402-core/types\";\nimport { NextFunction, Request, Response } from \"express\";\nimport { ExpressAdapter } from \"./adapter\";\n\n/**\n * Set settlement overrides on the response for partial settlement.\n * The middleware will extract these before settlement and strip the header from the client response.\n *\n * @param res - Express response object\n * @param overrides - Settlement overrides (e.g., { amount: \"500\" } for partial settlement)\n */\nexport function setSettlementOverrides(res: Response, overrides: SettlementOverrides): void {\n res.setHeader(SETTLEMENT_OVERRIDES_HEADER, JSON.stringify(overrides));\n}\n\n/**\n * Configuration for registering a payment scheme with a specific network\n */\nexport interface SchemeRegistration {\n /**\n * The network identifier (e.g., 'eip155:196', 'eip155:196')\n */\n network: Network;\n\n /**\n * The scheme server implementation for this network\n */\n server: SchemeNetworkServer;\n}\n\n/**\n * Sends a normalized 502 response for facilitator boundary failures.\n *\n * @param res - The Express response to write to\n * @param error - The facilitator response error to surface\n */\nfunction sendFacilitatorError(res: Response, error: FacilitatorResponseError): void {\n res.status(502).json({ error: error.message });\n}\n\n/**\n * Express payment middleware for x402 protocol (direct HTTP server instance).\n *\n * Use this when you need to configure HTTP-level hooks.\n *\n * @param httpServer - Pre-configured x402HTTPResourceServer instance\n * @param paywallConfig - Optional configuration for the built-in paywall UI\n * @param paywall - Optional custom paywall provider (overrides default)\n * @param syncFacilitatorOnStart - Whether to sync with the facilitator on startup (defaults to true)\n * @returns Express middleware handler\n *\n * @example\n * ```typescript\n * import { paymentMiddlewareFromHTTPServer, x402ResourceServer, x402HTTPResourceServer } from \"@okxweb3/app-x402-express\";\n *\n * const resourceServer = new x402ResourceServer(facilitatorClient)\n * .register(NETWORK, new ExactEvmScheme())\n *\n * const httpServer = new x402HTTPResourceServer(resourceServer, routes)\n * .onProtectedRequest(requestHook);\n *\n * app.use(paymentMiddlewareFromHTTPServer(httpServer));\n * ```\n */\nexport function paymentMiddlewareFromHTTPServer(\n httpServer: x402HTTPResourceServer,\n paywallConfig?: PaywallConfig,\n paywall?: PaywallProvider,\n syncFacilitatorOnStart: boolean = true,\n) {\n // Register custom paywall provider if provided\n if (paywall) {\n httpServer.registerPaywallProvider(paywall);\n }\n\n // Store initialization promise (not the result)\n // httpServer.initialize() fetches facilitator support and validates routes\n let initPromise: Promise<void> | null = syncFacilitatorOnStart ? httpServer.initialize() : null;\n let isInitialized = false;\n\n /**\n * Ensures facilitator initialization succeeds once, while allowing retries after failures.\n */\n async function initializeHttpServer(): Promise<void> {\n if (!syncFacilitatorOnStart || isInitialized) {\n return;\n }\n\n if (!initPromise) {\n initPromise = httpServer.initialize();\n }\n\n try {\n await initPromise;\n isInitialized = true;\n } catch (error) {\n initPromise = null;\n throw error;\n }\n }\n\n return async (req: Request, res: Response, next: NextFunction) => {\n // Create adapter and context\n const adapter = new ExpressAdapter(req);\n const context: HTTPRequestContext = {\n adapter,\n path: req.path,\n method: req.method,\n paymentHeader: adapter.getHeader(\"payment-signature\") || adapter.getHeader(\"x-payment\"),\n };\n\n // Check if route requires payment before initializing facilitator\n if (!httpServer.requiresPayment(context)) {\n return next();\n }\n\n // Only initialize when processing a protected route\n if (syncFacilitatorOnStart && !isInitialized) {\n try {\n await initializeHttpServer();\n } catch (error) {\n const facilitatorError = getFacilitatorResponseError(error);\n if (facilitatorError) {\n sendFacilitatorError(res, facilitatorError);\n return;\n }\n return next(error);\n }\n }\n\n // Process payment requirement check\n let result: Awaited<ReturnType<x402HTTPResourceServer[\"processHTTPRequest\"]>>;\n try {\n result = await httpServer.processHTTPRequest(context, paywallConfig);\n } catch (error) {\n if (error instanceof FacilitatorResponseError) {\n sendFacilitatorError(res, error);\n return;\n }\n return next(error);\n }\n\n // Handle the different result types\n switch (result.type) {\n case \"no-payment-required\":\n // No payment needed, proceed directly to the route handler\n return next();\n\n case \"payment-error\":\n // Payment required but not provided or invalid\n const { response } = result;\n res.status(response.status);\n Object.entries(response.headers).forEach(([key, value]) => {\n res.setHeader(key, value);\n });\n if (response.isHtml) {\n res.send(response.body);\n } else {\n res.json(response.body || {});\n }\n return;\n\n case \"payment-verified\":\n // Payment is valid, need to wrap response for settlement\n const { paymentPayload, paymentRequirements, declaredExtensions } = result;\n\n // Intercept and buffer all core methods that can commit response to client\n const originalWriteHead = res.writeHead.bind(res);\n const originalWrite = res.write.bind(res);\n const originalEnd = res.end.bind(res);\n const originalFlushHeaders = res.flushHeaders.bind(res);\n\n type BufferedCall =\n | [\"writeHead\", Parameters<typeof originalWriteHead>]\n | [\"write\", Parameters<typeof originalWrite>]\n | [\"end\", Parameters<typeof originalEnd>]\n | [\"flushHeaders\", []];\n let bufferedCalls: BufferedCall[] = [];\n let settled = false;\n\n // Create a promise that resolves when the handler finishes and calls res.end()\n let endCalled: () => void;\n const endPromise = new Promise<void>(resolve => {\n endCalled = resolve;\n });\n\n res.writeHead = function (...args: Parameters<typeof originalWriteHead>) {\n if (!settled) {\n bufferedCalls.push([\"writeHead\", args]);\n return res;\n }\n return originalWriteHead(...args);\n } as typeof originalWriteHead;\n\n res.write = function (...args: Parameters<typeof originalWrite>) {\n if (!settled) {\n bufferedCalls.push([\"write\", args]);\n return true;\n }\n return originalWrite(...args);\n } as typeof originalWrite;\n\n res.end = function (...args: Parameters<typeof originalEnd>) {\n if (!settled) {\n bufferedCalls.push([\"end\", args]);\n // Signal that the handler has finished\n endCalled();\n return res;\n }\n return originalEnd(...args);\n } as typeof originalEnd;\n\n res.flushHeaders = function () {\n if (!settled) {\n bufferedCalls.push([\"flushHeaders\", []]);\n return;\n }\n return originalFlushHeaders();\n };\n\n // Proceed to the next middleware or route handler\n next();\n\n // Wait for the handler to actually call res.end() before checking status\n await endPromise;\n\n // If the response from the protected route is >= 400, do not settle payment\n if (res.statusCode >= 400) {\n settled = true;\n res.writeHead = originalWriteHead;\n res.write = originalWrite;\n res.end = originalEnd;\n res.flushHeaders = originalFlushHeaders;\n // Replay all buffered calls in order\n for (const [method, args] of bufferedCalls) {\n if (method === \"writeHead\")\n originalWriteHead(...(args as Parameters<typeof originalWriteHead>));\n else if (method === \"write\")\n originalWrite(...(args as Parameters<typeof originalWrite>));\n else if (method === \"end\") originalEnd(...(args as Parameters<typeof originalEnd>));\n else if (method === \"flushHeaders\") originalFlushHeaders();\n }\n bufferedCalls = [];\n return;\n }\n\n try {\n // Build response body buffer from buffered write/end calls\n const responseBody = Buffer.concat(\n bufferedCalls.flatMap(([m, args]) =>\n (m === \"write\" || m === \"end\") && args[0] ? [Buffer.from(args[0])] : [],\n ),\n );\n\n // Extract settlement overrides from response header (set by route handler)\n const overridesHeaderValue = res.getHeader(SETTLEMENT_OVERRIDES_HEADER);\n const responseHeaders: Record<string, string> = {};\n if (overridesHeaderValue) {\n responseHeaders[SETTLEMENT_OVERRIDES_HEADER] = String(overridesHeaderValue);\n res.removeHeader(SETTLEMENT_OVERRIDES_HEADER);\n }\n\n const settleResult = await httpServer.processSettlement(\n paymentPayload,\n paymentRequirements,\n declaredExtensions,\n { request: context, responseBody, responseHeaders },\n );\n\n // If settlement fails, return an error and do not send the buffered response\n if (!settleResult.success) {\n bufferedCalls = [];\n const { response } = settleResult;\n Object.entries(response.headers).forEach(([key, value]) => {\n res.setHeader(key, value);\n });\n if (response.isHtml) {\n res.status(response.status).send(response.body);\n } else {\n res.status(response.status).json(response.body ?? {});\n }\n return;\n }\n\n // Settlement succeeded - add headers to response\n Object.entries(settleResult.headers).forEach(([key, value]) => {\n res.setHeader(key, value);\n });\n } catch (error) {\n if (error instanceof FacilitatorResponseError) {\n bufferedCalls = [];\n sendFacilitatorError(res, error);\n return;\n }\n console.error(error);\n // If settlement fails, don't send the buffered response\n bufferedCalls = [];\n res.status(402).json({});\n return;\n } finally {\n settled = true;\n res.writeHead = originalWriteHead;\n res.write = originalWrite;\n res.end = originalEnd;\n res.flushHeaders = originalFlushHeaders;\n\n // Replay all buffered calls in order\n for (const [method, args] of bufferedCalls) {\n if (method === \"writeHead\")\n originalWriteHead(...(args as Parameters<typeof originalWriteHead>));\n else if (method === \"write\")\n originalWrite(...(args as Parameters<typeof originalWrite>));\n else if (method === \"end\") originalEnd(...(args as Parameters<typeof originalEnd>));\n else if (method === \"flushHeaders\") originalFlushHeaders();\n }\n bufferedCalls = [];\n }\n return;\n\n // ── period dispatch results ────────────────────────────────────────\n case \"payment-presettle\": {\n // period: settle BEFORE handler so the on-chain\n // subscription is created (or fails clean) before any handler\n // side-effects run. No buffering — handlers can stream responses.\n try {\n const settleResult = await result.settle();\n if (!settleResult.success) {\n res.status(402).json({\n error: settleResult.error ?? \"subscription settle failed\",\n });\n return;\n }\n if (settleResult.headers) {\n for (const [k, v] of Object.entries(settleResult.headers)) {\n res.setHeader(k, v);\n }\n }\n // Surface settle data onto req for handler consumption.\n // Top-level `subscription` mirrors the access-flow shape so handlers\n // read the same field regardless of whether the request created a\n // new sub (subscribe) or used an existing one (access).\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (req as any).x402 = {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ...(req as any).x402,\n subscription: settleResult.data?.subscription,\n subId: settleResult.data?.subId,\n paymentPayload: result.paymentPayload,\n paymentRequirements: result.paymentRequirements,\n settleResult,\n };\n return next();\n } catch (err) {\n if (err instanceof FacilitatorResponseError) {\n sendFacilitatorError(res, err);\n return;\n }\n console.error(\"payment-presettle error:\", err);\n res.status(402).json({\n error: err instanceof Error ? err.message : \"subscription settle threw\",\n });\n return;\n }\n }\n\n case \"access-verified\": {\n // No facilitator / no on-chain interaction here — verifyAccess already\n // ran in dispatch. We just attach the subscription onto req and\n // forward to the handler.\n if (result.headers) {\n for (const [k, v] of Object.entries(result.headers)) {\n res.setHeader(k, v);\n }\n }\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (req as any).x402 = {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ...(req as any).x402,\n subscription: result.subscription,\n };\n return next();\n }\n }\n };\n}\n\n/**\n * Express payment middleware for x402 protocol (direct server instance).\n *\n * Use this when you want to pass a pre-configured x402ResourceServer instance.\n * This provides more flexibility for testing, custom configuration, and reusing\n * server instances across multiple middlewares.\n *\n * @param routes - Route configurations for protected endpoints\n * @param server - Pre-configured x402ResourceServer instance\n * @param paywallConfig - Optional configuration for the built-in paywall UI\n * @param paywall - Optional custom paywall provider (overrides default)\n * @param syncFacilitatorOnStart - Whether to sync with the facilitator on startup (defaults to true)\n * @returns Express middleware handler\n *\n * @example\n * ```typescript\n * import { paymentMiddleware } from \"@okxweb3/app-x402-express\";\n *\n * const server = new x402ResourceServer(myFacilitatorClient)\n * .register(NETWORK, new ExactEvmScheme());\n *\n * app.use(paymentMiddleware(routes, server, paywallConfig));\n * ```\n */\nexport function paymentMiddleware(\n routes: RoutesConfig,\n server: x402ResourceServer,\n paywallConfig?: PaywallConfig,\n paywall?: PaywallProvider,\n syncFacilitatorOnStart: boolean = true,\n) {\n // Create the x402 HTTP server instance with the resource server\n const httpServer = new x402HTTPResourceServer(server, routes);\n\n return paymentMiddlewareFromHTTPServer(\n httpServer,\n paywallConfig,\n paywall,\n syncFacilitatorOnStart,\n );\n}\n\n/**\n * Express payment middleware for x402 protocol (configuration-based).\n *\n * Use this when you want to quickly set up middleware with simple configuration.\n * This function creates and configures the x402ResourceServer internally.\n *\n * @param routes - Route configurations for protected endpoints\n * @param facilitatorClients - Optional facilitator client(s) for payment processing\n * @param schemes - Optional array of scheme registrations for server-side payment processing\n * @param paywallConfig - Optional configuration for the built-in paywall UI\n * @param paywall - Optional custom paywall provider (overrides default)\n * @param syncFacilitatorOnStart - Whether to sync with the facilitator on startup (defaults to true)\n * @returns Express middleware handler\n *\n * @example\n * ```typescript\n * import { paymentMiddlewareFromConfig } from \"@okxweb3/app-x402-express\";\n *\n * app.use(paymentMiddlewareFromConfig(\n * routes,\n * myFacilitatorClient,\n * [{ network: \"eip155:196\", server: evmSchemeServer }],\n * paywallConfig\n * ));\n * ```\n */\nexport function paymentMiddlewareFromConfig(\n routes: RoutesConfig,\n facilitatorClients?: FacilitatorClient | FacilitatorClient[],\n schemes?: SchemeRegistration[],\n paywallConfig?: PaywallConfig,\n paywall?: PaywallProvider,\n syncFacilitatorOnStart: boolean = true,\n) {\n const ResourceServer = new x402ResourceServer(facilitatorClients);\n\n if (schemes) {\n schemes.forEach(({ network, server: schemeServer }) => {\n ResourceServer.register(network, schemeServer);\n });\n }\n\n return paymentMiddleware(routes, ResourceServer, paywallConfig, paywall, syncFacilitatorOnStart);\n}\n\nexport { x402ResourceServer, x402HTTPResourceServer } from \"@okxweb3/app-x402-core/server\";\n\nexport type {\n PaymentRequired,\n PaymentRequirements,\n PaymentPayload,\n Network,\n SchemeNetworkServer,\n} from \"@okxweb3/app-x402-core/types\";\n\nexport type {\n PaywallProvider,\n PaywallConfig,\n SettlementOverrides,\n} from \"@okxweb3/app-x402-core/server\";\n\nexport {\n RouteConfigurationError,\n SETTLEMENT_OVERRIDES_HEADER,\n} from \"@okxweb3/app-x402-core/server\";\n\nexport type { RouteValidationError } from \"@okxweb3/app-x402-core/server\";\n\nexport { ExpressAdapter } from \"./adapter\";\n","import { HTTPAdapter } from \"@okxweb3/app-x402-core/server\";\nimport { Request } from \"express\";\n\n/**\n * Express adapter implementation\n */\nexport class ExpressAdapter implements HTTPAdapter {\n /**\n * Creates a new ExpressAdapter instance.\n *\n * @param req - The Express request object\n */\n constructor(private req: Request) {}\n\n /**\n * Gets a header value from the request.\n *\n * @param name - The header name\n * @returns The header value or undefined\n */\n getHeader(name: string): string | undefined {\n const value = this.req.header(name);\n return Array.isArray(value) ? value[0] : value;\n }\n\n /**\n * Gets the HTTP method of the request.\n *\n * @returns The HTTP method\n */\n getMethod(): string {\n return this.req.method;\n }\n\n /**\n * Gets the path of the request.\n *\n * @returns The request path\n */\n getPath(): string {\n return this.req.path;\n }\n\n /**\n * Gets the full URL of the request.\n *\n * @returns The full request URL\n */\n getUrl(): string {\n return `${this.req.protocol}://${this.req.headers.host}${this.req.originalUrl}`;\n }\n\n /**\n * Gets the Accept header from the request.\n *\n * @returns The Accept header value or empty string\n */\n getAcceptHeader(): string {\n return this.req.header(\"Accept\") || \"\";\n }\n\n /**\n * Gets the User-Agent header from the request.\n *\n * @returns The User-Agent header value or empty string\n */\n getUserAgent(): string {\n return this.req.header(\"User-Agent\") || \"\";\n }\n\n /**\n * Gets all query parameters from the request URL.\n *\n * @returns Record of query parameter key-value pairs\n */\n getQueryParams(): Record<string, string | string[]> {\n return this.req.query as Record<string, string | string[]>;\n }\n\n /**\n * Gets a specific query parameter by name.\n *\n * @param name - The query parameter name\n * @returns The query parameter value(s) or undefined\n */\n getQueryParam(name: string): string | string[] | undefined {\n const value = this.req.query[name];\n return value as string | string[] | undefined;\n }\n\n /**\n * Gets the parsed request body.\n * Requires express.json() or express.urlencoded() middleware.\n *\n * @returns The parsed request body\n */\n getBody(): unknown {\n return this.req.body;\n }\n\n /**\n * Return all request headers as a lowercase-keyed map.\n * Multi-value headers are joined with \", \".\n */\n getHeaders(): Record<string, string> {\n const out: Record<string, string> = {};\n for (const [k, v] of Object.entries(this.req.headers)) {\n if (v == null) continue;\n out[k.toLowerCase()] = Array.isArray(v) ? v.join(\", \") : String(v);\n }\n return out;\n }\n}\n"],"mappings":"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","names":["import_server","response"]}
@@ -72,6 +72,11 @@ declare class ExpressAdapter implements HTTPAdapter {
72
72
  * @returns The parsed request body
73
73
  */
74
74
  getBody(): unknown;
75
+ /**
76
+ * Return all request headers as a lowercase-keyed map.
77
+ * Multi-value headers are joined with ", ".
78
+ */
79
+ getHeaders(): Record<string, string>;
75
80
  }
76
81
 
77
82
  /**
@@ -94,11 +94,26 @@ var ExpressAdapter = class {
94
94
  getBody() {
95
95
  return this.req.body;
96
96
  }
97
+ /**
98
+ * Return all request headers as a lowercase-keyed map.
99
+ * Multi-value headers are joined with ", ".
100
+ */
101
+ getHeaders() {
102
+ const out = {};
103
+ for (const [k, v] of Object.entries(this.req.headers)) {
104
+ if (v == null) continue;
105
+ out[k.toLowerCase()] = Array.isArray(v) ? v.join(", ") : String(v);
106
+ }
107
+ return out;
108
+ }
97
109
  };
98
110
 
99
111
  // src/index.ts
100
112
  import { x402ResourceServer as x402ResourceServer2, x402HTTPResourceServer as x402HTTPResourceServer2 } from "@okxweb3/app-x402-core/server";
101
- import { RouteConfigurationError, SETTLEMENT_OVERRIDES_HEADER as SETTLEMENT_OVERRIDES_HEADER2 } from "@okxweb3/app-x402-core/server";
113
+ import {
114
+ RouteConfigurationError,
115
+ SETTLEMENT_OVERRIDES_HEADER as SETTLEMENT_OVERRIDES_HEADER2
116
+ } from "@okxweb3/app-x402-core/server";
102
117
  function setSettlementOverrides(res, overrides) {
103
118
  res.setHeader(SETTLEMENT_OVERRIDES_HEADER, JSON.stringify(overrides));
104
119
  }
@@ -127,6 +142,7 @@ function paymentMiddlewareFromHTTPServer(httpServer, paywallConfig, paywall, syn
127
142
  }
128
143
  }
129
144
  return async (req, res, next) => {
145
+ var _a, _b;
130
146
  const adapter = new ExpressAdapter(req);
131
147
  const context = {
132
148
  adapter,
@@ -295,6 +311,56 @@ function paymentMiddlewareFromHTTPServer(httpServer, paywallConfig, paywall, syn
295
311
  bufferedCalls = [];
296
312
  }
297
313
  return;
314
+ // ── period dispatch results ────────────────────────────────────────
315
+ case "payment-presettle": {
316
+ try {
317
+ const settleResult = await result.settle();
318
+ if (!settleResult.success) {
319
+ res.status(402).json({
320
+ error: settleResult.error ?? "subscription settle failed"
321
+ });
322
+ return;
323
+ }
324
+ if (settleResult.headers) {
325
+ for (const [k, v] of Object.entries(settleResult.headers)) {
326
+ res.setHeader(k, v);
327
+ }
328
+ }
329
+ req.x402 = {
330
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
331
+ ...req.x402,
332
+ subscription: (_a = settleResult.data) == null ? void 0 : _a.subscription,
333
+ subId: (_b = settleResult.data) == null ? void 0 : _b.subId,
334
+ paymentPayload: result.paymentPayload,
335
+ paymentRequirements: result.paymentRequirements,
336
+ settleResult
337
+ };
338
+ return next();
339
+ } catch (err) {
340
+ if (err instanceof FacilitatorResponseError) {
341
+ sendFacilitatorError(res, err);
342
+ return;
343
+ }
344
+ console.error("payment-presettle error:", err);
345
+ res.status(402).json({
346
+ error: err instanceof Error ? err.message : "subscription settle threw"
347
+ });
348
+ return;
349
+ }
350
+ }
351
+ case "access-verified": {
352
+ if (result.headers) {
353
+ for (const [k, v] of Object.entries(result.headers)) {
354
+ res.setHeader(k, v);
355
+ }
356
+ }
357
+ req.x402 = {
358
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
359
+ ...req.x402,
360
+ subscription: result.subscription
361
+ };
362
+ return next();
363
+ }
298
364
  }
299
365
  };
300
366
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/index.ts","../../src/adapter.ts"],"sourcesContent":["import {\n HTTPRequestContext,\n PaywallConfig,\n PaywallProvider,\n x402HTTPResourceServer,\n x402ResourceServer,\n RoutesConfig,\n FacilitatorClient,\n FacilitatorResponseError,\n getFacilitatorResponseError,\n SETTLEMENT_OVERRIDES_HEADER,\n SettlementOverrides,\n} from \"@okxweb3/app-x402-core/server\";\nimport { SchemeNetworkServer, Network } from \"@okxweb3/app-x402-core/types\";\nimport { NextFunction, Request, Response } from \"express\";\nimport { ExpressAdapter } from \"./adapter\";\n\n/**\n * Set settlement overrides on the response for partial settlement.\n * The middleware will extract these before settlement and strip the header from the client response.\n *\n * @param res - Express response object\n * @param overrides - Settlement overrides (e.g., { amount: \"500\" } for partial settlement)\n */\nexport function setSettlementOverrides(res: Response, overrides: SettlementOverrides): void {\n res.setHeader(SETTLEMENT_OVERRIDES_HEADER, JSON.stringify(overrides));\n}\n\n/**\n * Configuration for registering a payment scheme with a specific network\n */\nexport interface SchemeRegistration {\n /**\n * The network identifier (e.g., 'eip155:196', 'eip155:196')\n */\n network: Network;\n\n /**\n * The scheme server implementation for this network\n */\n server: SchemeNetworkServer;\n}\n\n/**\n * Sends a normalized 502 response for facilitator boundary failures.\n *\n * @param res - The Express response to write to\n * @param error - The facilitator response error to surface\n */\nfunction sendFacilitatorError(res: Response, error: FacilitatorResponseError): void {\n res.status(502).json({ error: error.message });\n}\n\n/**\n * Express payment middleware for x402 protocol (direct HTTP server instance).\n *\n * Use this when you need to configure HTTP-level hooks.\n *\n * @param httpServer - Pre-configured x402HTTPResourceServer instance\n * @param paywallConfig - Optional configuration for the built-in paywall UI\n * @param paywall - Optional custom paywall provider (overrides default)\n * @param syncFacilitatorOnStart - Whether to sync with the facilitator on startup (defaults to true)\n * @returns Express middleware handler\n *\n * @example\n * ```typescript\n * import { paymentMiddlewareFromHTTPServer, x402ResourceServer, x402HTTPResourceServer } from \"@okxweb3/app-x402-express\";\n *\n * const resourceServer = new x402ResourceServer(facilitatorClient)\n * .register(NETWORK, new ExactEvmScheme())\n *\n * const httpServer = new x402HTTPResourceServer(resourceServer, routes)\n * .onProtectedRequest(requestHook);\n *\n * app.use(paymentMiddlewareFromHTTPServer(httpServer));\n * ```\n */\nexport function paymentMiddlewareFromHTTPServer(\n httpServer: x402HTTPResourceServer,\n paywallConfig?: PaywallConfig,\n paywall?: PaywallProvider,\n syncFacilitatorOnStart: boolean = true,\n) {\n // Register custom paywall provider if provided\n if (paywall) {\n httpServer.registerPaywallProvider(paywall);\n }\n\n // Store initialization promise (not the result)\n // httpServer.initialize() fetches facilitator support and validates routes\n let initPromise: Promise<void> | null = syncFacilitatorOnStart ? httpServer.initialize() : null;\n let isInitialized = false;\n\n /**\n * Ensures facilitator initialization succeeds once, while allowing retries after failures.\n */\n async function initializeHttpServer(): Promise<void> {\n if (!syncFacilitatorOnStart || isInitialized) {\n return;\n }\n\n if (!initPromise) {\n initPromise = httpServer.initialize();\n }\n\n try {\n await initPromise;\n isInitialized = true;\n } catch (error) {\n initPromise = null;\n throw error;\n }\n }\n\n return async (req: Request, res: Response, next: NextFunction) => {\n // Create adapter and context\n const adapter = new ExpressAdapter(req);\n const context: HTTPRequestContext = {\n adapter,\n path: req.path,\n method: req.method,\n paymentHeader: adapter.getHeader(\"payment-signature\") || adapter.getHeader(\"x-payment\"),\n };\n\n // Check if route requires payment before initializing facilitator\n if (!httpServer.requiresPayment(context)) {\n return next();\n }\n\n // Only initialize when processing a protected route\n if (syncFacilitatorOnStart && !isInitialized) {\n try {\n await initializeHttpServer();\n } catch (error) {\n const facilitatorError = getFacilitatorResponseError(error);\n if (facilitatorError) {\n sendFacilitatorError(res, facilitatorError);\n return;\n }\n return next(error);\n }\n }\n\n // Process payment requirement check\n let result: Awaited<ReturnType<x402HTTPResourceServer[\"processHTTPRequest\"]>>;\n try {\n result = await httpServer.processHTTPRequest(context, paywallConfig);\n } catch (error) {\n if (error instanceof FacilitatorResponseError) {\n sendFacilitatorError(res, error);\n return;\n }\n return next(error);\n }\n\n // Handle the different result types\n switch (result.type) {\n case \"no-payment-required\":\n // No payment needed, proceed directly to the route handler\n return next();\n\n case \"payment-error\":\n // Payment required but not provided or invalid\n const { response } = result;\n res.status(response.status);\n Object.entries(response.headers).forEach(([key, value]) => {\n res.setHeader(key, value);\n });\n if (response.isHtml) {\n res.send(response.body);\n } else {\n res.json(response.body || {});\n }\n return;\n\n case \"payment-verified\":\n // Payment is valid, need to wrap response for settlement\n const { paymentPayload, paymentRequirements, declaredExtensions } = result;\n\n // Intercept and buffer all core methods that can commit response to client\n const originalWriteHead = res.writeHead.bind(res);\n const originalWrite = res.write.bind(res);\n const originalEnd = res.end.bind(res);\n const originalFlushHeaders = res.flushHeaders.bind(res);\n\n type BufferedCall =\n | [\"writeHead\", Parameters<typeof originalWriteHead>]\n | [\"write\", Parameters<typeof originalWrite>]\n | [\"end\", Parameters<typeof originalEnd>]\n | [\"flushHeaders\", []];\n let bufferedCalls: BufferedCall[] = [];\n let settled = false;\n\n // Create a promise that resolves when the handler finishes and calls res.end()\n let endCalled: () => void;\n const endPromise = new Promise<void>(resolve => {\n endCalled = resolve;\n });\n\n res.writeHead = function (...args: Parameters<typeof originalWriteHead>) {\n if (!settled) {\n bufferedCalls.push([\"writeHead\", args]);\n return res;\n }\n return originalWriteHead(...args);\n } as typeof originalWriteHead;\n\n res.write = function (...args: Parameters<typeof originalWrite>) {\n if (!settled) {\n bufferedCalls.push([\"write\", args]);\n return true;\n }\n return originalWrite(...args);\n } as typeof originalWrite;\n\n res.end = function (...args: Parameters<typeof originalEnd>) {\n if (!settled) {\n bufferedCalls.push([\"end\", args]);\n // Signal that the handler has finished\n endCalled();\n return res;\n }\n return originalEnd(...args);\n } as typeof originalEnd;\n\n res.flushHeaders = function () {\n if (!settled) {\n bufferedCalls.push([\"flushHeaders\", []]);\n return;\n }\n return originalFlushHeaders();\n };\n\n // Proceed to the next middleware or route handler\n next();\n\n // Wait for the handler to actually call res.end() before checking status\n await endPromise;\n\n // If the response from the protected route is >= 400, do not settle payment\n if (res.statusCode >= 400) {\n settled = true;\n res.writeHead = originalWriteHead;\n res.write = originalWrite;\n res.end = originalEnd;\n res.flushHeaders = originalFlushHeaders;\n // Replay all buffered calls in order\n for (const [method, args] of bufferedCalls) {\n if (method === \"writeHead\")\n originalWriteHead(...(args as Parameters<typeof originalWriteHead>));\n else if (method === \"write\")\n originalWrite(...(args as Parameters<typeof originalWrite>));\n else if (method === \"end\") originalEnd(...(args as Parameters<typeof originalEnd>));\n else if (method === \"flushHeaders\") originalFlushHeaders();\n }\n bufferedCalls = [];\n return;\n }\n\n try {\n // Build response body buffer from buffered write/end calls\n const responseBody = Buffer.concat(\n bufferedCalls.flatMap(([m, args]) =>\n (m === \"write\" || m === \"end\") && args[0] ? [Buffer.from(args[0])] : [],\n ),\n );\n\n // Extract settlement overrides from response header (set by route handler)\n const overridesHeaderValue = res.getHeader(SETTLEMENT_OVERRIDES_HEADER);\n const responseHeaders: Record<string, string> = {};\n if (overridesHeaderValue) {\n responseHeaders[SETTLEMENT_OVERRIDES_HEADER] = String(overridesHeaderValue);\n res.removeHeader(SETTLEMENT_OVERRIDES_HEADER);\n }\n\n const settleResult = await httpServer.processSettlement(\n paymentPayload,\n paymentRequirements,\n declaredExtensions,\n { request: context, responseBody, responseHeaders },\n );\n\n // If settlement fails, return an error and do not send the buffered response\n if (!settleResult.success) {\n bufferedCalls = [];\n const { response } = settleResult;\n Object.entries(response.headers).forEach(([key, value]) => {\n res.setHeader(key, value);\n });\n if (response.isHtml) {\n res.status(response.status).send(response.body);\n } else {\n res.status(response.status).json(response.body ?? {});\n }\n return;\n }\n\n // Settlement succeeded - add headers to response\n Object.entries(settleResult.headers).forEach(([key, value]) => {\n res.setHeader(key, value);\n });\n } catch (error) {\n if (error instanceof FacilitatorResponseError) {\n bufferedCalls = [];\n sendFacilitatorError(res, error);\n return;\n }\n console.error(error);\n // If settlement fails, don't send the buffered response\n bufferedCalls = [];\n res.status(402).json({});\n return;\n } finally {\n settled = true;\n res.writeHead = originalWriteHead;\n res.write = originalWrite;\n res.end = originalEnd;\n res.flushHeaders = originalFlushHeaders;\n\n // Replay all buffered calls in order\n for (const [method, args] of bufferedCalls) {\n if (method === \"writeHead\")\n originalWriteHead(...(args as Parameters<typeof originalWriteHead>));\n else if (method === \"write\")\n originalWrite(...(args as Parameters<typeof originalWrite>));\n else if (method === \"end\") originalEnd(...(args as Parameters<typeof originalEnd>));\n else if (method === \"flushHeaders\") originalFlushHeaders();\n }\n bufferedCalls = [];\n }\n return;\n }\n };\n}\n\n/**\n * Express payment middleware for x402 protocol (direct server instance).\n *\n * Use this when you want to pass a pre-configured x402ResourceServer instance.\n * This provides more flexibility for testing, custom configuration, and reusing\n * server instances across multiple middlewares.\n *\n * @param routes - Route configurations for protected endpoints\n * @param server - Pre-configured x402ResourceServer instance\n * @param paywallConfig - Optional configuration for the built-in paywall UI\n * @param paywall - Optional custom paywall provider (overrides default)\n * @param syncFacilitatorOnStart - Whether to sync with the facilitator on startup (defaults to true)\n * @returns Express middleware handler\n *\n * @example\n * ```typescript\n * import { paymentMiddleware } from \"@okxweb3/app-x402-express\";\n *\n * const server = new x402ResourceServer(myFacilitatorClient)\n * .register(NETWORK, new ExactEvmScheme());\n *\n * app.use(paymentMiddleware(routes, server, paywallConfig));\n * ```\n */\nexport function paymentMiddleware(\n routes: RoutesConfig,\n server: x402ResourceServer,\n paywallConfig?: PaywallConfig,\n paywall?: PaywallProvider,\n syncFacilitatorOnStart: boolean = true,\n) {\n // Create the x402 HTTP server instance with the resource server\n const httpServer = new x402HTTPResourceServer(server, routes);\n\n return paymentMiddlewareFromHTTPServer(\n httpServer,\n paywallConfig,\n paywall,\n syncFacilitatorOnStart,\n );\n}\n\n/**\n * Express payment middleware for x402 protocol (configuration-based).\n *\n * Use this when you want to quickly set up middleware with simple configuration.\n * This function creates and configures the x402ResourceServer internally.\n *\n * @param routes - Route configurations for protected endpoints\n * @param facilitatorClients - Optional facilitator client(s) for payment processing\n * @param schemes - Optional array of scheme registrations for server-side payment processing\n * @param paywallConfig - Optional configuration for the built-in paywall UI\n * @param paywall - Optional custom paywall provider (overrides default)\n * @param syncFacilitatorOnStart - Whether to sync with the facilitator on startup (defaults to true)\n * @returns Express middleware handler\n *\n * @example\n * ```typescript\n * import { paymentMiddlewareFromConfig } from \"@okxweb3/app-x402-express\";\n *\n * app.use(paymentMiddlewareFromConfig(\n * routes,\n * myFacilitatorClient,\n * [{ network: \"eip155:196\", server: evmSchemeServer }],\n * paywallConfig\n * ));\n * ```\n */\nexport function paymentMiddlewareFromConfig(\n routes: RoutesConfig,\n facilitatorClients?: FacilitatorClient | FacilitatorClient[],\n schemes?: SchemeRegistration[],\n paywallConfig?: PaywallConfig,\n paywall?: PaywallProvider,\n syncFacilitatorOnStart: boolean = true,\n) {\n const ResourceServer = new x402ResourceServer(facilitatorClients);\n\n if (schemes) {\n schemes.forEach(({ network, server: schemeServer }) => {\n ResourceServer.register(network, schemeServer);\n });\n }\n\n return paymentMiddleware(routes, ResourceServer, paywallConfig, paywall, syncFacilitatorOnStart);\n}\n\nexport { x402ResourceServer, x402HTTPResourceServer } from \"@okxweb3/app-x402-core/server\";\n\nexport type {\n PaymentRequired,\n PaymentRequirements,\n PaymentPayload,\n Network,\n SchemeNetworkServer,\n} from \"@okxweb3/app-x402-core/types\";\n\nexport type {\n PaywallProvider,\n PaywallConfig,\n SettlementOverrides,\n} from \"@okxweb3/app-x402-core/server\";\n\nexport { RouteConfigurationError, SETTLEMENT_OVERRIDES_HEADER } from \"@okxweb3/app-x402-core/server\";\n\nexport type { RouteValidationError } from \"@okxweb3/app-x402-core/server\";\n\nexport { ExpressAdapter } from \"./adapter\";\n","import { HTTPAdapter } from \"@okxweb3/app-x402-core/server\";\nimport { Request } from \"express\";\n\n/**\n * Express adapter implementation\n */\nexport class ExpressAdapter implements HTTPAdapter {\n /**\n * Creates a new ExpressAdapter instance.\n *\n * @param req - The Express request object\n */\n constructor(private req: Request) {}\n\n /**\n * Gets a header value from the request.\n *\n * @param name - The header name\n * @returns The header value or undefined\n */\n getHeader(name: string): string | undefined {\n const value = this.req.header(name);\n return Array.isArray(value) ? value[0] : value;\n }\n\n /**\n * Gets the HTTP method of the request.\n *\n * @returns The HTTP method\n */\n getMethod(): string {\n return this.req.method;\n }\n\n /**\n * Gets the path of the request.\n *\n * @returns The request path\n */\n getPath(): string {\n return this.req.path;\n }\n\n /**\n * Gets the full URL of the request.\n *\n * @returns The full request URL\n */\n getUrl(): string {\n return `${this.req.protocol}://${this.req.headers.host}${this.req.originalUrl}`;\n }\n\n /**\n * Gets the Accept header from the request.\n *\n * @returns The Accept header value or empty string\n */\n getAcceptHeader(): string {\n return this.req.header(\"Accept\") || \"\";\n }\n\n /**\n * Gets the User-Agent header from the request.\n *\n * @returns The User-Agent header value or empty string\n */\n getUserAgent(): string {\n return this.req.header(\"User-Agent\") || \"\";\n }\n\n /**\n * Gets all query parameters from the request URL.\n *\n * @returns Record of query parameter key-value pairs\n */\n getQueryParams(): Record<string, string | string[]> {\n return this.req.query as Record<string, string | string[]>;\n }\n\n /**\n * Gets a specific query parameter by name.\n *\n * @param name - The query parameter name\n * @returns The query parameter value(s) or undefined\n */\n getQueryParam(name: string): string | string[] | undefined {\n const value = this.req.query[name];\n return value as string | string[] | undefined;\n }\n\n /**\n * Gets the parsed request body.\n * Requires express.json() or express.urlencoded() middleware.\n *\n * @returns The parsed request body\n */\n getBody(): unknown {\n return this.req.body;\n }\n}\n"],"mappings":"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","names":["x402ResourceServer","x402HTTPResourceServer","SETTLEMENT_OVERRIDES_HEADER","response"]}
1
+ {"version":3,"sources":["../../src/index.ts","../../src/adapter.ts"],"sourcesContent":["import {\n HTTPRequestContext,\n PaywallConfig,\n PaywallProvider,\n x402HTTPResourceServer,\n x402ResourceServer,\n RoutesConfig,\n FacilitatorClient,\n FacilitatorResponseError,\n getFacilitatorResponseError,\n SETTLEMENT_OVERRIDES_HEADER,\n SettlementOverrides,\n} from \"@okxweb3/app-x402-core/server\";\nimport { SchemeNetworkServer, Network } from \"@okxweb3/app-x402-core/types\";\nimport { NextFunction, Request, Response } from \"express\";\nimport { ExpressAdapter } from \"./adapter\";\n\n/**\n * Set settlement overrides on the response for partial settlement.\n * The middleware will extract these before settlement and strip the header from the client response.\n *\n * @param res - Express response object\n * @param overrides - Settlement overrides (e.g., { amount: \"500\" } for partial settlement)\n */\nexport function setSettlementOverrides(res: Response, overrides: SettlementOverrides): void {\n res.setHeader(SETTLEMENT_OVERRIDES_HEADER, JSON.stringify(overrides));\n}\n\n/**\n * Configuration for registering a payment scheme with a specific network\n */\nexport interface SchemeRegistration {\n /**\n * The network identifier (e.g., 'eip155:196', 'eip155:196')\n */\n network: Network;\n\n /**\n * The scheme server implementation for this network\n */\n server: SchemeNetworkServer;\n}\n\n/**\n * Sends a normalized 502 response for facilitator boundary failures.\n *\n * @param res - The Express response to write to\n * @param error - The facilitator response error to surface\n */\nfunction sendFacilitatorError(res: Response, error: FacilitatorResponseError): void {\n res.status(502).json({ error: error.message });\n}\n\n/**\n * Express payment middleware for x402 protocol (direct HTTP server instance).\n *\n * Use this when you need to configure HTTP-level hooks.\n *\n * @param httpServer - Pre-configured x402HTTPResourceServer instance\n * @param paywallConfig - Optional configuration for the built-in paywall UI\n * @param paywall - Optional custom paywall provider (overrides default)\n * @param syncFacilitatorOnStart - Whether to sync with the facilitator on startup (defaults to true)\n * @returns Express middleware handler\n *\n * @example\n * ```typescript\n * import { paymentMiddlewareFromHTTPServer, x402ResourceServer, x402HTTPResourceServer } from \"@okxweb3/app-x402-express\";\n *\n * const resourceServer = new x402ResourceServer(facilitatorClient)\n * .register(NETWORK, new ExactEvmScheme())\n *\n * const httpServer = new x402HTTPResourceServer(resourceServer, routes)\n * .onProtectedRequest(requestHook);\n *\n * app.use(paymentMiddlewareFromHTTPServer(httpServer));\n * ```\n */\nexport function paymentMiddlewareFromHTTPServer(\n httpServer: x402HTTPResourceServer,\n paywallConfig?: PaywallConfig,\n paywall?: PaywallProvider,\n syncFacilitatorOnStart: boolean = true,\n) {\n // Register custom paywall provider if provided\n if (paywall) {\n httpServer.registerPaywallProvider(paywall);\n }\n\n // Store initialization promise (not the result)\n // httpServer.initialize() fetches facilitator support and validates routes\n let initPromise: Promise<void> | null = syncFacilitatorOnStart ? httpServer.initialize() : null;\n let isInitialized = false;\n\n /**\n * Ensures facilitator initialization succeeds once, while allowing retries after failures.\n */\n async function initializeHttpServer(): Promise<void> {\n if (!syncFacilitatorOnStart || isInitialized) {\n return;\n }\n\n if (!initPromise) {\n initPromise = httpServer.initialize();\n }\n\n try {\n await initPromise;\n isInitialized = true;\n } catch (error) {\n initPromise = null;\n throw error;\n }\n }\n\n return async (req: Request, res: Response, next: NextFunction) => {\n // Create adapter and context\n const adapter = new ExpressAdapter(req);\n const context: HTTPRequestContext = {\n adapter,\n path: req.path,\n method: req.method,\n paymentHeader: adapter.getHeader(\"payment-signature\") || adapter.getHeader(\"x-payment\"),\n };\n\n // Check if route requires payment before initializing facilitator\n if (!httpServer.requiresPayment(context)) {\n return next();\n }\n\n // Only initialize when processing a protected route\n if (syncFacilitatorOnStart && !isInitialized) {\n try {\n await initializeHttpServer();\n } catch (error) {\n const facilitatorError = getFacilitatorResponseError(error);\n if (facilitatorError) {\n sendFacilitatorError(res, facilitatorError);\n return;\n }\n return next(error);\n }\n }\n\n // Process payment requirement check\n let result: Awaited<ReturnType<x402HTTPResourceServer[\"processHTTPRequest\"]>>;\n try {\n result = await httpServer.processHTTPRequest(context, paywallConfig);\n } catch (error) {\n if (error instanceof FacilitatorResponseError) {\n sendFacilitatorError(res, error);\n return;\n }\n return next(error);\n }\n\n // Handle the different result types\n switch (result.type) {\n case \"no-payment-required\":\n // No payment needed, proceed directly to the route handler\n return next();\n\n case \"payment-error\":\n // Payment required but not provided or invalid\n const { response } = result;\n res.status(response.status);\n Object.entries(response.headers).forEach(([key, value]) => {\n res.setHeader(key, value);\n });\n if (response.isHtml) {\n res.send(response.body);\n } else {\n res.json(response.body || {});\n }\n return;\n\n case \"payment-verified\":\n // Payment is valid, need to wrap response for settlement\n const { paymentPayload, paymentRequirements, declaredExtensions } = result;\n\n // Intercept and buffer all core methods that can commit response to client\n const originalWriteHead = res.writeHead.bind(res);\n const originalWrite = res.write.bind(res);\n const originalEnd = res.end.bind(res);\n const originalFlushHeaders = res.flushHeaders.bind(res);\n\n type BufferedCall =\n | [\"writeHead\", Parameters<typeof originalWriteHead>]\n | [\"write\", Parameters<typeof originalWrite>]\n | [\"end\", Parameters<typeof originalEnd>]\n | [\"flushHeaders\", []];\n let bufferedCalls: BufferedCall[] = [];\n let settled = false;\n\n // Create a promise that resolves when the handler finishes and calls res.end()\n let endCalled: () => void;\n const endPromise = new Promise<void>(resolve => {\n endCalled = resolve;\n });\n\n res.writeHead = function (...args: Parameters<typeof originalWriteHead>) {\n if (!settled) {\n bufferedCalls.push([\"writeHead\", args]);\n return res;\n }\n return originalWriteHead(...args);\n } as typeof originalWriteHead;\n\n res.write = function (...args: Parameters<typeof originalWrite>) {\n if (!settled) {\n bufferedCalls.push([\"write\", args]);\n return true;\n }\n return originalWrite(...args);\n } as typeof originalWrite;\n\n res.end = function (...args: Parameters<typeof originalEnd>) {\n if (!settled) {\n bufferedCalls.push([\"end\", args]);\n // Signal that the handler has finished\n endCalled();\n return res;\n }\n return originalEnd(...args);\n } as typeof originalEnd;\n\n res.flushHeaders = function () {\n if (!settled) {\n bufferedCalls.push([\"flushHeaders\", []]);\n return;\n }\n return originalFlushHeaders();\n };\n\n // Proceed to the next middleware or route handler\n next();\n\n // Wait for the handler to actually call res.end() before checking status\n await endPromise;\n\n // If the response from the protected route is >= 400, do not settle payment\n if (res.statusCode >= 400) {\n settled = true;\n res.writeHead = originalWriteHead;\n res.write = originalWrite;\n res.end = originalEnd;\n res.flushHeaders = originalFlushHeaders;\n // Replay all buffered calls in order\n for (const [method, args] of bufferedCalls) {\n if (method === \"writeHead\")\n originalWriteHead(...(args as Parameters<typeof originalWriteHead>));\n else if (method === \"write\")\n originalWrite(...(args as Parameters<typeof originalWrite>));\n else if (method === \"end\") originalEnd(...(args as Parameters<typeof originalEnd>));\n else if (method === \"flushHeaders\") originalFlushHeaders();\n }\n bufferedCalls = [];\n return;\n }\n\n try {\n // Build response body buffer from buffered write/end calls\n const responseBody = Buffer.concat(\n bufferedCalls.flatMap(([m, args]) =>\n (m === \"write\" || m === \"end\") && args[0] ? [Buffer.from(args[0])] : [],\n ),\n );\n\n // Extract settlement overrides from response header (set by route handler)\n const overridesHeaderValue = res.getHeader(SETTLEMENT_OVERRIDES_HEADER);\n const responseHeaders: Record<string, string> = {};\n if (overridesHeaderValue) {\n responseHeaders[SETTLEMENT_OVERRIDES_HEADER] = String(overridesHeaderValue);\n res.removeHeader(SETTLEMENT_OVERRIDES_HEADER);\n }\n\n const settleResult = await httpServer.processSettlement(\n paymentPayload,\n paymentRequirements,\n declaredExtensions,\n { request: context, responseBody, responseHeaders },\n );\n\n // If settlement fails, return an error and do not send the buffered response\n if (!settleResult.success) {\n bufferedCalls = [];\n const { response } = settleResult;\n Object.entries(response.headers).forEach(([key, value]) => {\n res.setHeader(key, value);\n });\n if (response.isHtml) {\n res.status(response.status).send(response.body);\n } else {\n res.status(response.status).json(response.body ?? {});\n }\n return;\n }\n\n // Settlement succeeded - add headers to response\n Object.entries(settleResult.headers).forEach(([key, value]) => {\n res.setHeader(key, value);\n });\n } catch (error) {\n if (error instanceof FacilitatorResponseError) {\n bufferedCalls = [];\n sendFacilitatorError(res, error);\n return;\n }\n console.error(error);\n // If settlement fails, don't send the buffered response\n bufferedCalls = [];\n res.status(402).json({});\n return;\n } finally {\n settled = true;\n res.writeHead = originalWriteHead;\n res.write = originalWrite;\n res.end = originalEnd;\n res.flushHeaders = originalFlushHeaders;\n\n // Replay all buffered calls in order\n for (const [method, args] of bufferedCalls) {\n if (method === \"writeHead\")\n originalWriteHead(...(args as Parameters<typeof originalWriteHead>));\n else if (method === \"write\")\n originalWrite(...(args as Parameters<typeof originalWrite>));\n else if (method === \"end\") originalEnd(...(args as Parameters<typeof originalEnd>));\n else if (method === \"flushHeaders\") originalFlushHeaders();\n }\n bufferedCalls = [];\n }\n return;\n\n // ── period dispatch results ────────────────────────────────────────\n case \"payment-presettle\": {\n // period: settle BEFORE handler so the on-chain\n // subscription is created (or fails clean) before any handler\n // side-effects run. No buffering — handlers can stream responses.\n try {\n const settleResult = await result.settle();\n if (!settleResult.success) {\n res.status(402).json({\n error: settleResult.error ?? \"subscription settle failed\",\n });\n return;\n }\n if (settleResult.headers) {\n for (const [k, v] of Object.entries(settleResult.headers)) {\n res.setHeader(k, v);\n }\n }\n // Surface settle data onto req for handler consumption.\n // Top-level `subscription` mirrors the access-flow shape so handlers\n // read the same field regardless of whether the request created a\n // new sub (subscribe) or used an existing one (access).\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (req as any).x402 = {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ...(req as any).x402,\n subscription: settleResult.data?.subscription,\n subId: settleResult.data?.subId,\n paymentPayload: result.paymentPayload,\n paymentRequirements: result.paymentRequirements,\n settleResult,\n };\n return next();\n } catch (err) {\n if (err instanceof FacilitatorResponseError) {\n sendFacilitatorError(res, err);\n return;\n }\n console.error(\"payment-presettle error:\", err);\n res.status(402).json({\n error: err instanceof Error ? err.message : \"subscription settle threw\",\n });\n return;\n }\n }\n\n case \"access-verified\": {\n // No facilitator / no on-chain interaction here — verifyAccess already\n // ran in dispatch. We just attach the subscription onto req and\n // forward to the handler.\n if (result.headers) {\n for (const [k, v] of Object.entries(result.headers)) {\n res.setHeader(k, v);\n }\n }\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (req as any).x402 = {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ...(req as any).x402,\n subscription: result.subscription,\n };\n return next();\n }\n }\n };\n}\n\n/**\n * Express payment middleware for x402 protocol (direct server instance).\n *\n * Use this when you want to pass a pre-configured x402ResourceServer instance.\n * This provides more flexibility for testing, custom configuration, and reusing\n * server instances across multiple middlewares.\n *\n * @param routes - Route configurations for protected endpoints\n * @param server - Pre-configured x402ResourceServer instance\n * @param paywallConfig - Optional configuration for the built-in paywall UI\n * @param paywall - Optional custom paywall provider (overrides default)\n * @param syncFacilitatorOnStart - Whether to sync with the facilitator on startup (defaults to true)\n * @returns Express middleware handler\n *\n * @example\n * ```typescript\n * import { paymentMiddleware } from \"@okxweb3/app-x402-express\";\n *\n * const server = new x402ResourceServer(myFacilitatorClient)\n * .register(NETWORK, new ExactEvmScheme());\n *\n * app.use(paymentMiddleware(routes, server, paywallConfig));\n * ```\n */\nexport function paymentMiddleware(\n routes: RoutesConfig,\n server: x402ResourceServer,\n paywallConfig?: PaywallConfig,\n paywall?: PaywallProvider,\n syncFacilitatorOnStart: boolean = true,\n) {\n // Create the x402 HTTP server instance with the resource server\n const httpServer = new x402HTTPResourceServer(server, routes);\n\n return paymentMiddlewareFromHTTPServer(\n httpServer,\n paywallConfig,\n paywall,\n syncFacilitatorOnStart,\n );\n}\n\n/**\n * Express payment middleware for x402 protocol (configuration-based).\n *\n * Use this when you want to quickly set up middleware with simple configuration.\n * This function creates and configures the x402ResourceServer internally.\n *\n * @param routes - Route configurations for protected endpoints\n * @param facilitatorClients - Optional facilitator client(s) for payment processing\n * @param schemes - Optional array of scheme registrations for server-side payment processing\n * @param paywallConfig - Optional configuration for the built-in paywall UI\n * @param paywall - Optional custom paywall provider (overrides default)\n * @param syncFacilitatorOnStart - Whether to sync with the facilitator on startup (defaults to true)\n * @returns Express middleware handler\n *\n * @example\n * ```typescript\n * import { paymentMiddlewareFromConfig } from \"@okxweb3/app-x402-express\";\n *\n * app.use(paymentMiddlewareFromConfig(\n * routes,\n * myFacilitatorClient,\n * [{ network: \"eip155:196\", server: evmSchemeServer }],\n * paywallConfig\n * ));\n * ```\n */\nexport function paymentMiddlewareFromConfig(\n routes: RoutesConfig,\n facilitatorClients?: FacilitatorClient | FacilitatorClient[],\n schemes?: SchemeRegistration[],\n paywallConfig?: PaywallConfig,\n paywall?: PaywallProvider,\n syncFacilitatorOnStart: boolean = true,\n) {\n const ResourceServer = new x402ResourceServer(facilitatorClients);\n\n if (schemes) {\n schemes.forEach(({ network, server: schemeServer }) => {\n ResourceServer.register(network, schemeServer);\n });\n }\n\n return paymentMiddleware(routes, ResourceServer, paywallConfig, paywall, syncFacilitatorOnStart);\n}\n\nexport { x402ResourceServer, x402HTTPResourceServer } from \"@okxweb3/app-x402-core/server\";\n\nexport type {\n PaymentRequired,\n PaymentRequirements,\n PaymentPayload,\n Network,\n SchemeNetworkServer,\n} from \"@okxweb3/app-x402-core/types\";\n\nexport type {\n PaywallProvider,\n PaywallConfig,\n SettlementOverrides,\n} from \"@okxweb3/app-x402-core/server\";\n\nexport {\n RouteConfigurationError,\n SETTLEMENT_OVERRIDES_HEADER,\n} from \"@okxweb3/app-x402-core/server\";\n\nexport type { RouteValidationError } from \"@okxweb3/app-x402-core/server\";\n\nexport { ExpressAdapter } from \"./adapter\";\n","import { HTTPAdapter } from \"@okxweb3/app-x402-core/server\";\nimport { Request } from \"express\";\n\n/**\n * Express adapter implementation\n */\nexport class ExpressAdapter implements HTTPAdapter {\n /**\n * Creates a new ExpressAdapter instance.\n *\n * @param req - The Express request object\n */\n constructor(private req: Request) {}\n\n /**\n * Gets a header value from the request.\n *\n * @param name - The header name\n * @returns The header value or undefined\n */\n getHeader(name: string): string | undefined {\n const value = this.req.header(name);\n return Array.isArray(value) ? value[0] : value;\n }\n\n /**\n * Gets the HTTP method of the request.\n *\n * @returns The HTTP method\n */\n getMethod(): string {\n return this.req.method;\n }\n\n /**\n * Gets the path of the request.\n *\n * @returns The request path\n */\n getPath(): string {\n return this.req.path;\n }\n\n /**\n * Gets the full URL of the request.\n *\n * @returns The full request URL\n */\n getUrl(): string {\n return `${this.req.protocol}://${this.req.headers.host}${this.req.originalUrl}`;\n }\n\n /**\n * Gets the Accept header from the request.\n *\n * @returns The Accept header value or empty string\n */\n getAcceptHeader(): string {\n return this.req.header(\"Accept\") || \"\";\n }\n\n /**\n * Gets the User-Agent header from the request.\n *\n * @returns The User-Agent header value or empty string\n */\n getUserAgent(): string {\n return this.req.header(\"User-Agent\") || \"\";\n }\n\n /**\n * Gets all query parameters from the request URL.\n *\n * @returns Record of query parameter key-value pairs\n */\n getQueryParams(): Record<string, string | string[]> {\n return this.req.query as Record<string, string | string[]>;\n }\n\n /**\n * Gets a specific query parameter by name.\n *\n * @param name - The query parameter name\n * @returns The query parameter value(s) or undefined\n */\n getQueryParam(name: string): string | string[] | undefined {\n const value = this.req.query[name];\n return value as string | string[] | undefined;\n }\n\n /**\n * Gets the parsed request body.\n * Requires express.json() or express.urlencoded() middleware.\n *\n * @returns The parsed request body\n */\n getBody(): unknown {\n return this.req.body;\n }\n\n /**\n * Return all request headers as a lowercase-keyed map.\n * Multi-value headers are joined with \", \".\n */\n getHeaders(): Record<string, string> {\n const out: Record<string, string> = {};\n for (const [k, v] of Object.entries(this.req.headers)) {\n if (v == null) continue;\n out[k.toLowerCase()] = Array.isArray(v) ? v.join(\", \") : String(v);\n }\n return out;\n }\n}\n"],"mappings":"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","names":["x402ResourceServer","x402HTTPResourceServer","SETTLEMENT_OVERRIDES_HEADER","response"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@okxweb3/app-x402-express",
3
- "version": "0.1.2",
3
+ "version": "0.2.0",
4
4
  "main": "./dist/cjs/index.js",
5
5
  "module": "./dist/esm/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -33,7 +33,7 @@
33
33
  "typescript": "^5.7.3"
34
34
  },
35
35
  "dependencies": {
36
- "@okxweb3/app-x402-core": "0.1.2",
36
+ "@okxweb3/app-x402-core": "0.2.0",
37
37
  "viem": "^2.39.3",
38
38
  "zod": "^3.24.2"
39
39
  },