docs / gate an express route

Gate an Express route

Ten lines including imports.

Install

npm install express @orangecheck/gate

Minimum working example

import express from 'express';
import { ocGate } from '@orangecheck/gate';

const app = express();
app.use(express.json());

app.post(
  '/post',
  ocGate({
    minSats: 100_000,
    minDays: 30,
    address: { from: 'header' },   // reads X-OC-Address
  }),
  async (req, res) => {
    res.json({ ok: true });
  },
);

app.listen(3000);

Clients send X-OC-Address: bc1q... on requests to /post. The gate verifies via the hosted API and either calls your handler or sends 403 { error, reason, ... }.

Subject from a different source

// Query string
ocGate({ minSats: 100_000, address: { from: 'query', name: 'addr' } })

// JSON body
ocGate({ minSats: 100_000, address: { from: 'body', path: 'user.btcAddress' } })

// Signed session (recommended for high-stakes)
ocGate({
  minSats: 100_000,
  address: { from: (req) => req.session.verifiedAddress },
})

Custom 403 response

ocGate({
  minSats: 100_000,
  address: { from: 'header' },
  onBlocked: (req, res, decision) => {
    res.status(403).json({
      error: 'orangecheck',
      message: `this endpoint requires ${100_000} sats bonded for 30 days`,
      reasons: decision.check?.reasons ?? [],
    });
  },
})

Log every decision

ocGate({
  minSats: 100_000,
  address: { from: 'header' },
  onDecision: (req, decision) => {
    console.log({
      method: req.method, url: req.url,
      subject: decision.subject,
      ok: decision.ok, reason: decision.reason,
    });
  },
})

Combine with other middleware

app.post('/post',
  rateLimit({ windowMs: 60_000, max: 60 }),   // rate limit
  requireAuth,                                 // your auth
  ocGate({ minSats: 100_000, address: { from: (req) => req.user.btcAddress } }),
  postHandler,
);

Accessing the check result downstream

When the gate passes, the CheckResult is attached to req.orangecheck:

app.post('/post',
  ocGate({ minSats: 100_000, address: { from: 'header' } }),
  (req, res) => {
    // req.orangecheck.sats, .days, .score, .attestation_id
    res.json({ youHaveSats: req.orangecheck.sats });
  },
);

Further