What is NOSTR?


January 22, 2023

Back to projects

4 MIN READ

You can access the NOSTR client I made here.

A decentralized protocol

NOSTR(Notes and Other Stuff Transmitted by Relays) is a decentralized protocol designed to share Twitter-like data. Before getting into the specifics of exactly how NOSTR works, let's first go over what constitutes a decentralized protocol.


A protocol, despite sounding technically complex, is just a set of rules that inform a client on how they can access something. That might sound painfully abstract or general, so let's look at an example: Hypertext Transfer Protocol. HTTP is what defines how HTML pages are served by web servers to browsers. Another example of a well-known protocol is Bitcoin. A decentralized protocol is a protocol that does not rely on a central authority or entity, and is instead distributed among many parties.

How it usually works

It would also be useful to first understand how a normal data sharing system works, commonly (and sometimes pretentiously) called “Web 2.0”. Here, networks use a pub/sub model, meaning that a given user will “publish” their content to a central server, which another user can “subscribe” to. Note that there is one single central server (usually owned and run by a business).

Overview

At the core of the NOSTR “network” are relays. A relay is just a server somebody runs. Each server has a database that stores notes. Due to certain special rules when creating notes, we do not need to trust relays to verify whether these notes are valid. Relays are “dumb”, meaning that all they do is read or write the database, and perform no other complex logic. This aspect of relays also makes them quite simple to run, explained here. When a client wants to publish or request a note, they will connect to multiple relays and send their event/request to each.

Accounts

A user’s account is only made up of one thing, a public/private key pair. You can think of this as a username/password pair except with special features, the main one being digital signatures. NOSTR uses elliptic curve cryptography to do this, as opposed to something like RSA. Cryptographic signatures are out of the scope of this article, but it is useful to understand the broad strokes. Basically, you can “sign” some arbitrary string using a private key, and publish this signature along with the normal content. Then, another unrelated party can verify that this content was published by the original user using their public key. In layman’s terms, it means that it is impossible to send notes using someone else's public key.

Notes

A note (also called an event) is analogous to a single Tweet, it’s the data that is stored in the relays. Notes will include the actual content of the message along with other data such as the author of the note, and any tags it has. Here is all of the raw data of a single note.

Note Raw JSON

Since there are only seven pieces of data in each note, we can go through what each one means.

1. ID

The id is a unique identifier generated by putting all of the other data (besides the signature) into one long JSON string and hashing it using sha256.

2. pubkey

This is just the public key of the author, pretty self-explanatory.

3. created_at

This very large integer is the Unix timestamp in seconds (the number of seconds since January 1st 1970).

4. kind

The two most common kinds of notes you will see are kind 0 and kind 1, although there are many more. Kind 1 means that the note is a normal public tweet, where the content is just plain english (although it can include links to images). Kind 0 means that the content of the note contains the metadata for the user who wrote it, such as their display name or profile picture. Kind 0 notes should not be shown to end-users.

5. tags

As with the “kind” field there are a ton of valid values for this field. However, the most common are smaller arrays where the first item is “p” or “e”, which indicate the note is a reply or mention. The second item of a “p” tag is another user’s public key, and is similar to @ing someone (i.e. @jason or @bob12345) on Twitter. If the tag is an array where the first item is “e”, the second item is another note’s ID, which indicates that this note is replying to that one.

6. content

Depending on the kind of note, this can be either actual content that an end-user will read, or some kind of metadata or encrypted text that is not supposed to be displayed.

7. sig

As stated before, the signature is imperative to making sure that the entire network is trustless. To generate a signature for a note, a client will “sign” the id of the note with the user’s private key, providing proof that the user actually created the note themselves.

Requests

Besides events, the only other type of messages that relays deal with are requests. Technically, there is a third, called “close”, but that just ends a request, so it is not very interesting. Requests fetch notes from relays that satisfy certain conditions outlined in a filter. An example of a filter would be one that only returns notes that: have certain IDs, are written by certain authors, and are replies to certain events. There are many filter parameters that can be set. Notes are continuously sent to a client until either the connection is closed manually or a Close message is received by the relay.

Why use NOSTR at all?

NOSTR is much more than a simple Twitter alternative/clone, as there is a huge variety of projects that use it. At the core, though, NOSTR gives people control over how they share information without the threat of censorship.

Conclusion + Further Information

In summation, the NOSTR “network” is made up of independently-run relays (or servers) that store notes. A client makes a connection to many different relays using websockets, and can verify the notes using their signatures (created using the private key of a user). A user is simply a public/private key pair, and can set their metadata (display name, profile picture, etc.) the same way they publish notes.

If you’d like to get into the weeds on specific implementations, you can check the GitHub here. Most of the details are outlined in NIPs (NOSTR Improvement Proposal). Thanks for reading, and have a great day!