Compare commits

..

5 Commits

Author SHA1 Message Date
frnandu
01838f302d NIP-47 Add Hold Invoice Support (#1913)
Co-authored-by: Fmar <frnandu@gmail.com>
Co-authored-by: Roland <33993199+rolznz@users.noreply.github.com>
2026-02-03 13:41:08 -05:00
mattn
90a60bd210 chore: small fixes (#2209) 2026-02-03 08:22:08 -05:00
Vitor Pamplona
18b948abda NIP-05: Explicitly requires lowercase for hex keys and names (#2208) 2026-02-03 09:57:31 -03:00
Alex Gleason
06593632a8 Add ISO 3166 countries to NIP-73 (#2205) 2026-01-30 09:25:30 -08:00
Alex Gleason
d071018d5a Add NIP-85 to the README (#2203) 2026-01-28 15:47:17 -06:00
5 changed files with 139 additions and 7 deletions

6
05.md
View File

@@ -6,11 +6,11 @@ Mapping Nostr keys to DNS-based internet identifiers
`final` `optional`
On events of kind `0` (`user metadata`) one can specify the key `"nip05"` with an [internet identifier](https://datatracker.ietf.org/doc/html/rfc5322#section-3.4.1) (an email-like address) as the value. Although there is a link to a very liberal "internet identifier" specification above, NIP-05 assumes the `<local-part>` part will be restricted to the characters `a-z0-9-_.`, case-insensitive.
On events of kind `0` (`user metadata`) one can specify the key `"nip05"` with an [internet identifier](https://datatracker.ietf.org/doc/html/rfc5322#section-3.4.1) (an email-like address) as the value. Although there is a link to a very liberal "internet identifier" specification above, the `<local-part>` part MUST only use characters `a-z0-9-_.`.
Upon seeing that, the client splits the identifier into `<local-part>` and `<domain>` and use these values to make a GET request to `https://<domain>/.well-known/nostr.json?name=<local-part>`.
The result should be a JSON document object with a key `"names"` that should then be a mapping of names to hex formatted public keys. If the public key for the given `<name>` matches the `pubkey` from the `user metadata` event, the client then concludes that the given pubkey can indeed be referenced by its identifier.
The result should be a JSON document object with a key `"names"` that should then be a mapping of names to hex formatted public keys, in lowercase. If the public key for the given `<name>` matches the `pubkey` from the `user metadata` event, the client then concludes that the given pubkey can indeed be referenced by its identifier.
### Example
@@ -73,7 +73,7 @@ For example, if after finding that `bob@bob.com` has the public key `abc...def`,
### Public keys must be in hex format
Keys must be returned in hex format. Keys in NIP-19 `npub` format are only meant to be used for display in client UIs, not in this NIP.
Keys must be returned in hex format, in lowercase. Keys in NIP-19 `npub` format are only meant to be used for display in client UIs, not in this NIP.
### Showing just the domain as an identifier

2
22.md
View File

@@ -192,7 +192,7 @@ A reply to a podcast comment:
// this is a reference to the above comment
["e", "80c48d992a38f9c445b943a9c9f1010b396676013443765750431a9004bdac05", "wss://example.relay", "252f10c83610ebca1a059c0bae8255eba2f95be4d1d7bcfa89d7248a82d9f111"],
// the parent comment kind
["k", "1111"]
["k", "1111"],
["p", "252f10c83610ebca1a059c0bae8255eba2f95be4d1d7bcfa89d7248a82d9f111"]
]
// other fields

121
47.md
View File

@@ -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
@@ -485,6 +485,89 @@ 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 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
"min_cltv_expiry_delta": 144 // The minimum CLTV delta to use for the final hop, optional
}
}
```
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`
@@ -539,6 +622,30 @@ Notification:
}
```
### `hold_invoice_accepted`
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
{
"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
"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
"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.
}
}
```
## 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.
@@ -668,6 +775,16 @@ Here are some properties that are recognized by some NWC clients:
}
```
### 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.
### Deep-links
Wallet 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.

1
51.md
View File

@@ -135,7 +135,6 @@ Some clients have used these lists in the past, but they should work on transiti
["e", "340e0326b340e0326b4941ed78ba340e0326b4941ed78ba340e0326b49ed78ba"], // PWA
["a", "32267:d6dc95542e18b8b7aec2f14610f55c335abebec76f3db9e58c254661d0593a0c:com.example.app"] // Reference to parent software application
],
"content": "Example App is a decentralized marketplace for apps",
"sig": "a9a4e2192eede77e6c9d24ddfab95ba3ff7c03fbd07ad011fff245abea431fb4d3787c2d04aad001cb039cb8de91d83ce30e9a94f82ac3c5a2372aa1294a96bd"
}
```

16
73.md
View File

@@ -18,6 +18,7 @@ There are certain established global content identifiers such as [Book ISBNs](ht
| URLs | "`<URL, normalized, no fragment>`" | "web" |
| Books | "isbn:`<id, without hyphens>`" | "isbn" |
| Geohashes | "geo:`<geohash, lowercase>`" | "geo" |
| Countries | "iso3166:`<code, uppercase>`" | "iso3166" |
| Movies | "isan:`<id, without version part>`" | "isan" |
| Papers | "doi:`<id, lowercase>`" | "doi" |
| Hashtags | "#`<topic, lowercase>`" | "#" |
@@ -43,6 +44,21 @@ For the webpage "https://myblog.example.com/post/2012-03-27/hello-world" the "i"
]
```
### Geohashes:
- Geohash: `["i", "geo:ezs42e44yx96"]` - https://www.movable-type.co.uk/scripts/geohash.html
Geohashes are a geocoding system that encodes geographic locations into short strings of letters and digits. They MUST be lowercase.
### Countries:
ISO 3166 codes can reference countries (ISO 3166-1 alpha-2) or subdivisions like states/provinces (ISO 3166-2).
- Country (Venezuela): `["i", "iso3166:VE"]`
- Subdivision (California, USA): `["i", "iso3166:US-CA"]`
ISO 3166 codes MUST be uppercase. More info: https://en.wikipedia.org/wiki/ISO_3166
### Books:
- Book ISBN: `["i", "isbn:9780765382030"]` - https://isbnsearch.org/isbn/9780765382030