nips/37.md
2022-12-02 13:20:21 -03:00

3.2 KiB

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 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

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.