LangChain payment integration.
Add USDC payments to any LangChain agent. The real Python package gives it wallet tools - send, settle, and read - in a few lines.
Blockchain0x ships a real Python package, , that gives a LangChain agent native wallet tools: send USDC on Base, settle an invoice with on-chain proof, and read wallets and transactions. Install it, set , call , and hand the tools to your agent. On TypeScript? There is no npm adapter - wrap the x402 client in a LangChain.js tool.
One thin layer over the Blockchain0x HTTP API.
Every tool in blockchain0x-langchain is a thin wrapper over the official blockchain0x core SDK. No re-implemented REST or x402 logic, no key custody: the adapter forwards your API key to the backend and holds no secret of its own. create_blockchain0x_toolset(client) hands LangChain five tools - send a payment, settle an invoice, read a wallet, list wallets, read a transaction - each already typed and scoped.
You can still call the raw API or the core SDK directly if you prefer. The adapter is the path of least resistance; the API is the contract. Pin blockchain0x-langchain to the langchain-core range it supports rather than chasing the latest of both.
One install. One environment variable. Ready.
The package needs Python 3.9 or newer. It pulls in the core blockchain0x SDK and langchain-core as dependencies; nothing else to add.
pip install blockchain0x-langchainexport BLOCKCHAIN0X_API_KEY=sk_test_... # sk_test_ = Base Sepolia, sk_live_ = Base mainnet
BLOCKCHAIN0X_API_KEY is a sk_test_ testnet or sk_live_ mainnet key from your Blockchain0x dashboard. That is the only variable the adapter needs; it forwards the key to the backend and holds no secret of its own. For the webhook handler shown below you also set BLOCKCHAIN0X_WEBHOOK_SECRET, which the dashboard returns once when you create or rotate a webhook.
A working LangChain agent with payment support.
Below is a complete LangChain agent in Python. create_blockchain0x_toolset returns the wallet tools, create_react_agent wires them into a ReAct loop, and the model picks the right tool from the prompt. Set BLOCKCHAIN0X_API_KEY, run it, and the agent can move and read USDC on Base.
from blockchain0x import Client from blockchain0x_langchain import create_blockchain0x_toolset from langchain_openai import ChatOpenAI from langgraph.prebuilt import create_react_agent client = Client() # reads BLOCKCHAIN0X_API_KEY from the environment tools = create_blockchain0x_toolset(client) llm = ChatOpenAI(model="gpt-4o") agent = create_react_agent(llm, tools) result = agent.invoke({ "messages": [{ "role": "user", "content": "Pay 0.01 USDC from my agent to 0xRecipient for the dataset.", }], })
Run it with the prompt above and the model picks the send-payment tool, the SDK submits the transfer on Base, and you get a transaction hash back. amount_wei is USDC base units (6 decimals), so 0.01 USDC is the string "10000". A sk_test_ key keeps you on Base Sepolia until you switch to sk_live_. Heads up: payments.create can answer 503 until the chain adapter is wired for your network.
What happens after the user pays.
Your agent's webhook URL (set in the Blockchain0x dashboard) receives a POST when a payment settles. The webhook verify helper is in the Node SDK, so this handler is TypeScript even though your agent is Python. Below is an Express handler that checks the signature and runs the paid work. Use the same pattern in any HTTP framework.
import express from "express"; import { webhooks } from "@blockchain0x/node"; const app = express(); // Capture the RAW body. The HMAC is over the exact bytes on the wire. app.use(express.raw({ type: "application/json" })); app.post("/webhooks/payment", (req, res) => { const result = webhooks.verify({ headers: req.headers, rawBody: req.body, // Buffer, raw bytes secret: process.env.BLOCKCHAIN0X_WEBHOOK_SECRET!, }); if (!result.ok) return res.status(400).json({ code: result.code }); if (result.eventType === "payment.received") { // USDC landed in your agent wallet - do the paid work } res.status(200).send("ok"); });
webhooks.verify does HMAC-SHA256 in constant time and returns a discriminated union, so you branch on result.ok with no try/catch and read result.eventType. Read the raw body, not a parsed copy: parsing then re-serializing breaks the signature. The shipped events are payment.received, payment.sent, wallet.deployed, and webhook.test; an inbound charge to your agent is payment.received.
No npm LangChain adapter. Here is the honest recipe.
The shipped LangChain adapter is Python only. There is no LangChain adapter on npm. For a TypeScript LangChain or LangGraph agent, you wrap the real x402 client in a LangChain.js tool yourself. It is a few lines, and it is exactly what a dedicated adapter would do under the hood.
import { createClient } from "@blockchain0x/node"; import { createX402Client } from "@blockchain0x/x402/client"; import { tool } from "@langchain/core/tools"; import { z } from "zod"; const sdk = createClient({ apiKey: process.env.BLOCKCHAIN0X_API_KEY! }); const fetchWithPay = createX402Client({ sdk }); // There is no npm LangChain adapter. Wrap the x402 client in a LangChain.js tool. export const payAndFetch = tool( async ({ url }) => (await fetchWithPay(url)).text(), { name: "pay_and_fetch", description: "Fetch a URL, answering any x402 payment challenge automatically", schema: z.object({ url: z.string().url() }), }, );
The source and the testnet examples live at the Python SDK repo; the SDK support matrix is at the docs. The Python smoke example sends a real $0.01 USDC transfer on Base Sepolia through the same send-payment action the LangChain tool wraps.
Five things that bite on first integration.
These come from our support inbox. None of them are deal-breakers, but knowing about them in advance saves an hour of head-scratching each.
Amounts are USDC base units, as strings
The payment tools take amount_wei: a string of USDC base units, not a float and not a dollar figure. USDC has 6 decimals, so 0.01 USDC is "10000" and 5 USDC is "5000000". Always pass a string; large integers lose precision as JSON numbers. Send "5.00" and you will either get a validation error or move a millionth of what you meant.
The invoice tool settles, it does not create
blockchain0x_settle_invoice settles an EXISTING payment request with on-chain proof. There is no tool that mints a fresh invoice or a hosted checkout link: payment requests are created in the dashboard, and the core SDK exposes settlement only. If you expected the agent to generate a payable link on the fly, that is not the shape. Create the request out of band, then let the agent settle it.
Verify webhooks against the raw body
Webhooks POST to your URL, and anyone who learns that URL can POST junk. Run webhooks.verify from @blockchain0x/node over the RAW request bytes before you trust an event. Parse the JSON first and the HMAC will not match, because the signature covers the exact bytes that arrived. It is HMAC-SHA256 with a 300-second replay window. Skipping it is the most common production miss.
send_payment can answer 503 early on
payments.create, which blockchain0x_send_payment wraps, does not retry by default and can return 503 until the chain adapter is wired for your network. Do not let the LLM hammer the tool in a retry loop on an error: it burns tokens and muddies your intent log. Lean on the built-in idempotency key, surface the failure, move on.
Match the langchain-core version
blockchain0x-langchain 0.1.x targets langchain-core >=0.2,<0.4. If you are on a newer core than the adapter supports, pin the pair that matches instead of chasing the latest of both. The support matrix lives in the docs.