@tollgatepay/next
Wraps a Next.js App Router Route Handler (or anyfetch-style handler) behind the 402 → sign → 200 flow. Web-standard Request/Response, so it works on Node, Edge, and Vercel.
Entry points
initTollgate(config)— most ergonomic. Returns{ wrap, instance }. Usewrap()to gate a handler.createTollgate(config)— returns anTollgateInstance. UsewithTollgate(instance, options, handler)for lifecycle control.withTollgateNext(instance, options, handler)— typed alias forNextRequest/NextResponseconsumers.
Quick example
// app/tollgate.ts — instantiated once at module scope.
import { initTollgate } from "@tollgatepay/next";
export const { wrap } = initTollgate({
apiKey: process.env.TOLLGATE_API_KEY!,
payoutAddress: process.env.TOLLGATE_PAYOUT_ADDRESS as `0x${string}`,
developerSalt: process.env.TOLLGATE_DEV_SALT as `0x${string}`,
});
// app/api/premium/route.ts — gate a route behind a $0.05 charge.
import { wrap } from "../../tollgate";
export const GET = wrap({ price: 50_000 }, async (_req, payment) => {
return Response.json({
agent: payment.agentAddress,
owedMicros: payment.totalOwedMicros,
});
});Options
The options object for wrap() (full type at packages/next/src/types.ts):
interface WithTollgateOptions {
/** Price in micro-USDC (integer, > 0). 50_000 = $0.05. */
price: number;
/**
* Force strict verification (Postgres-authoritative). Default inferred from
* price: strict above the beta threshold ($0.10) / GA threshold ($1.00).
*/
strict?: boolean;
/**
* Template override for dynamic routes. If the runtime path does not match
* the canonicalized IOU path, the middleware normally returns
* PATH_APPEARS_DYNAMIC. Supply e.g. "/api/users/[id]" to tell the
* canonicalizer this path has a dynamic segment.
*/
endpointTemplate?: string;
/**
* Per-agent unsettled cap in micro-USDC. When set, stricter than the
* facilitator's global cap; still bounded by it.
*/
maxUnsettledPerAgent?: number;
/**
* Behaviour when the facilitator is unreachable. Default "reject" (returns
* 503 FACILITATOR_UNAVAILABLE). "serve-untracked" returns 200 but the IOU
* is not recorded — trades auditability for availability.
*/
onFacilitatorError?: "reject" | "serve-untracked";
}Payment context
Your handler receives (req, payment). The payment object carries the verified state:
interface PaymentContext {
agentAddress: Address;
developerAddress: Address;
/** Price of this specific request (micros). */
amountMicros: number;
/** Cumulative on this (agent, dev, path) after accepting (micros). */
totalOwedMicros: number;
/** Delta of this request vs the previous cumulative. */
deltaMicros: number;
/** Strictly monotonic nonce for the tuple. */
nonce: bigint;
/** Canonicalized path used for the tab key. */
canonicalPath: string;
/** The signature recovered and bound to agentAddress. */
iouSignature: `0x${string}`;
/** W3C Trace Context id shared with the middleware's spans. */
traceId: string;
/** True when the facilitator was consulted authoritatively. */
strictMode: boolean;
}Test mode
Any apiKey starting with aw_test_ puts the middleware into test mode. Requests short-circuit to deterministic scenarios picked by the x-tollgate-test-scenario header (success, signature-mismatch, deadline-expired, nonce-reused, ...). No facilitator or on-chain contact.
See also
- @tollgatepay/core — types, verify, constants.
- 402 envelope.
- Errors catalog.