upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
path: root/47.md
diff options
context:
space:
mode:
authorfrnandu <frnandu@atomicmail.io>2026-02-03 19:41:08 +0100
committerGitHub <noreply@github.com>2026-02-03 13:41:08 -0500
commit01838f302ddf639b2cfc1bfbe6232401e82eac58 (patch)
treee80530498a051cf421c3f08f45c51d6a2e8199fa /47.md
parent90a60bd210670787afb1f14caab8fd8d70028ea6 (diff)
NIP-47 Add Hold Invoice Support (#1913)
Co-authored-by: Fmar <frnandu@gmail.com> Co-authored-by: Roland <33993199+rolznz@users.noreply.github.com>
Diffstat (limited to '47.md')
-rw-r--r--47.md121
1 files changed, 119 insertions, 2 deletions
diff --git a/47.md b/47.md
index 13037cb..76c8f50 100644
--- a/47.md
+++ b/47.md
@@ -371,7 +371,7 @@ Response:
371 "result_type": "lookup_invoice", 371 "result_type": "lookup_invoice",
372 "result": { 372 "result": {
373 "type": "incoming", // "incoming" for invoices, "outgoing" for payments 373 "type": "incoming", // "incoming" for invoices, "outgoing" for payments
374 "state": "pending", // can be "pending", "settled", "expired" (for invoices) or "failed" (for payments), optional 374 "state": "pending", // can be "pending", "settled", "accepted" (for hold invoices), "expired" (for invoices) or "failed" (for payments), optional
375 "invoice": "string", // encoded invoice, optional 375 "invoice": "string", // encoded invoice, optional
376 "description": "string", // invoice's description, optional 376 "description": "string", // invoice's description, optional
377 "description_hash": "string", // invoice's description hash, optional 377 "description_hash": "string", // invoice's description hash, optional
@@ -420,7 +420,7 @@ Response:
420 "transactions": [ 420 "transactions": [
421 { 421 {
422 "type": "incoming", // "incoming" for invoices, "outgoing" for payments 422 "type": "incoming", // "incoming" for invoices, "outgoing" for payments
423 "state": "pending", // can be "pending", "settled", "expired" (for invoices) or "failed" (for payments), optional 423 "state": "pending", // can be "pending", "settled", "accepted" (for hold invoices), "expired" (for invoices) or "failed" (for payments), optional
424 "invoice": "string", // encoded invoice, optional 424 "invoice": "string", // encoded invoice, optional
425 "description": "string", // invoice's description, optional 425 "description": "string", // invoice's description, optional
426 "description_hash": "string", // invoice's description hash, optional 426 "description_hash": "string", // invoice's description hash, optional
@@ -485,6 +485,89 @@ Response:
485} 485}
486``` 486```
487 487
488### `make_hold_invoice`
489
490Creates a hold invoice using a pre-generated preimage.
491
492Request:
493```jsonc
494{
495 "method": "make_hold_invoice",
496 "params": {
497 "amount": 123, // value in msats
498 "description": "string", // invoice's description, optional
499 "description_hash": "string", // invoice's description hash, optional
500 "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`)
501 "payment_hash": "string" // Payment hash for the payment generated from the preimage
502 "min_cltv_expiry_delta": 144 // The minimum CLTV delta to use for the final hop, optional
503 }
504}
505```
506
507Response:
508```jsonc
509{
510 "result_type": "make_hold_invoice",
511 "result": {
512 "type": "incoming", // "incoming" for invoices, "outgoing" for payments
513 "invoice": "string", // encoded invoice, optional
514 "description": "string", // invoice's description, optional
515 "description_hash": "string", // invoice's description hash, optional
516 "payment_hash": "string", // Payment hash for the payment
517 "amount": 123, // value in msats
518 "created_at": unixtimestamp, // invoice/payment creation time
519 "expires_at": unixtimestamp, // invoice expiration time, optional if not applicable
520 "metadata": {} // generic metadata that can be used to add things like zap/boostagram details for a payer name/comment/etc.
521 }
522}
523```
524
525### `cancel_hold_invoice`
526
527Cancels a hold invoice using the payment hash
528
529Request:
530```jsonc
531{
532 "method": "cancel_hold_invoice",
533 "params": {
534 "payment_hash": "string" // Payment hash for the payment generated from the preimage
535 }
536}
537```
538
539Response:
540```jsonc
541{
542 "result_type": "cancel_hold_invoice",
543 "result": {}
544}
545```
546
547### `settle_hold_invoice`
548
549Settles a hold invoice using the preimage
550
551
552Request:
553```jsonc
554{
555 "method": "settle_hold_invoice",
556 "params": {
557 "preimage": "string" // preimage for the payment
558 }
559}
560```
561
562Response:
563```jsonc
564{
565 "result_type": "settle_hold_invoice",
566 "result": {}
567}
568```
569
570
488## Notifications 571## Notifications
489 572
490### `payment_received` 573### `payment_received`
@@ -539,6 +622,30 @@ Notification:
539} 622}
540``` 623```
541 624
625### `hold_invoice_accepted`
626
627Description: 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.
628
629Notification:
630```jsonc
631{
632 "notification_type": "hold_invoice_accepted",
633 "notification": {
634 "type": "incoming",
635 "state": "accepted", // optional
636 "invoice": "string", // encoded invoice
637 "description": "string", // invoice's description, optional
638 "description_hash": "string", // invoice's description hash, optional
639 "payment_hash": "string", // Payment hash for the payment
640 "amount": 123, // value in msats
641 "created_at": unixtimestamp, // invoice/payment creation time
642 "expires_at": unixtimestamp, // invoice expiration time
643 "settle_deadline": blocknumber, // invoice can only be safely settled or canceled before this block number.
644 "metadata": {} // generic metadata that can be used to add things like zap/boostagram details for a payer name/comment/etc.
645 }
646}
647```
648
542## Example pay invoice flow 649## Example pay invoice flow
543 650
5440. 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. 6510. 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.
@@ -668,6 +775,16 @@ Here are some properties that are recognized by some NWC clients:
668} 775}
669``` 776```
670 777
778### Example Hold Invoice Support Flow
779
7801. Client generates a 32-byte hex-encoded preimage.
7812. Computes SHA-256 to derive payment hash.
7823. Sends `make_hold_invoice` with payment hash and desired parameters.
7834. Waits for `hold_invoice_accepted` notification.
7845. Upon receiving notification, either:
785
786 * Calls `settle_hold_invoice` with the original preimage to release funds, or
787 * Calls `cancel_hold_invoice` with payment hash to abort.
671### Deep-links 788### Deep-links
672 789
673Wallet applications can register deeplinks in mobile systems to make it possible to create a linking UX that doesn't require the user scanning a QR code or pasting some code. 790Wallet applications can register deeplinks in mobile systems to make it possible to create a linking UX that doesn't require the user scanning a QR code or pasting some code.