跳至主要內容
進階

Custom Records 自定義 TLV 記錄

了解閃電網路的 Custom Records 機制,如何在支付中附加自定義資料。

8 分鐘

什麼是 Custom Records?

Custom Records 允許在閃電支付的洋蔥 payload 中附加任意資料。 這些資料使用 TLV 格式,可以被接收節點讀取和處理。

擴展協議: Custom Records 實現了支付的可編程性,支援訊息傳遞、 身份驗證、應用層資料等多種用途。

TLV 類型範圍

Onion Payload TLV Type Allocation:

Type Ranges:

0 - 63,999: Protocol-defined (reserved by BOLT spec)

Common Protocol Types:
  • 2: amt_to_forward (forward amount)
  • 4: outgoing_cltv_value (outbound CLTV)
  • 6: short_channel_id (next hop channel)
  • 8: payment_data (payment_secret + total_msat)
  • 10: encrypted_recipient_data (blinded paths)
  • 16: payment_metadata

64,000+: Custom records (application use)
  • Must be odd (odd type = optional)
  • Receiver can safely ignore if unrecognized

Odd/Even Rule ("it's ok to be odd"):

Even types: Must understand, otherwise fail
Odd types: Optional, can ignore if not understood

Custom Records should use odd types:
  65537, 65539, 65541, ...

This ensures backward compatibility:
  Old nodes can ignore unrecognized custom records

常見應用

Custom Records Use Cases:

1. Keysend (Spontaneous Payments):

Type 5482373484 (0x1466a3ac): keysend preimage

Payer generates preimage, sends in custom record
Receiver extracts preimage to complete payment

{
  5482373484: <32-byte preimage>
}

2. Messaging:

Whatsat / Sphinx Chat style:

Type 34349334: Text message
Type 34349337: Sender info
Type 34349339: Timestamp

{
  34349334: "Hello, Lightning!",
  34349337: <sender_pubkey>,
  34349339: 1699999999
}

3. Application Identification:

Identifying payment source application:

Type 65535: Application identifier

{
  65535: "my-app-v1.0"
}

Receiver can apply special handling based on this info

4. Order Information:

E-commerce scenario:

{
  65537: "order_id:12345",
  65539: "product:widget",
  65541: "quantity:3"
}

Or using JSON:
{
  65537: '{"order":"12345","product":"widget","qty":3}'
}

使用方式

Sending and Receiving Custom Records:

LND Sending (using lncli):

# Keysend with custom record
lncli sendpayment \
  --dest <pubkey> \
  --amt 1000 \
  --keysend \
  --data 65537=<hex_encoded_data>

# Multiple custom records
lncli sendpayment \
  --dest <pubkey> \
  --amt 1000 \
  --keysend \
  --data 65537=48656c6c6f \
  --data 65539=576f726c64

LND Receiving (subscribe to invoices):

// gRPC subscription
stream := client.SubscribeInvoices(ctx, &lnrpc.InvoiceSubscription{})

for {
    invoice, _ := stream.Recv()
    for _, htlc := range invoice.Htlcs {
        // Read custom records
        for typ, data := range htlc.CustomRecords {
            fmt.Printf("Type %d: %x\n", typ, data)
        }
    }
}

Core Lightning:

# Send
lightning-cli keysend <node_id> <amount> \
  extratlvs='{"65537": "48656c6c6f"}'

# Receive (via hook or listinvoices)
{
  "extra_tlvs": [
    { "type": 65537, "value": "48656c6c6f" }
  ]
}

已知類型註冊

Community-Used Custom Record Types:

Known Types (unofficial, community consensus):

5482373484 (0x1466a3ac): Keysend preimage
  Used for spontaneous payments without invoices

34349334: Whatsat text message
34349337: Whatsat sender
34349339: Whatsat timestamp
34349343: Whatsat signature

7629169: Podcasting 2.0 boost
7629171: Podcasting 2.0 stream

133773310: Zap (Nostr) sats

Recommendations for Choosing New Types:

1. Use sufficiently large random number (avoid collisions)
2. Use odd number (ensure optional)
3. Document your type usage
4. Consider registering with community

Example generation:
import random
type_id = 65536 + random.randint(0, 2**32) | 1  # ensure odd

限制與考量

Custom Records Limitations:

Size Limits:

Onion payload total size is limited:
  • Max ~1300 bytes per hop payload
  • Need to subtract space for protocol fields
  • Custom records available space ~1000 bytes

Recommendations:
  • Keep data concise
  • Use hash references for large data
  • Consider compression

Privacy Considerations:

Custom records only visible to final recipient:
  • Intermediate nodes cannot read (onion encrypted)
  • But receiver can see all content
  • Don't send sensitive info to untrusted receivers

Note:
  • Data is not encrypted, only onion wrapped
  • Receiver can store and share
  • Consider additional encryption for sensitive data

Compatibility:

Not all nodes support custom records:
  • Old versions may ignore
  • Some implementations may have bugs
  • Test target receiver's support

LND: Full support
Core Lightning: Supported (may need config)
Eclair: Partial support

vs Onion Messages

Onion messages 專門用於訊息傳遞,不需要支付。 Custom records 附加在支付中。

vs Invoice Description

發票描述對所有人可見。 Custom records 只對接收者可見。

標準化進行中: Custom records 的使用正在標準化過程中。 BOLT 12 的 payer_note 是正式化的一步。

相關資源

下一步: 了解 Keysend 如何使用 custom records 實現無發票支付。

已複製連結
已複製到剪貼簿