Description
Some thoughts on bolt12-based recurring invoices as implemented in cln. Hopefully this is an okay forum for that.
recurrence_limit
setting the maximum value of a 0-based counter is confusing. Should be the total number of invoices you can pay, not one less than it.fetchinvoice offer=X recurrence_label=Y recurrence_counter=0
is non-idempotent, and just requests a new invoice from the remote -- even if it's already been paid under that label, which potentially can result in double payments. When you use a higher counter value than 0, it either reports the existing payment, the current invoice, or gives an error that you haven't paid the previous invoice.- If you've got a recurring offer with a low interval,
listpays
becomes cluttered with many payments. It's also awkward to match up the payments with the actual invoice, and there doesn't seem any easy way to track which subscription index you're due to pay next?
It would perhaps be nicer to have a flow more like:
- fetchinvoice offer=OFFER recurrence_label=XXXX # recurrence_counter implicitly 0
- pay bolt11=INV label=XXXX
- pay label=XXXX # picks up the "recurring" status from the label, and begins the next payment
That way the initial fetchinvoice
is the only thing doing a bolt12 remote query, and the "pay" instructions are just calculating the timing and payment hash programmatically based on previous payments.
(You could perhaps still attempt fetchinvoice recurrence_counter=50
if you passed the calculated paywindow_end
and wanted to resume the subscription, or alternatively could just declare any recurring invoice complete as soon as a paywindow is missed, and use recurrence_start
for the scenario where resuming is okay?)
Could perhaps report all this via a single entry in listpays
something like:
{
"label": "XXXX",
"created_at": 1690000000,
"destination": "02...",
"bolt12": "lni1...",
"status": "recurring",
"recurrence_counter": 5,
"recurrence_limit": 100,
"payment_hash": "SHA256^5{preimage}",
"preimage": "preimage",
"payments": [
{"created_at": 1690000000, "completed_at": 1690010009, "amount_sent_msat": 1000 },
{"created_at": 1690010000, "completed_at": 1690010002, "amount_sent_msat": 1000 },
{"created_at": 1690020000, "completed_at": 1690010004, "amount_sent_msat": 1000 },
{"created_at": 1690030000, "completed_at": 1690010003, "amount_sent_msat": 1000 },
{"created_at": 1690040000, "completed_at": 1690010001, "amount_sent_msat": 1000 }
],
"amount_msat": 5000,
"amount_sent_msat": 5000
}