← Back to Home

SIP-3: Lightning-Atomic NFT Trades

Sparkle Improvement Proposal for Trustless Ordinal Swaps

SIP-3 Draft Specification

Version 0.2.0 | Status: Draft

Author: David A. Michael

Status: Draft Specification

  • Reference Implementation: TypeScript SDK available on NPM
  • Theoretical design: Untested in real environments
  • Subject to change: Specification may be revised

Abstract

SIP-3 defines a protocol for atomic swaps between Lightning Network payments and Bitcoin Ordinal inscriptions. The protocol uses Hash Time-Locked Contracts (HTLCs) to ensure that either both parties receive their expected assets, or neither transaction completes.

1. Motivation

Current Ordinal trading methods require either:

  • Custodial trust: Marketplaces hold assets during trade
  • Slow settlement: PSBT-based trades require on-chain confirmation

SIP-3 proposes a mechanism where Lightning payment settlement is instant while maintaining trustless guarantees through cryptographic locks.

2. Specification

2.1 Sparkle Swap Script

The ordinal is locked in a Taproot address with two spending paths:

// Taproot Script Tree
//
// Path 1: Buyer Claim (Hashlock)
// Requires: preimage + buyer_signature
OP_SHA256 <payment_hash> OP_EQUALVERIFY
<buyer_pubkey> OP_CHECKSIG

// Path 2: Seller Refund (Timelock)
// Requires: timeout expired + seller_signature
<locktime> OP_CHECKLOCKTIMEVERIFY OP_DROP
<seller_pubkey> OP_CHECKSIG

2.2 Trade Flow

Step Actor Action
1 Seller Generates random preimage r, computes H = SHA256(r)
2 Seller Creates Taproot address with hashlock H and buyer pubkey
3 Seller Transfers ordinal to Taproot address (on-chain)
4 Seller Creates Lightning invoice with payment_hash = H
5 Buyer Pays Lightning invoice, learns preimage r
6 Buyer Claims ordinal using r + signature (on-chain)

2.3 Timeout Parameters

To ensure safety, the protocol enforces delta-safe timelocks:

  • Lightning HTLC timeout: T_ln blocks
  • On-chain claim window: T_claim = T_ln - delta
  • Seller refund time: T_refund = T_ln + delta
  • Recommended delta: 144 blocks (24 hours)
Safety Requirement: The seller refund timelock MUST be at least 2x the Lightning HTLC timeout to prevent race conditions.

2.4 Buyer Deposit

To prevent "free option" attacks, the buyer MUST pay a non-refundable deposit:

  • Deposit amount: 1% of trade value (minimum 1000 sats)
  • Purpose: Compensates seller for locked liquidity if buyer abandons
  • Collection: Deposit is paid via separate Lightning invoice before trade initiation

3. Message Format

3.1 Trade Request

{
  "p": "sparkle",
  "op": "trade_request",
  "v": 1,
  "inscription_id": "abc123...i0",
  "buyer_pubkey": "02...",
  "offer_sats": 100000,
  "deposit_invoice": "lnbc10n1..."
}

3.2 Trade Accept

{
  "p": "sparkle",
  "op": "trade_accept",
  "v": 1,
  "inscription_id": "abc123...i0",
  "funding_txid": "def456...",
  "funding_vout": 0,
  "payment_hash": "789abc...",
  "invoice": "lnbc1m1...",
  "refund_locktime": 900144,
  "witness_script": "..."
}

3.3 Trade Complete

{
  "p": "sparkle",
  "op": "trade_complete",
  "v": 1,
  "inscription_id": "abc123...i0",
  "claim_txid": "fed987...",
  "preimage": "..."
}

4. Security Considerations

4.1 Atomicity Guarantee

The protocol ensures atomicity through cryptographic binding:

  • Lightning payment reveals preimage
  • Preimage is required to claim ordinal
  • Without payment, buyer cannot claim
  • After timeout, seller can refund

4.2 Attack Mitigations

Attack Mitigation
Free option (buyer delays) Non-refundable 1% deposit
Double-spend by seller Wait for funding tx confirmation before payment
Preimage withholding Buyer learns preimage from Lightning payment
Timeout race condition Delta-safe timelocks (2x margin)

4.3 Trust Assumptions

The protocol is trust-minimized, not trustless:

  • Coordinator can censor trades but cannot steal funds
  • Lightning routing must succeed within timeout
  • Bitcoin network must confirm claim before refund timeout

5. Reference Implementation

5.1 Witness Script Construction (JavaScript)

import * as btc from '@scure/btc-signer';
import { sha256 } from '@noble/hashes/sha256';

function createSparkleSwapScript(
  paymentHash,    // 32 bytes
  buyerPubkey,    // 33 bytes
  sellerPubkey,   // 33 bytes
  refundLocktime  // block height
) {
  // Hashlock branch (buyer claim)
  const hashlockScript = btc.Script.encode([
    'OP_SHA256',
    paymentHash,
    'OP_EQUALVERIFY',
    buyerPubkey,
    'OP_CHECKSIG'
  ]);

  // Timelock branch (seller refund)
  const timelockScript = btc.Script.encode([
    btc.Script.encodeNumber(refundLocktime),
    'OP_CHECKLOCKTIMEVERIFY',
    'OP_DROP',
    sellerPubkey,
    'OP_CHECKSIG'
  ]);

  return { hashlockScript, timelockScript };
}

5.2 Claim Transaction

function createClaimTransaction(
  fundingTxid,
  fundingVout,
  fundingAmount,
  preimage,
  buyerPrivkey,
  destinationAddress,
  feeRate
) {
  const tx = new btc.Transaction();

  tx.addInput({
    txid: fundingTxid,
    index: fundingVout,
    witnessUtxo: {
      script: taprootOutputScript,
      amount: BigInt(fundingAmount)
    },
    tapLeafScript: hashlockLeaf
  });

  const fee = BigInt(feeRate * 150); // ~150 vbytes
  tx.addOutput({
    address: destinationAddress,
    amount: BigInt(fundingAmount) - fee
  });

  // Sign and add preimage to witness
  tx.sign(buyerPrivkey);
  tx.finalize();

  return tx.hex;
}

6. Compatibility

6.1 Lightning Implementations

  • LND: Compatible via standard BOLT-11 invoices
  • Core Lightning: Compatible
  • Eclair: Compatible
  • LDK: Compatible

6.2 Bitcoin Requirements

  • Taproot: Required (activated block 709,632)
  • Schnorr signatures: Required
  • CLTV: Required (BIP-65)

7. Future Extensions

  • SIP-4: Multi-coordinator escrow for censorship resistance
  • SIP-5: Batch trades for collection purchases
  • SIP-6: Cross-chain atomic swaps