This specification defines the protocol for atomic NFT trades where Lightning payment settlement is cryptographically bound to PSBT finalization. It establishes the handshake flow, timeout rules, and failure handling to ensure buyer and seller atomicity.
Standard Bitcoin transactions take ~10 minutes to confirm. Lightning enables sub-second payment, but linking it atomically to NFT ownership transfer requires careful protocol design to prevent:
1. Seller → Coordinator: List NFT - Provide inscription ID, price (sats), PSBT transferring NFT 2. Buyer → Coordinator: Accept offer - Request Lightning invoice 3. Coordinator → Buyer: HTLC invoice - Payment hash H = hash(preimage) - Timeout: 60 blocks (~10 hours) 4. Buyer → Lightning: Pay invoice - Payment routed via Lightning Network 5. Seller receives preimage P - Seller verifies hash(P) = H - Seller broadcasts signed PSBT 6. Coordinator monitors blockchain - After 1 confirmation: Release preimage to buyer - Trade complete
| Timeout | Value | Rationale | 
|---|---|---|
| Lightning invoice | 60 blocks | Enough time for PSBT broadcast + confirmations | 
| PSBT broadcast | Within 30 blocks | After buyer pays, seller must broadcast quickly | 
| Confirmation wait | 6 blocks | Standard finality threshold | 
The protocol ensures atomicity through HTLC construction:
IF buyer pays Lightning invoice
    Seller learns preimage P
    Seller must broadcast PSBT to claim payment
    Coordinator cannot steal (doesn't know seller's keys)
ELSE
    Invoice expires, no payment captured
    Both parties refunded automatically
        Scenario: Buyer pays Lightning invoice, but seller's PSBT is invalid or double-spent.
Resolution:
Scenario: Attacker broadcasts low-fee conflicting tx to block PSBT.
Mitigation:
Scenario: PSBT confirmed, then chain reorgs and tx disappears.
Resolution:
POST /v1/trade/create
{
  "inscription_id": "abc123...i0",
  "price_sats": 100000,
  "seller_address": "bc1p...",
  "psbt": "cHNidP8BAH..."
}
Response:
{
  "trade_id": "uuid",
  "status": "pending"
}
---
GET /v1/trade/{trade_id}/invoice
Response:
{
  "payment_request": "lnbc1...",
  "payment_hash": "abc123...",
  "expires_at": 1234567890
}
---
POST /v1/trade/{trade_id}/finalize
{
  "payment_preimage": "def456..."
}
Response:
{
  "txid": "xyz789...",
  "confirmations": 0
}
        The coordinator can:
NOT IMPLEMENTED. This specification describes the intended design. To use this protocol, someone must build: