nips/05.md
David A. Harding 57b86d2482 NIP05: warn about CORS policies that may inhibit JS apps
JS Nostr apps such as Branle may not be able to load `nostr.json` files due to CORS policies.  Update NIP05 to warn about this and provide hints for troubleshooting and fixing the issue.
2022-05-07 17:18:23 -03:00

3.5 KiB

NIP-05

Mapping Nostr keys to DNS-based internet identifiers

draft optional author:fiatjaf

On events of type 0 (set_metadata) one can specify the key "nip05" with an internet identifier (an email-like address) as the value. Although there is a link to a very liberal "internet identifier" specification above, NIP-05 assumes the <local-part> part will be restricted to the characters a-z0-9-_., case insensitive.

Upon seeing that, the client splits the identifier into <local-part> and <domain> and use these values to make a GET request to https://<domain>/.well-known/nostr.json?name=<local-part>.

The result should be a JSON document object with a key "names" that should then be a mapping of names to public keys. If the public key for the given <name> matches the pubkey from the set_metadata event, the client then concludes that the given pubkey can indeed be referenced by its identifier.

Example

If a client sees an event like this:

{
  "pubkey": "b0635d6a9851d3aed0cd6c495b282167acf761729078d975fc341b22650b07b9",
  "kind": 0,
  "content": "{\"name\": \"bob\", \"nip05\": \"bob@example.com\"}"
  ...
}

It will make a GET request to https://example.com/.well-known/nostr.json?name=bob and get back a response that will look like

{
  "names": {
    "bob": "b0635d6a9851d3aed0cd6c495b282167acf761729078d975fc341b22650b07b9"
  }
}

That will mean everything is alright.

Notes

User Discovery implementation suggestion

A client can also use this to allow users to search other profiles. If a client has a search box or something like that, a user may be able to type "bob@example.com" there and the client would recognize that and do the proper queries to obtain a pubkey and suggest that to the user.

Showing just the domain as an identifier

Clients may treat the identifier _@domain as the "root" identifier, and choose to display it as just the <domain>. For example, if Bob owns bob.com, he may not want an identifier like bob@bob.com as that is redundant. Instead Bob can use the identifier _@bob.com and expect Nostr clients to show and treat that as just bob.com for all purposes.

Reasoning for the /.well-known/nostr.json?name=<local-part> format

By adding the <local-part> as a query string instead of as part of the path the protocol can support both dynamic servers that can generate JSON on-demand and static servers with a JSON file in it that may contain multiple names.

Allowing access from Javascript apps

Javascript Nostr apps may be restricted by browser CORS policies that prevent them from accesing nostr.json on the user's domain. When CORS prevents JS from loading a resource, the JS program sees it as a network failure identical to the resource not existing, so it is not possible for a pure-JS app to tell the user for certain that the failure was caused by a CORS issue. JS Nostr apps that see network failures requesting nostr.json files may want to recommend to users that they check the CORS policy of their servers, e.g.:

$ curl -sI https://example.com/.well-known/nostr.json?name=bob | grep ^Access-Control
Access-Control-Allow-Origin: *

Users should ensure that their nostr.json is served with the HTTP header Access-Control-Allow-Origin: * to ensure it can be validated by pure JS apps running in modern browsers.