upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
path: root/5A.md
blob: 7fe24b9e07bd8bedf5a48ce5f74a65a9054cc0c3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
NIP-5A
======

Pubkey Static Websites
----------------------

`draft` `optional`

This nip describes a method by which static websites can be hosted under public keys using specialized host servers

### Site Manifest Definition

A site manifest event MUST be a replaceable or an addressable event as defined in [NIP-01](01.md). There are two types of site manifest event kinds:

- **Root site**: Uses kind `15128` and MUST NOT include a `d` tag. This is a single replaceable event per pubkey and serves as the root site for the pubkey.
- **Named sites**: Uses kind `35128` and MUST have a `d` tag containing the site identifier. These can be smaller websites under a pubkey and can be throught of as sub-domains.

The event MUST include one or more `path` tags that map absolute paths to sha256 hashes. Each `path` tag MUST have the format `["path", "/absolute/path", "sha256hash"]` where:
- The first element is the literal string `"path"`
- The second element is an absolute path ending with a filename and extension
- The third element is the sha256 hash of the file that will be served under this path

The event MAY include `server` tags that hint at which blossom servers can be used to find the blobs associated with the hashes.

The event MAY include `title` and `description` tags that provide simple site information.

The event MAY include a `source` tag that links to the site's source code repository or source archive. The `source` tag MUST have the format `["source", "<url>"]`, where `<url>` is an absolute `http` or `https` URL.

The site icon SHOULD be provided by setting the `/favicon.ico` path in the manifest.

For example, a root site manifest:

```jsonc
{
  "content": "",
  "created_at": 1727373475,
  "id": "5324d695ed7abf7cdd2a48deb881c93b7f4e43de702989bbfb55a1b97b35a3de",
  "kind": 15128,
  "pubkey": "266815e0c9210dfa324c6cba3573b14bee49da4209a9456f9484e5106cd408a5",
  "sig": "f4e4a9e785f70e9fcaa855d769438fea10781e84cd889e3fcb823774f83d094cf2c05d5a3ac4aebc1227a4ebc3d56867286c15a6df92d55045658bb428fd5fb5",
  "tags": [
    // path mappings: absolute path -> sha256 hash
    ["path", "/index.html", "186ea5fd14e88fd1ac49351759e7ab906fa94892002b60bf7f5a428f28ca1c99"],
    ["path", "/about.html", "a1b2c3d4e5f6789012345678901234567890abcdef1234567890abcdef123456"],
    ["path", "/favicon.ico", "fedcba0987654321fedcba0987654321fedcba0987654321fedcba0987654321"],
    // optional: blossom server hints
    ["server", "https://blossom.example.com"],
    // optional: site metadata
    ["title", "My Nostr Site"],
    ["description", "A static website hosted on Nostr"],
    // optional: source code location
    ["source", "https://github.com/example/my-nostr-site"]
  ]
}
```

And a named site manifest:

```jsonc
{
  "content": "",
  "created_at": 1727373475,
  "id": "a1b2c3d4e5f6789012345678901234567890abcdef1234567890abcdef123456",
  "kind": 35128,
  "pubkey": "266815e0c9210dfa324c6cba3573b14bee49da4209a9456f9484e5106cd408a5",
  "sig": "f4e4a9e785f70e9fcaa855d769438fea10781e84cd889e3fcb823774f83d094cf2c05d5a3ac4aebc1227a4ebc3d56867286c15a6df92d55045658bb428fd5fb5",
  "tags": [
    // site identifier
    ["d", "blog"],
    // path mappings: absolute path -> sha256 hash
    ["path", "/index.html", "186ea5fd14e88fd1ac49351759e7ab906fa94892002b60bf7f5a428f28ca1c99"],
    ["path", "/post.html", "a1b2c3d4e5f6789012345678901234567890abcdef1234567890abcdef123456"],
    // optional: blossom server hints
    ["server", "https://blossom.example.com"],
    // optional: site metadata
    ["title", "My Blog"],
    ["description", "A blog hosted on Nostr"],
    // optional: source code location
    ["source", "https://github.com/example/my-nostr-blog"]
  ]
}
```

### Host server implementation

A host server is a HTTP server that is responsible for serving pubkey static websites

#### Resolving Pubkeys

For interoperability, host servers SHOULD use the following canonical URL formats:

- Root site: `<npub>.nsite-host.com`
- Named site: `<pubkeyB36><dTag>.nsite-host.com`

`pubkeyB36` is the author's raw 32-byte pubkey encoded with base36 (lowercase, digits `0-9` then letters `a-z`, no padding) and is always exactly 50 characters.

`dTag` is the site identifier (`d` tag value) as plain text. It is appended directly after `pubkeyB36` with no separator.

For canonical named-site URLs, `dTag` MUST match `^[a-z0-9-]{1,13}$` and MUST NOT end with `-`.

Because DNS labels are limited to 63 characters and `pubkeyB36` uses 50 of them, `dTag` MUST be 1-13 characters.

This single-label format avoids wildcard certificate limitations with multi-level subdomains.

If the host server is using subdomain routing it MAY serve anything at its own root domain `nsite-host.com` (a landing page for example).

Example subdomains:
- Root site: `npub10phxfsms72rhafrklqdyhempujs9h67nye0p67qe424dyvcx0dkqgvap0e.nsite-host.com`
- Named site: `<50-char-pubkeyB36><dTag>.nsite-host.com`

#### Resolving Paths

When the host server receives a request and is able to determine the pubkey and identifier, it should fetch the users `10002` [NIP-65](https://github.com/nostr-protocol/nips/blob/master/65.md) relay list and lookup the site manifest event for the pubkey and identifier.

For canonical subdomain formats, the host server MUST parse the left-most DNS label as follows:

1. If the label is a valid `npub`, decode it and query for the root site manifest.
2. Otherwise, if the label matches `^[0-9a-z]{50}[a-z0-9-]{1,13}$` and does not end with `-`, treat it as a named-site label where:
   - `pubkeyB36` is the first 50 characters
   - `dTag` is the remaining 1-13 characters
   - decode `pubkeyB36` to a 32-byte pubkey
   - use `dTag` as the identifier (`d` tag value)

If parsing fails, the host server MUST treat the site as not found.

The host server should query for the site manifest event:

```jsonc
// For root site (kind 15128, no d tag)
{ "kinds": [15128], "authors": [<pubkey>] }

// For named site (kind 35128, with d tag)
{ "kinds": [35128], "authors": [<pubkey>], "#d": [<identifier>] }
```

Once the site manifest event is found, the host server MUST extract the path-to-hash mappings from the `path` tags in the manifest. The host server should look for a `path` tag where the second element matches the requested path.

If the request path does not end with a filename the host server MUST fallback to using the `index.html` filename

For example: `/` -> `/index.html` or `/blog/` -> `/blog/index.html`

#### Resolving Files

Once the host server has found the site manifest event and located the matching `path` tag for the requested path, it should use the sha256 hash defined in the third element of the `path` tag to retrieve the file.

The host server SHOULD prioritize using `server` tags from the site manifest event as hints for which blossom servers to query. If the manifest includes `server` tags, the host server SHOULD attempt to retrieve the file from those servers first.

If the pubkey has a `10063` [BUD-03 user servers](https://github.com/hzrd149/blossom/blob/master/buds/03.md) event the server MUST attempt to retrieve the file from the listed servers using the path defined in [BUD-01](https://github.com/hzrd149/blossom/blob/master/buds/01.md#get-sha256---get-blob)
If a pubkey does not have a `10063` event and no `server` tags are found in the manifest, the host server MUST respond with a status code 404

The host server MUST forward the `Content-Type`, and `Content-Length` headers from the Blossom server. If none are defined the host server MAY set `Content-Type` from the file extension in the requested path

#### Handling Not Found

If a host server is unable to find a site manifest event or a matching `path` tag for the requested path, it MUST use `/404.html` as a fallback path

### Legacy Support

Kind `34128` is marked as legacy/deprecated. This kind was used for individual static file events where each file was represented by a separate event with a `d` tag for the path and an `x` tag for the sha256 hash.

Host servers MAY still support kind `34128` for backward compatibility with existing sites, but new sites SHOULD use kind `15128` (root site manifest) or kind `35128` (named site manifest) instead.

Read the [legacy version](https://github.com/hzrd149/nips/blob/41e77b45a1e8a8d170097e363f7d7254797cc5c5/nsite.md) for more details.