New:Introducing Socket Scanning for VS Code Marketplace Extensions.Learn more →
Get Started

@vouchscore/middleware

Package Overview
Dependencies
Maintainers
1
Versions
2
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@vouchscore/middleware

Drop-in x402 transaction gate: score a payment counterparty and ALLOW/WARN/BLOCK before it settles. Express, Next.js, and Hono adapters. Fail-closed by default.

latest
Source
npmnpm
Version
0.3.0
Version published
Maintainers
1
Created
Source

@vouchscore/middleware

Drop-in x402 transaction gate. Score the payment counterparty and ALLOW / WARN / BLOCK before the payment settles — from Express, Next.js, or Hono, in about three lines. Fail-closed by default, in both senses: a score you cannot fetch blocks the payment, and only a clean ALLOW verdict passes — the default policy blocks WARN too.

BREAKING (v0.2.0): fail-closed by default — money moves only on ALLOW unless you explicitly opt out. The default policy: "allow-only" blocks any verdict that is not ALLOW (a blocked WARN carries reason recommendation_not_allow). The pre-0.2.0 behaviour (WARN allowed downstream) is now the explicit opt-out policy: "block-only"; custom blockOn/warnOn banding requires policy: "custom".

This is the productized form of the facilitator-gate and x402-trust-gate reference adapters. The x402 payment gate stays your beacon; this middleware reads Vouch before it settles.

npm install @vouchscore/middleware

Which default do you have? Check with npm ls @vouchscore/middleware. 0.1.0 ships the old lenient default (a WARN passes downstream) and has no policy option — set blockOn: ["BLOCK", "WARN"] to get the fail-closed posture today. 0.2.0 and later are fail-closed out of the box, and the policy option documented below exists there.

Express — three lines

import { createExpressGate } from "@vouchscore/middleware/express";

// Mount AFTER x402 verification so `req.payer` is set.
app.use("/api/paid", createExpressGate({
  apiUrl: process.env.VOUCH_API_URL!,   // https://vet402.com/api/v1
  apiKey: process.env.VOUCH_API_KEY!,
  getAddress: (req) => req.payer,       // the counterparty to vet
}));

Anything but ALLOW returns 403 { error: "trust_blocked", ... } before your handler runs (default policy: "allow-only"). ALLOW continues with the full decision on req.vouchTrust; under the "block-only" /"custom" opt-outs a WARN also continues and fires onWarn.

Next.js (App Router)

import { withVouchGate } from "@vouchscore/middleware/next";

export const POST = withVouchGate(
  {
    apiUrl: process.env.VOUCH_API_URL!,
    apiKey: process.env.VOUCH_API_KEY!,
    getAddress: (req) => new URL(req.url).searchParams.get("payer") ?? undefined,
  },
  async (req, trust) => Response.json({ ok: true, trust }),
);

Or inline with createNextGate(...).check(address) → { decision, response }, returning response when it is non-null.

Hono

import { createHonoGate } from "@vouchscore/middleware/hono";

app.use("/api/paid/*", createHonoGate({
  apiUrl: process.env.VOUCH_API_URL!,
  apiKey: process.env.VOUCH_API_KEY!,
  getAddress: (c) => c.get("payer"),
}));

Configuration

OptionDefaultMeaning
scoreSource"wallet""wallet" (the x402 beacon) or "payee" (buyer-side receiving history).
policy"allow-only""allow-only" blocks anything that is not ALLOW (fail-closed). "block-only" lets WARN through (pre-0.2.0 behaviour). "custom" bands with your own blockOn/warnOn.
blockOn["BLOCK"]Recommendations that block. Requires policy: "custom" (rejected otherwise, never silently ignored).
warnOn["WARN"]Recommendations that warn (still allowed). Requires policy: "custom".
minScore—Stricter numeric floor (0–100): block below it even on ALLOW.
failMode"closed""closed" blocks on a lookup failure; "open" allows it (flagged degraded).
timeoutMs5000Score-lookup timeout — a hung Vouch never hangs the payment path.
blockStatus403HTTP status returned on a block.

Every decision carries { action, recommendation, score, reason, degraded }. degraded: true marks a verdict that came from failMode, not a real score — log or alert on those so trust-blind settlements are visible.

Settlement attestation (optional)

Feed successful settlements back so future scores weight them (10% of the score). Provide getAttestation on any adapter; it is fire-and-forget — a failed attestation never fails the paid request.

createExpressGate({
  /* ...as above... */
  getAttestation: (req) => req.paymentTxHash
    ? { wallet: req.payer, txHash: req.paymentTxHash, resource: req.path }
    : undefined,
});

Non-custodial

The gate reads a score and returns a verdict. It never touches keys, funds, signing, or transaction submission — settlement stays with your x402 stack.

  • API key — VOUCH_API_KEY
  • API docs · OpenAPI spec
  • x402 integration guide
  • @vouchscore/sdk — buyer side (SpendGuard)
  • @vouchscore/mcp-server — MCP tool

MIT · vet402

Keywords

x402

FAQs

Package last updated on 14 Aug 2026

Related posts