- commit
- 1f64d5812d21b55c458bc995fb3e3d0b1d8e769b
- parent
- 5029d16b9c26a9083058aa400c3620908b700c3c
- author
- Dami <dami.etoile@gmail.com>
| M | README.md | 12 | +++++++----- |
| M | docs/ | 14 | ++++++++++++++ |
| M | docs/ | 3 | +++ |
| M | docs/ | 2 | +- |
| M | docs/ | 2 | +- |
| M | docs/ | 6 | +++++- |
| M | docs/ | 1 | + |
| M | docs/ | 2 | +- |
@@ -15,11 +15,12 @@ That answers with a relay at a memorable name, open to anyone for 14 days. Claim
1515 1616 ## What a name gives you1717 18-- **A relay.** The standard protocol plus search, counts, sync, expiry, deletion, proof of work, a discovery record for relay directories and an HTTP door for scripts. Works with every client.18+- **A relay.** The standard protocol plus search, counts, sync, expiry, deletion, proof of work, a discovery record for relay directories and an HTTP door for scripts. Works with every client. Everything past the core, search, sync, counts, the discovery record, names, files, pages and signer traffic, switches off per relay.1919 - **A community.** Members, invite links, an invite tree, moderators with a log of what they did, a signed roster and one NIP-29 group per relay, so group-aware clients show it as a place.2020 - **A site.** Notes and articles as pages with link previews, an Atom feed, and a card with a QR of the group address.2121 - **A file host.** Blossom and NIP-96 on the same bucket, with mirroring, pre-flight checks and file reports.22-- **A console.** Nine tabs on the relay's own page, signed by a browser extension or a remote signer app on a phone. Presets set up an outbox, an inbox, a private relay, a chat, a search replica or a media host in one click.22+- **A console.** Nine tabs on the relay's own page, signed by a browser extension or a remote signer app on a phone. Presets set up an outbox, an inbox, a private relay, a chat, a search replica, a media host or a quiet relay with every costly feature off, in one click.23+- **A file.** Everything the console sets, as one document with a schema: check it offline, see what applying would change, apply it, pull it back. Keep your relay in your repository. The presets are the same files, in `relay-templates/`.2324 - **Jobs.** Pull another relay in, keep a standing mirror, fetch your own history from your relay list, rebroadcast to other relays, and dump everything to a file on a schedule.2425 - **Your own domain.** `wss://relay.example.com` onto your relay with one CNAME.2526 - **Succession.** Name an heir. If your key goes silent, the relay warns you for a month and then hands itself over.@@ -41,7 +42,7 @@ It runs on Cloudflare Workers with one Durable Object per name, SQLite inside it
4142 4243 **For scripts and agents**4344 44-- [Scripts and agents](docs/13-scripts-and-agents.md): a relay end to end with a key and curl, and every management method.45+- [Scripts and agents](docs/13-scripts-and-agents.md): a relay end to end with a key and curl, every management method, and the relay as a configuration file.4546 - [HTTP reference](docs/14-http-reference.md): every path, method, auth and answer.4647 4748 **For developers**@@ -49,7 +50,7 @@ It runs on Cloudflare Workers with one Durable Object per name, SQLite inside it
4950 - [Architecture](docs/10-architecture.md): routing, the object, storage, alarm, jobs, identity, groups.5051 - [Hosting bind.ws](docs/11-hosting-bindws.md): run your own on your own domain, and watch it through logs, traces and metrics.5152 - [Hosting without Cloudflare](docs/16-hosting-without-cloudflare.md): the same Worker on celld, with your own bucket and proxy, and what "supported" promises.52-- [Develop and extend](docs/12-develop-extend.md): layout, tests, adding methods and NIPs, the console.53+- [Develop and extend](docs/12-develop-extend.md): layout, tests, adding methods and NIPs, the console, the templates.5354 - [Costs and margins](docs/15-costs-and-margins.md): what a relay costs the host, what fuel charges, the weekly check against the bitcoin price.5455 5556 ## Quick start@@ -58,12 +59,13 @@ It runs on Cloudflare Workers with one Durable Object per name, SQLite inside it
5859 npm install5960 npm run dev # http://<name>.localhost:87876061 npm test62+npm run typecheck # types, generated files, the configs, every template6163 npm run deploy6264 ```6365 6466 ## Protocol surface6567 66-NIP-01, 05, 09, 11, 13, 17, 29, 40, 42, 43, 45, 46 transport, 50, 56, 57, 59, 62, 66, 67, 70, 77, 86, 94, 96, 98, and Blossom BUD-01, 02, 04, 06, 08, 09.68+NIP-01, 05, 09, 11, 13, 17, 29, 40, 42, 43, 45, 46 transport, 50, 56, 57, 59, 62, 66, 67, 70, 77, 86, 94, 96, 98, and Blossom BUD-01, 02, 04, 06, 08, 09. A relay's information document lists what its owner left on.6769 6870 ## License6971 @@ -62,6 +62,19 @@ A fresh relay lets anyone write. To keep it to your people, set **Rules > Writes
6262 6363 Members can have a name at your relay, such as `alice@<name>.bind.ws`. Set it in their row, or they set it in their profile.6464 65+## From a file66+67+Everything the console sets can live in a file in your own repository: the rules, the features, the kinds and keep-for rules, the members, the bans. Pull the relay as it is, edit the file, see what applying it would change, then apply:68+69+```70+export RELAY_SK=<your key, hex or nsec>71+node scripts/ops/relay.mjs pull wss://<name>.bind.ws relay.json72+node scripts/ops/relay.mjs plan relay.json wss://<name>.bind.ws73+node scripts/ops/relay.mjs push relay.json wss://<name>.bind.ws74+```75+76+The file has a schema, so an editor checks it as you type, and `plan` never touches the relay. A template from the repository's `relay-templates/` folder is a good start: `10-quiet.jsonc` is a small private relay with every costly feature off. See [Scripts and agents](13-scripts-and-agents.md#the-configuration-file).77+6578 ## What it costs6679 6780 Nothing until the relay passes its monthly free allowance. Past that, use is paid in sats, and anyone can zap the relay to top it up. See [Understanding fuel](02-understanding-fuel.md).@@ -71,4 +84,5 @@ Nothing until the relay passes its monthly free allowance. Past that, use is pai
7184 - [Relay configuration](01-relay-configuration.md): the console, tab by tab.7285 - [People and groups](03-people-and-groups.md): invites, moderators, groups in clients, handing the relay over.7386 - [Data and names](04-data-and-names.md): pulls, mirrors, dumps, presets and forks.87+- [Scripts and agents](13-scripts-and-agents.md): the relay from a key and curl, and as a file.7488 - [Your relay on the web](05-your-relay-on-the-web.md): pages, the feed, the card, your own domain and media.@@ -46,6 +46,9 @@ Names are cheap, so a relay does not have to do everything. On the Rules tab, **
4646 | search | only you | anyone | a copy of another relay's searchable kinds, refreshed every six hours |4747 | articles | only you | anyone | long-form articles and profiles; mirrored daily from a source if you give one |4848 | dm | anyone | members | private messages only; directory hidden |49+| quiet | members | members | every kind, forever; search, sync, counts, discovery, names, files, pages and signer traffic off |50+51+Each preset is a file in the repository's `relay-templates/` folder: a relay configuration with the rules sections only, which is also what a file of your own looks like ([Scripts and agents](13-scripts-and-agents.md#the-configuration-file)). A preset that names features sets them too.4952 5053 The search and articles presets take a source relay URL in the field next to the buttons. Applying one adds a standing pull of its kinds from that source. Applying any preset again replaces that pull rather than adding another, and applying one with no source removes it. The pull appears in the Jobs table.5154 @@ -59,7 +59,7 @@ A view is a record the relay signs from what it holds, so a client reads one eve
5959 6060 Profiles and relays follow the directory switch; calendar, articles, zaps, moderation and presence follow the read rule. A members-only view is never stored, since a stored event is readable by anyone the read rule lets in. It is folded and signed when a member asks for it with a signed request. Presence is an ephemeral event, kind 20078, sent to whoever subscribes to it and answered from memory at `/view/presence`; it is broadcast at most once every 30 seconds.6161 62-Views cost rows written, which fuel counts. The Views tab shows what each one wrote on its last run, and the weekly digest adds them up. Any view can be switched off there.62+Views cost rows written, which fuel counts. The Views tab shows what each one wrote on its last run, and the weekly digest adds them up. Any view can be set there to off, on write, hourly or daily; presence is on or off.6363 6464 ## Scripts6565 @@ -130,7 +130,7 @@ Rate limits are token buckets per connection (`ratelimit.ts`) and, beside them,
130130 131131 ## Presets132132 133-`presets.ts` holds the rule bundles: writes, reads, the directory, kind rules and keep-for rules in one go, applied through the same Settings methods the console uses one at a time. Limits, identity, people and bans stay. The `search` and `articles` presets also keep a standing pull labelled `replica` of their kinds from a source relay; applying any preset removes the earlier replica job first, so a name holds at most one. The owner's own replaceable kinds pass the kind rules, so a relay can always hold its owner's lists.133+`config.ts` is the configuration document: `parseConfig` says what a relay would take and, line by line, what it would drop; `planConfig` says what applying would change; `applyConfig` writes, section by section, and a section the document lacks is left alone. `importconfig` runs all three, or the first two with `dryRun`. `presets.ts` derives the presets from `relay-templates/`, folded into `src/gen/templates.ts`: each is a document with the rules sections, applied through `applyConfig`. Limits, identity, people and bans stay. The `search` and `articles` presets also keep a standing pull labelled `replica` of their kinds from a source relay; applying any preset removes the earlier replica job first, so a name holds at most one. The owner's own replaceable kinds pass the kind rules, so a relay can always hold its owner's lists.134134 135135 Wiring the relay into the owner's lists (kinds 10002, 10050, 10007, 10063) happens in the console: it fetches the newest copy from this relay over the NIP-98 bridge and from a few indexers over websockets, merges, signs once and publishes to every relay the list names.136136 @@ -50,6 +50,10 @@ npm run deploy
5050 5151 Nothing else is required: no origin, no certificates, no servers. An idle relay costs nothing; a busy one is billed per Cloudflare's Durable Object and R2 rates.5252 53+## Presets54+55+The presets the console offers are the files in `relay-templates/`, one relay configuration per template with a `template` block for its title and blurb. Add, edit or remove files there, run `npm run build:templates`, and deploy. `npm run typecheck` checks every file against the schema and the relay's own parser, and fails while the generated module is stale. The schema is served at `https://<domain>/relay-config.schema.json`, for editors and for owners who keep their relays as files ([Scripts and agents](13-scripts-and-agents.md#the-configuration-file)).56+5357 ## Operate5458 5559 - `wrangler tail` streams logs, including receipt validation.@@ -122,4 +126,4 @@ npm run dev
122126 123127 `wrangler dev --env dev` serves `http://<name>.localhost:8787` as the relay named `<name>`, `http://<domain>.localhost:8787` as the apex and anything else as `DEV_RELAY`. The dev environment has no routes, so hostnames pass through.124128 125-To use the console without a browser extension, run `node scripts/dev/dev-signer.mjs` and paste the snippet from that file into the devtools console before clicking sign in. `node scripts/seed.mjs <name>` publishes sample events.129+To use the console without a browser extension, run `node scripts/dev/dev-signer.mjs` and paste the snippet from that file into the devtools console before clicking sign in. `node scripts/dev/seed.mjs <name>` publishes sample events. `npm run dev` folds the console's files into their generated module first; the templates need `npm run build:templates` after a change.@@ -16,6 +16,7 @@ Any request with `Accept: application/nostr+json` answers the NIP-11 document, w
1616 | `/` | GET | none | the landing page | 200 |1717 | `/lease` | POST | NIP-98 optional | `{ name, url, console, expires_at, days, holder?, claim }`; a signature reserves the claim for that key | 201; 401 bad signature; 429 rate limited, five a minute per address, 60 overall; 503 no free name |1818 | `/favicon.svg` | GET | none | the icon | 200 |19+| `/relay-config.schema.json` | GET | none | the JSON Schema of a relay configuration file, for `$schema` ([Scripts and agents](13-scripts-and-agents.md#the-configuration-file)) | 200 |1920 | `/.well-known/bindws/hostname?domain=<host>` | GET, on any host | none | whether the hostname is one of ours: the apex, a valid name under it, or a mapped custom hostname; no body. For a proxy issuing certificates on demand ([Hosting without Cloudflare](16-hosting-without-cloudflare.md)) | 200 ours; 404 not |2021 2122 ## Relay page and information@@ -63,7 +63,7 @@ The line to look for is `ok bucket conditional write: create, reject-create, upd
6363 | `LIGHTNING_ADDRESS`, `SERVICE_PUBKEY` | as on Cloudflare ([Service key](11-hosting-bindws.md#service-key)) |6464 | `FREE_*`, `SATS_PER_*` | your allowances and prices |6565 66-`ZONE_ID` and `CNAME_TARGET` stay empty. A node can also override any var at start with `CELLD_VAR_<NAME>=value` or a `CELLD_VARS_FILE`, which is where a value you would rather not commit goes.66+The presets are the files in `relay-templates/`, folded into the code before a deploy ([Presets](11-hosting-bindws.md#presets)); the configuration schema is served at your apex the same way. `ZONE_ID` and `CNAME_TARGET` stay empty. A node can also override any var at start with `CELLD_VAR_<NAME>=value` or a `CELLD_VARS_FILE`, which is where a value you would rather not commit goes.6767 6868 ## Install celld, deploy, run a node6969