Give Your AI Agent a Bitcoin Wallet: MCP, SDK, and L402 Payments for Autonomous Agents
Connect any AI agent to the Lightning Network in minutes. MCP server, SDK integration, and L402 payments — your agent can earn, spend, and pay for APIs autonomously.
Your agent can browse the web, write code, call APIs, reason through multi-step problems, and produce work that would take a human hours. But the moment it needs to pay for something, it's stuck.
A premium data source behind a paywall. A compute API that charges per call. Another agent offering a service for a few sats. Your agent hits the wall, stops, and waits for a human to go sign up, grab an API key, configure billing, and come back. Multiply that by every paid service the agent could use, and you've got an autonomy problem that has nothing to do with intelligence.
The fix is embarrassingly simple: give the agent a wallet. One MCP connection or one SDK import, and your agent holds a balance, pays invoices, receives payments, and transacts with other agents — all over the Lightning Network, all settling in under a second.
Connect via MCP (2 minutes)
The fastest path. If your agent runs in Claude Desktop, Cursor, or anything that speaks MCP, you don't install a package. You add a config block.
{
"mcpServers": {
"lnbot": {
"url": "https://api.ln.bot/mcp",
"headers": { "Authorization": "Bearer key_..." }
}
}
}That's it. The agent discovers Lightning wallet tools automatically — create invoices, send payments, check balance, pay L402 challenges. No code changes. The agent just gains financial capabilities the same way it gains any other tool: through discovery.
What this looks like in practice:
You: Pay alice@ln.bot 500 sats for the dataset she shared.
Agent: [calls send_payment tool] Done. Sent 500 sats to alice@ln.bot, fee: 0, settled in 84ms.
The agent doesn't know what Lightning is. It doesn't need to. It found a tool called send_payment, figured out the parameters, and ran it.
Discovery endpoint for tooling that supports it: https://ln.bot/.well-known/mcp.json
Connect via SDK (5 minutes)
For custom agents, background workers, LangChain tools, CrewAI — anything where you control the code.
Python, since that's where most agent frameworks live:
from lnbot import LnBot
ln = LnBot(api_key="key_...")
# Agent creates an invoice to get paid
invoice = ln.invoices.create(amount=1000, memo="Task completed")
print(invoice.bolt11) # share this to receive payment
# Agent pays another agent
ln.payments.create(target="other-agent@ln.bot", amount=500)
# Agent checks balance before committing to something expensive
wallet = ln.wallets.current()
if wallet.available >= 5000:
# proceed with the expensive API call
passTypeScript, for agents running on Node:
import { LnBot } from "@lnbot/sdk";
const ln = new LnBot({ apiKey: "key_..." });
const invoice = await ln.invoices.create({
amount: 1000,
memo: "Task completed",
});
await ln.payments.create({
target: "other-agent@ln.bot",
amount: 500,
});The pattern is the same in both: create a client, call methods. The SDK handles authentication, serialization, error handling, retries. Your agent code reads like business logic, not protocol wrangling.
Auto-pay L402 APIs
Holding money is one thing. Spending it without asking permission is another.
L402 is the protocol that connects HTTP's 402 Payment Required status to Lightning. An API responds with an invoice instead of data. The agent pays the invoice, retries with proof of payment, gets the data. Whole thing takes under a second.
With the SDK, you can handle this explicitly:
from lnbot import LnBot
ln = LnBot(api_key="key_...")
payment = ln.l402.pay(
www_authenticate="L402 macaroon=..., invoice=lnbc..."
)
# payment.authorization → ready-to-use header for the retryOr wrap your HTTP client so it happens transparently — the agent never even knows a payment occurred:
import { l402, LnBot } from "@lnbot/l402";
const ln = new LnBot({ apiKey: "key_..." });
const client = l402.client(ln, {
maxPrice: 100,
budgetSats: 50_000,
budgetPeriod: "day",
});
const response = await client.fetch(
"https://premium-api.example.com/data"
);
// Hit a 402 → paid the invoice → retried → got dataThe budget controls matter. maxPrice caps any single payment at 100 sats. budgetSats caps total daily spend at 50,000 sats. The agent has a credit limit, not a blank check. If a rogue API tries to charge 10,000 sats for a single request, the client throws L402BudgetExceededError and moves on.
Your agent as a paid service
The other direction: your agent earns money.
If your agent exposes capabilities over HTTP — research, summarization, code review, data analysis — you can gate it behind L402. Every request pays a Lightning invoice before it reaches your agent's logic.
import express from "express";
import { l402, LnBot } from "@lnbot/l402";
const app = express();
const ln = new LnBot({ apiKey: process.env.LNBOT_API_KEY });
app.use("/api/research", l402.paywall(ln, {
price: 50,
description: "Research query",
}));
app.post("/api/research", async (req, res) => {
// This only runs after payment clears
const result = await doResearch(req.body.query);
res.json(result);
});Fifty sats per query. Anyone can pay it — human, agent, script. The agent earns from one side, spends on the other. Full setup in the pay-per-API-call guide.
Agent-to-agent payments
Agent A needs data cleaned. Agent B offers data cleaning for 100 sats per job. Agent A knows Agent B's Lightning address. So it pays:
from lnbot import LnBot
# Agent A
agent_a = LnBot(api_key="key_agent_a")
agent_a.payments.create(
target="b3kx9q@ln.bot",
amount=100,
)
# Agent B, somewhere else entirely
agent_b = LnBot(api_key="key_agent_b")
for event in agent_b.events.stream():
if event.event == "invoice.settled":
print(f"Got paid {event.data.amount} sats")
# do the workBoth SDKs are published. The payments settle over Lightning in milliseconds. The only thing that's new is having agents on both ends instead of humans.
Security and controls
You're giving software a wallet. Think about what it should be allowed to do with it.
API keys can be scoped — read-only for balance checks and transaction history, full-access for sending payments. Give the agent the minimum it needs. If it only receives, it doesn't need send permissions.
Budget limits on the L402 client enforce maxPrice per transaction and total spend per period. Set them tight. You can always raise them — you can't un-send sats.
The agent never holds a private key. ln.bot manages custody; the API key just authorizes operations. If a key gets compromised, rotate it. The wallet and its balance survive. Wallets can also be recovered via passphrase or passkey.
Treat ln.bot wallets as operational balances — a hot wallet for near-term spending, not cold storage. An agent needs 50,000 sats to cover its daily API budget; it doesn't need to hold 10 BTC on any custodial service. Keep only what your agent needs. Move everything else to self-custody.
For retries, pass an idempotency_key on payments. Same key, same payment — even if the agent fires the request twice, the sats only move once.
Go
A config block or an import statement. That's the distance between an agent that stops at every paywall and one that handles it.
- MCP server docs — full tool reference for Claude Desktop, Cursor, and other MCP clients
- SDK reference — TypeScript, Python, Go, Rust, C#
- Pay-per-API-call guide — L402 paywall setup in detail
- Lightning Network explained — how the underlying payment network works
FAQ
> How do I give my AI agent a Bitcoin wallet?
> Can AI agents pay for APIs automatically?
> What is MCP and how does it connect to Lightning?
> How do I prevent my agent from spending too much?
> Can agents pay other agents directly?
Related
Lightning Network Explained: What It Is, How It Works, and Why It Matters
The Lightning Network makes Bitcoin instant and nearly free. How payment channels, routing, and invoices work — from everyday payments to programmatic micropayments for AI agents.
Pay-Per-API-Call: Monetize Any API with Bitcoin Micropayments
Charge per request with Lightning Network micropayments. No signup, no API keys, no Stripe fees. Drop-in middleware for Express.js and ASP.NET Core.