Give your LangChain agent a leash
Your LangChain agent can reason, plan, and call tools. The moment you give it a wallet, it can also spend — on every run, at machine speed, with nobody watching. An agent that can pay any price, to any seller, as often as it wants doesn't have a wallet. It has your credit card and a hole in its head where the judgment should be.
This tutorial wires a LangChain agent to the SML x402 Agent Wallet — a free (MIT), MCP-native x402 payer wallet from Script Master Labs that holds the operator's own key and refuses to spend outside the rules you set:
- Per-call cap and session budget, persisted across restarts
- Provider Trust pre-flight on every seller, before anything is signed
- A Verdict Protocol step-up for unusual payments — a decision jury that can say WAIT, and the wallet obeys
- A hash-chained evidence log of every settlement and every refusal
Every number in this tutorial is a live read-back from the wallet's own proof runs on 2026-11-07. The proofs are SELF-PROOF — SML's proof wallet paying SML's own services — and they're labeled that way, because that's what honest receipts look like.
What you're building
A LangChain agent with five new MCP tools:
| Tool | What it does |
|---|---|
wallet_status | Address, live on-chain USDC balance per network, leash state, evidence-chain check |
wallet_quote | Dry run: fetch a URL's 402 challenge, price it, run trust + leash, report exactly what wallet_pay would do. Signs nothing |
wallet_pay | Fetch a URL, paying its x402 price if it answers 402. Returns the content + settlement receipt, or a structured refusal with a reason code |
wallet_trust_check | The Provider Trust result for a seller origin, as the wallet sees it pre-flight |
wallet_history | Recent evidence-log entries — settlements and refusals — with the chain-integrity check |
The wallet is an MCP server (stdio). LangChain talks to it through the standard MCP adapter — the agent never sees the private key, and there is deliberately no MCP tool that can change the caps. An agent that can raise its own leash has none.
Step 1 — Scaffold the wallet
The wallet ships as a mode of the SML x402 Kit (v1.1.0). Scaffold it straight from the live repo:
npx gitlab:script-master-labs-llc-group/x402-kit my-wallet --mode wallet cd my-wallet pip install -r requirements.txt One honest note on install paths:
npm create @scriptmasterlabs/x402still serves Kit 1.0.1 today — the 1.1.0 npm publish is blocked on a GitLab CI quota issue, not on code. Thenpx gitlab:path above scaffolds wallet mode from the live repo and is the working route right now. Once 1.1.0 publishes to npm, the npm create command picks up wallet mode too.
Step 2 — Set the leash (operator config only)
Caps, budgets, and allowlists are read from the environment once, at launch. This is your config, not the agent's:
# File containing ONLY the operator's 0x private key (chmod 600) export SML_WALLET_KEY_FILE=/path/to/operator.key # The leash — shipped defaults export SML_WALLET_MAX_PER_CALL_USD=0.50 export SML_WALLET_BUDGET_USD=5.00 # Optional guardrails export SML_WALLET_MERCHANTS= # host allowlist, comma-separated (empty = all) export SML_WALLET_PAY_TO_ALLOWLIST= # 0x payTo allowlist (empty = all) export SML_WALLET_MAX_CALLS_PER_HOUR=0 # 0 = unlimited export SML_WALLET_VERDICT_THRESHOLD_USD=1.00 export SML_WALLET_JEV_KEY_FILE= # Verdict's jury is BYOK (X-JEV-API-KEY) Spend state persists across restarts in .sml-wallet/leash.json, and every outcome is appended to a hash-chained evidence log in the same state directory. Restart the agent mid-session and the budget it already burned stays burned.
Start the server:
python3 sml_wallet_server.py Step 3 — Point LangChain at the wallet
With langchain-mcp-adapters, the wallet is just another MCP server:
from langchain_mcp_adapters.client import MultiServerMCPClient from langchain.agents import create_agent from langchain_openai import ChatOpenAI # or your model of choice client = MultiServerMCPClient( { "sml-wallet": { "command": "python3", "args": ["sml_wallet_server.py"], "transport": "stdio", } } ) tools = await client.get_tools() agent = create_agent(ChatOpenAI(model="gpt-4o"), tools) result = await agent.ainvoke( { "messages": [ { "role": "user", "content": ( "Use wallet_pay to fetch this page as markdown: " "https://example.com/some-article — and if the wallet " "refuses, tell me the exact reason code. Do not retry " "a refusal with a different tool." ), } ] } ) That instruction at the end matters. A refusal is a result, not an error to route around — the reason codes (over_cap, over_budget, trust_blocked, verdict_denied, insufficient_balance, not_allowlisted, unsupported_network, velocity_limited) are structured precisely so your agent can report them instead of improvising.
Step 4 — A real $0.001 payment
Here's what a good payment looks like, from the wallet's own proof run (SELF-PROOF, 2026-11-07). The target was SML's URL-to-Markdown API — a paid read priced at $0.001 USDC on Base:
- The request goes out unpaid. The API answers
402with its price. - The wallet reads the real on-chain balance — never a stored number. If the RPC is unreachable, the balance reports as unreadable, never as zero.
- The leash checks the payment: $0.001 is under the $0.50 per-call cap and inside the remaining budget. Funds are reserved.
- Provider Trust classifies the seller origin: verified. Proceed.
- The wallet signs (EIP-3009) and delivers. Spend is counted only when the seller returns a settlement receipt.
- The outcome is appended to the hash-chained evidence log.
Receipt: transaction 0x3020594624d1fc1896a74b7e11d5b29ad18c4f450be16e8c18c5ffe0612cbb43 — the proof wallet's on-chain balance moved 0.5489 → 0.5479 USDC. After a restart, the spent tally and the log entry were read back from disk: the leash survived the reboot, exactly as designed.
Want to see the decision without spending? wallet_quote runs the same 402 fetch, pricing, trust, and leash checks and reports what wallet_pay would do — signing nothing.
Step 5 — Watch it refuse
A leash you never see pull is just a hope. Two refusals from the same proof runs, both SELF-PROOF:
Trust block — $0 spent. A payment was attempted to a route on an origin whose Provider Trust profile is do_not_trust (reason EVIDENCE_CONFLICT — its payment-rail-consistency gate failed). The wallet refused with trust_blocked before signing; the balance never moved, and the refusal went into the evidence log. Stated plainly: that origin is SML's own gateway host. The conflict turned out to be a bug in SML's own trust evaluator — fiat price blocks were being read as payment records, and the USDC contract address and the USDC symbol were compared as if they were different assets. Fixed the same morning (2026-11-07): the evaluator was patched and the gateway's agent card aliased to the path the evaluator fetches; the gateway origin now reads provisional_for_read_only_routing with its payment gate passing. Re-test minutes later (SELF-PROOF): the same wallet paid the same route — a $0.02 Regime Scan ticker read — end-to-end, settlement tx 0xd96be71bc3b3ea34023ad5d502740100faab787047b3d5225e8093c20081db9a, balance 0.2979 → 0.2779 USDC. The wallet reports profiles as they stand, even ours — which is exactly why the bug got found and fixed instead of argued with. Verified origins pay normally; unknown profiles pay within the leash and are logged as unverified — missing evidence is never dressed up as fraud, or as trust.
Verdict step-up — the jury said WAIT. With a test step-up threshold of $0.0005, a $0.001 payment crossed the line and the wallet first bought a Verdict Protocol decision for $0.25 (settlement tx 0x978711281636cefd1e6616e64231d8012bcce11e599f4c87e4c0553dda19d8b7, receipt e6cc16a7-d33f-4e40-b8a9-19c80dfbd5e5). The jury's majority answer was WAIT — and the wallet obeyed, refusing the payment with verdict_denied. It also fails closed the other way: if the Verdict decision itself can't be bought, the payment is refused, not waved through. (In production the default step-up threshold is $1.00 — above the default $0.50 cap, so it engages for operators who deliberately raise their caps.)
Total proof spend across every run in this tutorial: $0.271 USDC ($0.251 in the original proof battery, plus the $0.02 post-fix re-test above).
An over-cap call is the simplest refusal of all: ask the wallet to pay anything above $0.50 under the default config and you get over_cap back, unsigned, unspent, logged.
How it settles, what it costs
- Rails: the wallet signs as a stock x402 client and settles through OMNIGATE. The seller's own facilitator settles; the wallet adds no fee of its own and signs seller-presented requirements verbatim — it invents nothing.
- Networks live today: Base (
eip155:8453) and Arc (eip155:5042), USDC, x402 v2exact. - NOT YET — honestly: Solana, XRPL, and Xahau. Those rails sign differently (no EIP-3009) and there is no funded non-EVM operator wallet to prove a settle with. Rather than fake a rail, the wallet ships EVM-complete and says so. A rail lands when it can be proven with a real settlement, not before.
- Custody: none. No escrow, no holding funds — the wallet gates before payment (trust + leash + Verdict) instead of holding money until delivery.
- Price: free. MIT licensed.
The other side of the counter
This tutorial is about agents that buy safely. If you're the one selling to agents — an API, a file, a dataset, an MCP tool — the seller-side counterpart is Business in a Box — for Agents + Humans (Seller Templates): one config generates your agent surface plus a human storefront, settling through the same x402 rails for $149 at scriptmasterlabs.com/seller-templates.
Business in a Box sells; the Agent Wallet buys — safely.
Steal this checklist
Whatever wallet you end up using, hold it to this standard:
- Caps and budgets set by the operator, in config — never changeable by the agent through any tool.
- Spend state persisted, so a restart isn't a budget reset.
- A trust check on the seller before signing, with a hard block that costs $0.
- A step-up for unusual payments that can actually stop the payment — and fails closed.
- An evidence log that records refusals with the same care as settlements.
- No custody, no invented fees, and receipts you can read back on-chain.
The SML x402 Agent Wallet checks all six, it's free, and the proofs above are on-chain for anyone to verify.
SML x402 Agent Wallet — free (MIT), from Script Master Labs LLC (SDVOSB). Canonical home: scriptmasterlabs.com/x402-agent-wallet. Part of the x402 Kit.

