Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions AD.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
NIP-AD
======

Web Addresses for Nostr things
------------------------------

`final` `optional`

This NIP defines how to make URLs that can both work as normal URLs or have Nostr counterparts.

Such URLs, when pasted on a Nostr client, can be turned into a single event (specially when the filter has `"limit": 1`) or a list of events, and handled accordingly. When used in a normal web browser it can just render HTML like any normal web URL.

To get the Nostr counterpart of any URL, call that URL's domain at path `https://<domain>/.well-known/nostr.json?ad=<original-path>` and look for a key with the desired path in the resulting object. That should contain an object with `{"filter": {<any-nostr-filter>}, "relays": [<relay-to-use>, ...]}`. `"relays"` is optional. If it doesn't exist the `kind:10002` "write" relays of the authors in the filter should be used.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's slight ambiguity in what <original-path> should be. Clients should probably drop any hash but include any query string. Servers should percent decode so a URL like this still works:

https://golf.com/.well-known/nostr.json?ad=%2Fplayers

and this:

https://golf.com/.well-known/nostr.json?ad=%2Fplayers%3Fplayer%3DMario%26player%3DLuigi

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, let's drop query strings entirely. They are super annoying.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using ad as the parameter is slightly bothersome. Why am I thinking about the resurrection of Christ while I'm implementing Nostr URL resolution? NIP-05 doesn't say nostr.json?05= it says nostr.json?name=. So I would think nostr.json?url= or nostr.json?path=

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not about Christ; @fiatjaf wants to sell us ads, obviously

@fiatjaf fiatjaf Jul 2, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Everything is arbitrary, but I'm fine with ?path=.


For example, upon seeing the URL `https://golf.com/players`, a client will make a `GET` request to `https://golf.com/.well-known/nostr.json?ad=/players` and get a response like:

```yaml
{
"/players": {
"filter": {
"kinds": [30000],
"#d": ["players"],
"authors": ["da12d96d63e31383a5b526bdc747ae1a41aa580a4f962aadfd134b631edd43dd"],
"limit": 1
},
"relays": [
"wss://relay.golf.com"
]
}
}
```

Why this convoluted scheme involving `/.well/known/nostr.json` and paths as object keys? That's to be friendly to static sites.

## Some notable use cases

1. [NIP-29](29.md) group names: `groups.com/quiche` resolves to a `kind:39000` on a specific relay, avoiding the need for group id farming.
2. [NIP-5A](5A.md) nsites: `nsites.com/something` resolves to an nsite event.
3. Hosted feeds: servers can create feeds using whatever algorithm they want and publish those simply as a `{"ids": [...]}` filter, or something else.
4. People that have websites and blogs fueled by Nostr content can have those sites exist both natively inside Nostr and to people living outside. This also works for `https://njump.me/nevent1...` or client-specific URLs like `https://yakihonne.com/nevent1...`.
5. This fixes pasted links: when a user pastes a URL on a Nostr client the client can preemptively try to resolve that URL into an event and make a native reference instead.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Implementers should be considerate of the usecase: "your client shows it like that? Look how my client shows it: https://webclient.xyz/nevent1..."

People should still have the option to click the original link and not have it completely replaced by something else. Of course it depends on the type of client and type of link.

I don't think any wording needs to be changed, just wanted to note it.