Don't take money from, or send it to, a sanctioned wallet
x402 payments arrive from wallets you know nothing about, and agents pay addresses they have never seen. The US Treasury publishes the crypto addresses of sanctioned people and organisations in the OFAC SDN list. Fizzl screens against it on both sides of an x402 payment, on every chain the list covers.
- Sellers: refuse a payment from a listed wallet before it settles, with one Express middleware.
- Agents that pay: the pre-payment checks answer "do not pay" when the seller's payout address is listed.
- One address:
GET /v1/screen, $0.01 over x402, any chain. - The list itself: free open data, refreshed every 6 hours.
Why not the free reputation APIs?
The usual free source, GoPlus, answers sanctioned: 0 for OFAC-listed addresses outside EVM. Three examples, all on the SDN list:
| Address | Chain | SDN entry | GoPlus |
|---|---|---|---|
TNiq9AXBp9EjUqhDhrwrfvAA8U3GUQZH81 | Tron | Bank Markazi (Central Bank of Iran) | sanctioned: 0 |
42RLPACwZPx3vYYmxSueqsogfynBDqXK298EDsNoyoHi | Solana | an SDN individual | sanctioned: 0 |
rnXyVQzgxZe7TR1EPzTkGj2jxH4LMJYh66 | XRP Ledger | Chatex | sanctioned: 0 |
Commercial screening costs $0.20 to $1 per check, too much for an API call that costs a cent. So presign-guard downloads the list from the Treasury itself (SDN.XML), keeps all of its digital currency addresses and matches them exactly.
For sellers: screen the payer before you settle
presign-guard-payer-screen goes before your x402 payment middleware. It reads the payer from the payment header and looks it up in memory. A listed payer gets 451 Unavailable For Legal Reasons, so the payment never settles and the money never reaches you. Everyone else goes straight on.
npm install presign-guard-payer-screen
import express from "express";
import { paymentMiddleware } from "@x402/express";
import { screenPayers } from "presign-guard-payer-screen";
const app = express();
app.use(screenPayers({
onBlocked: (info) => console.warn("refused a payment from a sanctioned address", info),
}));
app.use(paymentMiddleware(routes, resourceServer)); // your existing x402 setup
- Every x402 payment kind: EVM EIP-3009 and Permit2, Solana, Algorand and the XRP Ledger.
- No calls, no cost per payment: it downloads the free list once and refreshes it every 6 hours.
- No dependencies. Hono, Next.js or plain Node:
checkPayment(header, screen)returns{ blocked, payer, entries }and you answer 451 yourself. - failClosed: while no list can be loaded, answer 503 instead of letting payments through (the default lets them through, with one warning).
npm: presign-guard-payer-screen · source on GitHub
For agents that pay: never pay a sanctioned seller
- x402 Doctor preflight ($0.001, also an MCP tool): before your agent pays an x402 or MPP endpoint, it screens the seller's payout address (
payTo, or the MPP recipient). A listed address answersno_gowith reasonpayto_sanctionedand the SDN entry. x402-safe-fetch runs it before every payment and never pays ano_go. - presign-guard
POST /v1/check($0.01): before signing, it screens everyone a transaction pays or hands control to, on EVM, Solana, the XRP Ledger and Algorand. A listed party is redSANCTIONED_ADDRESS. - Agent tools:
screen_walletin the AI SDK tools, LangChain.js and Python, and in presign-guard's MCP server. - The daily Trust Index applies the same screen to the ~34,000 x402 and MPP endpoints it checks: x402-doctor.fizzl.eu/trust.
One address: GET /v1/screen ($0.01)
Any chain's address: EVM, Solana, Tron, Bitcoin, XRP Ledger, Algorand or another currency OFAC lists. Paid per call over x402 (USDC on Base, Solana or Algorand, RLUSD on the XRP Ledger) or MPP. EVM addresses also get theft, phishing and mixer reports. Every answer is signed, so your agent can show later which verdict it got.
GET https://presign-guard.fizzl.eu/v1/screen?address=TNiq9AXBp9EjUqhDhrwrfvAA8U3GUQZH81
{
"verdict": "red",
"grade": "AVOID",
"one_liner": "AVOID: on the OFAC SDN list (BANK MARKAZI JOMHOURI ISLAMI IRAN)",
"sanctions": {
"list": "OFAC SDN", "listed": true, "published": "2026-10-09",
"matches": [{ "name": "BANK MARKAZI JOMHOURI ISLAMI IRAN", "programs": ["IRAN", "IFSR", "IRGC", "SDGT"], "currency": "TRX" }]
}
}
No list, no verdict: if the list can't be loaded, the answer is a 503 and nothing is charged.
The list: GET /v1/sanctions (free)
Every digital currency address on the SDN list with its entry, as JSON, open to anyone (CORS on, cached for an hour, refreshed from the Treasury every 6 hours). Screen locally with it, in any language.
GET https://presign-guard.fizzl.eu/v1/sanctions
{
"list": "OFAC SDN",
"published": "2026-10-09",
"count": 1050,
"match": "exact; EVM and bech32 addresses lowercased, all others as published",
"addresses": [
{ "address": "0x098b716b8aaf21512996dc57eb0615e2383e2f96",
"entries": [{ "name": "LAZARUS GROUP", "type": "Entity", "programs": ["DPRK3"], "currency": "ETH" }] },
…
]
}
What it covers, and what it doesn't
- An exact match against every digital currency address OFAC publishes in the SDN list.
- Not covered: addresses of sanctioned persons that OFAC has not published, indirect exposure (money that passed through a listed wallet), and lists other than OFAC SDN.
- This is a tool, not legal advice.
More
- presign-guard: safety checks for agents that pay and sign
- x402 Doctor: is this x402 API safe to pay, and why is my 402 broken
- The Fizzl agent wallet: spending limits your agent can't talk its way past