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:
authorAlex Gleason <alex@alexgleason.me>2026-04-10 13:31:37 -0500
committerAlex Gleason <alex@alexgleason.me>2026-04-10 13:31:37 -0500
commit5e1e24766910fc07cb61a049aed2623987458ec2 (patch)
treeb7588f61fddf9374268d5cd6f4e3f2655d7c840a /47.md
parentb8782df594b4e7e8f088869134908eed58be6078 (diff)
parent3465f540e3eaedccb5309711b502f0febf56b52f (diff)
Merge nip44-big-payloads into bigger-nip44bigger-nip44
Diffstat (limited to '47.md')
-rw-r--r--47.md380
1 files changed, 283 insertions, 97 deletions
diff --git a/47.md b/47.md
index 84f710e..6830820 100644
--- a/47.md
+++ b/47.md
@@ -28,15 +28,16 @@ Fundamentally NWC is communication between a **client** and **wallet service** b
28 28
29 4. Once the payment is complete the **wallet service** will send an encrypted `response` (kind 23195) to the **user** over the relay(s) in the URI. 29 4. Once the payment is complete the **wallet service** will send an encrypted `response` (kind 23195) to the **user** over the relay(s) in the URI.
30 30
31 5. The **wallet service** may send encrypted notifications (kind 23196) of wallet events (such as a received payment) to the **client**. 31 5. The **wallet service** may send encrypted notifications (kind 23197) of wallet events (such as a received payment) to the **client**.
32 32
33## Events 33## Events
34 34
35There are four event kinds: 35There are four event kinds:
36
36- `NIP-47 info event`: 13194 37- `NIP-47 info event`: 13194
37- `NIP-47 request`: 23194 38- `NIP-47 request`: 23194
38- `NIP-47 response`: 23195 39- `NIP-47 response`: 23195
39- `NIP-47 notification event`: 23196 40- `NIP-47 notification event`: 23197 (23196 for backwards compatibility with NIP-04)
40 41
41### Info Event 42### Info Event
42 43
@@ -46,34 +47,71 @@ The content should be a plaintext string with the supported capabilities space-s
46 47
47If the **wallet service** supports notifications, the info event SHOULD contain a `notifications` tag with the supported notification types space-separated, eg. `payment_received payment_sent`. 48If the **wallet service** supports notifications, the info event SHOULD contain a `notifications` tag with the supported notification types space-separated, eg. `payment_received payment_sent`.
48 49
50It should also contain supported encryption modes as described in the [Encryption](#encryption) section. For example:
51
52```jsonc
53{
54 "kind": 13194,
55 "tags": [
56 ["encryption", "nip44_v2 nip04"], // List of supported encryption schemes as described in the Encryption section.
57 ["notifications", "payment_received payment_sent"]
58 // ...
59 ],
60 "content": "pay_invoice get_balance make_invoice lookup_invoice list_transactions get_info notifications",
61 // ...
62}
63```
64
49### Request and Response Events 65### Request and Response Events
50 66
51Both the request and response events SHOULD contain one `p` tag, containing the public key of the **wallet service** if this is a request, and the public key of the **client** if this is a response. The response event SHOULD contain an `e` tag with the id of the request event it is responding to. 67Both the request and response events SHOULD contain one `p` tag, containing the public key of the **wallet service** if this is a request, and the public key of the **client** if this is a response. The response event SHOULD contain an `e` tag with the id of the request event it is responding to.
52Optionally, a request can have an `expiration` tag that has a unix timestamp in seconds. If the request is received after this timestamp, it should be ignored. 68Optionally, a request can have an `expiration` tag that has a unix timestamp in seconds. If the request is received after this timestamp, it should be ignored.
53 69
54The content of requests and responses is encrypted with [NIP04](04.md), and is a JSON-RPCish object with a semi-fixed structure: 70The content of requests and responses is encrypted with [NIP44](44.md), and is a JSON-RPCish object with a semi-fixed structure.
55 71
56Request: 72**Important note for backwards-compatibility:** The initial version of the protocol used [NIP04](04.md). If a **wallet service** or client app does not include the `encryption` tag in the
57```jsonc 73`info` or request events, it should be assumed that the connection is using NIP04 for encryption. See the [Encryption](#encryption) section for more information.
74
75Example request:
76
77```js
58{ 78{
59 "method": "pay_invoice", // method, string 79 "kind" 23194,
60 "params": { // params, object 80 "tags": [
61 "invoice": "lnbc50n1..." // command-related data 81 ["encryption", "nip44_v2"],
62 } 82 ["p", "03..." ] // public key of the wallet service.
83 // ...
84 ],
85 "content": nip44_encrypt({ // Encryption type corresponds to the `encryption` tag.
86 "method": "pay_invoice", // method, string
87 "params": { // params, object
88 "invoice": "lnbc50n1..." // command-related data
89 }
90 }),
63} 91}
64``` 92```
65 93
66Response: 94Example response:
67```jsonc 95
96```js
68{ 97{
69 "result_type": "pay_invoice", //indicates the structure of the result field 98 "kind" 23195,
70 "error": { //object, non-null in case of error 99 "tags": [
71 "code": "UNAUTHORIZED", //string error code, see below 100 ["p", "03..." ] // public key of the requesting client app
72 "message": "human readable error message" 101 ["e", "1234"] // id of the request event this is responding to
73 }, 102 // ...
74 "result": { // result, object. null in case of error. 103 ],
75 "preimage": "0123456789abcdef..." // command-related data 104 "content": nip44_encrypt({ // Encrypted using the scheme requested by the client.
76 } 105 "result_type": "pay_invoice", //indicates the structure of the result field
106 "error": { //object, non-null in case of error
107 "code": "UNAUTHORIZED", //string error code, see below
108 "message": "human readable error message"
109 },
110 "result": { // result, object. null in case of error.
111 "preimage": "0123456789abcdef..." // command-related data
112 }
113 })
114 // ...
77} 115}
78``` 116```
79 117
@@ -83,9 +121,9 @@ If the command was successful, the `error` field must be null.
83 121
84### Notification Events 122### Notification Events
85 123
86The notification event SHOULD contain one `p` tag, the public key of the **client**. 124The notification event is a kind 23197 event SHOULD contain one `p` tag, the public key of the **client**.
87 125
88The content of notifications is encrypted with [NIP04](04.md), and is a JSON-RPCish object with a semi-fixed structure: 126The content of notifications is encrypted with [NIP44](44.md) (or NIP-04 for legacy client apps), and is a JSON-RPCish object with a semi-fixed structure:
89 127
90```jsonc 128```jsonc
91{ 129{
@@ -96,7 +134,6 @@ The content of notifications is encrypted with [NIP04](04.md), and is a JSON-RPC
96} 134}
97``` 135```
98 136
99
100### Error codes 137### Error codes
101- `RATE_LIMITED`: The client is sending commands too fast. It should retry in a few seconds. 138- `RATE_LIMITED`: The client is sending commands too fast. It should retry in a few seconds.
102- `NOT_IMPLEMENTED`: The command is not known or is intentionally not implemented. 139- `NOT_IMPLEMENTED`: The command is not known or is intentionally not implemented.
@@ -105,6 +142,7 @@ The content of notifications is encrypted with [NIP04](04.md), and is a JSON-RPC
105- `RESTRICTED`: This public key is not allowed to do this operation. 142- `RESTRICTED`: This public key is not allowed to do this operation.
106- `UNAUTHORIZED`: This public key has no wallet connected. 143- `UNAUTHORIZED`: This public key has no wallet connected.
107- `INTERNAL`: An internal error. 144- `INTERNAL`: An internal error.
145- `UNSUPPORTED_ENCRYPTION`: The encryption type of the request is not supported by the wallet service.
108- `OTHER`: Other error. 146- `OTHER`: Other error.
109 147
110## Nostr Wallet Connect URI 148## Nostr Wallet Connect URI
@@ -148,6 +186,7 @@ Request:
148 "params": { 186 "params": {
149 "invoice": "lnbc50n1...", // bolt11 invoice 187 "invoice": "lnbc50n1...", // bolt11 invoice
150 "amount": 123, // invoice amount in msats, optional 188 "amount": 123, // invoice amount in msats, optional
189 "metadata": {} // generic metadata that can be used to add things like zap/boostagram details for a payer name/comment/etc, optional
151 } 190 }
152} 191}
153``` 192```
@@ -166,42 +205,6 @@ Response:
166Errors: 205Errors:
167- `PAYMENT_FAILED`: The payment failed. This may be due to a timeout, exhausting all routes, insufficient capacity or similar. 206- `PAYMENT_FAILED`: The payment failed. This may be due to a timeout, exhausting all routes, insufficient capacity or similar.
168 207
169### `multi_pay_invoice`
170
171Description: Requests payment of multiple invoices.
172
173Request:
174```jsonc
175{
176 "method": "multi_pay_invoice",
177 "params": {
178 "invoices": [
179 {"id":"4da52c32a1", "invoice": "lnbc1...", "amount": 123}, // bolt11 invoice and amount in msats, amount is optional
180 {"id":"3da52c32a1", "invoice": "lnbc50n1..."},
181 ],
182 }
183}
184```
185
186Response:
187
188For every invoice in the request, a separate response event is sent. To differentiate between the responses, each
189response event contains a `d` tag with the id of the invoice it is responding to; if no id was given, then the
190payment hash of the invoice should be used.
191
192```jsonc
193{
194 "result_type": "multi_pay_invoice",
195 "result": {
196 "preimage": "0123456789abcdef...", // preimage of the payment
197 "fees_paid": 123, // value in msats, optional
198 }
199}
200```
201
202Errors:
203- `PAYMENT_FAILED`: The payment failed. This may be due to a timeout, exhausting all routes, insufficient capacity or similar.
204
205### `pay_keysend` 208### `pay_keysend`
206 209
207Request: 210Request:
@@ -236,44 +239,6 @@ Response:
236Errors: 239Errors:
237- `PAYMENT_FAILED`: The payment failed. This may be due to a timeout, exhausting all routes, insufficient capacity or similar. 240- `PAYMENT_FAILED`: The payment failed. This may be due to a timeout, exhausting all routes, insufficient capacity or similar.
238 241
239### `multi_pay_keysend`
240
241Description: Requests multiple keysend payments.
242
243Has an array of keysends, these follow the same semantics as `pay_keysend`, just done in a batch
244
245Request:
246```jsonc
247{
248 "method": "multi_pay_keysend",
249 "params": {
250 "keysends": [
251 {"id": "4c5b24a351", "pubkey": "03...", "amount": 123},
252 {"id": "3da52c32a1", "pubkey": "02...", "amount": 567, "preimage": "abc123..", "tlv_records": [{"type": 696969, "value": "77616c5f6872444873305242454d353736"}]},
253 ],
254 }
255}
256```
257
258Response:
259
260For every keysend in the request, a separate response event is sent. To differentiate between the responses, each
261response event contains a `d` tag with the id of the keysend it is responding to; if no id was given, then the
262pubkey should be used.
263
264```jsonc
265{
266 "result_type": "multi_pay_keysend",
267 "result": {
268 "preimage": "0123456789abcdef...", // preimage of the payment
269 "fees_paid": 123, // value in msats, optional
270 }
271}
272```
273
274Errors:
275- `PAYMENT_FAILED`: The payment failed. This may be due to a timeout, exhausting all routes, insufficient capacity or similar.
276
277### `make_invoice` 242### `make_invoice`
278 243
279Request: 244Request:
@@ -284,7 +249,8 @@ Request:
284 "amount": 123, // value in msats 249 "amount": 123, // value in msats
285 "description": "string", // invoice's description, optional 250 "description": "string", // invoice's description, optional
286 "description_hash": "string", // invoice's description hash, optional 251 "description_hash": "string", // invoice's description hash, optional
287 "expiry": 213 // expiry in seconds from time invoice is created, optional 252 "expiry": 213, // expiry in seconds from time invoice is created, optional
253 "metadata": {} // generic metadata that can be used to add things like zap/boostagram details for a payer name/comment/etc, optional
288 } 254 }
289} 255}
290``` 256```
@@ -295,6 +261,7 @@ Response:
295 "result_type": "make_invoice", 261 "result_type": "make_invoice",
296 "result": { 262 "result": {
297 "type": "incoming", // "incoming" for invoices, "outgoing" for payments 263 "type": "incoming", // "incoming" for invoices, "outgoing" for payments
264 "state": "pending", // optional
298 "invoice": "string", // encoded invoice, optional 265 "invoice": "string", // encoded invoice, optional
299 "description": "string", // invoice's description, optional 266 "description": "string", // invoice's description, optional
300 "description_hash": "string", // invoice's description hash, optional 267 "description_hash": "string", // invoice's description hash, optional
@@ -328,6 +295,7 @@ Response:
328 "result_type": "lookup_invoice", 295 "result_type": "lookup_invoice",
329 "result": { 296 "result": {
330 "type": "incoming", // "incoming" for invoices, "outgoing" for payments 297 "type": "incoming", // "incoming" for invoices, "outgoing" for payments
298 "state": "pending", // can be "pending", "settled", "accepted" (for hold invoices), "expired" (for invoices) or "failed" (for payments), optional
331 "invoice": "string", // encoded invoice, optional 299 "invoice": "string", // encoded invoice, optional
332 "description": "string", // invoice's description, optional 300 "description": "string", // invoice's description, optional
333 "description_hash": "string", // invoice's description hash, optional 301 "description_hash": "string", // invoice's description hash, optional
@@ -376,6 +344,7 @@ Response:
376 "transactions": [ 344 "transactions": [
377 { 345 {
378 "type": "incoming", // "incoming" for invoices, "outgoing" for payments 346 "type": "incoming", // "incoming" for invoices, "outgoing" for payments
347 "state": "pending", // can be "pending", "settled", "accepted" (for hold invoices), "expired" (for invoices) or "failed" (for payments), optional
379 "invoice": "string", // encoded invoice, optional 348 "invoice": "string", // encoded invoice, optional
380 "description": "string", // invoice's description, optional 349 "description": "string", // invoice's description, optional
381 "description_hash": "string", // invoice's description hash, optional 350 "description_hash": "string", // invoice's description hash, optional
@@ -440,6 +409,89 @@ Response:
440} 409}
441``` 410```
442 411
412### `make_hold_invoice`
413
414Creates a hold invoice using a pre-generated preimage.
415
416Request:
417```jsonc
418{
419 "method": "make_hold_invoice",
420 "params": {
421 "amount": 123, // value in msats
422 "description": "string", // invoice's description, optional
423 "description_hash": "string", // invoice's description hash, optional
424 "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`)
425 "payment_hash": "string" // Payment hash for the payment generated from the preimage
426 "min_cltv_expiry_delta": 144 // The minimum CLTV delta to use for the final hop, optional
427 }
428}
429```
430
431Response:
432```jsonc
433{
434 "result_type": "make_hold_invoice",
435 "result": {
436 "type": "incoming", // "incoming" for invoices, "outgoing" for payments
437 "invoice": "string", // encoded invoice, optional
438 "description": "string", // invoice's description, optional
439 "description_hash": "string", // invoice's description hash, optional
440 "payment_hash": "string", // Payment hash for the payment
441 "amount": 123, // value in msats
442 "created_at": unixtimestamp, // invoice/payment creation time
443 "expires_at": unixtimestamp, // invoice expiration time, optional if not applicable
444 "metadata": {} // generic metadata that can be used to add things like zap/boostagram details for a payer name/comment/etc.
445 }
446}
447```
448
449### `cancel_hold_invoice`
450
451Cancels a hold invoice using the payment hash
452
453Request:
454```jsonc
455{
456 "method": "cancel_hold_invoice",
457 "params": {
458 "payment_hash": "string" // Payment hash for the payment generated from the preimage
459 }
460}
461```
462
463Response:
464```jsonc
465{
466 "result_type": "cancel_hold_invoice",
467 "result": {}
468}
469```
470
471### `settle_hold_invoice`
472
473Settles a hold invoice using the preimage
474
475
476Request:
477```jsonc
478{
479 "method": "settle_hold_invoice",
480 "params": {
481 "preimage": "string" // preimage for the payment
482 }
483}
484```
485
486Response:
487```jsonc
488{
489 "result_type": "settle_hold_invoice",
490 "result": {}
491}
492```
493
494
443## Notifications 495## Notifications
444 496
445### `payment_received` 497### `payment_received`
@@ -452,6 +504,7 @@ Notification:
452 "notification_type": "payment_received", 504 "notification_type": "payment_received",
453 "notification": { 505 "notification": {
454 "type": "incoming", 506 "type": "incoming",
507 "state": "settled", // optional
455 "invoice": "string", // encoded invoice 508 "invoice": "string", // encoded invoice
456 "description": "string", // invoice's description, optional 509 "description": "string", // invoice's description, optional
457 "description_hash": "string", // invoice's description hash, optional 510 "description_hash": "string", // invoice's description hash, optional
@@ -477,6 +530,7 @@ Notification:
477 "notification_type": "payment_sent", 530 "notification_type": "payment_sent",
478 "notification": { 531 "notification": {
479 "type": "outgoing", 532 "type": "outgoing",
533 "state": "settled", // optional
480 "invoice": "string", // encoded invoice 534 "invoice": "string", // encoded invoice
481 "description": "string", // invoice's description, optional 535 "description": "string", // invoice's description, optional
482 "description_hash": "string", // invoice's description hash, optional 536 "description_hash": "string", // invoice's description hash, optional
@@ -492,6 +546,30 @@ Notification:
492} 546}
493``` 547```
494 548
549### `hold_invoice_accepted`
550
551Description: 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.
552
553Notification:
554```jsonc
555{
556 "notification_type": "hold_invoice_accepted",
557 "notification": {
558 "type": "incoming",
559 "state": "accepted", // optional
560 "invoice": "string", // encoded invoice
561 "description": "string", // invoice's description, optional
562 "description_hash": "string", // invoice's description hash, optional
563 "payment_hash": "string", // Payment hash for the payment
564 "amount": 123, // value in msats
565 "created_at": unixtimestamp, // invoice/payment creation time
566 "expires_at": unixtimestamp, // invoice expiration time
567 "settle_deadline": blocknumber, // invoice can only be safely settled or canceled before this block number.
568 "metadata": {} // generic metadata that can be used to add things like zap/boostagram details for a payer name/comment/etc.
569 }
570}
571```
572
495## Example pay invoice flow 573## Example pay invoice flow
496 574
4970. 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. 5750. 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.
@@ -499,9 +577,89 @@ Notification:
4992. **wallet service** verifies that the author's key is authorized to perform the payment, decrypts the payload and sends the payment. 5772. **wallet service** verifies that the author's key is authorized to perform the payment, decrypts the payload and sends the payment.
5003. **wallet service** responds to the event by sending an event with kind `23195` and content being a response either containing an error message or a preimage. 5783. **wallet service** responds to the event by sending an event with kind `23195` and content being a response either containing an error message or a preimage.
501 579
580## Encryption
581
582The initial version of NWC used [NIP-04](04.md) for encryption which has been deprecated and replaced by [NIP-44](44.md). NIP-44 should always be preferred for encryption, but there may be legacy cases
583where the **wallet service** or **client** has not yet migrated to NIP-44. The **wallet service** and **client** should negotiate the encryption method to use based on the `encryption` tag in the `info` event.
584
585The encryption tag can contain either `nip44_v2` or `nip04`. The absence of this tag implies that the wallet only supports `nip04`.
586
587| Encryption code | Use | Notes |
588|-----------------|----------------------|---------------------------------------------------------|
589| `nip44_v2` | NIP-44 | Required |
590| `nip04` | NIP-04 | Deprecated and only here for backward compatibility |
591| `<not present>` | NIP-04 | Deprecated and only here for backward compatibility |
592
593The negotiation works as follows.
594
5951. The **wallet service** includes an `encryption` tag in the `info` event. This tag contains a space-separated list of encryption schemes that the **wallet service** supports (eg. `nip44_v2 nip04`)
5962. The **client application** includes an `encryption` tag in each request event. This tag contains the encryption scheme which should be used for the request. The **client application** should always prefer nip44 if supported by the **wallet service**.
597
598When a **client application** establishes a connection, it should read the info event and look for the `encryption` tag.
599
600**Absence of this tag implies that the wallet only supports nip04.**
601
602If the `encryption` tag is present, the **client application** will choose optimal encryption supported by both itself, and the **wallet service**, which should always be nip44 if possible.
603
604### Request events
605
606When a **client application** sends a request event, it should include a `encryption` tag with the encryption scheme it is using. The scheme MUST be supported by the **wallet service** as indicated by the info event.
607For example, if the client application supports nip44, the request event might look like:
608
609```jsonc
610{
611 "kind": 23194,
612 "tags": [
613 ["encryption", "nip44_v2"],
614 // ...
615 ],
616 // ...
617}
618```
619
620If the **wallet service** does not support the specified encryption scheme, it will return an `UNSUPPORTED_ENCRYPTION` error. Absence of the `encryption` tag indicates use of nip04 for encryption.
621
622### Notification events
623
624If a **wallet service** supports both nip04 and nip44, it should publish two notification events for each notification - kind 23196 encrypted with NIP-04, and kind 23197 encrypted with NIP-44. If the **wallet service** only supports nip44, it should only publish kind 23197 events.
625
626The **client** should check the `encryption` tag in the `info` event to determine which encryption schemes the **wallet service** supports, and listen to the appropriate notification event.
627
502## Using a dedicated relay 628## Using a dedicated relay
503This NIP does not specify any requirements on the type of relays used. However, if the user is using a custodial service it might make sense to use a relay that is hosted by the custodial service. The relay may then enforce authentication to prevent metadata leaks. Not depending on a 3rd party relay would also improve reliability in this case. 629This NIP does not specify any requirements on the type of relays used. However, if the user is using a custodial service it might make sense to use a relay that is hosted by the custodial service. The relay may then enforce authentication to prevent metadata leaks. Not depending on a 3rd party relay would also improve reliability in this case.
504 630
631## Metadata
632Metadata MAY be stored by the **wallet service** alongside invoices and payments. The metadata MUST be no more than 4096 characters, otherwise MUST be dropped. This is to ensure transactions do not get too large to be relayed.
633
634NWC relays SHOULD allow at least a payload size of 64KB and **clients** SHOULD fetch small page sizes (maximum of 20 transactions per page) otherwise there is risk of `list_transactions` responses being rejected.
635
636Here are some properties that are recognized by some NWC clients:
637
638```jsonc
639{
640 "comment": "string", // LUD-12 comment
641 "payer_data": {
642 "email": "string",
643 "name": "string",
644 "pubkey": "string",
645 }, // LUD-18 payer data
646 "recipient_data": {
647 "identifier": "string"
648 }, // similar to LUD-18 payer data, but to record recipient data e.g. the lightning address of the recipient
649 "nostr": {
650 "pubkey": "string",
651 "tags": [],
652 // ... rest of zap request event
653 }, // NIP-57 Zap Request event (kind 9734)
654 "tlv_records": [
655 {
656 "type": 5482373484, // tlv type
657 "value": "0123456789abcdef" // hex encoded tlv value
658 }
659 ] // keysend TLV records (e.g. for podcasting 2.0 boostagrams)
660} & Record<string, unknown>;
661```
662
505## Appendix 663## Appendix
506 664
507### Example NIP-47 info event 665### Example NIP-47 info event
@@ -513,6 +671,7 @@ This NIP does not specify any requirements on the type of relays used. However,
513 "created_at": 1713883677, 671 "created_at": 1713883677,
514 "kind": 13194, 672 "kind": 13194,
515 "tags": [ 673 "tags": [
674 [ "encryption", "nip44_v2 nip04" ],
516 [ 675 [
517 "notifications", 676 "notifications",
518 "payment_received payment_sent" 677 "payment_received payment_sent"
@@ -522,3 +681,30 @@ This NIP does not specify any requirements on the type of relays used. However,
522 "sig": "31f57b369459b5306a5353aa9e03be7fbde169bc881c3233625605dd12f53548179def16b9fe1137e6465d7e4d5bb27ce81fd6e75908c46b06269f4233c845d8" 681 "sig": "31f57b369459b5306a5353aa9e03be7fbde169bc881c3233625605dd12f53548179def16b9fe1137e6465d7e4d5bb27ce81fd6e75908c46b06269f4233c845d8"
523} 682}
524``` 683```
684
685### Example Hold Invoice Support Flow
686
6871. Client generates a 32-byte hex-encoded preimage.
6882. Computes SHA-256 to derive payment hash.
6893. Sends `make_hold_invoice` with payment hash and desired parameters.
6904. Waits for `hold_invoice_accepted` notification.
6915. Upon receiving notification, either:
692
693 * Calls `settle_hold_invoice` with the original preimage to release funds, or
694 * Calls `cancel_hold_invoice` with payment hash to abort.
695
696### Deep-links
697
698Wallet 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.
699
700`nostrnwc://connect` and `nostrnwc+{app_name}://connect` can be registered by wallet apps and queried by apps that want to receive an NWC pairing code.
701
702All URI parameters, MUST be URI-encoded.
703
704URI parameters:
705 * `appicon` -- URL to an icon of the client that wants to create a connection.
706 * `appname` -- Name of the client that wants to create a connection.
707 * `callback` -- URI schema the wallet should open with the connection string
708
709Once a connection has been created by the wallet, it should be returned to the client by opening the callback with the following parameters
710 * `value` -- NWC pairing code (e.g. `nostr+walletconnect://...`)