Skip to main content

Installation

npm install @agentscore/gate

Quick start

Add AgentScore trust gating to any Express route in one line:
import express from "express";
import { agentGate } from "@agentscore/gate";

const app = express();

// Gate all routes behind a B-grade minimum
app.use(
  agentGate({
    apiKey: process.env.AGENTSCORE_API_KEY,
    minGrade: "B",
    minTransactions: 5,
  })
);

app.post("/api/execute", (req, res) => {
  // Only wallets with grade B+ and 5+ transactions reach here
  res.json({ status: "executed" });
});

How it works

The middleware:
  1. Extracts the wallet address from the request (header, query, or body)
  2. Calls GET /v1/reputation/:address?view=full with your policy
  3. If decision.allow is true, passes the request through with reputation data attached to req.agentscore
  4. If decision.allow is false, returns 403 Forbidden with reason codes

Configuration

agentGate({
  // Required
  apiKey: string,

  // Policy (optional)
  minGrade: "A" | "B" | "C" | "D" | "F",  // default: "C"
  minTransactions: number,                   // default: 1

  // Wallet extraction (optional)
  addressFrom: "header" | "query" | "body",  // default: "header"
  addressField: string,                       // default: "X-Wallet-Address"

  // Behavior (optional)
  failOpen: boolean,      // default: false — deny on API errors
  cache: boolean,         // default: true — cache results per TTL
  onDeny: (req, res, reputation) => void,  // custom deny handler
})

Accessing reputation data

After the middleware passes, the full reputation response is available on req.agentscore:
app.post("/api/execute", (req, res) => {
  const { score, grade, decision } = req.agentscore;
  console.log(`Wallet ${req.agentscore.address}: score=${score} grade=${grade}`);

  // Use score for tiered behavior
  if (score >= 90) {
    // Premium path for high-trust wallets
  }

  res.json({ status: "executed" });
});

Custom deny handler

Override the default 403 response:
app.use(
  agentGate({
    apiKey: process.env.AGENTSCORE_API_KEY,
    minGrade: "B",
    onDeny: (req, res, reputation) => {
      res.status(403).json({
        error: "wallet_not_trusted",
        score: reputation.score,
        grade: reputation.grade,
        reasons: reputation.decision.reasons,
        upgrade_url: "https://docs.example.com/trust-requirements",
      });
    },
  })
);

Fail-open vs fail-closed

By default, the middleware fails closed — if the AgentScore API is unreachable, requests are denied. Set failOpen: true to allow requests through when the API is unavailable:
agentGate({
  apiKey: process.env.AGENTSCORE_API_KEY,
  minGrade: "C",
  failOpen: true,  // allow requests if AgentScore API is down
})

Per-route configuration

Apply different policies to different routes:
// Loose policy for reads
app.get(
  "/api/data",
  agentGate({ apiKey, minGrade: "D" }),
  dataHandler
);

// Strict policy for writes
app.post(
  "/api/execute",
  agentGate({ apiKey, minGrade: "B", minTransactions: 10 }),
  executeHandler
);

TypeScript support

The middleware is fully typed. The req.agentscore property is typed as ReputationFullResponse:
import type { AgentScoreRequest } from "@agentscore/gate";

app.post("/api/execute", (req: AgentScoreRequest, res) => {
  const reputation = req.agentscore; // fully typed
});