5.3 KiB
NIP-46
Nostr Connect
draft
optional
author:tiero
author:giowe
author:vforvalerio87
Rationale
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
{
"id": <random_string>,
"method": <one_of_the_methods>,
"params": [<anything>, <else>]
}
Response
{
"id": <request_id>,
"result": <anything>,
"error": <reason>
}
Methods
Mandatory
These are mandatory methods the remote signer app MUST implement:
- describe
- params []
- result
["describe", "get_public_key", "sign_event", "connect", "disconnect", "delegate", ...]
- get_public_key
- params []
- result
pubkey
- sign_event
- params [
event
] - result
event_with_signature
- params [
optional
- connect
- params [
pubkey
]
- params [
- disconnect
- params []
- delegate
- params [
delegatee
,{ kind: number, since: number, until: number }
] - result
{ from: string, to: string, cond: string, sig: string }
- params [
- get_relays
- params []
- result
{ [url: string]: {read: boolean, write: boolean} }
- nip04_encrypt (deprecated)
- params [
pubkey
,plaintext
] - result
nip4 ciphertext
- params [
- nip04_decrypt (deprecated)
- params [
pubkey
,nip4 ciphertext
] - result [
plaintext
]
- params [
- nip44_encrypt
- params [
pubkey
,plaintext
] - result
nip44 encrypted payload
- params [
- nip44_decrypt
- params [
pubkey
,nip44 encrypted payload
] - result [
plaintext
]
- params [
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 Appname
human-readable name of the Appurl
(optional) URL of the website requesting the connectiondescription
(optional) description of the Appicons
(optional) array of URLs for icons of the App.
JavaScript
const uri = `nostrconnect://<pubkey>?relay=${encodeURIComponent("wss://relay.damus.io")}&metadata=${encodeURIComponent(JSON.stringify({"name": "Example"}))}`
Example
nostrconnect://b889ff5b1513b641e2a139f661a661364979c5beee91842f8f0ef42ab558e9d4?relay=wss%3A%2F%2Frelay.damus.io&metadata=%7B%22name%22%3A%22Example%22%7D
Flows
The content
field contains encrypted message as specified by NIP04. The kind
chosen is 24133
.
Connect
- User clicks on "Connect" button on a website or scan it with a QR code
- It will show an URI to open a "nostr connect" enabled Signer
- In the URI there is a pubkey of the App ie.
nostrconnect://<pubkey>&relay=<relay>&metadata=<metadata>
- The Signer will send a message to ACK the
connect
request, along with his public key
Disconnect (from App)
- User clicks on "Disconnect" button on the App
- The App will send a message to the Signer with a
disconnect
request - The Signer will send a message to ACK the
disconnect
request
Disconnect (from Signer)
- User clicks on "Disconnect" button on the Signer
- The Signer will send a message to the App with a
disconnect
request
Get Public Key
- The App will send a message to the Signer with a
get_public_key
request - The Signer will send back a message with the public key as a response to the
get_public_key
request
Sign Event
- The App will send a message to the Signer with a
sign_event
request along with the event to be signed - The Signer will show a popup to the user to inspect the event and sign it
- The Signer will send back a message with the event including the
id
and the schnorrsignature
as a response to thesign_event
request
Delegate
- 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. - The Signer will show a popup to the user to delegate the App to sign on his behalf
- The Signer will send back a message with the signed NIP-26 delegation token or reject it