The official TypeScript SDK for ln.bot — Bitcoin for AI Agents.
Give your AI agents, apps, and services access to Bitcoin over the Lightning Network. Create wallets, send and receive sats, and get real-time payment notifications — all in a few lines of code.
import { LnBot } from "@lnbot/sdk";
const ln = new LnBot({ apiKey: "key_..." });
await ln.payments.create({ target: "alice@ln.bot", amount: 1000 });ln.bot also ships a Python SDK, Go SDK, Rust SDK, CLI, and MCP server.
- Built for agents — programmatic wallets, API keys, and idempotent payments designed for autonomous software
- Instant settlement — payments arrive in seconds, not days
- Lightning addresses — human-readable addresses like
name@ln.bot - Real-time events — SSE streams and webhooks for payment notifications
- Recovery built in — 12-word BIP-39 passphrase and passkey backup
- Simple pricing — no monthly fees, pay only when you move sats off-network
- Zero dependencies — native
fetch(Node 18+, Bun, Deno, browsers) - Fully typed — every request, response, and error has TypeScript types
- Tiny — under 10 KB minified + gzipped
- Dual format — ESM + CJS with source maps and
.d.tsdeclarations - Idiomatic — resource-based API (
ln.invoices.create(), notcreateInvoice())
npm install @lnbot/sdkpnpm add @lnbot/sdkyarn add @lnbot/sdkNo API key needed — create a wallet and get your keys:
import { LnBot } from "@lnbot/sdk";
const ln = new LnBot();
const wallet = await ln.wallets.create({ name: "my-agent" });
console.log(wallet.primaryKey); // your API key
console.log(wallet.address); // your Lightning address
console.log(wallet.recoveryPassphrase); // back this up!const ln = new LnBot({ apiKey: wallet.primaryKey });
const invoice = await ln.invoices.create({
amount: 1000,
memo: "Payment for task #42",
});
console.log(invoice.bolt11); // share with the payerfor await (const event of ln.invoices.watch(invoice.number)) {
if (event.event === "settled") {
console.log("Paid!");
}
}// To a Lightning address
await ln.payments.create({
target: "alice@ln.bot",
amount: 500,
});
// To a BOLT11 invoice
await ln.payments.create({
target: "lnbc10u1p...",
});const wallet = await ln.wallets.current();
console.log(`${wallet.available} sats available`);Every wallet gets a Lightning address. Create more or claim vanity addresses:
const random = await ln.addresses.create();
const vanity = await ln.addresses.create({ address: "myagent" });
const all = await ln.addresses.list();
await ln.addresses.delete("myagent");
await ln.addresses.transfer("myagent", {
targetWalletKey: "other-wallet-api-key",
});Full history of credits and debits:
const txs = await ln.transactions.list({ limit: 20 });
for (const tx of txs) {
console.log(`${tx.type} ${tx.amount} sats — ${tx.note}`);
}Get notified when invoices are paid:
const hook = await ln.webhooks.create({
url: "https://example.com/webhooks/lnbot",
});
// hook.secret — save this for signature verification. Only returned once.
const hooks = await ln.webhooks.list();
await ln.webhooks.delete(hook.id);Each wallet has a primary and secondary key for zero-downtime rotation:
const rotated = await ln.keys.rotate(0); // 0 = primary, 1 = secondary
// rotated.key — new plaintext key, shown onceconst backup = await ln.backup.recovery();
// backup.passphrase — 12-word BIP-39, show once
const restored = await ln.restore.recovery({
passphrase: "word1 word2 ... word12",
});
// restored.primaryKey, restored.secondaryKey — fresh keysconst begin = await ln.backup.passkeyBegin();
// pass begin.options to navigator.credentials.create()
await ln.backup.passkeyComplete({
sessionId: begin.sessionId,
attestation: credential,
});Monetize APIs with Lightning-native authentication:
// Create a challenge (server side)
const challenge = await ln.l402.createChallenge({
amount: 100,
description: "API access",
expirySeconds: 3600,
});
// Pay the challenge (client side)
const result = await ln.l402.pay({ wwwAuthenticate: challenge.wwwAuthenticate });
// Verify a token (server side, stateless)
const { valid } = await ln.l402.verify({ authorization: result.authorization! });All list endpoints support cursor-based pagination:
const page1 = await ln.invoices.list({ limit: 10 });
const page2 = await ln.invoices.list({
limit: 10,
after: page1[page1.length - 1].number,
});Works the same for ln.payments.list() and ln.transactions.list().
All API errors throw typed exceptions:
import {
LnBotError,
BadRequestError,
NotFoundError,
ConflictError,
} from "@lnbot/sdk";
try {
await ln.payments.create({ target: "invalid", amount: 100 });
} catch (err) {
if (err instanceof BadRequestError) {
// 400 — validation failed
} else if (err instanceof NotFoundError) {
// 404 — resource not found
} else if (err instanceof ConflictError) {
// 409 — duplicate or conflict
} else if (err instanceof LnBotError) {
// Other API error
console.error(err.status, err.body);
}
}import { LnBot } from "@lnbot/sdk";
const ln = new LnBot({
apiKey: "key_...", // optional — not needed for wallet creation or restore
baseUrl: "https://api.ln.bot", // optional — this is the default
fetch: customFetch, // optional — bring your own fetch for testing or proxies
});| Method | Description |
|---|---|
ln.wallets.create(req?) |
Create a new wallet (no auth required) |
ln.wallets.current() |
Get current wallet info and balance |
ln.wallets.update(req) |
Update wallet name |
| Method | Description |
|---|---|
ln.invoices.create(req) |
Create a BOLT11 invoice to receive sats |
ln.invoices.list(params?) |
List invoices |
ln.invoices.get(number) |
Get invoice by number |
ln.invoices.watch(number, timeout?, signal?) |
SSE stream — yields when invoice settles or expires |
| Method | Description |
|---|---|
ln.payments.create(req) |
Send sats to a Lightning address or BOLT11 invoice |
ln.payments.list(params?) |
List payments |
ln.payments.get(number) |
Get payment by number |
| Method | Description |
|---|---|
ln.addresses.create(req?) |
Create a random or vanity Lightning address |
ln.addresses.list() |
List all addresses |
ln.addresses.delete(address) |
Delete an address |
ln.addresses.transfer(address, req) |
Transfer address to another wallet |
| Method | Description |
|---|---|
ln.transactions.list(params?) |
List credit and debit transactions |
| Method | Description |
|---|---|
ln.webhooks.create(req) |
Register a webhook endpoint (max 10) |
ln.webhooks.list() |
List all webhooks |
ln.webhooks.delete(id) |
Delete a webhook |
| Method | Description |
|---|---|
ln.keys.rotate(slot) |
Rotate a key (0 = primary, 1 = secondary) |
| Method | Description |
|---|---|
ln.backup.recovery() |
Generate 12-word BIP-39 recovery passphrase |
ln.backup.passkeyBegin() |
Start passkey backup (WebAuthn) |
ln.backup.passkeyComplete(req) |
Complete passkey backup |
| Method | Description |
|---|---|
ln.restore.recovery(req) |
Restore wallet with recovery passphrase |
ln.restore.passkeyBegin() |
Start passkey restore (WebAuthn) |
ln.restore.passkeyComplete(req) |
Complete passkey restore |
- Node.js 18+, Bun, Deno, or any environment with a global
fetch - Get your API key at ln.bot
ln.bot isn't just an SDK — pick the interface that fits your stack:
- CLI —
lnbot pay lnbc1...f3q --amount 1000 - MCP Server — Model Context Protocol for AI agents
- REST API — direct HTTP calls
- ln.bot — website
- Documentation
- GitHub
- npm
- Python SDK · pypi
- Go SDK · pkg.go.dev
- Rust SDK · crates.io · docs.rs
MIT