x402 payment security for LangChain agents

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.

Overview

Integration details

PackageSerializableJS supportLatest
langchain-tollwarden❌❌

Tool features

Returns artifactNative asyncReturn dataPricing
❌❌JSON verdict (allow/flag/block + per-check reasons, Ed25519-signed)First 100 scans free per key, then $0.01/scan (paid over x402)

Setup

Install langchain-tollwarden from PyPI.

pip install -U langchain-tollwarden

Credentials

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

Instantiation

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.

Invocation

Invoke directly with args

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.

Use within an agent

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

API reference

Other integrations