Safety checks for Python agents that pay
fizzl gives a Python agent four checks to run before it signs or pays, as plain functions and as LangChain tools and as OpenAI Agents SDK tools (StructuredTool works in LangGraph, CrewAI and other frameworks that take LangChain tools too). The checks only check: they never sign, pay or move anything themselves.
Listed in the LangChain docs ↗ — Fizzl is listed in the LangChain docs under tools.
Install
pip install "fizzl[langchain]" # LangChain tools
pip install "fizzl[openai-agents]" # OpenAI Agents SDK tools (Python 3.10+)
pip install "fizzl[langchain,x402]" # plus the x402 client, to pay for the full checks
Try it without a wallet
With no payment set up, the token, signing and endpoint checks answer with the free quick check: the verdict only, a few per hour, marked "free": True.
from langchain.agents import create_agent
from fizzl.langchain import fizzl_tools
agent = create_agent(
"anthropic:claude-sonnet-5-5",
tools=fizzl_tools(),
system_prompt="Before you pay any API, call check_endpoint_before_paying. "
"Before you sign anything, call check_before_signing. Never continue on red or no_go.",
)
result = agent.invoke({"messages": [{"role": "user", "content":
"Is USDC (0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913) on Base safe to buy?"}]})
print(result["messages"][-1].content)
Or call a check directly:
from fizzl import Fizzl
Fizzl().check_token("base", "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913")
# {'verdict': 'green', 'grade': 'SAFE', 'free': True, 'note': 'Free quick check: ...'}
OpenAI Agents SDK
from agents import Agent, Runner
from fizzl.openai_agents import fizzl_tools
agent = Agent(
name="buyer",
tools=fizzl_tools(), # free quick checks; pass session=... or credit_keys=... for the full ones
instructions="Before you pay any API, call check_endpoint_before_paying. "
"Before you sign anything, call check_before_signing. Never continue on red or no_go.",
)
print(Runner.run_sync(agent, "Is https://ichimoku-signal.fizzl.eu/signal/BTC-USDT safe to pay?").final_output)
The checks run in a worker thread, so the agent's event loop isn't blocked. Bad arguments from the model come back as {"error": "bad_input"} without calling, or paying for, the check.
The tools
| Tool | What it checks | Full check | Free quick check |
|---|---|---|---|
check_before_signing | A transaction, token approval or signature (permit, Permit2, Seaport) before signing: drainers, unlimited approvals, look-alike dapps. Green / orange / red with reasons. | $0.01 | verdict only |
check_token | A token before buying, holding or accepting it: honeypots, rug-pull signs, look-alikes. Solana and EVM chains. | $0.01 | verdict and grade |
check_wallet_approvals | Every open token approval of an EVM wallet, and which ones to revoke. | $0.02 | none |
check_endpoint_before_paying | An x402 or MPP paid API before paying it: go / caution / no_go, the cheapest option that settles, budget, track record, bait signs. | $0.001 | go / caution / no_go with the problems found |
Pick some with fizzl_tools(only=["check_endpoint_before_paying"]). A failed check comes back as {"error": ..., "message": ...} instead of raising, so the model can tell its user.
The full checks: pay per call over x402
Wrap a requests session with the x402 client. The agent pays each check in USDC on Base from its own wallet.
import requests
from eth_account import Account
from x402 import x402ClientSync
from x402.http.clients import wrapRequestsWithPayment
from x402.mechanisms.evm.exact import ExactEvmScheme
from fizzl.langchain import fizzl_tools
payer = x402ClientSync().register("eip155:8453", ExactEvmScheme(Account.from_key(AGENT_KEY)))
session = wrapRequestsWithPayment(requests.Session(), payer)
tools = fizzl_tools(session=session)
Or prepaid credits
Buy a pack once (presign-guard: 100 checks for $0.80; x402 Doctor: 1000 preflights for $0.80), then pass the keys:
tools = fizzl_tools(credit_keys={"presign": PRESIGN_CREDIT_KEY, "doctor": DOCTOR_CREDIT_KEY})
Options
| Option | Default | |
|---|---|---|
session | a plain requests.Session | Anything with request(method, url, **kw); wrap it with x402 to pay per check |
credit_keys | none | {"presign": ..., "doctor": ...}, sent as x-credit-key |
only | all four | Tool names to include |
free | True | Fall back to the free quick check when a check can't be paid |
timeout | 30 | Seconds per check |
More
- PyPI: fizzl · source on GitHub
- JavaScript: fizzl-langchain for LangChain.js · presign-guard-ai-sdk for the Vercel AI SDK
- Want the wallet to stop the agent itself, not just tell the model? The Fizzl agent wallet