NIP-21: nostr URI scheme

This NIP is intended to extend the interoperability of the network be defining the URI scheme for Nostr as nostr:. This prefix is then followed by identifiers as specified in NIP-19 (with the exclusion of nsec). For more information on the bech32 encoding used for NIP-19 please refer to the earlier examples.

Rust

TODO

Python

Generally speaking the simplest way for handling NIP-21 objects is by the to_nostr_uri() and from_nostr_uri() methods for encoding or decoding data, respectively.

Additionally, if it is unclear what type of Nip21 object we're handling then the Nip21 class, in conjunction with the parse() and as_enum() methods, can be used to parse these objects without knowing ahead of what they are.

Public key:

keys = Keys.generate()

# URI npub
pk_uri = keys.public_key().to_nostr_uri()
print(f" Public key (URI):    {pk_uri}")

# bech32 npub
pk_parse = Nip21.parse(pk_uri)
if pk_parse.as_enum().is_pubkey():
    pk_bech32 = PublicKey.from_nostr_uri(pk_uri).to_bech32()
    print(f" Public key (bech32): {pk_bech32}")

Note:

event = EventBuilder.text_note("Hello from rust-nostr Python bindings!").sign_with_keys(keys)

# URI note
note_uri = event.id().to_nostr_uri()
print(f" Event (URI):    {note_uri}")

# bech32 note
note_pasre = Nip21.parse(note_uri)
if note_pasre.as_enum().is_note():
    event_bech32 = EventId.from_nostr_uri(note_uri).to_bech32()
    print(f" Event (bech32): {event_bech32}")

Profile identifier:

relays = ["wss://relay.damus.io"]
nprofile = Nip19Profile(keys.public_key(), relays)

# URI nprofile
nprofile_uri = nprofile.to_nostr_uri()
print(f" Profile (URI):    {nprofile_uri}")

# bech32 nprofile
nprofile_parse = Nip21.parse(nprofile_uri)
if nprofile_parse.as_enum().is_profile():
    nprofile_bech32 = Nip19Profile.from_nostr_uri(nprofile_uri).to_bech32()
    print(f" Profile (bech32): {nprofile_bech32}")

Event identifier:

relays = ["wss://relay.damus.io"]
nevent = Nip19Event(event.id(), keys.public_key(), kind=None, relays=relays)

# URI nevent
nevent_uri = nevent.to_nostr_uri()
print(f" Event (URI):    {nevent_uri}")

# bech32 nevent
nevent_parse = Nip21.parse(nevent_uri)
if nevent_parse.as_enum().is_event():
    nevent_bech32 = Nip19Event.from_nostr_uri(nevent_uri).to_bech32()
    print(f" Event (bech32): {nevent_bech32}")

Coordinate identifier:

coord = Coordinate(Kind(0), keys.public_key())

# URI naddr
coord_uri = coord.to_nostr_uri()
print(f" Coordinate (URI):    {coord_uri}")

# bech32 naddr
coord_parse = Nip21.parse(coord_uri)
if coord_parse.as_enum().is_coord():
    coord_bech32 = Coordinate.from_nostr_uri(coord_uri).to_bech32()
    print(f" Coordinate (bech32): {coord_bech32}")
JavaScript

Generally speaking the simplest way for handling NIP-21 objects is by the toNostrUri() and fromNostrUri() methods for encoding or decoding data, respectively.

Public key:

let pk_uri = keys.publicKey.toNostrUri();
console.log(` Public key (URI): ${pk_uri}`);

Note:

let event = EventBuilder.textNote("Hello from rust-nostr JS bindings!").signWithKeys(keys);
let note_uri = event.id.toNostrUri()
console.log(` Event (URI): ${note_uri}`);

Profile identifier:

let relays = ["wss://relay.damus.io"];
let nprofile = new Nip19Profile(keys.publicKey, relays);

// URI nprofile
let nprofile_uri = nprofile.toNostrUri();
console.log(` Profile (URI):    ${nprofile_uri}`);

// bech32 nprofile
let nprofile_bech32 = Nip19Profile.fromNostrUri(nprofile_uri).toBech32();
console.log(` Profile (bech32): ${nprofile_bech32}`);

Event identifier:

let nevent = new Nip19Event(event.id, keys.publicKey, undefined, relays);

// URI nevent
let nevent_uri = nevent.toNostrUri();
console.log(` Event (URI):    ${nevent_uri}`);

// bech32 nevent
let nevent_bech32 = Nip19Event.fromNostrUri(nevent_uri).toBech32();
console.log(` Event (bech32): ${nevent_bech32}`);

Coordinate identifier:

// URI naddr
let coord_uri = new Coordinate(event.kind, keys.publicKey).toNostrUri();
console.log(` Coordinate (URI):    ${coord_uri}`);

// bech32 naddr
let coord_bech32 = new Coordinate(event.kind, keys.publicKey).toBech32();
console.log(` Coordinate (bech32): ${coord_bech32}`);
Kotlin

TODO

Swift

TODO

Flutter

TODO