mirror of
https://github.com/profullstack/logicsrc.git
synced 2026-09-10 19:26:00 +00:00
feat(agentswarm): M5 — x402 billing wrapper for the swarm route
withX402() wraps the Web handler so unpaid calls get a standard HTTP 402 challenge (x402Version + accepts[]) and paid calls fall through to the agent. Payment verification is injectable (host wires CoinPay/x402); CORS preflight passes through untouched; custom challenge responses supported. README documents the optional c0mpute.com GPU backend. 4 new tests; 38/38 pass. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
fbbb323477
commit
0e5a13f5fb
4 changed files with 137 additions and 0 deletions
57
packages/agentswarm/src/x402.ts
Normal file
57
packages/agentswarm/src/x402.ts
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
/**
|
||||
* x402 billing wrapper — gate a swarm route behind payment. Wraps the Web
|
||||
* handler so unpaid requests get a standard HTTP 402 challenge (the x402
|
||||
* "accepts" shape) and paid requests fall through to the agent. The actual
|
||||
* payment verification is injectable so a host wires it to CoinPay/x402.
|
||||
*/
|
||||
|
||||
export interface X402Accept {
|
||||
scheme: string;
|
||||
network: string;
|
||||
asset: string;
|
||||
/** Price in the asset's minor units. */
|
||||
amount: number;
|
||||
/** Address / CoinPay account that receives payment. */
|
||||
payTo?: string;
|
||||
}
|
||||
|
||||
export interface X402Options {
|
||||
/** Returns true when the request carries valid payment/authorization. */
|
||||
verify: (request: Request) => boolean | Promise<boolean>;
|
||||
/** Payment options advertised in the 402 challenge. */
|
||||
accepts?: X402Accept[];
|
||||
/** Fully custom 402 response; overrides `accepts`. */
|
||||
challenge?: (request: Request) => Response | Promise<Response>;
|
||||
}
|
||||
|
||||
const CORS_ORIGIN = { "access-control-allow-origin": "*" };
|
||||
|
||||
/**
|
||||
* Wrap a `(Request) => Response` swarm handler so each call must be paid for.
|
||||
* CORS preflights pass through untouched; everything else must satisfy `verify`
|
||||
* or receives a 402 with the advertised payment options.
|
||||
*/
|
||||
export function withX402(
|
||||
handler: (request: Request) => Promise<Response>,
|
||||
options: X402Options
|
||||
): (request: Request) => Promise<Response> {
|
||||
return async function paid(request: Request): Promise<Response> {
|
||||
if (request.method === "OPTIONS") {
|
||||
return handler(request);
|
||||
}
|
||||
if (await options.verify(request)) {
|
||||
return handler(request);
|
||||
}
|
||||
if (options.challenge) {
|
||||
return options.challenge(request);
|
||||
}
|
||||
return new Response(
|
||||
JSON.stringify({
|
||||
x402Version: 1,
|
||||
error: "payment_required",
|
||||
accepts: options.accepts ?? []
|
||||
}),
|
||||
{ status: 402, headers: { "content-type": "application/json", ...CORS_ORIGIN } }
|
||||
);
|
||||
};
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue