vet402-check

io.github.kzmttkcv0.1.2更新于 Oct 7, 2026

Before your agent pays an x402 API, check if vet402 bought it with its own money and what came back.

已验证STDIO仅桌面FinanceSecurity & Monitoring

概览

AI 生成的概览

查询 vet402 对某个 x402 或 MPP 卖家的公开购买记录,让智能体在付款前了解情况。

功能
通过 stdio 提供两个只读工具。check_before_paying 接收卖家 URL 以及可选的 chain 和 pay_to 过滤条件,返回 vet402 尝试购买的次数、成功结算的次数、有回答返回的次数、最新一次购买及其交易、归因于卖家的失败、rank.json 中的评级,以及已签名记录。verify_record 校验记录的签名、Merkle 证明、链上支付和 Solana memo 锚定。它只读取公开文件和公开 RPC。
适用场景
当智能体即将向某个 x402 或 MPP 卖家付款,而你想先了解该卖家被观察到的交付历史时使用。它也适合作为 fetch 钩子,在客户端签名前检查每个 402 响应,或用于独立验证一条已签名记录。
运行要求
需要 Node.js 22 或更高版本;首次运行会通过 npx 从 npm 下载 @vet402/check 包。不需要密钥、钱包或账号。验证会读取公开 RPC,可通过 SOLANA_RPC_URL、BASE_RPC_URL 和 TEMPO_RPC_URL 配置。可选变量 VET402_CHECK_RANK、VET402_CHECK_RECORDS_INDEX 和 VET402_CHECK_RECORDS_BASE 可指向公开数据的其他副本。
安装前请注意
只读:不持有密钥或钱包,不付款也不写入。它会把你查询的卖家 URL 发送到 vet402 的公开站点,验证时还会发送到公开 RPC 端点。记录是快照:vet402 按计划购买,卖家可能在最新一次购买之后发生变化,没有负面记录的卖家在 rank.json 中仍可能有失败。购买次数过少时评级可能显示为 measuring。

安装

在 SourceWeft 中

  1. 打开 控制台中的 vet402-check,将其添加到工作区。
  2. 为需要使用其工具的对话启用该服务。

Desktop only,通过 STDIO。 STDIO 服务会启动本地进程,因此需要 SourceWeft 桌面宿主。

其他 MCP 客户端

参照 仓库 中的启动说明。

README

@vet402/check (command: vet402-check)

Look an x402 or MPP seller up in vet402's public record before an agent pays it.

This package reads the public record of vet402's own purchases (the vet402-delivery repository). It is separate from @vet402/mcp-server, the MCP tools for vet402's scoring API.

vet402 buys from x402 and MPP sellers with its own money on Solana, Tempo and Base (and Algorand, on its own page), checks each payment on chain, and publishes what came back: a ranking (rank.json) and signed records whose daily Merkle root is written into a Solana memo. vet402-check reads that record. It returns facts: how many purchases vet402 tried from the seller, how many settled, how many came back with an answer, the newest purchase and its tx, the failures counted against the seller and the ones that are not, the grade as rank.json prints it (measuring while there are too few purchases), and the signed records for that seller. When vet402 has never bought from the seller, the answer is "vet402 has no record of this seller". What to do with the facts is up to the caller.

Reads only public files: rank.json and records/<id>.json on the public site, and data/records/index.json in this repository. Verifying a record also reads public RPC. No key, no wallet, no payment, no write.

Try it in 60 seconds

Node 22 or newer. The first run downloads the package from npm (@vet402/check); later runs start at once.

sh
npx -y @vet402/check https://api.xona-agent.com/token/pumpfun-trending

Verify the newest signed record of that seller as well (signature, Merkle proof, payment on chain, Solana memo anchor):

sh
npx -y @vet402/check https://api.xona-agent.com/token/pumpfun-trending --verify

As an MCP server in Claude Code (run the line above once first, so the install is cached before the client starts the server):

sh
claude mcp add vet402-check -- npx -y @vet402/check --mcp

Without Node: Python and curl

The same lookup over HTTP, free and with no key: GET https://vet402-delivery.vercel.app/v1/check?url=<seller URL> (optional chain and payTo). The answer starts with verdict and why (what the verdict means).

  • Python, standard library only: examples/python/check_before_paying.py. A command, a pay_after_check(url, pay) function, and a hook for the x402 Python HTTP client (x402HTTPClientSync(client).on_payment_required(vet402_on_payment_required)) that looks up the requested URL on every 402, before the client signs.
  • curl, one line each with jq and without: use.html#curl.

The command line

vet402-check <url> [--chain solana|tempo|base|algorand|<CAIP-2>] [--pay-to <address>] [--verify] [--offline] [--json]vet402-check verify <record id | https URL | file> [--offline] [--json]vet402-check --mcp
  • --chain limits the answer to one chain (eip155:8453 is Base, eip155:4217 is Tempo).
  • --pay-to compares the payTo in the 402 you hold with the payTo addresses vet402 recorded for that seller.
  • --json prints the whole result: sellers[] (one per page the seller is on), records, payTo, asOf, sources.
  • Exit 0 after a lookup, found or not; 1 when a record fails verification; 2 on bad input or unreadable data.

From a clone: npm ci, then npm run check-before-paying -- <url>.

MCP tools

Two read-only tools (stdio, newline-delimited JSON-RPC):

ToolInputReturns
check_before_payingurl, optional chain, pay_to, verify_newest_recordthe facts above, as text and as structuredContent
verify_recordrecord (id or https URL), optional offlineOK, OK_NOT_ANCHORED, OK_OFFLINE or FAIL, one line per check

Claude Desktop (claude_desktop_config.json):

json
{ "mcpServers": { "vet402-check": { "command": "npx", "args": ["-y", "@vet402/check", "--mcp"] } } }

At the payment: the x402 fetch hook

Wrap the fetch an x402 client pays through. Every 402 is looked up before the client signs:

ts
import { wrapFetchWithPayment } from "@x402/fetch";import { wrapFetchWithCheck } from "@vet402/check"; // npm install @vet402/check
const fetchWithPay = wrapFetchWithPayment(  wrapFetchWithCheck(fetch, {    onCheck: (e) => {      console.log(e.checks.map((c) => c.summary).join("\n"));      // The rule is yours. To stop the payment, throw here:      // if (e.checks.some((c) => c.sellers.some((s) => s.settled > 0 && s.delivered === 0))) throw new Error("not paying");    },  }),  client,);

The hook goes under the payment wrapper because @x402/fetch calls the fetch it was given and creates the payment only after that returns 402. The hook reads the 402 through a clone (x402 accepts from the body or the PAYMENT-REQUIRED header, and an MPP WWW-Authenticate: Payment challenge), runs check_before_paying for each chain and payTo it offers, passes the result to onCheck, and returns the 402 unchanged. It never sees a key or a signer and changes no header. A request that already carries a payment (X-PAYMENT, PAYMENT-SIGNATURE, Authorization: Payment) is the client's retry and passes straight through. If vet402's record cannot be read, onCheck gets error set and no checks.

rank.json and the records index are read once and kept in memory for 10 minutes (new PublicData({ ttlMs })), so a busy agent does not download them for every 402.

Reading the answer

  • tried / settled / came back with an answer: an answer is a 2xx with a non-empty body after the payment settled. vet402 does not check that the answer is what the listing promised.
  • Failures counted against the seller: rules whose fault is the seller's in rank.json's method.faultRules (for example paid_not_delivered: vet402's payment settled and the seller answered 5xx or nothing).
  • Not counted against the seller: failures on vet402's or the facilitator's side, and failures whose cause cannot be told.
  • Grade: as rank.json prints it. measuring means too few purchases for a grade.
  • Signed records: published for DELIVERED purchases, and for other verdicts once vet402 has told the seller. A seller with purchases and no negative record may still have failures in rank.json.
  • as of: the date of rank.json and the record days read. vet402 buys again on a schedule; a seller can change after the newest purchase.

Why a record can be checked

Each record is signed by vet402's observation key (EIP-712). Each day's records form a Merkle tree, and its root is written in a Solana memo by vet402's anchor wallet, so a record cannot be added to or dropped from a day later without the root changing. verify_record checks that the bytes are the ones the records index lists, the key, the signature, that the verdict follows from the recorded checks, the Merkle proof, the payment on Solana, Base or Tempo over public RPC, and the memo. It uses the same code as scripts/verify-receipt.ts (src/receipt/). RPCs: SOLANA_RPC_URL, BASE_RPC_URL, TEMPO_RPC_URL, or the public endpoints.

Other sources

VET402_CHECK_RANK, VET402_CHECK_RECORDS_INDEX and VET402_CHECK_RECORDS_BASE point the check at other copies (an https URL or a local path), for example a local build of the site.

Tests

npm test runs packages/check/test/check.test.ts with no network, on fixtures cut from the public data by packages/check/test/make-fixtures.ts: a seller with seller-side failures and negative records, a seller that delivered, an unknown seller, chain and payTo filters, a shared host, record verification that passes, and records changed by one character, a Merkle proof and a memo from another wallet that fail.

packages/check/test/no-node.test.ts runs the Python example and the Python and curl lines of use.html against /v1/check's own handler on loopback. packages/check/test/package.test.ts builds the npm package (scripts/build.mjs) and runs it from a folder outside the repository.

Prior work: the placement of the hook under the payment wrapper follows probe402-check, which checks a different public record (probe402's).

来源:packages/check/README.md,提交 4abf216

工具

0
工具元数据尚未被收录。

版本历史

1
  1. v0.1.2最新Oct 7, 2026