Gate a Next.js route (Pages Router)
Two equivalent patterns — the cleaner one uses withOcGate.
Install
yarn add @orangecheck/gate
Option 1: middleware function
// pages/api/post.ts
import type { NextApiHandler } from 'next';
import { ocGate } from '@orangecheck/gate';
const gate = ocGate({
minSats: 100_000,
minDays: 30,
address: { from: 'query', name: 'addr' },
});
const handler: NextApiHandler = async (req, res) => {
await new Promise<void>((resolve, reject) => {
gate(req, res, (err) => (err ? reject(err) : resolve()));
});
if (res.writableEnded) return; // gate already sent 403
res.status(200).json({ ok: true });
};
export default handler;
Option 2: withOcGate wrapper (cleaner)
// pages/api/post.ts
import { withOcGate } from '@orangecheck/gate';
async function handler(req, res) {
// req.orangecheck is the passing CheckResult
res.json({ sats: req.orangecheck.sats });
}
export default withOcGate(handler, {
minSats: 100_000,
minDays: 30,
address: { from: 'query', name: 'addr' },
});
Both are identical at runtime. The wrapper just handles promise plumbing.
Subject from a signed session
For high-stakes gates, run the signed-challenge flow first and stash the proven address in a signed session cookie. Then:
import { withOcGate } from '@orangecheck/gate';
import { getIronSession } from 'iron-session';
export default withOcGate(
async (req, res) => {
res.json({ ok: true });
},
{
minSats: 100_000,
address: {
from: async (req) => {
const session = await getIronSession(req, res, { password: process.env.SESSION_KEY!, cookieName: 'oc' });
return session.verifiedAddress;
},
},
},
);
(Async from works because withOcGate awaits it.)
CORS
The gate doesn't add CORS headers — your existing setup (or Next's default) owns that. If you're allowing cross-origin requests:
// pages/api/post.ts
export default withOcGate(async (req, res) => {
res.setHeader('Access-Control-Allow-Origin', 'https://yourclient.example.com');
res.json({ ok: true });
}, { minSats: 100_000, address: { from: 'header' } });