Menu
Lightning Beginner 6 min read

Lightning Wallets

Lightning wallet options for agents. Self-custody vs custodial, API access, and wallet selection criteria.

wallets custody mobile api lnbits

Lightning Wallets

A Lightning wallet manages your channels and enables payments. For agents, wallet selection determines API access, custody model, and operational complexity.

Wallet Selection Criteria

FactorQuestion
CustodyDo you control the keys?
API accessCan agents interact programmatically?
LiquidityHow do you get inbound capacity?
UptimeWhat happens when wallet is offline?
CostSetup and operational costs?

Agent-Friendly Wallets

LNbits

Type: Self-hosted wallet manager Best for: Agents needing simple REST API

import requests

LNBITS_URL = "https://your-lnbits.com"
API_KEY = "your-invoice-key"

# Create invoice
response = requests.post(
    f"{LNBITS_URL}/api/v1/payments",
    headers={"X-Api-Key": API_KEY},
    json={"out": False, "amount": 1000, "memo": "Agent payment"}
)
invoice = response.json()["payment_request"]

# Pay invoice
response = requests.post(
    f"{LNBITS_URL}/api/v1/payments",
    headers={"X-Api-Key": ADMIN_KEY},  # Admin key for sending
    json={"out": True, "bolt11": "lnbc..."}
)

Pros:

  • Simple REST API
  • Multiple wallets from one node
  • Extensions (LNURL, PoS, etc.)
  • Can use shared instances

Cons:

  • Requires underlying node
  • Shared instances = custody risk

Alby

Type: Browser extension + API Best for: Web integrations, Lightning Address

// Alby API
const response = await fetch('https://api.getalby.com/invoices', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${ALBY_TOKEN}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    amount: 1000,
    description: 'Agent payment'
  })
});

const { payment_request } = await response.json();

Pros:

  • Lightning Address (you@getalby.com)
  • OAuth for user wallets
  • NWC (Nostr Wallet Connect)

Cons:

  • Custodial by default
  • Rate limits on free tier

Phoenix

Type: Mobile self-custody Best for: Personal use, not agents

Pros:

  • True self-custody
  • Automatic channel management
  • Swap in/out

Cons:

  • No server API
  • Mobile only
  • LSP dependent

Wallet of Satoshi

Type: Custodial mobile Best for: Quick testing

Cons:

  • Fully custodial
  • No API
  • KYC in some regions

Wallet Comparison

WalletCustodyAPIAgent UseSetup
LNbitsSelf*REST⭐⭐⭐⭐⭐Medium
AlbyCustodialREST⭐⭐⭐⭐Easy
LNDSelfgRPC⭐⭐⭐⭐⭐Hard
Core LightningSelfJSON-RPC⭐⭐⭐⭐⭐Hard
PhoenixSelfNoneEasy
BreezSelfSDK⭐⭐⭐Medium
MutinySelfWASM⭐⭐Easy

*LNbits is as custodial as the underlying node

Setting Up LNbits

Using Public Instance (Testing Only)

# legend.lnbits.com - DO NOT USE FOR REAL FUNDS
LNBITS_URL = "https://legend.lnbits.com"
# Docker setup
git clone https://github.com/lnbits/lnbits.git
cd lnbits
cp .env.example .env
# Edit .env with your settings
docker-compose up -d

Connect to Your Node

# .env for LNbits
LNBITS_BACKEND_WALLET_CLASS=LndRestWallet
LND_REST_ENDPOINT=https://your-lnd:8080
LND_REST_CERT=/path/to/tls.cert
LND_REST_MACAROON=your-admin-macaroon-hex

API Patterns

Invoice Polling

def wait_for_payment(payment_hash, timeout=300):
    """Poll until invoice is paid or timeout."""
    start = time.time()

    while time.time() - start < timeout:
        response = requests.get(
            f"{LNBITS_URL}/api/v1/payments/{payment_hash}",
            headers={"X-Api-Key": API_KEY}
        )
        status = response.json()

        if status["paid"]:
            return True

        time.sleep(5)

    return False

Webhook Notifications

# LNbits supports webhooks
invoice = requests.post(
    f"{LNBITS_URL}/api/v1/payments",
    headers={"X-Api-Key": API_KEY},
    json={
        "out": False,
        "amount": 1000,
        "memo": "Webhook test",
        "webhook": "https://your-server.com/lnbits-webhook"
    }
)

Balance Monitoring

def get_balance():
    response = requests.get(
        f"{LNBITS_URL}/api/v1/wallet",
        headers={"X-Api-Key": API_KEY}
    )
    return response.json()["balance"] // 1000  # msat to sats

Key Management

LNbits Keys

Key TypePermissionUse Case
Invoice keyCreate invoices, check statusReceiving
Admin keySend payments, full accessAll operations

Security: Never expose admin key in client-side code.

Multi-Wallet Setup

# Create separate wallets for different purposes
wallets = {
    "receiving": {"url": LNBITS_URL, "key": INVOICE_KEY_1},
    "sending": {"url": LNBITS_URL, "key": ADMIN_KEY_1},
    "savings": {"url": LNBITS_URL, "key": INVOICE_KEY_2}
}

Wallet Security

For Agents

  1. Separate wallets: Don’t mix agent funds with personal
  2. Limited balances: Keep minimum needed for operations
  3. Admin key protection: Store securely, rotate regularly
  4. Monitoring: Alert on unexpected balance changes

Backup Strategies

Wallet TypeBackup Method
LNDchannel.backup (SCB)
Core Lightninghsm_secret + database
LNbitsDatabase export
MobileSeed phrase

Choosing a Wallet

Decision Tree

Need API access?
├── No → Phoenix, Mutiny (personal use)
└── Yes
    ├── Have your own node?
    │   ├── Yes → LNbits self-hosted
    │   └── No
    │       ├── Trust a provider? → LNbits shared, Alby
    │       └── No → Set up a node first
    └── Just testing? → legend.lnbits.com (small amounts)

Machine-Readable Summary

{
  "topic": "lightning-wallets",
  "agent_recommended": [
    {
      "name": "lnbits",
      "custody": "self",
      "api": "rest",
      "setup": "medium"
    },
    {
      "name": "alby",
      "custody": "custodial",
      "api": "rest",
      "setup": "easy"
    }
  ],
  "api_patterns": [
    "create_invoice",
    "pay_invoice",
    "check_balance",
    "webhook_notifications"
  ]
}