[NIP-47] Add versioning and migrate to NIP-44.

This commit is contained in:
Jeremy Klein 2024-10-10 11:48:46 -07:00
parent 561059ff85
commit 298386f0fa

135
47.md
View File

@ -43,34 +43,69 @@ The content should be a plaintext string with the supported capabilities space-s
If 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`.
It should also contain supported versions as described in the [Versioning](#versioning) section. For example:
```jsonc
{
"kind": 13194,
"tags": [
["v", "1.3 0.0"], // List of supported versions as described in the Versioning section.
["notifications", "payment_received payment_sent"]
// ...
],
"content": "pay_invoice get_balance make_invoice lookup_invoice list_transactions get_info notifications",
// ...
}
```
### Request and Response Events
Both 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 **user** if this is a response. The response event SHOULD contain an `e` tag with the id of the request event it is responding to.
Optionally, 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.
The content of requests and responses is encrypted with [NIP04](04.md), and is a JSON-RPCish object with a semi-fixed structure:
The content of requests and responses is encrypted with [NIP44](44.md), and is a JSON-RPCish object with a semi-fixed structure.
Request:
```jsonc
**Important note for backwards-compatibility:** v0 of the protocol used [NIP04](04.md). If a **wallet service** or client app does not include the `v` tag in the
`info` or request events, it should be assumed that the connection is using v0 of the protocol and NIP04 should be used for encryption. See the [Versioning](#versioning) section for more information.
Example request:
```js
{
"method": "pay_invoice", // method, string
"params": { // params, object
"invoice": "lnbc50n1..." // command-related data
}
"kind" 23194,
"tags": [
["v", "1.2"],
["p", "03..." ] // public key of the wallet service.
// ...
],
"content": nip44_encrypt({
"method": "pay_invoice", // method, string
"params": { // params, object
"invoice": "lnbc50n1..." // command-related data
}
}),
}
```
Response:
```jsonc
Example response:
```js
{
"result_type": "pay_invoice", //indicates the structure of the result field
"error": { //object, non-null in case of error
"code": "UNAUTHORIZED", //string error code, see below
"message": "human readable error message"
},
"result": { // result, object. null in case of error.
"preimage": "0123456789abcdef..." // command-related data
}
"kind" 23195,
"tags": [
["p", "03..." ] // public key of the requesting client app
["e", "1234"] // id of the request event this is responding to
// ...
],
"content": nip44_encrypt({
"result_type": "pay_invoice", //indicates the structure of the result field
"error": { //object, non-null in case of error
"code": "UNAUTHORIZED", //string error code, see below
"message": "human readable error message"
},
"result": { // result, object. null in case of error.
"preimage": "0123456789abcdef..." // command-related data
}
})
// ...
}
```
@ -102,6 +137,7 @@ The content of notifications is encrypted with [NIP04](https://github.com/nostr-
- `RESTRICTED`: This public key is not allowed to do this operation.
- `UNAUTHORIZED`: This public key has no wallet connected.
- `INTERNAL`: An internal error.
- `UNSUPPORTED_VERSION`: The version of the request is not supported by the wallet service.
- `OTHER`: Other error.
## Nostr Wallet Connect URI
@ -488,6 +524,71 @@ Notification:
2. **wallet service** verifies that the author's key is authorized to perform the payment, decrypts the payload and sends the payment.
3. **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.
## Versioning
Versioning for NIP-47 allows the protocol to evolve and even make breaking changes while maintaining backwards-compatibility where needed. Versions are represented as `<major>.<minor>` (e.g. 1.3).
Major version bumps imply breaking changes that are incompatible with the previous major version. Minor version bumps, however, only include non-breaking feature additions or improvements which
can maintain full compatibility with the previous minor version.
**Note:** Version 0.0 or absence of a version specification implies the version of NIP-47 prior to adding the versioning system. This is the protocol as defined at commit hash `e655247`.
Versioning works as follows.
1. The **wallet service** includes a `v` tag in the `info` event. This tag contains a space-separated list of versions that the **wallet service** supports.
2. The **client application** includes a `v` tag in each request event. This tag contains the highest version that the **client application** supports and is compatible with the **wallet service**.
### Info event
First, the **wallet service** adds a `v` tag to its `info` event containing a list of versions it supports. This list should be a space-separated list in decreasing order with the format
`<major>.<minor>`. There should be one entry in the list for each major version supported by the wallet, where the minor version is the highest minor version for that major version. For example,
if a wallet service supports version 1.0-1.3 and version 0.0, their `v` tag in the `info` event might look something like:
```jsonc
{
"kind": 13194,
"tags": [
["v", "1.3 0.0"], // List of supported versions as described in the Versioning section.
// ...
],
"content": "pay_invoice get_balance make_invoice lookup_invoice list_transactions get_info",
// ...
}
```
When a **client application** establishes a connection, it should read the info event and look for the v tag.
**Absence of this tag implies that the wallet only supports version 0.**
If the `v` tag is present, the **client application** will choose the highest version supported by both itself, and the **wallet service**. Note that minor version bumps are non-breaking. For example,
if the client application supports a highest version of 1.2, and the wallet published the info event shown above, it would select version 1.2 since the wallets support for v1.3 implies support for v1.2.
### Request events
When a **client application** sends a request event, it should include a `v` tag with the version it is using. This tag should contain the highest version that the **client application** supports
and is compatible with the **wallet service**. The version MUST be supported by the **wallet service** as indicated by the info event. For example, if the client application supports version 1.2,
the request event might look like:
```jsonc
{
"kind": 23194,
"tags": [
["v", "1.2"], // Version tag
// ...
],
// ...
}
```
If the **wallet service** does not support the specified version, it will return an `UNSUPPORTED_VERSION` error. Absence of the `v` tag indicates use of version 0.
### Changelog
- **0.0**:
- Initial version using the protocol as defined at commit hash `e655247`. Uses NIP-04 for encryption.
- **1.0**
- Adds versioning system.
- Uses NIP-44 for encryption.
## Using a dedicated relay
This 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.