diff --git a/67.md b/67.md new file mode 100644 index 00000000..63f6707d --- /dev/null +++ b/67.md @@ -0,0 +1,101 @@ +NIP-67 +====== + +Nostr Wallet Auth +-------------------- + +`draft` `optional` + +## Rationale + +[Nostr Wallet Connect](47.md) is a protocol for talking to a lightning wallet over nostr. It is great but hinges on +having the user copy-paste a wallet connection URI into the app they wish to connect with. This can be a UX hurdle and +often has the user handling sensitive information that they may not understand. + +As well, Nostr Wallet Connect has lots of different functions that a wallet may or may not support or an app may or may +not need. This either runs into silent failures or requires the user to understand what functions their wallet supports +and what functions the app needs. + +Finally, Nostr Wallet Connect requires the wallet to generate both key pairs and the app to use these. This limits the +key management strategies that an app can use and often leads to suboptimal key management. + +This NIP proposes a new protocol that solves these problems by having the wallet and app generate the parameters for a +NWC connection together. This URI is then used to connect the wallet and app. + +## Terms + +- **app**: Nostr app on any platform that wants to permissioned access to a user's lightning wallet. +- **wallet**: A nostr wallet connect capable lightning wallet that the user wants to connect to the app. + +## Theory of Operation + +1. The user wants to connect their wallet to an app. The app provides a QR code or other means of connecting to the app. + The QR code contains a `nostr+walletauth://` URI that contains the app's public key, the relay to communicate over, + and a list of functions that the app requires. +2. The user scans the QR code and their wallet prompts them the required functions and asks them to confirm that they + want to connect to the app. +3. On confirmation, the wallet generates a new key pair and sends the public key to the app in a confirmation event. +4. With the combination of both keys, the wallet and the app both will generate the same connection URI. They can now + use NWC to communicate. + +## Specification + +### URI Format + +The **app** generates this connection URI with protocol `nostr+walletauth:` and base path it's hex-encoded `pubkey` +with the following query string parameters: + +- `relay` Required. URL of the relay where the **app** is connected and will be listening for events. May be + more than one. +- `secret` Required. A random identifier that the **wallet** will use to identify the connection. Without this the + **app** cannot authenticate they are receiving a message from the user they want, it could be an attacker just sending + kind `33194` events to the **app**. This should be unique for each connection. This is not a key and should be + different for every new URI. +- `required_commands` Required. A space-separated list of commands that the **app** requires from the **wallet**. The + **wallet** MUST NOT connect if it does not support all of these permissions. +- `optional_commands` Optional. A space-separated list of commands that the **wallet** can enable to add additional + functionality. The **wallet** MAY ignore these. +- `budget` Optional. A budget that the **wallet** will use to limit the amount of funds that the **app** can spend. + The **app** MUST NOT spend more than this amount. The budget is a string of the form `max_amount/period`. + The `period` is one of `daily`, `weekly`, `monthly`, `yearly`. The `max_amount` is a satoshi amount. +- `identity` Optional. The hex-encoded `pubkey` of the *app* that the **wallet** is connecting to. This is used to + for the wallet to display to the user. The **wallet** MAY ignore this. + +#### Example URI + +```sh +nostr+walletauth://b889ff5b1513b641e2a139f661a661364979c5beee91842f8f0ef42ab558e9d4?relay=wss%3A%2F%2Frelay.damus.io&secret=b8a30fafa48d4795b6c0eec169a383de&required_commands=pay_invoice%20pay_keysend%20make_invoice%20lookup_invoice&optional_commands=list_transactions&budget=10000%2Fdaily +``` + +### Event + +This NIP only uses one event kind `33194`. We use a parameterized replaceable event to allow for the wallet and app to +renegotiate the connection if needed and to allow for the wallet being able to look up the connection details later. + +The event SHOULD contain one `d` tag, containing the public key of the app from the URI. + +The content of the event is encrypted with [NIP04](04.md), and should be a JSON structure as follows: + +```jsonc +{ + "secret": "b8a30fafa48d4795b6c0eec169a383de", // string, the secret from the URI + "commands": [ // array of strings, commands that the wallet agrees to support + "pay_invoice", + "pay_keysend", + "make_invoice", + "lookup_invoice", + "list_transactions", + ], + "relay": "wss://relay.damus.io", // Optional string, alternative relay that the wallet will use + "lud16": "user@example.com", // Optional string, user's lightning address +} +``` + +After the user approves the connection, the wallet should send this event to the **app**. + +The *app* should validate that the `secret` matches the one in the URI and that the `commands` are a subset of the +`required_commands` and `optional_commands` from the URI. If the `relay` is present, the *app* should use that instead +of the one from the URI. + +The wallet and app should both then have all the necessary information be able to communicate using NWC. The app will +have the wallet's key from the event's pubkey. The wallet will have the app's key from the URI. diff --git a/README.md b/README.md index 9ce96fc3..34653680 100644 --- a/README.md +++ b/README.md @@ -66,6 +66,7 @@ They exist to document what may be implemented by [Nostr](https://github.com/nos - [NIP-57: Lightning Zaps](57.md) - [NIP-58: Badges](58.md) - [NIP-65: Relay List Metadata](65.md) +- [NIP-67: Wallet Auth](67.md) - [NIP-72: Moderated Communities](72.md) - [NIP-75: Zap Goals](75.md) - [NIP-78: Application-specific data](78.md) @@ -155,6 +156,7 @@ They exist to document what may be implemented by [Nostr](https://github.com/nos | `31925` | Calendar Event RSVP | [52](52.md) | | `31989` | Handler recommendation | [89](89.md) | | `31990` | Handler information | [89](89.md) | +| `33194` | Nostr Wallet Auth | [49](49.md) | | `34550` | Community Definition | [72](72.md) | [nostrocket]: https://github.com/nostrocket/NIPS/blob/main/Problems.md