upleb.uk

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

summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarco Argentieri <3596602+tiero@users.noreply.github.com>2023-02-20 20:26:13 +0100
committerGitHub <noreply@github.com>2023-02-20 16:26:13 -0300
commitb1a5ad355a8b376170471a41817d8722ba7443b1 (patch)
tree3e8ac83e12cf82fc6b4901b02db91fa7a1f0ec46
parent524caa38563f49fc2aacbbe48b212fde0f24f97e (diff)
NIP-46: Nostr Connect 🔌 connect your Nostr app with remote signing devices (#153)
-rw-r--r--46.md162
-rw-r--r--README.md2
2 files changed, 164 insertions, 0 deletions
diff --git a/46.md b/46.md
new file mode 100644
index 0000000..a9f37c1
--- /dev/null
+++ b/46.md
@@ -0,0 +1,162 @@
1NIP-46
2======
3
4Nostr Connect
5------------------------
6
7`draft` `optional` `author:tiero` `author:giowe` `author:vforvalerio87`
8
9## Rationale
10
11Private keys should be exposed to as few systems - apps, operating systems, devices - as possible as each system adds to the attack surface.
12
13Entering private keys can also be annoying and requires exposing them to even more systems such as the operating system's clipboard that might be monitored by malicious apps.
14
15
16## Terms
17
18* **App**: Nostr app on any platform that *requires* to act on behalf of a nostr account.
19* **Signer**: Nostr app that holds the private key of a nostr account and *can sign* on its behalf.
20
21
22## `TL;DR`
23
24
25**App** and **Signer** sends ephemeral encrypted messages to each other using kind `24133`, using a relay of choice.
26
27App prompts the Signer to do things such as fetching the public key or signing events.
28
29The `content` field must be an encrypted JSONRPC-ish **request** or **response**.
30
31## Signer Protocol
32
33### Messages
34
35#### Request
36
37```json
38{
39 "id": <random_string>,
40 "method": <one_of_the_methods>,
41 "params": [<anything>, <else>]
42}
43```
44
45#### Response
46
47```json
48{
49 "id": <request_id>,
50 "result": <anything>,
51 "error": <reason>
52}
53```
54
55### Methods
56
57
58#### Mandatory
59
60These are mandatory methods the remote signer app MUST implement:
61
62- **describe**
63 - params []
64 - result `{"get_public_key": { params: [], result: anything }}`
65- **get_public_key**
66 - params []
67 - result `pubkey`
68- **sign_event**
69 - params [`event`]
70 - result `signature`
71
72#### optional
73
74
75- **connect**
76 - params [`pubkey`]
77- **disconnect**
78 - params []
79- **delegate**
80 - params [`pubkey`, `conditions query string`]
81 - result `nip26 delegation token`
82- **get_relays**
83 - params []
84 - result `{ [url: string]: {read: boolean, write: boolean} }`
85- **nip04_encrypt**
86 - params [`pubkey`, `plaintext`]
87 - result `nip4 ciphertext`
88- **nip04_decrypt**
89 - params [`pubkey`, `nip4 ciphertext`]
90 - result [`plaintext`]
91
92
93NOTICE: `pubkey` and `signature` are hex-encoded strings.
94
95
96### Nostr Connect URI
97
98**Signer** discovers **App** by scanning a QR code, clicking on a deep link or copy-pasting an URI.
99
100The **App** generates a special URI with prefix `nostrconnect://` and base path the hex-encoded `pubkey` with the following querystring parameters **URL encoded**
101
102- `relay` URL of the relay of choice where the **App** is connected and the **Signer** must send and listen for messages.
103- `metadata` metadata JSON of the **App**
104 - `name` human-readable name of the **App**
105 - `url` (optional) URL of the website requesting the connection
106 - `description` (optional) description of the **App**
107 - `icons` (optional) array of URLs for icons of the **App**.
108
109#### JavaScript
110
111```js
112const uri = `nostrconnect://<pubkey>?relay=${encodeURIComponent("wss://relay.damus.io")}&metadata=${encodeURIComponent(JSON.stringify({"name": "Example"}))}`
113```
114
115#### Example
116```sh
117nostrconnect://b889ff5b1513b641e2a139f661a661364979c5beee91842f8f0ef42ab558e9d4?relay=wss%3A%2F%2Frelay.damus.io&metadata=%7B%22name%22%3A%22Example%22%7D
118```
119
120
121
122## Flows
123
124The `content` field contains encrypted message as specified by [NIP04](https://github.com/nostr-protocol/nips/blob/master/04.md). The `kind` chosen is `24133`.
125
126### Connect
127
1281. User clicks on **"Connect"** button on a website or scan it with a QR code
1292. It will show an URI to open a "nostr connect" enabled **Signer**
1303. In the URI there is a pubkey of the **App** ie. `nostrconnect://<pubkey>&relay=<relay>&metadata=<metadata>`
1314. The **Signer** will send a message to ACK the `connect` request, along with his public key
132
133### Disconnect (from App)
134
1351. User clicks on **"Disconnect"** button on the **App**
1362. The **App** will send a message to the **Signer** with a `disconnect` request
1373. The **Signer** will send a message to ACK the `disconnect` request
138
139### Disconnect (from Signer)
140
1411. User clicks on **"Disconnect"** button on the **Signer**
1422. The **Signer** will send a message to the **App** with a `disconnect` request
143
144
145### Get Public Key
146
1471. The **App** will send a message to the **Signer** with a `get_public_key` request
1483. The **Signer** will send back a message with the public key as a response to the `get_public_key` request
149
150### Sign Event
151
1521. The **App** will send a message to the **Signer** with a `sign_event` request along with the **event** to be signed
1532. The **Signer** will show a popup to the user to inspect the event and sign it
1543. The **Signer** will send back a message with the schnorr `signature` of the event as a response to the `sign_event` request
155
156### Delegate
157
1581. The **App** will send a message with metadata to the **Signer** with a `delegate` request along with the **conditions** query string and the **pubkey** of the **App** to be delegated.
1592. The **Signer** will show a popup to the user to delegate the **App** to sign on his behalf
1603. The **Signer** will send back a message with the signed [NIP-26 delegation token](https://github.com/nostr-protocol/nips/blob/master/26.md) or reject it
161
162
diff --git a/README.md b/README.md
index e45c531..25e5861 100644
--- a/README.md
+++ b/README.md
@@ -30,6 +30,7 @@ NIPs stand for **Nostr Implementation Possibilities**. They exist to document wh
30- [NIP-36: Sensitive Content](36.md) 30- [NIP-36: Sensitive Content](36.md)
31- [NIP-40: Expiration Timestamp](40.md) 31- [NIP-40: Expiration Timestamp](40.md)
32- [NIP-42: Authentication of clients to relays](42.md) 32- [NIP-42: Authentication of clients to relays](42.md)
33- [NIP-46: Nostr Connect](46.md)
33- [NIP-50: Keywords filter](50.md) 34- [NIP-50: Keywords filter](50.md)
34- [NIP-56: Reporting](56.md) 35- [NIP-56: Reporting](56.md)
35- [NIP-57: Lightning Zaps](57.md) 36- [NIP-57: Lightning Zaps](57.md)
@@ -56,6 +57,7 @@ NIPs stand for **Nostr Implementation Possibilities**. They exist to document wh
56| 9735 | Zap | [57](57.md) | 57| 9735 | Zap | [57](57.md) |
57| 10002 | Relay List Metadata | [65](65.md) | 58| 10002 | Relay List Metadata | [65](65.md) |
58| 22242 | Client Authentication | [42](42.md) | 59| 22242 | Client Authentication | [42](42.md) |
60| 24133 | Nostr Connect | [46](46.md) |
59| 30023 | Long-form Content | [23](23.md) | 61| 30023 | Long-form Content | [23](23.md) |
60| 1000-9999 | Regular Events | [16](16.md) | 62| 1000-9999 | Regular Events | [16](16.md) |
61| 10000-19999 | Replaceable Events | [16](16.md) | 63| 10000-19999 | Replaceable Events | [16](16.md) |