Minor grammar fix at line 48. Minor spelling fix at line 56.
3.5 KiB
NIP-05
Mapping Nostr keys to DNS-based internet identifiers
final
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 accessing /.well-known/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 /.well-known/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 /.well-known/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.