upleb.uk

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

summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorfiatjaf_ <fiatjaf@gmail.com>2023-05-02 17:00:22 -0300
committerGitHub <noreply@github.com>2023-05-02 17:00:22 -0300
commit544095d23fe6521f46242137c7dbe77918254ec8 (patch)
tree75ce96979f11852761d011d27c8737ded553657c
parentd7c189d70bd1f9489a388920bc325576bd9cf8e4 (diff)
parent5a8c463641b3dbaf927f7e0479ff046f0f6fb646 (diff)
Merge pull request #406 from nostr-protocol/47-wallet-connect
-rw-r--r--47.md125
1 files changed, 125 insertions, 0 deletions
diff --git a/47.md b/47.md
new file mode 100644
index 0000000..aa58b5c
--- /dev/null
+++ b/47.md
@@ -0,0 +1,125 @@
1NIP-47
2======
3
4Nostr Wallet Connect
5--------------------
6
7`draft` `optional` `author:kiwiidb` `author:bumi` `author:semisol` `author:vitorpamplona`
8
9## Rationale
10
11This NIP describes a way for clients to access a remote Lightning wallet through a standardized protocol. Custodians may implement this, or the user may run a bridge that bridges their wallet/node and the Nostr Wallet Connect protocol.
12
13## Terms
14
15* **client**: Nostr app on any platform that wants to pay Lightning invoices
16* **wallet service**: Nostr app that typically runs on an always-on computer (eg. in the cloud or on a Raspberry Pi).
17
18## Events
19
20There are three event kinds:
21- `NIP-47 info event`: 13194
22- `NIP-47 request`: 23194
23- `NIP-47 response`: 23195
24
25The info event should be a replaceable event that is published by the **wallet service** on the relay to indicate which commands it supports. The content should be
26a plaintext string with the supported commands, space-seperated, eg. `pay_invoice get_balance`. Only the `pay_invoice` command is described in this NIP, but other commands might be defined in different NIPs.
27Both 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.
28
29The content of requests and responses is encrypted with [NIP04](https://github.com/nostr-protocol/nips/blob/master/04.md), and is a JSON-RPCish object with a semi-fixed structure:
30
31Request:
32```jsonc
33{
34 "method": "pay_invoice", // method, string
35 "params": { // params, object
36 "invoice": "lnbc50n1..." // command-related data
37 }
38}
39```
40
41Response:
42```jsonc
43{
44 "result_type": "pay_invoice", //indicates the structure of the result field
45 "error": { //object, non-null in case of error
46 "code": "UNAUTHORIZED", //string error code, see below
47 "message": "human readable error message"
48 },
49 "result": { // result, object. null in case of error.
50 "preimage": "0123456789abcdef..." // command-related data
51 }
52}
53```
54
55The `result_type` field MUST contain the name of the method that this event is responding to.
56The `error` field MUST contain a `message` field with a human readable error message and a `code` field with the error code if the command was not succesful.
57If the command was succesful, the `error` field must be null.
58
59### Error codes
60- `RATE_LIMITED`: The client is sending commands too fast. It should retry in a few seconds.
61- `NOT_IMPLEMENTED`: The command is not known or is intentionally not implemented.
62- `INSUFFICIENT_BALANCE`: The wallet does not have enough funds to cover a fee reserve or the payment amount.
63- `QUOTA_EXCEEDED`: The wallet has exceeded its spending quota.
64- `RESTRICTED`: This public key is not allowed to do this operation.
65- `UNAUTHORIZED`: This public key has no wallet connected.
66- `INTERNAL`: An internal error.
67- `OTHER`: Other error.
68
69## Nostr Wallet Connect URI
70**client** discovers **wallet service** by scanning a QR code, handling a deeplink or pasting in a URI.
71
72The **wallet service** generates this connection URI with protocol `nostr+walletconnect:` and base path it's hex-encoded `pubkey` with the following query string parameters:
73
74- `relay` Required. URL of the relay where the **wallet service** is connected and will be listening for events. May be more than one.
75- `secret` Required. 32-byte randomly generated hex encoded string. The **client** MUST use this to sign events and encrypt payloads when communicating with the **wallet service**.
76 - Authorization does not require passing keys back and forth.
77 - The user can have different keys for different applications. Keys can be revoked and created at will and have arbitrary constraints (eg. budgets).
78 - The key is harder to leak since it is not shown to the user and backed up.
79 - It improves privacy because the user's main key would not be linked to their payments.
80
81The **client** should then store this connection and use it when the user wants to perform actions like paying an invoice. Due to this NIP using ephemeral events, it is recommended to pick relays that do not close connections on inactivity to not drop events.
82
83### Example connection string
84```sh
85nostr+walletconnect:b889ff5b1513b641e2a139f661a661364979c5beee91842f8f0ef42ab558e9d4?relay=wss%3A%2F%2Frelay.damus.io&secret=71a8c14c1407c113601079c4302dab36460f0ccd0ad506f1f2dc73b5100e4f3c
86```
87
88## Commands
89
90### `pay_invoice`
91
92Description: Requests payment of an invoice.
93
94Request:
95```jsonc
96{
97 "method": "pay_invoice",
98 "params": {
99 "invoice": "lnbc50n1..." // bolt11 invoice
100 }
101}
102```
103
104Response:
105```jsonc
106{
107 "result_type": "pay_invoice",
108 "result": {
109 "preimage": "0123456789abcdef..." // preimage of the payment
110 }
111}
112```
113
114Errors:
115- `PAYMENT_FAILED`: The payment failed. This may be due to a timeout, exhausting all routes, insufficient capacity or similar.
116
117## Example pay invoice flow
118
1190. 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.
1201. **client** sends an event to with **wallet service** service with kind `23194`. The content is a `pay_invoice` request. The private key is the secret from the connection string above.
1212. **wallet service** verifies that the author's key is authorized to perform the payment, decrypts the payload and sends the payment.
1223. **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.
123
124## Using a dedicated relay
125This 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.