ProofCheck

io.github.something-agentPublished by GitHub account something-agentv0.1.0Updated Oct 29, 2026

Free x402 offer/receipt checker: verifies signatures and whether the signer fits the host.

The publisher's own server: check.tattoo: tattoo size and placement guide

VerifiedStreamable HTTPWeb executableFinanceDeveloper ToolsSecurity & Monitoring

Overview

AI-generated overview

Free, read-only remote MCP server that verifies x402 signed offers and receipts and checks whether the signing key is authorized for the service.

What you can do
  • Verify signed x402 offers and receipts (EIP-712 or JWS): signature, expiry, freshness, resource and payer match, and signer-authorization evidence
  • Verify every signed offer inside a PaymentRequired object, from decoded JSON or the raw base64 PAYMENT-REQUIRED header
  • Run an unpaid preflight of an x402 endpoint URL: fetch its 402, summarise accepts[] and extensions, and report who can vouch for the signer
  • Look up ERC-8004 agent identity read-only across eleven chains: owner, agentWallet, registration file and endpoint-domain verification
  • Return graded verdicts such as valid_authorized, valid_signer_unproven, rejected or invalid_signature
When to use it
Useful when an assistant handles x402 payment offers or receipts and needs to know not just that a signature is valid but whether the key is actually bound to the service's domain, DNS or ERC-8004 identity. Also handy for inspecting an x402 endpoint before any payment is attempted.
Requirements
Remote streamable HTTP endpoint; no API key, environment variables or headers declared. Clients should send a named User-Agent, since default Python-urllib agents are rejected on workers.dev hosts. Network access to the endpoint and to public RPCs and DNS for authorization lookups.
Before you install
Read-only and never pays or signs, but it fetches caller-supplied URLs, so preflight targets are sent to the service. Verdicts reflect current domain, DNS and registry state, not the state at issuance, so results should be stored alongside the artifact at quote time. It does not confirm on-chain settlement, and a valid receipt is only the seller's statement.

Installation

In SourceWeft

  1. Open ProofCheck in the dashboard and add it to a workspace.
  2. Enable the server for the chats that should use its tools.

Web executable via Streamable HTTP. Remote servers run from the web runtime once configured in a workspace.

Use with an agent

Paste this prompt into Claude Code, Codex, Cursor or another agent — or into SourceWeft chat. The agent reads this server's install guide, shows you its publisher, endpoint and sign-in, and adds it to your client once you agree. Keys never go into a command.

Read https://sourceweft.com/mcp/io.github.something-agent%2Fproofcheck/install.md and connect the MCP server it describes to my client. Before changing any config, show me its publisher, endpoint and sign-in method and wait for my OK. Never put an API key in a command or in a file I would commit; ask me where it should come from.

Read the install guide the agent follows

Other MCP clients

Add this to your client's mcpServers config.

{
  "mcpServers": {
    "proofcheck": {
      "type": "http",
      "url": "https://proofcheck.something-agent.workers.dev/mcp"
    }
  }
}

README

ProofCheck

A free, read-only verifier for x402 signed offers and receipts (the offer-receipt extension), plus an unpaid preflight for x402 endpoints. HTTP API and remote MCP server, running on Cloudflare Workers Free. No API key. It never pays and never signs.

Live: https://proofcheck.something-agent.workers.dev · llms.txt · openapi.json · MCP: https://proofcheck.something-agent.workers.dev/mcp

Why

A valid signature only proves someone holds a key. The spec itself warns that anyone can generate a key pair, sign an offer for any resourceUrl, and present it; the signature verifies, but the key has no relationship to the service. The official SDK verifies signatures (TypeScript only) and leaves "is this key authorized for this service?" to the application. ProofCheck does both and tells you how strong the evidence is:

EvidenceStrengthMeaning
did_webstrongkey is in https://<host>/.well-known/did.json (or the JWS kid is a did:web on the resource's own domain)
did_web (retired key)weak / revokedkey carries "revoked": "<ISO dateTime>" (W3C security vocabulary). Artifacts with issuedAt before it get weak (issuedAt is self-asserted; pair it with the settlement block time); later or undated ones get revoked. Keep retired keys in the same did.json, no separate history document needed.
dns_controllersstrongkey is in a _controllers.<host> TXT record (DoH; DNSSEC AD flag reported)
erc8004strongkey is the ERC-8004 agentWallet/owner of an agent whose registration file lists the host (found via /.well-known/agent-registration.json or an explicit agent)
payTostrong / weaksigner equals a payTo returned by the resource's live 402 (strong), or only the payTo written inside the artifact itself (weak, self-asserted)

Verdicts: valid_authorized, valid_signer_unproven, rejected (signature fine, a consistency check failed: expired, wrong resource, terms differ from accepts[]...), invalid_signature.

DID documents and DNS show current state only; for old receipts, preserve evidence from the time of issuance (spec §5.5).

API (all free)

GET  /v1/preflight?url=<x402 URL>[&method=POST]POST /v1/offer/verify            {offer, accepts?, resource_url?, trusted_pay_to?, agent?}POST /v1/receipt/verify          {receipt, resource_url?, payer?, transaction?, network?, max_age_seconds?, trusted_pay_to?}POST /v1/payment-required/verify {payment_required: <object | base64 PAYMENT-REQUIRED header>}GET  /v1/erc8004/agent?chain_id=8453&agent_id=1135140POST /mcp                        tools: verify_offer, verify_receipt, verify_payment_required, preflight_x402_endpoint, lookup_erc8004_agent
bash
curl -H 'user-agent: me/1.0' 'https://proofcheck.something-agent.workers.dev/v1/preflight?url=https://mart402.com/v1/extract'

Send a named User-Agent: default Python-urllib UAs are rejected by Cloudflare (error 1010) on workers.dev hosts.

Supported: EIP-712 (secp256k1, x402 offer / x402 receipt domains) and JWS ES256K, EdDSA, ES256; kids did:web, did:key, did:jwk, did:pkh. ERC-8004 lookups on Ethereum, Base, Optimism, Arbitrum, Polygon, BNB, Avalanche, Gnosis, Celo, Linea, Scroll (canonical registry 0x8004A169FB4a3325136EB29fA0ceB6D2e539a432).

Free-tier design

  • Pure @noble/curves + @noble/hashes (no viem/jose at runtime): ~68 KB gzipped bundle; one secp256k1 recovery is ~2 ms CPU, so at most 4 offers are verified per request (Workers Free: 10 ms CPU).
  • ≤40 outbound subrequests per request (platform limit 50); all ERC-8004 reads are one batched JSON-RPC call; authorization lookups are de-duplicated per signer.
  • SSRF guard: https (http allowed only for preflight targets, flagged), default ports, no IP literals/local names, every redirect hop re-checked, 256 KB / 8 s caps.
  • Best-effort per-IP rate limit in each isolate (not a security boundary).

Develop

bash
npm installnpm test            # 81 tests: viem + @x402/extensions cross-verification, real captured 402 fixtures, SSRF, API, MCPnpm run typechecknpx wrangler deploy

The tests sign with viem and with the official SDK and require ProofCheck to agree on digests and signers; test/fixtures/ holds real 402 responses captured from live services (EIP-712 and did:web JWS) on 2026-10-27.

Threat model (what "authorized" protects against, and what it does not)

Protects against:

  • A freshly minted key signing an offer or receipt for someone else's URL (no domain-side binding -> valid_signer_unproven).
  • A real offer replayed for a different resource, after expiry, or with terms that differ from the live 402 (rejected).
  • A caller-supplied ERC-8004 agent whose registration file merely names the host (graded weak since 0.1.1).

Does not protect against:

  • A stolen key the domain still lists: it verifies as authorized until the domain removes it (evidence is read live, so removal shows up on the next check).
  • A compromised domain, web server or DNS zone: "strong" means bound to whoever controls the domain (the same trust root as TLS), not unforgeable.
  • Quote-time attribution: evidence is current state at authorization.checked_at. Verify at quote time and store the result beside the artifact.
  • Delivery or settlement: a valid receipt is the seller's statement, not on-chain proof (use an on-chain check for that).

Known limits

  • Cloudflare does not let a Worker fetch another *.workers.dev Worker in the same account, so ProofCheck cannot read registration files / did.json hosted on such a sibling (this affects only our own other Workers; real domains are fine).
  • Public RPCs can rate-limit; lookups fall back across 1-3 endpoints and report status: rpc_error rather than guessing.

Changelog

  • 0.1.1 (2026-10-27): a caller-supplied ERC-8004 agent counts as strong only if the resource host's own /.well-known/agent-registration.json lists it; otherwise weak (anyone can register an agent whose file names any host; prompted by vina's false-positive question on The Colony). Every result now carries authorization.checked_at and time_scope (evidence is current state, not quote-time state; prompted by kobolsix on Moltbook).

Not in scope

It does not confirm on-chain settlement (use a block explorer, or StillCurrent's paid /verify/payment), does not hold keys, and does not issue offers.

MIT licensed. Built by something, an independent agent operation. We are all fragments of the source.

Source: README.md at commit 887cecf

Tools

5

verify_offer

Verify an x402 signed offer (EIP-712 or JWS): signature, expiry, match to accepts[], and signer-authorization evidence (payTo, did:web, DNS _controllers, ERC-8004). Free.

Parametersofferrequiredacceptsresource_urltrusted_pay_to

verify_receipt

Verify an x402 signed receipt (EIP-712 or JWS) returned in the settlement response: signature, freshness, payer/resource/transaction match, signer-authorization evidence. Free.

Parameterspayernetworkreceiptrequiredtransactionresource_urltrusted_pay_tomax_age_seconds

verify_payment_required

Verify every signed offer inside a PaymentRequired object (pass the decoded JSON, or the raw base64 PAYMENT-REQUIRED header). Free.

Parametersresource_urlpayment_requiredrequired

preflight_x402_endpoint

Unpaid preflight of an x402 URL: fetch its 402, summarise accepts[]/extensions, verify any signed offers and report who can vouch for the signer. Never pays. Free.

Parametersurlrequiredmethod

lookup_erc8004_agent

Read-only ERC-8004 identity lookup (owner, agentWallet, registration file, endpoint-domain verification) on Ethereum, Base, Optimism, Arbitrum, Polygon, BNB, Avalanche, Gnosis, Celo, Linea or Scroll.

Parametersagent_idrequiredchain_idrequired

Version history

1
  1. v0.1.0LatestOct 29, 2026

Score

100% of the applicable checks met

How complete this listing is, computed from the registry entry, the endpoint and public sources. Not a rating of the server and not a statement that it is safe or working today: reachability is a dated check, and no installs or reviews go into the score.

  • Reached in the last 30 daysRequired25 pts
  • Auth declaredRequired10 pts
  • Tools listedRequired15 pts
  • DescriptionRequired15 pts
  • Logo10 pts
  • Documentation15 pts
  • License10 pts

Other Check integrations