From a6f7f4b4cc3dba8e8092324da59da8df66c1437c Mon Sep 17 00:00:00 2001 From: Fmar Date: Sat, 14 Oct 2023 23:29:24 +0200 Subject: [PATCH 01/11] add prioritization (by trust) of list guidelines --- 65.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/65.md b/65.md index b676029039..656d14576d 100644 --- a/65.md +++ b/65.md @@ -61,3 +61,7 @@ This NIP allows Clients to connect directly with the most up-to-date relay set f 5. If a relay signals support for this NIP in their [NIP-11](11.md) document that means they're willing to accept kind 10002 events from a broad range of users, not only their paying customers or whitelisted group. 6. Clients SHOULD deduplicate connections by normalizing relay URIs according to [RFC 3986](https://datatracker.ietf.org/doc/html/rfc3986#section-6). + +7. Clients SHOULD guide users to treat the list as prioritized, with most trusted relays (less probability of censoring events, like a personal relay) at the top. + +8. When seeking events **from** a user, clients SHOULD if possible start by using the relays most at the top of list, since these should be the most trusted by the user. From aa8bedeebd1d5198436f6deefb2852c16ec904fc Mon Sep 17 00:00:00 2001 From: Fmar Date: Wed, 7 May 2025 23:57:39 +0200 Subject: [PATCH 02/11] add hold invoice support --- 47.md | 116 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 65.md | 9 ----- 2 files changed, 116 insertions(+), 9 deletions(-) diff --git a/47.md b/47.md index 84f710e2ba..dc19583284 100644 --- a/47.md +++ b/47.md @@ -440,6 +440,88 @@ Response: } ``` +### `make_hold_invoice` + +Creates a hold invoice using a pre-generated preimage. + +Request: +```jsonc +{ + "method": "make_hold_invoice", + "params": { + "amount": 123, // value in msats + "description": "string", // invoice's description, optional + "description_hash": "string", // invoice's description hash, optional + "expiry": 213 // expiry in seconds from time invoice is created, optional + "payment_hash": "string" // Payment hash for the payment generated from the preimage + } +} +``` + +Response: +```jsonc +{ + "result_type": "make_hold_invoice", + "result": { + "type": "incoming", // "incoming" for invoices, "outgoing" for payments + "invoice": "string", // encoded invoice, optional + "description": "string", // invoice's description, optional + "description_hash": "string", // invoice's description hash, optional + "payment_hash": "string", // Payment hash for the payment + "amount": 123, // value in msats + "created_at": unixtimestamp, // invoice/payment creation time + "expires_at": unixtimestamp, // invoice expiration time, optional if not applicable + "metadata": {} // generic metadata that can be used to add things like zap/boostagram details for a payer name/comment/etc. + } +} +``` + +### `cancel_hold_invoice` + +Cancels a hold invoice using the payment hash + +Request: +```jsonc +{ + "method": "cancel_hold_invoice", + "params": { + "payment_hash": "string" // Payment hash for the payment generated from the preimage + } +} +``` + +Response: +```jsonc +{ + "result_type": "cancel_hold_invoice", + "result": {} +} +``` + +### `settle_hold_invoice` + +Settles a hold invoice using the preimage + + +Request: +```jsonc +{ + "method": "settle_hold_invoice", + "params": { + "preimage": "string" // preimage for the payment + } +} +``` + +Response: +```jsonc +{ + "result_type": "settle_hold_invoice", + "result": {} +} +``` + + ## Notifications ### `payment_received` @@ -492,6 +574,29 @@ Notification: } ``` +### `hold_invoice_accepted` + +Description: Sent when a payer accepts (locks in) a hold invoice. + +Notification: +```jsonc +{ + "notification_type": "hold_invoice_accepted", + "notification": { + "type": "incoming", + "invoice": "string", // encoded invoice + "description": "string", // invoice's description, optional + "description_hash": "string", // invoice's description hash, optional + "payment_hash": "string", // Payment hash for the payment + "amount": 123, // value in msats + "created_at": unixtimestamp, // invoice/payment creation time + "expires_at": unixtimestamp, // invoice expiration time, optional if not applicable + "settled_at": unixtimestamp, // invoice/payment settlement time + "metadata": {} // generic metadata that can be used to add things like zap/boostagram details for a payer name/comment/etc. + } +} +``` + ## Example pay invoice flow 0. The user scans the QR code generated by the **wallet service** with their **client** application, they follow a `nostr+walletconnect://` deeplink or configure the connection details manually. @@ -522,3 +627,14 @@ This NIP does not specify any requirements on the type of relays used. However, "sig": "31f57b369459b5306a5353aa9e03be7fbde169bc881c3233625605dd12f53548179def16b9fe1137e6465d7e4d5bb27ce81fd6e75908c46b06269f4233c845d8" } ``` + +### Example Hold Invoice Support Flow + +1. Client generates a 32-byte hex-encoded preimage. +2. Computes SHA-256 to derive payment hash. +3. Sends `make_hold_invoice` with payment hash and desired parameters. +4. Waits for `hold_invoice_accepted` notification. +5. Upon receiving notification, either: + + * Calls `settle_hold_invoice` with the original preimage to release funds, or + * Calls `cancel_hold_invoice` with payment hash to abort. diff --git a/65.md b/65.md index a5cc4d16b6..36f0d12215 100644 --- a/65.md +++ b/65.md @@ -41,12 +41,3 @@ Clients SHOULD guide users to keep `kind:10002` lists small (2-4 relays of each ### Discoverability Clients SHOULD spread an author's `kind:10002` event to as many relays as viable, paying attention to relays that, at any moment, serve naturally as well-known public indexers for these relay lists (where most other clients and users are connecting to in order to publish and fetch those). - -Clients SHOULD guide users to treat the list as prioritized, with most trusted relays (less probability of censoring events, like a personal relay) at the top. - -When seeking events **from** a user, clients SHOULD if possible start by using the relays most at the top of list, since these should be the most trusted by the user. - -## Related articles -- [Outbox model](https://mikedilger.com/gossip-model/) -- [What is the Outbox Model?](https://habla.news/u/hodlbod@coracle.social/8YjqXm4SKY-TauwjOfLXS) - From c25c456cf91687f39ed17c1ef4af3fac8ee8d896 Mon Sep 17 00:00:00 2001 From: frnandu Date: Fri, 9 May 2025 00:26:58 +0200 Subject: [PATCH 03/11] make expiry required --- 47.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/47.md b/47.md index dc19583284..4dec8855e7 100644 --- a/47.md +++ b/47.md @@ -452,7 +452,7 @@ Request: "amount": 123, // value in msats "description": "string", // invoice's description, optional "description_hash": "string", // invoice's description hash, optional - "expiry": 213 // expiry in seconds from time invoice is created, optional + "expiry": 213 // expiry in seconds from time invoice is created "payment_hash": "string" // Payment hash for the payment generated from the preimage } } From b4836918ee59f418a26c239be76cffe8fe62c7cd Mon Sep 17 00:00:00 2001 From: frnandu Date: Wed, 21 May 2025 09:48:05 +0200 Subject: [PATCH 04/11] Update 47.md Co-authored-by: Roland <33993199+rolznz@users.noreply.github.com> --- 47.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/47.md b/47.md index 4dec8855e7..c0d2c8d672 100644 --- a/47.md +++ b/47.md @@ -452,7 +452,7 @@ Request: "amount": 123, // value in msats "description": "string", // invoice's description, optional "description_hash": "string", // invoice's description hash, optional - "expiry": 213 // expiry in seconds from time invoice is created + "expiry": 213 // expiry in seconds from time invoice is created for a payment to be initiated, optional. This does not determine how long a payment can be held (see `settle_deadline`) "payment_hash": "string" // Payment hash for the payment generated from the preimage } } From 9f6770bcf7c7fdd73b1e789731c8b6870642ee51 Mon Sep 17 00:00:00 2001 From: frnandu Date: Wed, 21 May 2025 09:48:42 +0200 Subject: [PATCH 05/11] Update 47.md Co-authored-by: Roland <33993199+rolznz@users.noreply.github.com> --- 47.md | 1 + 1 file changed, 1 insertion(+) diff --git a/47.md b/47.md index c0d2c8d672..35c782e340 100644 --- a/47.md +++ b/47.md @@ -592,6 +592,7 @@ Notification: "created_at": unixtimestamp, // invoice/payment creation time "expires_at": unixtimestamp, // invoice expiration time, optional if not applicable "settled_at": unixtimestamp, // invoice/payment settlement time + "settle_deadline": blocknumber, // invoice can only be safely settled or canceled before this block number. "metadata": {} // generic metadata that can be used to add things like zap/boostagram details for a payer name/comment/etc. } } From 71ab3b2f1b1fcec9c22600b44d542f5cfacb2125 Mon Sep 17 00:00:00 2001 From: frnandu Date: Wed, 21 May 2025 09:49:30 +0200 Subject: [PATCH 06/11] Update 47.md Co-authored-by: Roland <33993199+rolznz@users.noreply.github.com> --- 47.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/47.md b/47.md index 35c782e340..e6c0c3cf2a 100644 --- a/47.md +++ b/47.md @@ -576,7 +576,7 @@ Notification: ### `hold_invoice_accepted` -Description: Sent when a payer accepts (locks in) a hold invoice. +Description: Sent when a payer accepts (locks in) a hold invoice. To avoid locking up funds in channels the hold invoice SHOULD be settled or canceled within a few minutes of receiving this event. Notification: ```jsonc From c86bcd98378f43b1153b92caa24ab4f1955bd59f Mon Sep 17 00:00:00 2001 From: Fmar Date: Thu, 31 Jul 2025 12:33:04 +0200 Subject: [PATCH 07/11] non-optional --- 47.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/47.md b/47.md index e6c0c3cf2a..46ffce50ad 100644 --- a/47.md +++ b/47.md @@ -590,7 +590,7 @@ Notification: "payment_hash": "string", // Payment hash for the payment "amount": 123, // value in msats "created_at": unixtimestamp, // invoice/payment creation time - "expires_at": unixtimestamp, // invoice expiration time, optional if not applicable + "expires_at": unixtimestamp, // invoice expiration time "settled_at": unixtimestamp, // invoice/payment settlement time "settle_deadline": blocknumber, // invoice can only be safely settled or canceled before this block number. "metadata": {} // generic metadata that can be used to add things like zap/boostagram details for a payer name/comment/etc. From 381cc2e131685be27bce137633fcc95d51706cef Mon Sep 17 00:00:00 2001 From: Fmar Date: Thu, 31 Jul 2025 12:33:27 +0200 Subject: [PATCH 08/11] remove settled_at --- 47.md | 1 - 1 file changed, 1 deletion(-) diff --git a/47.md b/47.md index 46ffce50ad..a711ea1320 100644 --- a/47.md +++ b/47.md @@ -591,7 +591,6 @@ Notification: "amount": 123, // value in msats "created_at": unixtimestamp, // invoice/payment creation time "expires_at": unixtimestamp, // invoice expiration time - "settled_at": unixtimestamp, // invoice/payment settlement time "settle_deadline": blocknumber, // invoice can only be safely settled or canceled before this block number. "metadata": {} // generic metadata that can be used to add things like zap/boostagram details for a payer name/comment/etc. } From e074930cbb5105c6a7cb62dac6be0f2670e22129 Mon Sep 17 00:00:00 2001 From: Fmar Date: Thu, 31 Jul 2025 12:41:17 +0200 Subject: [PATCH 09/11] cltv_expiry_delta --- 47.md | 1 + 1 file changed, 1 insertion(+) diff --git a/47.md b/47.md index a711ea1320..b594bcdcb3 100644 --- a/47.md +++ b/47.md @@ -454,6 +454,7 @@ Request: "description_hash": "string", // invoice's description hash, optional "expiry": 213 // expiry in seconds from time invoice is created for a payment to be initiated, optional. This does not determine how long a payment can be held (see `settle_deadline`) "payment_hash": "string" // Payment hash for the payment generated from the preimage + "cltv_expiry_delta": 144 // The minimum CLTV delta to use for the final hop, optional } } ``` From 7aca1ebe6780aeef0525fce24d122bd5d12809fd Mon Sep 17 00:00:00 2001 From: Fmar Date: Thu, 25 Sep 2025 14:43:40 +0200 Subject: [PATCH 10/11] add accepted state --- 47.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/47.md b/47.md index 95872c8698..eec25f6439 100644 --- a/47.md +++ b/47.md @@ -371,7 +371,7 @@ Response: "result_type": "lookup_invoice", "result": { "type": "incoming", // "incoming" for invoices, "outgoing" for payments - "state": "pending", // can be "pending", "settled", "expired" (for invoices) or "failed" (for payments), optional + "state": "pending", // can be "pending", "settled", "accepted" (for hold invoices), "expired" (for invoices) or "failed" (for payments), optional "invoice": "string", // encoded invoice, optional "description": "string", // invoice's description, optional "description_hash": "string", // invoice's description hash, optional @@ -420,7 +420,7 @@ Response: "transactions": [ { "type": "incoming", // "incoming" for invoices, "outgoing" for payments - "state": "pending", // can be "pending", "settled", "expired" (for invoices) or "failed" (for payments), optional + "state": "pending", // can be "pending", "settled", "accepted" (for hold invoices), "expired" (for invoices) or "failed" (for payments), optional "invoice": "string", // encoded invoice, optional "description": "string", // invoice's description, optional "description_hash": "string", // invoice's description hash, optional @@ -632,6 +632,7 @@ Notification: "notification_type": "hold_invoice_accepted", "notification": { "type": "incoming", + "state": "accepted", // optional "invoice": "string", // encoded invoice "description": "string", // invoice's description, optional "description_hash": "string", // invoice's description hash, optional From a14eda42c70f036c420d887d57bd756c15d78f05 Mon Sep 17 00:00:00 2001 From: frnandu Date: Thu, 29 Jan 2026 16:11:54 +0100 Subject: [PATCH 11/11] Rename cltv_expiry_delta to min_cltv_expiry_delta --- 47.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/47.md b/47.md index c23babb81e..76c8f50233 100644 --- a/47.md +++ b/47.md @@ -499,7 +499,7 @@ Request: "description_hash": "string", // invoice's description hash, optional "expiry": 213 // expiry in seconds from time invoice is created for a payment to be initiated, optional. This does not determine how long a payment can be held (see `settle_deadline`) "payment_hash": "string" // Payment hash for the payment generated from the preimage - "cltv_expiry_delta": 144 // The minimum CLTV delta to use for the final hop, optional + "min_cltv_expiry_delta": 144 // The minimum CLTV delta to use for the final hop, optional } } ```