Reliability scores built from signed fulfillment attestations — each one tied to a payment that provably settled. Recency-decayed, per-attestor capped, and honest about its own confidence.
git clone https://github.com/nirholas/x402-reputation && cd x402-reputation npm install && npm run dev
Every paid route answers with a dual-rail 402. The accepts array carries one EVM entry and one Solana entry; your client (or the checkout modal) picks whichever wallet it has. Each rail settles through its own facilitator — no single one handles both.
base-sepolia / base0x40252CFDF8B20Ed757D61ff157719F33Ec332402x402.org/facilitatorsolana-devnet / solanaWwwuGbqHrwF5RG89KhUbmRWEvjnRH9k5kVM5p7T3WwWfacilitator.payai.networkEvery attestation names the payment it is about, so the evidence behind a score is auditable: pull the sample from a report, check each payment.transaction on its own chain, and re-verify the signature offline.
| Route | Price | Returns |
|---|---|---|
GET /score/:merchantId | $0.001 | Reliability report (fulfillment rate, refund rate, sample attestations) |
POST /attest | $0.001 | Signed attestation record (links payment tx + outcome) |
GET /merchants | free | Merchant index with attestation counts |
GET /attestations/:id | free | Signed attestation record |
POST /verify | free | `{ valid: true | false }` |
GET /health | free | `{ ok: true }` |
import { wrapFetchWithPayment } from "x402-fetch";
import { privateKeyToAccount } from "viem/accounts";
const payFetch = wrapFetchWithPayment(fetch, privateKeyToAccount(process.env.PRIVATE_KEY));
// $0.001 — record what happened after a payment settled
await payFetch("http://localhost:4024/attest", {
method: "POST", headers: { "content-type": "application/json" },
body: JSON.stringify({
merchantId: "osteria-fiorentina.example",
outcome: "fulfilled",
payment: { network: "solana-devnet", transaction: "5Kq7xJ2mN…", amount: "$0.75" },
attestor: "WwwuGbqHrwF5RG89KhUbmRWEvjnRH9k5kVM5p7T3WwW",
note: "Table was held, seated on time."
})
});
// $0.001 — buy the merchant's record before you spend with them
const report = await (await payFetch(
"http://localhost:4024/score/osteria-fiorentina.example"
)).json();
report.score; // 88
report.confidence; // "high"
report.sample; // recent attestations, each naming its payment tx
/.well-known/x402 — machine-readable manifest, both networks per resource (indexable by x402scan.com, the x402 Bazaar, agentic.market)