Extension: Split Payments #13
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Implement a Nostr-native split payments extension for Lightning.Pub, replacing the LNbits splitpayments extension. Automatically distribute a percentage of every incoming payment to one or more recipients.
What LNbits splitpayments Does
Extremely simple extension (~400 lines of Python total):
splitted: truein payment extras to prevent infinite recursionData model — just one table:
API — just 3 endpoints:
GET /api/v1/targets— list targets for walletPUT /api/v1/targets— set targets (replaces all)DELETE /api/v1/targets— clear all targetsLightning.Pub Implementation
ExtensionContext API Usage
onPaymentReceived()payInvoice()createInvoice()registerMethod()getDatabase()log()RPC Methods
Data Model
Core Logic
Complexity
VERY LOW — ~300-500 lines of TypeScript. The simplest possible extension. Could be implemented in a few hours.
The entire LNbits extension is ~400 lines of Python across 4 files. The LP version would be comparable or smaller since the ExtensionContext handles payment plumbing.
Nostr-Native Advantages
NIP Review
NIP-57: Zap Tags — NATIVE SPLIT STANDARD
NIP-57 Appendix G already defines a
zaptag split mechanism on Nostr events:Weights are relative (not percentages) — clients sum all weights and calculate each recipient's share. This is the existing Nostr standard for split payments.
Implication: The extension could optionally publish a kind 30078 event with
zaptags representing the split configuration, making it interoperable with any NIP-57 compliant wallet. Wallets zapping the LP user would automatically split according to the tags.Other Applicable NIPs
zaptag weights for split configuration; zap receipts as split proofpay_keysendfor direct pubkey payments without invoiceRecommended Architecture
The simplest path: implement splits purely in the extension using
onPaymentReceived()+payInvoice(). Optionally publish a NIP-57zaptag event so external wallets also respect the splits when zapping.Reference
nips/57.mdlightning-pub/withdraw/Dual-Layer Split Architecture
The internal split mechanism (like LNbits) and NIP-57 zap tags should be combined as two complementary layers:
Layer 1: NIP-57 Zap Tags (Preferred Path)
The extension publishes the split configuration as
zaptags on the user's profile or events:Nostr-aware wallets (Amethyst, Damus, Primal, etc.) read these tags and split the zap at the sender side. Each recipient gets their own independent zap with a proper zap receipt signed by their own LNURL provider. No double-hop through the source wallet.
Layer 2: Internal Splits (Fallback)
For payments that arrive outside the Nostr ecosystem — raw BOLT11 invoices, LNURL-pay from non-Nostr wallets, CLINK payments, keysend — the extension catches them via
onPaymentReceived()and splits internally, just like LNbits does.How They Interact
zaptagsonPaymentReceived()and splits internallyWhy Both Layers
metadata.splitted = trueprevents the two layers from fighting. If a Nostr wallet already split the payment, the extension recognizes this and stays quiet.Implementation Note
When the extension publishes
zaptags, it should use NIP-57's weight system (not raw percentages). Weights are more flexible —[1, 1, 2]means 25%/25%/50% — and are the standard that Nostr clients already understand.