diff options
| author | kiwiidb <33457577+kiwiidb@users.noreply.github.com> | 2023-04-27 16:21:15 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-04-27 17:21:15 +0300 |
| commit | de095e47580e63d91faf541e6a0c84ae5c0ca8fd (patch) | |
| tree | 24f00b1df011da3b3ac6d7c14ec69ccc29beddc7 | |
| parent | c232c9a46a279883f7d8e07db9f2ae6a79a784c6 (diff) | |
NIP-47: Implement feedback
Co-authored-by: Semisol <hi@semisol.dev>
| -rw-r--r-- | 47.md | 79 |
1 files changed, 27 insertions, 52 deletions
| @@ -17,19 +17,22 @@ This NIP describes a way for clients to access a remote Lightning wallet through | |||
| 17 | 17 | ||
| 18 | ## Events | 18 | ## Events |
| 19 | 19 | ||
| 20 | There are two event kinds: | 20 | There are three event kinds: |
| 21 | - `NIP-47 info event`: 13194 | ||
| 21 | - `NIP-47 request`: 23194 | 22 | - `NIP-47 request`: 23194 |
| 22 | - `NIP-47 response`: 23195 | 23 | - `NIP-47 response`: 23195 |
| 23 | 24 | ||
| 24 | Both the request and response events SHOULD only 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. | 25 | The 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 |
| 26 | a 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. | ||
| 27 | 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 **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. | ||
| 25 | 28 | ||
| 26 | The content is encrypted with [NIP04](https://github.com/nostr-protocol/nips/blob/master/04.md), and is a JSON object. The content depends on the kind. | 29 | The 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: |
| 27 | 30 | ||
| 28 | Request: | 31 | Request: |
| 29 | ```jsonc | 32 | ```jsonc |
| 30 | { | 33 | { |
| 31 | "cmd": "pay_invoice", // command, string | 34 | "method": "pay_invoice", // method, string |
| 32 | "data": { // data, object | 35 | "params": { // params, object |
| 33 | "invoice": "lnbc50n1..." // command-related data | 36 | "invoice": "lnbc50n1..." // command-related data |
| 34 | } | 37 | } |
| 35 | } | 38 | } |
| @@ -38,21 +41,26 @@ Request: | |||
| 38 | Response: | 41 | Response: |
| 39 | ```jsonc | 42 | ```jsonc |
| 40 | { | 43 | { |
| 41 | "status": "ok", // status, "ok" | "error" | 44 | "result_type": "pay_invoice", //indicates the structure of the result field |
| 42 | "event": "0123456789abcdef...", // event the command is in response to, string | 45 | "error": { //object, non-null in case of error |
| 43 | "data": { // response data | 46 | "code": "UNAUTHORIZED", //string error code, see below |
| 47 | "message": "human readable error message" | ||
| 48 | }, | ||
| 49 | "result": { // result, object. null in case of error. | ||
| 44 | "preimage": "0123456789abcdef..." // command-related data | 50 | "preimage": "0123456789abcdef..." // command-related data |
| 45 | } | 51 | } |
| 46 | } | 52 | } |
| 47 | ``` | 53 | ``` |
| 48 | 54 | ||
| 49 | The data field SHOULD contain a `message` field with a human readable error message and a `code` field with the error code if the status is `error`. | 55 | The `result_type` field MUST contain the name of the method that this event is responding to. |
| 56 | The `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. | ||
| 57 | If the command was succesful, the `error` field must be null. | ||
| 50 | 58 | ||
| 51 | ### Error codes | 59 | ### Error codes |
| 52 | - `RATE_LIMITED`: The client is sending commands too fast. It should retry in a few seconds. | 60 | - `RATE_LIMITED`: The client is sending commands too fast. It should retry in a few seconds. |
| 53 | - `NOT_IMPLEMENTED`: The command is not known or is intentionally not implemented. | 61 | - `NOT_IMPLEMENTED`: The command is not known or is intentionally not implemented. |
| 54 | - `INSUFFICIENT_BALANCE`: The wallet does not have enough funds to cover a fee reserve or the payment amount. | 62 | - `INSUFFICIENT_BALANCE`: The wallet does not have enough funds to cover a fee reserve or the payment amount. |
| 55 | - `QUOTA_EXCEEDED`: The wallet has exceeded | 63 | - `QUOTA_EXCEEDED`: The wallet has exceeded its spending quota. |
| 56 | - `RESTRICTED`: This public key is not allowed to do this operation. | 64 | - `RESTRICTED`: This public key is not allowed to do this operation. |
| 57 | - `UNAUTHORIZED`: This public key has no wallet connected. | 65 | - `UNAUTHORIZED`: This public key has no wallet connected. |
| 58 | - `INTERNAL`: An internal error. | 66 | - `INTERNAL`: An internal error. |
| @@ -64,7 +72,7 @@ The data field SHOULD contain a `message` field with a human readable error mess | |||
| 64 | The **wallet service** generates this connection URI with protocol `nostr+walletconnect:` and base path it's hex-encoded `pubkey` with the following query string parameters: | 72 | The **wallet service** generates this connection URI with protocol `nostr+walletconnect:` and base path it's hex-encoded `pubkey` with the following query string parameters: |
| 65 | 73 | ||
| 66 | - `relay` Required. URL of the relay where the **wallet service** is connected and will be listening for events. May be more than one. | 74 | - `relay` Required. URL of the relay where the **wallet service** is connected and will be listening for events. May be more than one. |
| 67 | - `secret` Required. 32-byte randomly generated hex encoded string. The **client** should use this to sign events when communicating with the **wallet service**. | 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**. |
| 68 | - Authorization does not require passing keys back and forth. | 76 | - Authorization does not require passing keys back and forth. |
| 69 | - The user can have different keys for different applications. Keys can be revoked and created at will and have arbitrary constraints (eg. budgets). | 77 | - The user can have different keys for different applications. Keys can be revoked and created at will and have arbitrary constraints (eg. budgets). |
| 70 | - The key is harder to leak since it is not shown to the user and backed up. | 78 | - The key is harder to leak since it is not shown to the user and backed up. |
| @@ -79,45 +87,6 @@ nostr+walletconnect:b889ff5b1513b641e2a139f661a661364979c5beee91842f8f0ef42ab558 | |||
| 79 | 87 | ||
| 80 | ## Commands | 88 | ## Commands |
| 81 | 89 | ||
| 82 | ### `get_info` | ||
| 83 | |||
| 84 | Description: Get information about the wallet and service. | ||
| 85 | |||
| 86 | Request: Empty object. | ||
| 87 | |||
| 88 | Response: | ||
| 89 | ```jsonc | ||
| 90 | { | ||
| 91 | "balance": 100000, // balance in msat, int | ||
| 92 | // this should be capped at the quota allowed for this client | ||
| 93 | // to not report unspendable balance. | ||
| 94 | "implemented_commands": ["get_info", "pay_invoice"] // commands supported, string array | ||
| 95 | // extensions can be specified via command+extension: | ||
| 96 | // get_info+node_info | ||
| 97 | } | ||
| 98 | ``` | ||
| 99 | |||
| 100 | ### `create_invoice` | ||
| 101 | |||
| 102 | Description: Requests creation of an invoice. | ||
| 103 | |||
| 104 | Request: | ||
| 105 | ```jsonc | ||
| 106 | { | ||
| 107 | "amount": 1000, // amount in msat, int | ||
| 108 | // must be a whole number of sats unless | ||
| 109 | // create_invoice+msat_amount is implemented. | ||
| 110 | "description": "memo" // a description, string, optional | ||
| 111 | } | ||
| 112 | ``` | ||
| 113 | |||
| 114 | Response: | ||
| 115 | ```jsonc | ||
| 116 | { | ||
| 117 | "invoice": "lnbc50n1..." // BOLT11 invoice, string | ||
| 118 | } | ||
| 119 | ``` | ||
| 120 | |||
| 121 | ### `pay_invoice` | 90 | ### `pay_invoice` |
| 122 | 91 | ||
| 123 | Description: Requests payment of an invoice. | 92 | Description: Requests payment of an invoice. |
| @@ -125,14 +94,20 @@ Description: Requests payment of an invoice. | |||
| 125 | Request: | 94 | Request: |
| 126 | ```jsonc | 95 | ```jsonc |
| 127 | { | 96 | { |
| 128 | "invoice": "lnbc50n1..." // BOLT11 invoice, string | 97 | "method": "pay_invoice", |
| 98 | "params": { | ||
| 99 | "invoice": "lnbc50n1..." // bolt11 invoice | ||
| 100 | } | ||
| 129 | } | 101 | } |
| 130 | ``` | 102 | ``` |
| 131 | 103 | ||
| 132 | Response: | 104 | Response: |
| 133 | ```jsonc | 105 | ```jsonc |
| 134 | { | 106 | { |
| 135 | "preimage": "0123456789abcdef..." // preimage after payment, string | 107 | "result_type": "pay_invoice", |
| 108 | "result": { | ||
| 109 | "preimage": "0123456789abcdef..." // preimage of the payment | ||
| 110 | } | ||
| 136 | } | 111 | } |
| 137 | ``` | 112 | ``` |
| 138 | 113 | ||