TollWarden is a payment security firewall for x402 micropayments. Agents that pay for APIs and data over x402 get drained in predictable ways, through payments triggered by prompt-injected content, replayed payment authorizations, inflated prices, secrets leaking through payment metadata, lookalike tokens, and address poisoning. langchain-tollwarden gives a LangChain/LangGraph agent an allow / flag / block verdict on every payment before it settles, plus a callback that makes TollWarden's strongest detector work automatically.
| Package | Serializable | JS support | Latest |
|---|---|---|---|
| langchain-tollwarden | ❌ | ❌ |
| Returns artifact | Native async | Return data | Pricing |
|---|---|---|---|
| ❌ | ❌ | JSON verdict (allow/flag/block + per-check reasons, Ed25519-signed) | First 100 scans free per key, then $0.01/scan (paid over x402) |
Install langchain-tollwarden from PyPI.
pip install -U langchain-tollwarden
No signup needed. A free API key (100 free scans) is minted automatically on first use and kept on the client. To pin a key across sessions, mint one and set it in the environment.
import os
os.environ["TOLLWARDEN_API_KEY"] = "psk_..." # optional; from POST https://tollwarden.com/v1/keys
Create one TollWardenClient and share it between the tools and the callback.
from tollwarden import TollWardenClient
from langchain_tollwarden import TollWardenProvenanceCallback, tollwarden_tools
tollwarden = TollWardenClient(agent_id="my-agent", api_key=os.environ.get("TOLLWARDEN_API_KEY"))
tools = tollwarden_tools(tollwarden) # scan / check reputation / report
callbacks = [TollWardenProvenanceCallback(tollwarden)]
The callback is the important part. TollWarden's strongest check catches payments whose decision came from content the agent just read (a prompt-injected page or tool result). The callback observes every tool output and retrieval automatically, so the next scan is provenance-tagged and that check runs with real input. No prompt engineering required.
scan_tool = next(t for t in tools if t.name == "tollwarden_scan_payment")
scan_tool.invoke({
"payment": {
"network": "eip155:8453",
"asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
"amount": "10000", # atomic units ($0.01 USDC)
"pay_to": "0x2096...287C",
"resource_url": "https://api.example.com/premium",
"nonce": "0x1a2b3c",
},
"expected_price_usd": 0.01,
})
# -> '{"scan_id": "...", "verdict": "allow", "risk_score": 0, "checks": [...], ...}'
A block verdict means do not pay; flag means pause and confirm intent. Use direction="incoming" to screen a 402 offer the agent received before paying it.
from langchain.agents import create_agent # or your framework's equivalent
agent = create_agent(
model="claude-sonnet-4-5",
tools=[*tools, *my_other_tools],
)
agent.invoke(
{"messages": [("user", "Buy the premium market report if it costs $0.01")]},
config={"callbacks": callbacks},
)
To make payments that cannot execute when blocked (instead of trusting the model to scan first), wrap your payment executor.
from langchain_tollwarden import guarded_payment
safe_pay = guarded_payment(execute_x402_payment, tollwarden)
# raises TollWardenBlockedError on a block verdict; the executor is never called
crewai-tollwarden@tollwarden/ai-sdkagentkit-tollwardennemo-tollwarden