nip-37: remote signing helpers.

This commit is contained in:
fiatjaf 2022-12-02 13:14:03 -03:00
parent 27c6652e0e
commit 65c8a3cdc0
No known key found for this signature in database
GPG Key ID: BAD43C4BE5C1A3A1
2 changed files with 55 additions and 11 deletions

41
37.md Normal file
View File

@ -0,0 +1,41 @@
NIP-37
======
Remote signing of events
------------------------
`draft` `optional` `author:fiatjaf`
## Long, unnecessary rambling introduction
There could be a myriad of other Nostr apps, mainly web apps, that a Nostr user wants to use for different purposes (not as their daily social-networking driver, but for other, small, low or one-time uses), for example, there could be a micro webapp dedicated only to changing profile metadata.
It is a bad experience for these small single-purpose apps to request the user's private key. It is easier for the developer and safer for the user if they could just prepare events and ask the user to sign them. [NIP-07](07.md) exists for this exact purpose, but it's probably reasonable to expect that most users won't install a browser extension and give it their private keys, specially the group of the most paranoid users (who would be using hardware wallets for their Nostr keys) and the less tech-savvy users (who won't even know what a browser extension is).
## Solution
Suppose a Nostr user Ulysses has its main key on an app a Nostr Android Application called ANA. Now to change its profile name, Ulysses visits a webapp called CPN.
After typing his profile name, Ulysses presses the button and that triggers CPN to open a connection to a relay R (chosen by CPN through any means it deems best) and fire a message `UNSIGNED` containing the new event `set_metadata` event without a signature:
```
["UNSIGNED", {"id": "ad68ae903460554de77e397230e54343c6e1247c0c3c0bd21bb5ee968b3ec50f", "pubkey": "11bd73a4b8dfe3434b83baaab1bd5cd3d4c4f63879cc35d28f1cfbaf843f7d3c", "created_at": 1669995181, "kind": 0, "tags": [], "content": "{\"name\": \"ulysses\"}"}]
```
After that, CPN shows a QR code containing the bech32-encoded event id (as bytes) followed by the relay URL (as UTF-8 encoded bytes) and the bech32 prefix `nrs`: `NRS14452AYP5VP25MEM789ERPE2RG0RWZFRUPS7QH5SMKHHFDZE7C58HWUMN8GHJ7UN9D3SHJTNWDAEHGU3WVDHK6W609C5` (along with a clickable link `nostr:nrs14452ayp5vp25mem789erpe2rg0rwzfrups7qh5smkhhfdze7c58hwumn8ghj7un9d3shjtnwdaehgu3wvdhk6w609c5`):
![QR Code](https://user-images.githubusercontent.com/1653275/205337809-a7a8a5ab-e4b5-445c-a2ec-25fcd23d00d1.png)
Ulysses scans that with his phone camera and opens the scanned code on ANA. Upon seeing the `nrs1` prefix, ANA will decode it, open a connection to relay R and fire a message:
```
["UNSIGNED", "ad68ae903460554de77e397230e54343c6e1247c0c3c0bd21bb5ee968b3ec50f"]
```
The relay R will have stored the unsigned for some short time period, like 5 minutes, before discarding it, so when it gets the `UNSIGNED` message it knows to return that unsigned event to the caller.
```
["UNSIGNED", {"id": "ad68ae903460554de77e397230e54343c6e1247c0c3c0bd21bb5ee968b3ec50f", "pubkey": "11bd73a4b8dfe3434b83baaab1bd5cd3d4c4f63879cc35d28f1cfbaf843f7d3c", "created_at": 1669995181, "kind": 0, "tags": [], "content": "{\"name\": \"ulysses\"}"}]
```
Upon getting the unsigned event, ANA can display it to the user before submitting it again to the same relay or to other relays it decides to using a normal `EVENT` message. It is recommended to submit it back at least to the same relay R just in case CPN wants to learn that the event was properly signed and published and wants to do something in its UI after that.

View File

@ -25,6 +25,7 @@ NIPs stand for **Nostr Implementation Possibilities**. They exist to document wh
- [NIP-28: Public Chat](28.md)
- [NIP-35: User Discovery](35.md)
- [NIP-36: Sensitive Content](36.md)
- [NIP-37: Remote Signing of Events](37.md)
## Event Kinds
@ -50,19 +51,21 @@ NIPs stand for **Nostr Implementation Possibilities**. They exist to document wh
## Message types
### Client to Relay
| type | description | NIP |
|-------|-----------------------------------------------------|------------|
| EVENT | used to publish events | [1](01.md) |
| REQ | used to request events and subscribe to new updates | [1](01.md) |
| CLOSE | used to stop previous subscriptions | [1](01.md) |
| type | description | NIP |
| ------- | ----------------------------------------------------- | ------------ |
| EVENT | used to publish events | [1](01.md) |
| REQ | used to request events and subscribe to new updates | [1](01.md) |
| CLOSE | used to stop previous subscriptions | [1](01.md) |
| UNSIGNED | used to send and request unsigned events | [37](37.md) |
### Relay to Client
| type | description | NIP |
|--------|---------------------------------------------------------|-------------|
| EVENT | used to send events requested to clients | [1](01.md) |
| NOTICE | used to send human-readable messages to clients | [1](01.md) |
| EOSE | used to notify clients all stored events have been sent | [15](15.md) |
| OK | used to notify clients if an EVENT was successuful | [20](20.md) |
| type | description | NIP |
| -------- | --------------------------------------------------------- | ------------- |
| EVENT | used to send events requested to clients | [1](01.md) |
| NOTICE | used to send human-readable messages to clients | [1](01.md) |
| EOSE | used to notify clients all stored events have been sent | [15](15.md) |
| OK | used to notify clients if an EVENT was successuful | [20](20.md) |
| UNSIGNED | used to send unsigned events | [37](37.md) |
Please update these lists when proposing NIPs introducing new event kinds.