# Nostr Events

## Overview

Events are the fundamental data structure in the Nostr protocol. All information exchanged on Nostr is formatted as events. Each event is created by a user (identified by their public key), serialized, signed, and then distributed to relays.

## Event Structure

A Nostr event is a JSON object with the following fields:

| Field | Type | Description |
|-------|------|-------------|
| `id` | string | 32-bytes lowercase hex-encoded sha256 hash of the serialized event data |
| `pubkey` | string | 32-bytes lowercase hex-encoded public key of the event creator |
| `created_at` | integer | Unix timestamp (seconds) when the event was created |
| `kind` | integer | Integer between 0 and 65535 identifying the event type |
| `tags` | array | Array of arrays of strings, representing the event's tags |
| `content` | string | Arbitrary string content, format depends on event kind |
| `sig` | string | 64-bytes lowercase hex of the signature |

## Event Serialization and ID Generation

To obtain the `id` field value, the event data must be serialized and hashed:

1. Create an array with the following elements in order:
   ```
   [
     0,
     <pubkey, as a lowercase hex string>,
     <created_at, as a number>,
     <kind, as a number>,
     <tags, as an array of arrays of non-null strings>,
     <content, as a string>
   ]
   ```

2. Serialize this array to a JSON string with the following rules:
   - Use UTF-8 encoding
   - No whitespace, line breaks, or unnecessary formatting
   - Proper character escaping in the content field:
     - Line break (`0x0A`): `\n`
     - Double quote (`0x22`): `\"`
     - Backslash (`0x5C`): `\\`
     - Carriage return (`0x0D`): `\r`
     - Tab character (`0x09`): `\t`
     - Backspace (`0x08`): `\b`
     - Form feed (`0x0C`): `\f`

3. Calculate the SHA-256 hash of this serialized string
4. Encode the resulting hash as a lowercase hex string

## Event Signature

After calculating the event ID, the creator signs the ID using their private key according to the Schnorr signatures standard for the curve `secp256k1`. The resulting signature is hex-encoded and stored in the `sig` field.

## Event Kinds

Events are categorized by their `kind` value:

- **Regular** (1 ≤ kind < 10000 || 4 ≤ kind < 45 || kind == 1 || kind == 2)
  - Expected to be stored by relays
  - Used for persistent content like notes, articles, etc.

- **Replaceable** (10000 ≤ kind < 20000 || kind == 0 || kind == 3) 
  - For each combination of `pubkey` and `kind`, only the latest event is stored
  - Used for profile metadata, contact lists, etc.

- **Ephemeral** (20000 ≤ kind < 30000)
  - Not expected to be stored by relays
  - Used for temporary messages like chat

- **Addressable** (30000 ≤ kind < 40000)
  - Identified by a combination of `kind`, `pubkey`, and `d` tag value
  - For each unique combination, only the latest event is stored

## Tags

Tags provide additional metadata and relationships for events. They are represented as arrays of strings:

```
[
  ["<tag-name>", "<tag-value>", "...additional optional fields"],
  // more tags
]
```

### Standard Tags

- **e-tag**: References another event
  - Format: `["e", "<event-id>", "<optional-relay-url>", "<optional-marker>"]`

- **p-tag**: References a pubkey (user)
  - Format: `["p", "<pubkey>", "<optional-relay-url>", "<optional-petname>"]`

- **a-tag**: References an addressable/replaceable event 
  - Addressable: `["a", "<kind>:<pubkey>:<d-tag-value>", "<optional-relay-url>"]`
  - Replaceable: `["a", "<kind>:<pubkey>:", "<optional-relay-url>"]`

## Example Event

```json
{
  "id": "4376c65d2f232afbe9b882a35baa4f6fe8667c4e684749af565f981833ed6a65",
  "pubkey": "79dff8f82963424e0bb02708a22e44b4980893e3a4be0fa3cb60a43b946764e3",
  "created_at": 1671217411,
  "kind": 1,
  "tags": [
    ["e", "5c83da77af1dec6d7289834998ad7aafbd9e2191396d75ec3cc27f5a77226f36", "wss://nostr.example.com"],
    ["p", "f7234bd4c1394dda46d09f35bd384dd30cc552ad5541990f98844fb06676e9ca"]
  ],
  "content": "This is a reply to another note!",
  "sig": "908a15e46fb4d8675bab026fc230a0e3542bfade63da02d542fb78b2a8513fcd0092619a2c8c1221e581946e0191f2af505dfdf8657a414dbca329186f009262"
}
```

## References

- [NIP-01: Basic protocol flow description](https://github.com/nostr-protocol/nips/blob/master/01.md)