- commit
- db08d3502ec8c3b65637d0a80c6f65a9af6b0421
- parent
- 8008443ea0763acaa90224ddedbb96c1ca882f18
- author
- Dami <dami.etoile@gmail.com>
| M | .github/ | 2 | +- |
| M | docs/ | 8 | ++++---- |
| M | docs/ | 4 | ++-- |
| M | docs/ | 11 | ++++++----- |
| M | docs/ | 10 | +++++----- |
| M | docs/ | 6 | +++--- |
| M | docs/ | 2 | +- |
| M | package.json | 12 | ++++++++++-- |
| M | relay-templates/ | 4 | ++-- |
| M | scripts/ | 6 | +++--- |
| M | scripts/ | 2 | +- |
| M | scripts/ | 2 | +- |
| M | scripts/ | 2 | +- |
| M | scripts/ | 2 | +- |
| M | scripts/ | 2 | +- |
| M | scripts/ | 8 | ++++---- |
| M | scripts/ | 10 | +++++----- |
@@ -64,13 +64,13 @@ Members can have a name at your relay, such as `alice@<name>.bind.ws`. Set it in
6464 6565 ## From a file6666 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: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. From a checkout of the [repository](https://github.com/FelineStateMachine/bindws), pull the relay as it is, edit the file, see what applying it would change, then apply:6868 6969 ```7070 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.ws71+npm run relay pull wss://<name>.bind.ws relay.json72+npm run relay plan relay.json wss://<name>.bind.ws73+npm run relay push relay.json wss://<name>.bind.ws7474 ```7575 7676 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).@@ -22,7 +22,7 @@ Edit `wrangler.jsonc`:
2222 | `LEASE_DAYS` | how long a temporary relay from `POST /lease` lives; 14 if unset |2323 | `ratelimits` | how many leases a minute, per address and overall; the defaults are 5 and 60 |2424 25-The prices carry a comment with the Cloudflare rates they were set from. `node scripts/ops/margin.mjs` compares them with those rates at the current bitcoin price, and a weekly workflow does the same; see [Costs and margins](15-costs-and-margins.md).25+The prices carry a comment with the Cloudflare rates they were set from. `npm run margin` compares them with those rates at the current bitcoin price, and a weekly workflow does the same; see [Costs and margins](15-costs-and-margins.md).2626 2727 Point `routes` at your zone: the apex as a custom domain and `*.<domain>/*` as a zone route. Create the R2 bucket named in `r2_buckets`.2828 @@ -126,4 +126,4 @@ npm run dev
126126 127127 `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.128128 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.129+To use the console without a browser extension, run `npm run dev:signer` and paste the snippet from that file into the devtools console before clicking sign in. `npm run dev:seed <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.@@ -62,9 +62,10 @@ scripts/
6262 build-console.mjs fold src/console into src/gen/console.ts6363 build-templates.mjs fold relay-templates/ into src/gen/templates.ts6464 check/ check-console.mjs check-celld.mjs check-config.mjs run by npm run typecheck; check-config also checks any file65- dev/ dev-signer.mjs seed.mjs stage.mjs junk.mjs shot.mjs zaptest.mjs for a dev relay66- ops/ margin.mjs fuel prices against Cloudflare's rates, weekly in CI67- relay.mjs check, plan, push or pull a relay's configuration file65+ dev/ dev-signer.mjs seed.mjs stage.mjs junk.mjs shot.mjs zaptest.mjs npm run dev:signer, dev:seed, dev:stage, dev:junk, dev:shot, dev:zaptest66+ ops/ margin.mjs relay.mjs npm run margin; npm run relay check|plan|push|pull67+68+Every script has an npm name (package.json), and the docs use those names: a tutorial never says node and a path.6869 wrangler.jsonc the Worker on Cloudflare6970 wrangler.celld.jsonc the same Worker on celld (docs/16)7071 ```@@ -117,13 +118,13 @@ Remote signing needs NIP-44 and secp256k1, which browsers do not ship. `scripts/
117118 118119 The console is three ordinary files in `src/console`: `console.html` (the body), `console.css` and `console.js`. `npm run build:console` folds them into `src/gen/console.ts`, the strings the relay serves; `npm run dev` runs it first, and `npm run typecheck` fails when the generated file is stale. It is a generated module rather than a text-module rule in `wrangler.jsonc` because celld deploy refuses a config with `rules`. `scripts/check/check-console.mjs` runs the script's synchronous start against a stub document, so a handler wired above the helper it calls fails typecheck instead of a live page. The shared shell in `ui.ts` provides fonts, colors, buttons, inputs and the sticker vocabulary; keep new pages inside it.119120 120-To look at what you changed: `npm run dev`, then `node scripts/dev/dev-signer.mjs`, open `http://<name>.localhost:8787/`, paste the `window.nostr` snippet from that script into the devtools console, and sign in or claim. Playwright's CLI can drive the same loop: open the page, inject the snippet with `eval`, click, screenshot at a phone width and at a desktop width. `scripts/dev/shot.mjs` renders a page over the Chrome debugging protocol when Playwright is not around.121+To look at what you changed: `npm run dev`, then `npm run dev:signer`, open `http://<name>.localhost:8787/`, paste the `window.nostr` snippet from that script into the devtools console, and sign in or claim. Playwright's CLI can drive the same loop: open the page, inject the snippet with `eval`, click, screenshot at a phone width and at a desktop width. `scripts/dev/shot.mjs` renders a page over the Chrome debugging protocol when Playwright is not around.121122 122123 Rules that hold across pages: no middle dots, no purposeless subtext, tables scroll inside their card on narrow screens, decorative elements are not selectable, a multi-field form uses the labelled grid rather than one row of inputs, and the copy above a block is one sentence.123124 124125 ## Screenshots125126 126-`node scripts/dev/shot.mjs <url> <out.png> [width] [height]` renders a page with phone or desktop emulation over the Chrome debugging protocol and prints the layout's scroll width, which should equal the viewport width.127+`npm run dev:shot <url> <out.png> [width] [height]` renders a page with phone or desktop emulation over the Chrome debugging protocol and prints the layout's scroll width, which should equal the viewport width.127128 128129 ## Pull requests129130 @@ -168,13 +168,13 @@ The bridge takes the same header. `POST /events` answers `{ event_id, accepted,
168168 169169 `exportconfig` is a document, and a document can live in a repository. The format is `bind.ws/relay-config/2`: `policy`, `members`, `bans`, `addresses`, `banned_events`, `kinds` and `retention`, each a section, and a section the file leaves out is left alone when it is applied, so a file may carry the rules and nothing about people. The schema is at `https://bind.ws/relay-config.schema.json`; put it in `$schema` and the editor checks the file as you type. JSONC is fine: comments and trailing commas.170170 171-Four verbs, in `scripts/ops/relay.mjs`, with `RELAY_SK` holding the owner's key as hex or nsec:171+Four verbs, run from a checkout of the repository with `RELAY_SK` holding the owner's key as hex or nsec:172172 173173 ```174-node scripts/ops/relay.mjs check relay.jsonc # the schema and the relay's own parser, offline175-node scripts/ops/relay.mjs plan relay.jsonc wss://name.bind.ws # what applying would change; touches nothing176-node scripts/ops/relay.mjs push relay.jsonc wss://name.bind.ws # the plan, then the change177-node scripts/ops/relay.mjs pull wss://name.bind.ws relay.json # the relay as it is, into a file174+npm run relay check relay.jsonc # the schema and the relay's own parser, offline175+npm run relay plan relay.jsonc wss://name.bind.ws # what applying would change; touches nothing176+npm run relay push relay.jsonc wss://name.bind.ws # the plan, then the change177+npm run relay pull wss://name.bind.ws relay.json # the relay as it is, into a file178178 ```179179 180180 `check` fails on anything a relay would drop, since a silently dropped entry is a mistake in a file under source control. `plan` is `importconfig` with `{ dryRun: true }`: the answer lists the changes section by section with a `summary` line each, plus the entries the relay would not take. `pull` then `git diff` shows drift between the file and the relay.@@ -8,9 +8,9 @@ audience: developer
88 What a relay costs the host, what fuel charges for it, and how to keep the two apart as the bitcoin price moves. The numbers come from one script:99 1010 ```11-node scripts/ops/margin.mjs # today's price12-node scripts/ops/margin.mjs --btc 60000 # a price you pick13-node scripts/ops/margin.mjs --relays 5000 # the deployment at that size11+npm run margin # today's price12+npm run margin -- --btc 60000 # a price you pick13+npm run margin -- --relays 5000 # the deployment at that size1414 ```1515 1616 It prints markdown and exits with code 1 when any priced line is under the target margin. A GitHub Actions workflow runs it every Monday, puts the tables in the run summary and opens or refreshes one issue when a line is under target.@@ -54,7 +54,7 @@ The line to look for is `ok bucket conditional write: create, reject-create, upd
5454 5555 ## Configure5656 57-`wrangler.celld.jsonc` is the Worker's config for celld: the same code, bindings, migrations and prices as `wrangler.jsonc`, and only the keys celld accepts, since it stops on any other. `node scripts/check/check-celld.mjs`, part of `npm run typecheck`, fails when the two drift. Edit:57+`wrangler.celld.jsonc` is the Worker's config for celld: the same code, bindings, migrations and prices as `wrangler.jsonc`, and only the keys celld accepts, since it stops on any other. `npm run check:celld`, part of `npm run typecheck`, fails when the two drift. Edit:5858 5959 | Setting | Meaning |6060 |---|---|@@ -9,10 +9,18 @@
99 "test": "vitest run",1010 "test:conformance": "vitest run --config vitest.conformance.config.ts",1111 "typecheck": "tsc --noEmit && node scripts/build/build-signer.mjs --check && node scripts/build/build-console.mjs --check && node scripts/build/build-templates.mjs --check && node scripts/check/check-console.mjs && node scripts/check/check-celld.mjs && node scripts/check/check-config.mjs relay-templates/*.jsonc",12+ "relay": "node scripts/ops/relay.mjs",13+ "margin": "node scripts/ops/margin.mjs",1214 "build:signer": "node scripts/build/build-signer.mjs",1315 "build:console": "node scripts/build/build-console.mjs",14- "check:config": "node scripts/check/check-config.mjs",15- "build:templates": "node scripts/build/build-templates.mjs"16+ "build:templates": "node scripts/build/build-templates.mjs",17+ "check:celld": "node scripts/check/check-celld.mjs",18+ "dev:signer": "node scripts/dev/dev-signer.mjs",19+ "dev:seed": "node scripts/dev/seed.mjs",20+ "dev:stage": "node scripts/dev/stage.mjs",21+ "dev:junk": "node scripts/dev/junk.mjs",22+ "dev:shot": "node scripts/dev/shot.mjs",23+ "dev:zaptest": "node scripts/dev/zaptest.mjs"1624 },1725 "dependencies": {1826 "@noble/hashes": "^2.4.0",@@ -35,8 +35,8 @@ the relay serves as its presets; `npm run typecheck` checks every file here
3535 against the schema and the relay's parser, fails when the generated module3636 is stale, and fails when a file is missing from the table above.3737 38-To try one on a relay without applying it:38+To try one on a relay without applying it, from the repository root:3939 4040 ```41-node ../scripts/ops/relay.mjs plan 10-quiet.jsonc wss://<name>.bind.ws41+npm run relay plan relay-templates/10-quiet.jsonc wss://<name>.bind.ws4242 ```@@ -1,10 +1,10 @@
1-// Checks relay configuration files: node scripts/check/check-config.mjs <file.jsonc>...2-// Part of npm run typecheck for every template in relay-templates/.1+// Checks relay configuration files, part of npm run typecheck for every2+// template in relay-templates/. For one file of your own: npm run relay check <file>.33 import { checkConfig, describe, readConfig } from "./config.mjs";44 55 const files = process.argv.slice(2);66 if (files.length === 0) {7- console.error("usage: node scripts/check/check-config.mjs <file.jsonc>...");7+ console.error("usage: check-config.mjs <file.jsonc>...; for one file, npm run relay check <file>");88 process.exit(2);99 }1010 let failed = false;@@ -1,4 +1,4 @@
1-// Fills a relay with test files and reports, signed by the dev seed key. Usage: node scripts/junk.mjs https://<name>.bind.ws1+// Fills a relay with test files and reports, signed by the dev seed key. Usage: npm run dev:junk https://<name>.bind.ws22 import { finalizeEvent, getPublicKey } from "nostr-tools/pure";33 import { createHash } from "node:crypto";44 import { readFileSync } from "node:fs";@@ -1,4 +1,4 @@
1-// Screenshot a page with phone emulation over CDP. Usage: node scripts/shot.mjs <url> <out.png> [width] [height]1+// Screenshot a page with phone emulation over CDP. Usage: npm run dev:shot <url> <out.png> [width] [height]22 import { spawn } from "node:child_process";33 import { writeFileSync } from "node:fs";44 import WebSocket from "ws";@@ -1,6 +1,6 @@
11 // Stages a local relay for screenshots: claims it with the dev signer's key,22 // gives it a name and a description, and adds a few members. Run the dev3-// server first. Usage: node scripts/stage.mjs <name>3+// server first. Usage: npm run dev:stage <name>44 import { finalizeEvent, getPublicKey } from "nostr-tools/pure";55 import { getToken } from "nostr-tools/nip98";66 @@ -1,5 +1,5 @@
11 // Asks a relay for a fuel invoice from a signed zap request, to check the2-// lightning provider end to end. Usage: node scripts/dev/zaptest.mjs [wss://relay] [direct]2+// lightning provider end to end. Usage: npm run dev:zaptest [wss://relay] [direct]33 // With `direct`, the provider's LNURL callback is called straight, skipping the relay.44 import { finalizeEvent } from "nostr-tools/pure";55 const sk = new Uint8Array(32).fill(7);@@ -1,9 +1,9 @@
11 // Fuel prices against what Cloudflare bills, at today's bitcoin price.22 //3-// node scripts/margin.mjs tables, markdown4-// node scripts/margin.mjs --btc 77000 at a given price5-// node scripts/margin.mjs --target 0.4 a different margin target6-// node scripts/margin.mjs --relays 500 the deployment projection at that count3+// npm run margin tables, markdown4+// npm run margin -- --btc 77000 at a given price5+// npm run margin -- --target 0.4 a different margin target6+// npm run margin -- --relays 500 the deployment projection at that count77 //88 // Exit code 1 when a priced line sits below the target margin, so a weekly99 // run can raise a flag. Cloudflare rates are list prices for Workers Paid,@@ -1,10 +1,10 @@
11 // A relay's configuration as a file in your repository: check it, see what22 // applying it would change, apply it, or pull the relay's current one.33 //4-// node scripts/ops/relay.mjs check <file.jsonc>5-// node scripts/ops/relay.mjs plan <file.jsonc> <wss://name.bind.ws>6-// node scripts/ops/relay.mjs push <file.jsonc> <wss://name.bind.ws>7-// node scripts/ops/relay.mjs pull <wss://name.bind.ws> [file.json]4+// npm run relay check <file.jsonc>5+// npm run relay plan <file.jsonc> <wss://name.bind.ws>6+// npm run relay push <file.jsonc> <wss://name.bind.ws>7+// npm run relay pull <wss://name.bind.ws> [file.json]88 //99 // plan, push and pull sign as the owner: RELAY_SK holds the secret key, hex1010 // or nsec. check needs no relay. plan is importconfig with dryRun, so it@@ -18,7 +18,7 @@ import { checkConfig, describe, readConfig } from "../check/config.mjs";
1818 1919 const [cmd, a, b] = process.argv.slice(2);2020 const usage = () => {21- console.error("usage: relay.mjs check <file> | plan <file> <url> | push <file> <url> | pull <url> [file]");21+ console.error("usage: npm run relay check <file> | plan <file> <url> | push <file> <url> | pull <url> [file]");2222 process.exit(2);2323 };2424