Choosing Your Protocol: A Decision Framework
Bitcoin, Lightning, or Nostr? A structured decision framework for choosing the right protocol for each agent operation.
“Should I use Bitcoin or Lightning?” is the wrong question.
The right question is: what does my agent need to accomplish in the next 500 milliseconds? The protocol follows from the operation, not the other way around. An agent that always uses Lightning will overpay for settlement assurance. An agent that always uses Bitcoin will wait ten minutes for a $0.01 transfer.
Protocol selection isn’t a one-time architectural decision. It’s a runtime choice your agent makes hundreds of times a day.
The Capability Matrix
Each protocol does different things well. None does everything.
| Capability | Bitcoin | Lightning | Nostr |
|---|---|---|---|
| Payment finality | Probabilistic (6 conf) | Instant but revocable | None |
| Throughput | ~7 TPS global | Millions TPS | Unlimited |
| Minimum practical tx | ~$0.50 (fees) | 1 sat (~$0.0005) | Free |
| Maximum practical tx | Unlimited | ~0.4 BTC/channel | N/A |
| Identity | Pseudonymous addresses | Node pubkey | Persistent keypair |
| Communication | OP_RETURN (40 bytes) | Keysend messages | Full messaging |
| Privacy | Poor (public chain) | Good (routing privacy) | Best (NIP-44 encryption) |
| Offline support | Yes (broadcast later) | No (channel state) | Partial (queue events) |
The pattern is clear: Bitcoin for settlement, Lightning for speed, Nostr for communication. But the edges are where it gets interesting.
The Payment Decision Tree
When your agent needs to move value, three variables determine the protocol: amount, urgency, and recipient capability.
By Amount
| Amount Range | Protocol | Reasoning |
|---|---|---|
| < 100 sats | Lightning | On-chain fees would exceed the payment |
| 100 - 100,000 sats | Lightning | Fast, cheap, practical |
| 100,000 - 1,000,000 sats | Context-dependent | Check urgency and fees |
| > 1,000,000 sats | Bitcoin | Settlement assurance matters |
The crossover point shifts with mempool conditions. When on-chain fees are 5 sat/vB, the threshold drops. When they’re 50 sat/vB, Lightning wins for larger amounts.
A useful heuristic: if fee / amount > 0.01 (fees exceed 1% of the payment), switch protocols or batch.
By Urgency
| Urgency | Protocol | Confirmation Time |
|---|---|---|
| Instant (< 1s) | Lightning | 100-500ms |
| Fast (< 10 min) | Lightning | Seconds |
| Standard (< 1 hour) | Bitcoin (1 conf) | 10-60 minutes |
| Non-urgent | Bitcoin (6 conf) | 1-2 hours |
Lightning is the only option for real-time agent-to-agent commerce. If your agent is paying for an API call that needs to complete before returning a response, waiting ten minutes for a Bitcoin confirmation isn’t viable.
By Recipient
| Recipient Type | Identifier | Protocol |
|---|---|---|
| Lightning-capable | lnbc... invoice | Lightning |
| LNURL-enabled | lnurl... or user@domain | Lightning |
| Bitcoin address | bc1..., 1..., 3... | Bitcoin |
| Nostr pubkey with lud16 | npub... | Lightning (via zap) |
| Unknown | - | Bitcoin (universal fallback) |
Destination detection is simple string matching. If it starts with lnbc, it’s a Lightning invoice. If it starts with bc1, it’s a Bitcoin address. If it starts with npub, look up the profile for a lud16 field and zap via Lightning.
The Communication Decision Tree
When your agent needs to communicate, Nostr is almost always the answer. The question is which Nostr pattern to use.
| Need | Nostr Pattern | Event Kind |
|---|---|---|
| Public announcement | Text note | Kind 1 |
| Private message | NIP-44 encrypted DM | Kind 1059 |
| Payment + notification | Zap (NIP-57) | Kind 9734/9735 |
| Long-form content | Article | Kind 30023 |
| Profile update | Metadata | Kind 0 |
The key advantage: all of these use the same keypair, the same relays, and the same transport. Your agent doesn’t need five different API integrations for five different communication needs.
Multi-Protocol Patterns
Real-world operations rarely fit neatly into one protocol. The most powerful patterns combine two or three.
Pattern 1: Pay + Notify
The agent pays via Lightning and confirms via Nostr. Include the payment preimage in the DM as cryptographic proof of payment.
# 1. Pay the Lightning invoice
payment = lightning.pay_invoice(bolt11="lnbc10u1p3...")
# 2. Notify via Nostr DM with proof
note = create_signed_event(
private_key_hex=nostr_key,
kind=1,
content=f"Payment sent. Preimage: {payment['preimage']}",
tags=[["p", recipient_pubkey]]
)
publish_event(note)
Lightning handles the value transfer. Nostr handles the communication. Neither depends on the other to function, but together they create a complete transaction with proof.
Pattern 2: Broadcast + Timestamp
Post content to Nostr, then anchor a hash to Bitcoin for permanent proof of existence.
The Nostr event is fast and free. The Bitcoin anchor is slow and costs fees, but it proves the content existed at a specific block height. Use this for contracts, commitments, or any content where future disputes are possible.
Pattern 3: Degradation Fallback
When a protocol fails, fall back gracefully:
| Primary | Failure | Fallback | Action |
|---|---|---|---|
| Lightning | No route found | Bitcoin | Send on-chain with delay warning |
| Lightning | Insufficient channel capacity | Lightning (MPP) | Split across multiple paths |
| Nostr | All relays down | Local queue | Store events, retry with backoff |
| Bitcoin | Mempool congested (>50 sat/vB) | Lightning | Pay via channel if possible |
The agent should never silently fail. Log the fallback decision, notify the operator if configured, and proceed with the next-best option.
Anti-Patterns to Avoid
1. Single-Protocol Maximalism
Building an agent that only speaks Lightning means it can’t settle large amounts securely. Building one that only uses Bitcoin means it can’t do micropayments. The protocols complement each other. Use all three.
2. Hardcoded Protocol Selection
# WRONG: Hardcoded protocol choice
def pay(amount, destination):
return lightning.pay(amount, destination)
# RIGHT: Runtime protocol selection
def pay(amount, destination):
if destination.startswith("lnbc"):
return lightning.pay_invoice(destination)
elif destination.startswith("bc1") or destination.startswith("1"):
return bitcoin.send(amount, destination)
elif destination.startswith("npub"):
return zap(amount, destination)
The protocol should be determined by the destination format and operation requirements, not by a config file set at deploy time.
3. Ignoring Fee Economics
An agent that sends 100 sats on-chain when fees are 20 sat/vB is burning 56% of the payment on fees (a minimal P2WPKH transaction is ~141 vB = 2,820 sats in fees). Always check: does the fee make economic sense for this amount?
4. Atomicity Assumptions
If your agent pays Lightning and then posts to Nostr, and the Nostr publish fails, the payment still happened. These are not atomic operations. Design for partial failure. Use idempotency keys. Log everything.
Getting Started
- Study the protocol selection guide for detailed decision criteria
- Walk through the decision trees for implementation-ready logic
- Read about multi-protocol workflows for composition patterns
- Understand the trade-offs between protocols
- Review cost comparisons for fee analysis
The protocols are tools. Bitcoin is the vault. Lightning is the cash register. Nostr is the voice. An agent that masters all three operates with a freedom that no single-protocol system can match.
Choose the right tool for the job. Let your agent decide at runtime.