Private keys should be exposed to as few systems - apps, operating systems, devices - as possible as each system adds to the attack surface.
Entering 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.
## Terms
* **App**: Nostr app on any platform that *requires* to act on behalf of a nostr account.
* **Signer**: Nostr app that holds the private key of a nostr account and *can sign* on its behalf.
## `TL;DR`
**App** and **Signer** sends ephemeral encrypted messages to each other using kind `24133`, using a relay of choice.
App prompts the Signer to do things such as fetching the public key or signing events.
The `content` field must be an encrypted JSONRPC-ish **request** or **response**.
## Signer Protocol
### Messages
#### Request
```json
{
"id": <random_string>,
"method": <one_of_the_methods>,
"params": [<anything>, <else>]
}
```
#### Response
```json
{
"id": <request_id>,
"result": <anything>,
"error": <reason>
}
```
### Methods
#### Mandatory
These are mandatory methods the remote signer app MUST implement:
- result `{ [url: string]: {read: boolean, write: boolean} }`
- **nip04_encrypt**
- params [`pubkey`, `plaintext`]
- result `nip4 ciphertext`
- **nip04_decrypt**
- params [`pubkey`, `nip4 ciphertext`]
- result [`plaintext`]
NOTICE: `pubkey` and `signature` are hex-encoded strings.
### Nostr Connect URI
**Signer** discovers **App** by scanning a QR code, clicking on a deep link or copy-pasting an URI.
The **App** generates a special URI with prefix `nostrconnect://` and base path the hex-encoded `pubkey` with the following querystring parameters **URL encoded**
-`relay` URL of the relay of choice where the **App** is connected and the **Signer** must send and listen for messages.
-`metadata` metadata JSON of the **App**
-`name` human-readable name of the **App**
-`url` (optional) URL of the website requesting the connection
-`description` (optional) description of the **App**
-`icons` (optional) array of URLs for icons of the **App**.
#### JavaScript
```js
const uri = `nostrconnect://<pubkey>?relay=${encodeURIComponent("wss://relay.damus.io")}&metadata=${encodeURIComponent(JSON.stringify({"name": "Example"}))}`
1. 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.
2. The **Signer** will show a popup to the user to delegate the **App** to sign on his behalf