Skip to main content

Installation

npm install @agent-score/gate

Quick start

Add AgentScore trust gating to any Express route in one line:
import express from "express";
import { agentscoreGate } from "@agent-score/gate";

const app = express();

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

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

How it works

The middleware:
  1. Extracts the wallet address from the X-Wallet-Address request header (or a custom extractor)
  2. Calls POST /v1/assess with your policy
  3. If decision is "allow", passes the request through with reputation data attached to req.agentscore
  4. If decision is "deny", returns 403 Forbidden with reason codes

Configuration

import { agentscoreGate } from "@agent-score/gate";
import type { AgentScoreGateOptions } from "@agent-score/gate";

agentscoreGate({
  // Required
  apiKey: string,

  // Policy (optional)
  minGrade: "A" | "B" | "C" | "D" | "F",
  minScore: number,                          // minimum score (0-100)
  requireVerifiedActivity: boolean,          // default: false

  // Wallet extraction (optional)
  extractAddress: (req) => string | undefined,  // default: reads X-Wallet-Address header
  extractChain: (req) => string | undefined,    // default: "base"

  // Behavior (optional)
  failOpen: boolean,         // default: false — deny on API errors
  cacheSeconds: number,      // default: 300 — TTL for cached results
  baseUrl: string,           // default: "https://api.agentscore.sh"
  onDenied: (req, res, reason) => 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 reputation = req.agentscore;
  console.log(`Score: ${reputation.score.value}, Grade: ${reputation.score.grade}`);

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

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

Custom deny handler

Override the default 403 response:
import type { DenialReason } from "@agent-score/gate";

app.use(
  agentscoreGate({
    apiKey: process.env.AGENTSCORE_API_KEY,
    minGrade: "B",
    onDenied: (req, res, reason: DenialReason) => {
      res.status(403).json({
        error: reason.code,
        decision: reason.decision,
        reasons: reason.reasons,
      });
    },
  })
);

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:
agentscoreGate({
  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",
  agentscoreGate({ apiKey, minGrade: "D" }),
  dataHandler
);

// Strict policy for writes
app.post(
  "/api/execute",
  agentscoreGate({ apiKey, minGrade: "B", minScore: 50 }),
  executeHandler
);

Custom wallet extraction

By default, the middleware reads the wallet address from the X-Wallet-Address header. Override with a custom extractor:
agentscoreGate({
  apiKey: process.env.AGENTSCORE_API_KEY,
  minGrade: "C",
  extractAddress: (req) => req.query.wallet as string,
  extractChain: (req) => (req.query.chain as string) || "base",
})

Denial reason codes

When a request is denied, the onDenied callback receives a DenialReason:
CodeDescription
wallet_not_trustedWallet didn’t meet the policy threshold
missing_wallet_addressNo wallet address found in the request
api_errorAgentScore API returned an error (and failOpen is false)
payment_requiredAPI key doesn’t have access to assess endpoint