Middleware Reference
Drop-in request verification for Next.js and Express.
Next.js
typescript
import { withAuthProof } from "@authproof/middleware/next";
export const POST = withAuthProof(config, async (request, context) => {
const { actor } = context;
return Response.json({ wallet: actor.address, chain: actor.chainId });
});Express
typescript
import { expressAuthProof } from "@authproof/middleware/express";
app.post("/orders", expressAuthProof(config), (req, res) => {
const { actor } = res.locals.authProof;
res.json({ wallet: actor.address });
});Framework-agnostic core
typescript
import { verifyAuthProofRequest } from "@authproof/middleware";
const result = await verifyAuthProofRequest(request, config);
if (!result.ok) {
return new Response(result.error.message, { status: result.error.status });
}
// result.context.actor — verified actor
AuthProofConfig
| Prop | Type | Description |
|---|---|---|
| project | AuthProofProject | Project config loaded from the database via loadProject(projectId). |
| publicClients | Record<number, PublicClient> | Viem PublicClient instances keyed by chain ID. Used for signature verification and policy evaluation. |
| nonceStore | NonceStore | Store for replay protection. MemoryNonceStore for dev, RedisNonceStore for production. |
| rateLimitStore | RateLimitStore (optional) | Store for per-wallet rate limiting. Required if rateLimit policy is configured. |
| usageLogger | UsageLogger (optional) | Writes every request to RequestLog. Use DatabaseUsageLogger in production. |
AuthProofContext
| Prop | Type | Description |
|---|---|---|
| actor.address | 0x${string} | Verified wallet address of the signer. |
| actor.chainId | number | Chain ID the wallet signed on. |
| actor.keyId | string | Canonical key ID: erc8128:<chainId>:<address>. |
| actor.smartAccount | boolean | True if the signer is a smart contract wallet (ERC-1271). |
| project | AuthProofProject | The project config used for verification. |
Error responses
All verification failures return a JSON body with { error, code, message }.
json
// 401 — signature invalid or expired
{ "error": "ERC-8128 verification failed: expired", "code": "expired" }
// 403 — policy rejected
{ "error": "Chain 1 is not enabled for this project.", "code": "chain_not_allowed" }
// 429 — rate limited
{ "error": "Per-wallet rate limit exceeded.", "code": "rate_limited" }