@faremeter/middleware

中文文档
0.22.0发布于 2026/05/27LGPL-3.0-onlyTypeScriptESM + CJS近 30 天下载 2533

Server middleware for adding payment walls to API endpoints using x402 protocol

原始使用文档
文档目录48 节
  1. Installation
  2. Features
  3. API Reference
  4. Functions
  5. createHTTPFacilitatorHandler
  6. findMatchingPaymentRequirements
  7. findMatchingPaymentRequirementsV2
  8. relaxedRequirementsToV2
  9. resolveSupportedVersions
  10. validateMiddlewareArgs
  11. deriveCapabilities
  12. deriveSchemes
  13. deriveResourceInfo
  14. acceptsToPricing
  15. createRemoteX402Handlers
  16. resolveConfig
  17. resolveCapturesAt
  18. handleMiddlewareRequest
  19. createMiddleware
  20. createMiddleware
  21. AgedLRUCache
  22. Methods
  23. Types
  24. AgedLRUCacheOpts
  25. RelaxedRequirements
  26. RelaxedRequirementsV2
  27. SupportedVersionsConfig
  28. CommonMiddlewareArgs
  29. CreateRemoteX402HandlersArgs
  30. ResolvedConfig
  31. CaptureResultV1
  32. CaptureResultV2
  33. CaptureResult
  34. AuthorizeResultV1
  35. AuthorizeResultV2
  36. AuthorizeResult
  37. CapturesAt
  38. PaymentPolicy
  39. MiddlewareBodyContextV1
  40. MiddlewareBodyContextV2
  41. CaptureResultMPP
  42. AuthorizeResultMPP
  43. MiddlewareBodyContextMPP
  44. MiddlewareBodyContext
  45. HandleMiddlewareRequestArgs
  46. Examples
  47. Related Packages
  48. License

@faremeter/middleware

Server middleware for adding payment walls to API endpoints using the x402 protocol.

Installation

pnpm install @faremeter/middleware

Features

  • Paywall any endpoint - Add middleware to any route
  • Framework agnostic - Express, Hono, or custom
  • Multi-chain support - Solana, EVM, extensible
  • Fast validation - Payment requirements caching
  • Facilitator integration - Handles settlement verification

API Reference

Functions

createHTTPFacilitatorHandler

Creates a FacilitatorHandler that delegates to a remote facilitator via HTTP.

The glue layer constructs valid x402PaymentRequirements from ResourcePricing using the handler's declared schemes, then passes them to getRequirements. This handler POSTs those to the facilitator's /accepts endpoint for enrichment.

Cache key stability: caching assumes that identical accepts arrays produce identical facilitator responses. If the facilitator returns time-dependent values (e.g. recentBlockhash), use a short maxAge or disable caching.

FunctionType
createHTTPFacilitatorHandler(facilitatorURL: string, opts: CreateHTTPFacilitatorHandlerOpts) => FacilitatorHandler

findMatchingPaymentRequirements

Finds the payment requirement that matches the client's v1 payment payload.

FunctionType
findMatchingPaymentRequirements(accepts: x402PaymentRequirementsV1[], payload: x402PaymentPayloadV1) => any

Parameters:

  • accepts: - Array of accepted payment requirements from the facilitator
  • payload: - The client's payment payload

Returns:

The matching requirement, or undefined if no match found

findMatchingPaymentRequirementsV2

Finds the payment requirement that matches the client's v2 payment payload.

FunctionType
findMatchingPaymentRequirementsV2(accepts: x402PaymentRequirements[], payload: x402PaymentPayload) => any

Parameters:

  • accepts: - Array of accepted payment requirements from the facilitator
  • payload: - The client's v2 payment payload

Returns:

The matching requirement, or undefined if no match found

relaxedRequirementsToV2

Converts v1 relaxed requirements to v2 format, preserving all fields including extra.

FunctionType
relaxedRequirementsToV2(req: x402PaymentRequirementsV1) => x402PaymentRequirements

resolveSupportedVersions

Resolve and validate supported versions config. Returns resolved config with defaults applied. Throws if configuration is invalid.

FunctionType
resolveSupportedVersions(config?: SupportedVersionsConfig or undefined) => Required<SupportedVersionsConfig>

validateMiddlewareArgs

Validates that CommonMiddlewareArgs has exactly one configuration mode.

FunctionType
validateMiddlewareArgs(args: CommonMiddlewareArgs) => void

deriveCapabilities

Derives HandlerCapabilities from relaxed v1 requirements. Used by framework adapters to construct capabilities for the HTTP wrapper from the legacy accepts configuration.

FunctionType
deriveCapabilities(accepts: x402PaymentRequirementsV1[]) => HandlerCapabilities

deriveSchemes

Derives the distinct set of x402 schemes from relaxed v1 requirements. Sibling of {@link deriveCapabilities}; kept separate because schemes are x402-specific and live on the handler rather than on {@link HandlerCapabilities }.

FunctionType
deriveSchemes(accepts: x402PaymentRequirementsV1[]) => string[]

deriveResourceInfo

Extracts resource info from v1 accepts entries. Used by framework adapters to build the resource info for the 402 response.

FunctionType
deriveResourceInfo(accepts: x402PaymentRequirementsV1[], resourceURL: string) => x402ResourceInfo

acceptsToPricing

FunctionType
acceptsToPricing(accepts: x402PaymentRequirementsV1[]) => ResourcePricing[]

createRemoteX402Handlers

Creates x402 facilitator handlers backed by a remote HTTP facilitator.

This is the composable equivalent of the facilitatorURL + accepts shorthand on {@link CommonMiddlewareArgs}. Use it when you need to combine a remote x402 facilitator with in-process MPP handlers in the same middleware.

FunctionType
createRemoteX402Handlers(args: CreateRemoteX402HandlersArgs) => FacilitatorHandler[]

Returns:

An array of FacilitatorHandler suitable for createMiddleware({ x402Handlers: ... }).

resolveConfig

Resolves {@link CommonMiddlewareArgs} into the handlers + pricing tuple that {@link handleMiddlewareRequest} needs. For the facilitatorURL path, creates an HTTP handler wrapper and converts accepts to pricing.

FunctionType
resolveConfig(args: CommonMiddlewareArgs) => ResolvedConfig

resolveCapturesAt

Resolves whether the body callback should capture at /request (one-phase) or defer to /response (two-phase).

canAuthorizehasAuthorizepincapturesAt
falseanynonerequest
truefalsenonerequest
truetruenoneresponse
anyany"request"request
trueany"response"response

canAuthorize is "any handler that actually accepts THIS scheme / method declares verification". For x402 the candidate set is narrowHandlers(handlers, requirements) further filtered by h.schemes?.includes(requirements.scheme) — the scheme filter is load-bearing because narrowHandlers only checks network and asset, so without it a multi-scheme handler set with one verify- capable handler would leak canAuthorize = true to schemes served only by settle-only handlers. For MPP the candidate set is the handlers filtered by exact method match. The middleware computes the predicate per request before invoking body, so the body callback only has to read context.capturesAt.

pin is the operator-supplied override from PaymentPolicy.pin keyed by <protocol>:<scheme-or-method>. A pin to "response" against a handler that cannot authorize is rejected at construction by validateOperationPolicies in middleware-openapi. If one somehow reaches this resolver at runtime (e.g. a programmatic spec that bypasses validation) the body's authorize() call will throw "no handler accepted the verification", which propagates up as a 500 -- loud failure rather than a silent demotion to one-phase.

FunctionType
resolveCapturesAt(canAuthorize: boolean, hasAuthorize: boolean, pin?: CapturesAt or undefined) => CapturesAt

handleMiddlewareRequest

Core middleware request handler that processes x402 and MPP payment flows.

Delegates to protocol-specific glue layers for challenge generation, settlement, and verification. The middleware formats HTTP responses but never constructs protocol types directly.

FunctionType
handleMiddlewareRequest<MiddlewareResponse>(args: HandleMiddlewareRequestArgs<MiddlewareResponse>) => Promise<MiddlewareResponse or undefined>

createMiddleware

Creates Express middleware that gates routes behind x402 and MPP payment.

FunctionType
createMiddleware(args: CommonMiddlewareArgs) => Promise<(req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>, res: Response<...>, next: NextFunction) => Promise<...>>

Parameters:

  • args: - Configuration including handlers + pricing or facilitator URL

Returns:

An Express middleware function

createMiddleware

Creates Hono middleware that gates routes behind x402 and MPP payment.

The middleware intercepts requests, checks for payment headers, validates and settles payments via x402 or MPP protocol, and only allows the request to proceed if payment is successful.

FunctionType
createMiddleware(args: CreateMiddlewareArgs) => Promise<MiddlewareHandler>

Parameters:

  • args: - Configuration including handlers + pricing or facilitator URL

Returns:

A Hono middleware handler

AgedLRUCache

An LRU cache with time-based expiration.

Entries are evicted when they exceed maxAge or when the cache reaches capacity (least recently used entries are removed first).

Methods

get

MethodType
get(key: K) => V or undefined

put

MethodType
put(key: K, value: V) => void

Types

AgedLRUCacheOpts

Configuration options for the AgedLRUCache.

TypeType
AgedLRUCacheOpts{ /** Maximum number of entries. Defaults to 256. */ capacity?: number; /** Maximum age in milliseconds before entries expire. Defaults to 30000. */ maxAge?: number; /** Custom time function for testing. Defaults to Date.now. */ now?: () => number; }

RelaxedRequirements

TypeType
RelaxedRequirementsPartial<x402PaymentRequirementsV1>

RelaxedRequirementsV2

TypeType
RelaxedRequirementsV2Partial<x402PaymentRequirements>

SupportedVersionsConfig

Configuration for which x402 protocol versions the middleware supports. At least one version must be enabled.

TypeType
SupportedVersionsConfig{ /** Support x402 v1 protocol (JSON body responses, X-PAYMENT header). Default: true */ x402v1?: boolean; /** Support x402 v2 protocol (PAYMENT-REQUIRED header, PAYMENT-SIGNATURE header). Default: false */ x402v2?: boolean; }

CommonMiddlewareArgs

Common configuration arguments shared by all middleware implementations. Supports two mutually exclusive modes: in-process handlers or remote facilitator.

TypeType
CommonMiddlewareArgs{ /** x402 handlers for in-process settlement. */ x402Handlers?: FacilitatorHandler[]; /** MPP method handlers for in-process settlement. */ mppMethodHandlers?: MPPMethodHandler[]; /** Protocol-agnostic pricing for in-process handlers. */ pricing?: ResourcePricing[]; /** URL of a remote facilitator service (backward compat). */ facilitatorURL?: string; /** Payment requirements for the remote facilitator path. */ accepts?: (RelaxedRequirements or RelaxedRequirements[])[]; /** Cache configuration for remote facilitator responses. */ cacheConfig?: AgedLRUCacheOpts and { disable?: boolean }; /** Which x402 protocol versions to support. */ supportedVersions?: SupportedVersionsConfig; }

CreateRemoteX402HandlersArgs

TypeType
CreateRemoteX402HandlersArgs{ facilitatorURL: string; accepts: (RelaxedRequirements or RelaxedRequirements[])[]; cacheConfig?: AgedLRUCacheOpts and { disable?: boolean }; }

ResolvedConfig

TypeType
ResolvedConfig{ handlers: FacilitatorHandler[]; pricing: ResourcePricing[]; mppHandlers: MPPMethodHandler[]; resourceInfo?: x402ResourceInfo; }

CaptureResultV1

| Type | Type | | ----------------- | ---- | ----------------------------------------------------------------------------------------------------------------------------------- | | CaptureResultV1 | | { success: true; response: x402SettleResponseV1 } or { success: false; errorResponse: MiddlewareResponse; errorMessage?: string; } |

CaptureResultV2

| Type | Type | | ----------------- | ---- | --------------------------------------------------------------------------------------------------------------------------------- | | CaptureResultV2 | | { success: true; response: x402SettleResponse } or { success: false; errorResponse: MiddlewareResponse; errorMessage?: string; } |

CaptureResult

| Type | Type | | --------------- | ---- | --------------------------------------------------------------------------- | | CaptureResult | | CaptureResultV1<MiddlewareResponse> or CaptureResultV2<MiddlewareResponse> |

AuthorizeResultV1

| Type | Type | | ------------------- | ---- | ----------------------------------------------------------------------------------------------------------------------------------- | | AuthorizeResultV1 | | { success: true; response: x402VerifyResponseV1 } or { success: false; errorResponse: MiddlewareResponse; errorMessage?: string; } |

AuthorizeResultV2

| Type | Type | | ------------------- | ---- | --------------------------------------------------------------------------------------------------------------------------------- | | AuthorizeResultV2 | | { success: true; response: x402VerifyResponse } or { success: false; errorResponse: MiddlewareResponse; errorMessage?: string; } |

AuthorizeResult

| Type | Type | | ----------------- | ---- | ------------------------------------------------------------------------------- | | AuthorizeResult | | AuthorizeResultV1<MiddlewareResponse> or AuthorizeResultV2<MiddlewareResponse> |

CapturesAt

When the body callback should drive capture.

"request" — one-phase: body calls capture() immediately and the payment clears before the resource is produced.

"response" — two-phase: body calls authorize() now and defers capture to a later phase (the OpenAPI gateway captures at /response once the final amount is known).

The middleware resolves this per-request via {@link resolveCapturesAt} from the matched handler's authorize capability and the rule's hasAuthorize flag, so the body callback never has to inspect the context shape to decide which path to take.

TypeType
CapturesAtrequest" or "response

PaymentPolicy

Per-operation payment policy. Restricts which protocol schemes / methods are accepted for a given route and optionally pins specific ones to one-phase or two-phase capture regardless of the handler's declared capability.

Keys in allow and pin are of the form "<protocol>:<id>":

  • "x402:exact", "x402:permit2" — x402 schemes
  • "mpp:solana" — MPP methods

The protocol prefix is case-sensitive and uses the lowercase wire form ("mpp:", not "MPP:"), matching how schemes and methods are identified on the protocol surface itself.

allow: undefined permits every registered scheme and method. allow: [] denies all of them (the deny-all sentinel).

pin["x402:exact"].capturesAt: "request" forces one-phase capture for that scheme regardless of whether the handler supports handleVerify and regardless of whether the rule has authorize. A pin to "response" against a handler that cannot authorize is a configuration error caught at construction.

TypeType
PaymentPolicy{ allow?: string[]; pin?: Record<string, { capturesAt?: CapturesAt }>; }

MiddlewareBodyContextV1

Context provided to the middleware body handler for v1 protocol requests. Contains payment information and the industry-standard authorize / capture operations. Under the hood these dispatch to the matched x402 facilitator handler's handleVerify / handleSettle.

TypeType
MiddlewareBodyContextV1{ protocolVersion: 1; capturesAt: CapturesAt; paymentRequirements: x402PaymentRequirementsV1; paymentPayload: x402PaymentPayloadV1; capture: () => Promise<CaptureResultV1<MiddlewareResponse>>; authorize: () => Promise<AuthorizeResultV1<MiddlewareResponse>>; }

MiddlewareBodyContextV2

Context provided to the middleware body handler for v2 protocol requests. Contains payment information and the industry-standard authorize / capture operations. Under the hood these dispatch to the matched x402 facilitator handler's handleVerify / handleSettle.

TypeType
MiddlewareBodyContextV2{ protocolVersion: 2; capturesAt: CapturesAt; paymentRequirements: x402PaymentRequirements; paymentPayload: x402PaymentPayload; capture: () => Promise<CaptureResultV2<MiddlewareResponse>>; authorize: () => Promise<AuthorizeResultV2<MiddlewareResponse>>; }

CaptureResultMPP

| Type | Type | | ------------------ | ---- | ------------------------------------------------------------------------------------------------------------------------ | | CaptureResultMPP | | { success: true; receipt: mppReceipt } or { success: false; errorResponse: MiddlewareResponse; errorMessage?: string; } |

AuthorizeResultMPP

| Type | Type | | -------------------- | ---- | ------------------------------------------------------------------------------------------------------------------------ | | AuthorizeResultMPP | | { success: true; receipt: mppReceipt } or { success: false; errorResponse: MiddlewareResponse; errorMessage?: string; } |

MiddlewareBodyContextMPP

Context provided to the middleware body handler for MPP protocol requests.

authorize is optional because not every MPP method handler implements handleVerify. When capturesAt === "response" the middleware guarantees authorize is defined (the resolver only picks "response" when at least one matching handler can verify).

TypeType
MiddlewareBodyContextMPP{ protocolVersion: "mpp"; capturesAt: CapturesAt; credential: mppCredential; capture: () => Promise<CaptureResultMPP<MiddlewareResponse>>; authorize?: or (() => Promise<AuthorizeResultMPP<MiddlewareResponse>>) or undefined; }

MiddlewareBodyContext

Context provided to the middleware body handler. Use protocolVersion to discriminate between v1, v2, and mpp request types.

| Type | Type | | ----------------------- | ---- | ------------------------------------------------------------------------------------------------------------------------------------------- | | MiddlewareBodyContext | | MiddlewareBodyContextV1<MiddlewareResponse> or MiddlewareBodyContextV2<MiddlewareResponse> or MiddlewareBodyContextMPP<MiddlewareResponse> |

HandleMiddlewareRequestArgs

Arguments for the core middleware request handler. Framework-specific middleware implementations adapt their request/response objects to this interface.

TypeType
HandleMiddlewareRequestArgs{ /** x402 handlers for in-process settlement. */ x402Handlers?: FacilitatorHandler[]; /** MPP method handlers for in-process settlement. */ mppMethodHandlers?: MPPMethodHandler[]; /** Protocol-agnostic pricing entries for the current request. */ pricing: ResourcePricing[]; /** The resource URL being accessed. */ resource: string; /** Resolved supported versions configuration. */ supportedVersions: Required<SupportedVersionsConfig>; /** Function to retrieve a request header value. */ getHeader: (key: string) => string or undefined; /** Function to send a JSON response with optional headers. */ sendJSONResponse: ( status: PossibleStatusCodes, body?: PossibleJSONResponse, headers?: Record<string, string>, ) => MiddlewareResponse; /** Handler function called when a valid payment is received. */ body: ( context: MiddlewareBodyContext<MiddlewareResponse>, ) => Promise<MiddlewareResponse or undefined>; /** Optional function to set a response header. */ setResponseHeader?: (key: string, value: string) => void; /** Optional pre-built resource info for the 402 response. */ resourceInfo?: x402ResourceInfo; /** Optional accessor for the request body (for RFC 9530 digest). */ getBody?: () => Promise<ArrayBuffer or null>; /** * Whether the matched pricing rule has an explicit authorize* expression (i.e. is two-phase). Drives the per-handlercapturesAt* decision resolved before eachbodyinvocation. Defaults to false; * non-OpenAPI callers that have no rule shape leave this unset and * the middleware treats every request as one-phase. */ hasAuthorize?: boolean; /** * Per-operation payment policy. Restricts which schemes / methods * are advertised in the 402 challenge, rejects payments for * disallowed schemes, and threadspinoverrides into the *capturesAt resolution per matched handler. */ policy?: PaymentPolicy; }

Examples

See working examples in the faremeter repository:

License

LGPL-3.0-only

版本与发布记录

@faremeter/middleware 共发布 33 个版本,首次发布于 2025/07/31;过去 12 个月发布了 12 个版本。

版本发布日期距今
0.22.0latest2026/05/275 个月前
0.21.02026/04/216 个月前
0.20.12026/04/147 个月前
0.20.02026/04/147 个月前
0.19.02026/03/217 个月前
0.18.02026/03/207 个月前

关于 @faremeter/middleware 的常见问题

@faremeter/middleware 是什么?

Server middleware for adding payment walls to API endpoints using x402 protocol

如何安装 @faremeter/middleware?

在项目目录运行 npm install @faremeter/middleware,或使用 pnpm add / yarn add / bun add。

@faremeter/middleware 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@faremeter/middleware 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@faremeter/middleware 可以商用吗?

@faremeter/middleware 使用 LGPL-3.0-only 许可。弱 Copyleft:作为库被调用时通常不要求开源你自己的代码,但修改库本身需以 LGPL 开源;前端打包合并后的适用边界存在不同理解。以上为概括,不构成法律意见,请以许可原文为准。

@faremeter/middleware 的下载量有多少?

根据 npm 官方下载统计,@faremeter/middleware 在 2026/10/15 – 2026/11/13 这 30 天内被下载 2,533 次,日均约 84 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@faremeter/middleware 还在维护吗?

最新版本 0.22.0 发布于 2026/05/27(5 个月前);至今共发布 33 个版本,其中过去 12 个月发布了 12 个;首次发布于 2025/07/31。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。