blockyard 0.0.9 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +359 -1
- package/README.md +48 -27
- package/SECURITY.md +2 -2
- package/bin/blockyard.js +2 -1
- package/docs/API.md +17 -15
- package/docs/ARCHITECTURE.md +128 -10
- package/docs/CONFIGURATION.md +39 -30
- package/docs/DEFECTS.md +4 -1
- package/docs/GETTING-STARTED.md +18 -8
- package/docs/INSTALL.md +97 -37
- package/docs/MEASUREMENTS.md +147 -0
- package/docs/PLAN-SCORCHED-YARD.md +456 -0
- package/docs/PLAN-SKIES.md +142 -0
- package/docs/SECURITY-AUDIT-2026-09-16.md +647 -0
- package/docs/SECURITY.md +58 -22
- package/docs/TROUBLESHOOTING.md +44 -5
- package/docs/USER-GUIDE.md +505 -35
- package/package.json +4 -2
- package/public/404.html +1 -1
- package/public/css/app.css +393 -82
- package/public/donate-qr.png +0 -0
- package/public/index.html +353 -109
- package/public/js/agents.js +228 -51
- package/public/js/app.js +131 -16
- package/public/js/blockanoid.js +15 -7
- package/public/js/blockout.js +15 -7
- package/public/js/blockscene3d.js +230 -38
- package/public/js/charts.js +21 -21
- package/public/js/depthchart.js +31 -27
- package/public/js/details3d.js +1481 -73
- package/public/js/doom.js +31 -0
- package/public/js/dosaudio.js +48 -0
- package/public/js/dosgame.js +389 -0
- package/public/js/dosio.js +186 -0
- package/public/js/dospc.js +1353 -0
- package/public/js/dosworker.js +196 -0
- package/public/js/explorer.js +7 -1
- package/public/js/livingsky.js +494 -0
- package/public/js/login.js +8 -2
- package/public/js/markets.js +46 -8
- package/public/js/mining.js +314 -36
- package/public/js/panels.js +41 -28
- package/public/js/pricechart.js +14 -13
- package/public/js/quake.js +20 -0
- package/public/js/safenext.js +14 -0
- package/public/js/scorched.js +1051 -0
- package/public/js/scorchedai.js +227 -0
- package/public/js/scorchedair.js +286 -0
- package/public/js/scorchedfx.js +376 -0
- package/public/js/scorchedshop.js +105 -0
- package/public/js/scorchedwind.js +69 -0
- package/public/js/scorchedyard.js +1338 -0
- package/public/js/settings.js +368 -100
- package/public/js/soundcard.js +459 -0
- package/public/js/tetrust.js +15 -6
- package/public/js/tetsound.js +35 -5
- package/public/js/theme.js +235 -0
- package/public/js/wolf3d.js +22 -0
- package/public/js/x86.js +1978 -0
- package/scripts/check.js +46 -0
- package/scripts/donate-qr.py +12 -9
- package/scripts/dos-bench.js +56 -0
- package/scripts/index-build.js +9 -2
- package/scripts/pool-map.js +152 -36
- package/scripts/setup.js +142 -22
- package/scripts/shots.mjs +27 -0
- package/scripts/smoke.sh +7 -6
- package/scripts/tls.js +31 -0
- package/scripts/ui.js +4 -2
- package/server/auth/sessions.js +33 -13
- package/server/chain/blockfile.js +64 -5
- package/server/chain/index/build.js +451 -58
- package/server/chain/index/heights.js +29 -3
- package/server/chain/index/live.js +13 -7
- package/server/chain/index/rows.js +6 -1
- package/server/chain/index/store.js +28 -5
- package/server/chain/index/worker.js +23 -11
- package/server/collect/logparse.js +65 -18
- package/server/collect/markets.js +76 -7
- package/server/collect/mining.js +32 -0
- package/server/collect/monitor.js +54 -12
- package/server/collect/network.js +305 -0
- package/server/config.js +53 -22
- package/server/http/api.js +119 -18
- package/server/http/games.js +77 -0
- package/server/http/server.js +30 -5
- package/server/http/sse.js +53 -7
- package/server/main.js +66 -11
- package/server/rpc/allowlist.js +26 -0
- package/server/rpc/client.js +30 -2
- package/server/store/audit.js +6 -1
- package/server/store/history.js +19 -3
- package/server/store/ledger.js +15 -4
- package/server/tls/selfsigned.js +160 -0
- package/systemd/blockyard.service +41 -8
- package/docs/PRIVATE-LEADERBOARD.md +0 -230
- package/docs/STATE-2026-09-09.md +0 -200
package/CHANGELOG.md
CHANGED
|
@@ -6,7 +6,364 @@ All notable changes to this project are documented here. The format follows
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
## [0.1.1] — 2026-09-17
|
|
10
|
+
|
|
11
|
+
A day of hardening, and a new game. The headline is the **third AI security audit**, run on
|
|
12
|
+
2026-09-16 over the whole codebase by four auditors in parallel, and every one of its findings
|
|
13
|
+
fixed the same day with a test that holds it: one high (a client that opened the live stream and
|
|
14
|
+
stopped reading was never dropped, so memory grew without bound), eight medium, seventeen low and
|
|
15
|
+
six informational. The **address index** learned to resume an interrupted build instead of starting
|
|
16
|
+
its hours-long read again, and is now checked in the suite against a second, deliberately naive
|
|
17
|
+
implementation; property tests over Bitcoin Core's file formats found and fixed three flaws in
|
|
18
|
+
reading undo data. The **skies** were made clear: every board picks the Galaxy or the Earth sky in
|
|
19
|
+
one place, and the Earth sky gained a warm sun with a halo, a moon that glows through its real
|
|
20
|
+
phases, and softer clouds. And under Diversions, **Scorched Yard**: Scorched Earth on the block
|
|
21
|
+
engine, with the manual's weapons and computer players, up to eight tanks, a cheat mode that draws
|
|
22
|
+
the firing solution, and wind that is a real fluid simulation flowing over the hills. The games now
|
|
23
|
+
load only when their page is first opened. 1,068 tests, from 945.
|
|
24
|
+
|
|
25
|
+
### Upgrading from 0.1.0
|
|
26
|
+
|
|
27
|
+
- **Node.js 22.2 or newer** is required (was 22.0): the resumable index build uses Node's built-in
|
|
28
|
+
CRC-32.
|
|
29
|
+
- **With accounts off, the node connection form works only from the monitor's own machine**
|
|
30
|
+
(`127.0.0.1`). `auth.openNodeConfigFromNetwork: true` restores the old reach; with accounts on,
|
|
31
|
+
an admin can use it from anywhere, as before.
|
|
32
|
+
- **Wallet RPCs are refused** in the RPC console, reads included (`getbalance`, `listunspent`, …).
|
|
33
|
+
- **The shipped systemd unit is sandboxed.** If you install it again, edit its `ReadWritePaths=`
|
|
34
|
+
lines to your install's `data` and `config` directories, and add your address index directory.
|
|
35
|
+
- **The address index build refuses a directory** that holds anything an index does not write, a
|
|
36
|
+
symlink, or a home, working or blocks directory. Point `addressIndex` at a new or empty
|
|
37
|
+
directory, or at an existing index.
|
|
38
|
+
- **Sky settings are migrated** from the old global sky and per-board star switches to one Sky
|
|
39
|
+
choice per board; each board keeps what it drew.
|
|
40
|
+
- **`scripts/pool-map.js`** asks before replacing the pool map (`--yes` to skip), and
|
|
41
|
+
**`scripts/setup.js`** takes the RPC password from `--rpc-password-file` or stdin; the plain
|
|
42
|
+
`--rpc-password` still works, with a warning.
|
|
43
|
+
|
|
44
|
+
### Security
|
|
45
|
+
|
|
46
|
+
- **The third audit's low and informational findings, fixed the same day** (`docs/SECURITY-AUDIT-2026-09-16.md`, tests in `test/audit-2026-09-16-low-*.test.js`), so every finding of that audit is closed. *Browser*: the post-sign-in redirect stays on this site; the page's key-value lists escape every value unless it is markup the page built, and the server passes the node's chain name, pruned and IBD flags and unbroadcast count on only in their own types; RPC URLs shown to viewers lose any username and password; viewers see the last two parts of cookie, log and settings paths; a malformed explorer link opens the explorer's home. *HTTP*: a malformed escape in a route is a 400; the sign-in lockout is per username and address, so one address can no longer lock an account for everyone (an address trying many accounts, or an account tried from many addresses, still locks at a higher count). *Collectors*: a coinbase with a truncated push no longer throws or stalls pool attribution; an order book far from the others is not drawn, the depth grid is capped and market responses are size-capped with redirects refused; long log lines can no longer take seconds to parse. *Index*: the height table is sized from the tip and cannot loop; a transaction whose input count disagrees with its undo record fails the build; a lock file stops two builds sharing a directory; files are created owner-only and temporary files are never written through a symlink; `--workers` is validated; malformed self-written files are cut or skipped rather than crashing. *Scripts and supply chain*: `setup.js` no longer echoes the RPC password and takes it from a file or stdin; `pool-map.js` refuses non-HTTPS redirects and shows a diff before replacing the map; CI actions are pinned to commit hashes; `config/*.bak-*` is ignored; the game files have a hash manifest. `SECURITY.md` names 0.1.x as supported, and the smoke script's open-access instance now really opens access
|
|
47
|
+
- **The third audit's high and medium findings, fixed the same day** (`docs/SECURITY-AUDIT-2026-09-16.md`, tests in `test/audit-2026-09-16.test.js`). *Stalled stream readers*: a client whose socket is full is sent nothing more until it drains (the newest snapshot waits, as the stream's comments always claimed), and is dropped at 4 MB buffered or after a minute blocked; one address or account holds at most 16 streams. *Open mode and scripts*: with accounts off, the node connection form (save and test) answers only a caller on this machine's loopback address, since a browser check cannot stop a script; `auth.openNodeConfigFromNetwork` restores the old reach. A save that moves the node to another host drops the old endpoint's `rpcUser`, `rpcPassword` and `cookieFile`, and testing a foreign endpoint reports the kind of failure, never what it answered. *The index build* refuses a symlink, the filesystem root, a home or working directory, the node's blocks directory, or a directory holding anything an index does not write, and only ever removes its own files. *Wallet RPCs* are all refused by name, reads included. *Request bodies* must arrive within 30 seconds; the event stream is unaffected. *Audit rows* clamp every string to 1,024 characters. *The npm package* no longer includes the gitignored private notes, and a test holds it to tracked files. *The shipped systemd unit* is sandboxed (`ProtectSystem=strict` with `ReadWritePaths` for `data/` and `config/`, `ProtectHome=read-only`, no capabilities, a system-call filter, `UMask=0077`), and the app was started and exercised under exactly those settings
|
|
48
|
+
- **Third AI security audit** (`docs/SECURITY-AUDIT-2026-09-16.md`), every finding fixed the same day (above). One high: a client that opens the live event stream and stops reading is never dropped, and 400 such connections took a test instance from 73 MB to 1.5 GB in three minutes. Eight medium: in open mode a script (not a browser) can rewrite the node connection and receive the node cookie after a restart, and can use the connection probe to read internal URLs; the address index build deletes its output directory recursively without checking it; the RPC console admits `listdescriptors` and `gethdkeys`, which return private keys from an unlocked wallet; request bodies have no read deadline; oversized RPC method names flush the audit trail; the npm package includes the gitignored private notes; the shipped systemd unit is barely sandboxed. Seventeen low and six informational. Both earlier audits' fixes re-verified
|
|
49
|
+
|
|
50
|
+
### Address index
|
|
51
|
+
|
|
52
|
+
- **An interrupted address index build resumes.** Stopping BlockYard, Ctrl-C in the installer, a crash or a reboot used to throw away the whole build, which reads about 880 GB and runs for hours on a shared disk. The build now keeps a small journal beside its output, written atomically with a checksum of its own contents, and the next start carries on from it: block files already scanned are not read again, and buckets already sorted are not sorted again. Nothing it cannot prove finished is used: the bucket files are cut back to the length the journal recorded, so rows from a file that was half appended are gone, and a bucket about to be sorted is checked against the length and CRC-32 the scan recorded. The resumed index is byte for byte the one an uninterrupted build writes, which the tests check after stops at seven points, from the directory the stopped build left and from a copy taken at the instant of the stop. A journal for another index format or file selection, for a tip the node's chain no longer has, or that is torn or damaged is thrown away, the log says why, and the build starts over. The manifest is still written last. The progress and its ETA pick up from the resumed position. Also fixed on the way: a worker that died between two jobs left the pool waiting for it forever, and when two things went wrong at once the build reported the second rather than the cause
|
|
53
|
+
- **Fixed: three flaws in reading Bitcoin Core's undo files, found by new property tests.** The suite now generates thousands of seeded encodings (CompactSizes, Core VARINTs, compressed amounts, undo records, legacy and segwit transactions, blocks, block and undo files), checks each decoder against an oracle written from Core's format, and truncates and flips bytes to hold every decoder to throwing or decoding exactly. An output amount above about 10 million BTC was rounded when read, and is now exact. An undo record cut inside its last script was accepted as whole, and is now refused. A corrupt VARINT could decode as an enormous height, and is now refused past Core's own 32-bit limit. No real chain data reaches the first flaw
|
|
54
|
+
- **The address index is checked automatically against a second implementation.** Until now its correctness was checked by hand, with scripts against a live node, and history had no independent check at all. The suite now builds a seeded synthetic chain (301 blocks, 6,346 transactions, 384 addresses across eight script types, XOR-obfuscated block and undo files with a stale block and reordered, duplicated records), indexes it with the real build, and compares every address's balance and whole history, walked through the store's paged queries past the counting limit, with a deliberately naive replay of the UTXO set that shares no indexing code. It compares again after the live follower folds and merges sixty more blocks, after a reorganisation inside the tail and a restart, and asserts a reorganisation into folded layers is refused as stale. It found no discrepancy; it fails on each of five deliberately introduced faults. About three seconds
|
|
55
|
+
|
|
56
|
+
### Performance
|
|
57
|
+
|
|
58
|
+
- **Games load when first opened.** The seven games (Tetrust, Blockout, Blockanoid, Scorched Yard and the three DOS ports) were imported by the app shell at startup, so every page paid for all of them. They are now fetched the first time their page is opened: the modules loaded at startup drop from 39 to 21, and from 1.42 MB to 1.09 MB. A failed load shows a message and is retried on the next visit. A test holds the shell's static imports free of any game module
|
|
59
|
+
|
|
60
|
+
### Skies and lighting
|
|
61
|
+
|
|
62
|
+
- **The moon glows, and its phases can be watched.** The same two-layer halo the sun has, in moonlight silver, stronger the fuller the moon. The phase has always followed the real calendar (full on the real full-moon dates, new on the new ones, the quarters between); under the cycle clock, where a day is 24 minutes, the calendar now runs a day per cycle day, so a whole month of phases goes by in about twelve hours on the wall. The disc is a little larger
|
|
63
|
+
- **The sun has a halo, and no rings.** Its soft edge was twelve steps, which on a big panel is several pixels a step and showed as concentric rings; the ring counts are left to the fill's own rule now, about one a pixel. And a halo in front of the clouds, a wide faint corona and a tighter bright one, so the sun sits in its own light rather than being a coin on the sky
|
|
64
|
+
- **The Earth sky's cirrus is gas, not a chain of discs.** Each high wisp was a row of hard-edged flat discs fourteen pixels apart, and where they overlapped the outlines stacked into a visible row of rings. A wisp is a scatter of soft-edged puffs now, built the way the cumulus is, jittered off the line and stretched along it, so nothing in it has an edge to band
|
|
65
|
+
- **The Earth sky's sun and moon are there to be seen.** The sun is half again as big and its disc is drawn in front of the clouds (its glow still behind them), so it is no longer a pale spot under a cumulus at noon; the moon likewise. A board can say where its horizon is — Scorched Yard's land fills the lower third, so its sun sets behind the hills instead of under them. And a **Moon** choice under the Earth: up every night, highest at midnight and never thinner than a fat crescent (the shipped choice), or its real track and phase, which some nights means no moon at all
|
|
66
|
+
- **One sky per board: the Galaxy or the Earth** (docs/PLAN-SKIES.md; operator: "The skybox settings are not clear in the preferences, for which sky settings apply to which panel"). There were two skies described from two directions and no board named anywhere: one global Space-or-Living switch for every board at once, six scattered "Star field" toggles that under the living sky meant "draw the day or draw nothing", and four private galaxy switches beside the Sky tab's own. Now: the Sky tab opens with a table of every board that has a sky and the one it draws — Block space (and the Kiosk's left panel), Markets & Price (and its right), Tetrust, Blockout, Blockanoid, Scorched Yard — each a select for **Galaxy**, **Earth** or **None**; below it, the two skies with only their own controls, never dimmed. Each board's tab carries the same one **Sky** choice in place of its old star and galaxy toggles, and the games' panels have one **sky** button round the three. The star-field sky is named the **Galaxy** (not Space, which is Block space's word), its arms toggle is **Spiral arms** and its placement **Arms centre**; the living sky is the **Earth**. Scorched Yard ships under the Earth, everything else under the Galaxy. A stored setting comes forward drawing exactly what it drew: stars off becomes none, stars on becomes whichever sky the old global switch named; the step is idempotent, because server-stored settings carry no version and re-run it on every boot
|
|
67
|
+
- **A board can ask for a harder lamp.** The renderer put every face of every cube between 0.34 and 0.86 of its own colour with the top at 0.8 — a narrow band, which reads as tinted rather than lit. `lightGain` stretches that range about its middle and `topLight` sets where the tops sit; 1 and 0.8 are exactly what every board drew before. Scorched Yard's field uses a hard lamp at the viewer, so the front of the land carries the light and the strata separate
|
|
68
|
+
- **The sun is not white.** The Living sky's sun ran to a near-white disc at noon; it is deep orange on the horizon and warm gold overhead now, which is what a sun looks like to an eye rather than to a camera
|
|
69
|
+
- **The Living sky no longer depends on the Star field switch.** With the Living sky chosen and that switch off, every board went black: a control about stars was hiding the whole day. A board that asks for the Living sky now draws it whatever the star switch says, and the star field still comes out at night by itself
|
|
70
|
+
- **The deep sky belongs to the star field.** The spiral galaxy, nebulae, dust lanes, halo clusters and distant galaxies are off while the Living sky is drawing, the way the Space effects already are, and their rows in Display settings → Sky are dimmed and say "Star field only" (the Living sky's own rows dim the same way under Space). Nothing is forgotten: choosing Space brings them all back as saved. Scorched Yard's panel hides its star and galaxy switches under the Living sky for the same reason
|
|
71
|
+
- **The Block space lamp hangs in six places at three heights**: straight above, top left, top right, bottom left, bottom right, or at the viewer, each low, middle or high (Display settings → Block space → Light and Light height). A saved upper-left, upper-right or front comes forward as top left, top right and the viewer
|
|
72
|
+
- **The Living sky**: a second sky type (Display settings → Sky → Sky: Living sky) for every board that draws a sky — a real day from this machine's clock. The sun rises on the left and sets on the right, the dome passes through night, dawn, day and dusk by the sun's altitude, a twilight glow stands at the sun's side, clouds drift lit from the sun (cumulus in clusters of soft discs, cirrus above them), the moon comes up at tonight's phase with its terminator, and the star field fades in as the sun goes down. A clock setting (real time, a day every 24 minutes, a fixed hour), weather (clear, scattered, overcast, storm with rain and lightning), cloud cover, an optional latitude for real sunrise and season, and switches for crepuscular rays, a rainbow and shooting stars. Drawn under the same canvas rules as everything else (no gradients or blend modes: the dome is one huge soft disc cached until the sun moves half a degree). The Space effects are off while the Living sky is on, their switches kept
|
|
73
|
+
|
|
74
|
+
### Scorched Yard
|
|
75
|
+
|
|
76
|
+
- **Scorched Yard: the rest of the control plan.** *Correcting*: click an enemy tank to mark it; after your shot the panel says how it did against it (*10 over*, *6 short*, *close*, *hit*) and **C** sets the power that miss implies, from your own last shot. *Weapons*: **W** opens a grid of what you own, biggest blast first, with counts and keys; **1–9** pick in the shop's order; **Q** picks your last weapon; the item pills are buttons. *The aim guide*: a ghost of the first fifth of the flight while you aim, or the whole flight, or off. *The fire button* names what it will send, and the last of a weapon sold one at a time asks once before it goes. A press on your own tank turns the barrel without touching the power. The keys are a table. Three new settings: Aim guide, Correction helper, Confirm the last of a weapon
|
|
77
|
+
- **Scorched Yard: the old wind code is gone.** The four earlier wind pictures (marching particles, dashed currents, a plasma wash, bowing bands), the smoke dye the fluid first carried, and the air clock only they used are deleted, with the tests that covered only them: the wind module drops from about 400 lines to 69, and the air module loses its dye grid. What is drawn is unchanged — the simulated air, its flow lines, and the sky's faint ripple
|
|
78
|
+
- **Fixed: Scorched Yard's computer players seemed to aim at tanks already destroyed.** A computer player chose its shot only when its thinking pause ran out, so for the whole pause its gauge (and, in cheat mode, its trajectory) still showed its previous shot, usually aimed at the tank it had just destroyed. It now plans the moment its turn begins, against the tanks alive then, and its barrel and power ease from the old aim to the new one while it thinks. Cheat mode draws only your own firing solution. And the random shot that the Moron fires, and that the Shooter and Poolshark fall back on, heads toward a living enemy instead of the middle of the field, which had kept shelling the empty half once the tanks there were gone: in 4,357 simulated shots none now fires away from every tank still standing, against 20 before
|
|
79
|
+
- **Fixed: Scorched Yard froze when the land was blown up.** Measured on a nuke in the browser: frames of 150 ms, and 136 frames over 33 ms in seven seconds. Four causes, each measured and fixed. The simulated air re-ran six seconds of warm-up and read the land canvas back from the GPU on every crater; it now does that only for a new round's land, and a crater moves the air's floor from the rules' own column heights. The land's redraw used the renderer's general paint sort, which builds an outline for every cube and tests pairs for overlap, 43 ms for 1,800 resting cubes twice a blast; resting land now draws in a known order (back rows first, columns outside in), pixel-identical in a full-canvas diff and 7 ms. The flow lines were 5,500 separate round-capped segments a frame; they are continuous paths at half the points. And the wind layer redrew at sixty frames a second during every shot; it is held to thirty, and the effects' soft fills name a modest ring count rather than one per pixel of radius. The same nuke now runs with a worst frame of 33 ms, like the idle game
|
|
80
|
+
- **Scorched Yard: the flow lines fade out at the edges instead of vanishing.** A tracer was removed the moment it crossed the field's edge, so its whole line disappeared at once. Each line segment now fades by how near it is to the left, right or top edge, and a tracer runs on past the boundary, out of sight and already faded, before it is reborn
|
|
81
|
+
- **Scorched Yard: the simulated air is shown as streaklines, not smoke.** Any soft density drifting across the sky reads as smoke however it is tuned. The picture is now the wind-map kind: 320 weightless tracers carried by the simulated velocity, each drawn as a thin line along its recent path, so the lines curve where the air curves — up over a hill, round the eddy behind it. They taper to nothing at both ends with no bright head, and the whole field is four strokes, about a millisecond and a half to draw. The simulation's smoke is no longer computed in the game, which also brings its per-frame cost back to under half a millisecond
|
|
82
|
+
- **Scorched Yard: the air is an actual fluid simulation.** Every earlier wind effect was kinematic, sprites and finally sine curves told where to be at a given moment, so nothing in them could flow round anything. The wind layer now runs a small Stable Fluids solver (96 by 48 cells, about half a millisecond a step): the wind drives the air toward its speed and direction, the land is the solid floor so the air rises over the hills and rolls into eddies behind them, vorticity confinement keeps the eddies alive, and streams of smoke breathed in on the upwind edge are carried, bent and pulled apart by that flow. A new round's land gets eight simulated seconds of warm-up, so the air is already flowing when it is seen; a change of wind turns the air round by its own momentum. The smoke's opacity is compressed so thin smoke downstream stays visible and the dense streams at the edge do not dominate, and it reads stronger against a bright sky than a dark one. The bowing bands are gone; the faint refraction of the sky underneath stays
|
|
83
|
+
- **Scorched Yard: twice the bands of air, and they hold up in daylight.** Ten bowing bands instead of five. Pale air on a pale blue sky has a fraction of the contrast it has on black, so the bands sample how bright the sky behind them is every second and a half and carry up to about three times more at noon, and no more than before at night
|
|
84
|
+
- **Scorched Yard: the wind is seen by what it does to the sky.** Every streak had a bright head and a fading tail, which is the shape of a meteor, so on a starry sky the wind read as shooting stars. The streaks and the dashed currents are gone. The sky behind the land now refracts: it is copied across the wind plane in narrow columns, each lifted or lowered by a wave that rolls downwind at the wind's speed, so the stars, the moon and the clouds sway a few pixels as if seen through moving air; the land in front is untouched. Over it, a handful of broad, faint bands of air bow as they cross, with no head and no point anywhere in them. Both follow a signed distance the air has travelled, so they only move downwind and bend round through zero when the wind turns, and neither draws anything in still air
|
|
85
|
+
- **Scorched Yard: the air at half the count, tuned for night as well as day.** Each particle is a little brighter and thicker with a longer tail, so the wind still reads at a glance with half the particles it had; the currents are few, thin and faint, since on a dark sky at a strong wind they were a wall of dashes
|
|
86
|
+
- **Scorched Yard: half the air particles.** The wind layer runs half as many particles as it did (at most 210 on a wide panel, down from 420); the tails and the currents carry the motion, so the picture keeps its flow at half the per-frame cost
|
|
87
|
+
- **Scorched Yard: every one of the twenty-seven shells that fly looks like itself.** Every projectile was the same white dot. Each weapon now has its own entry: its core colour and size, a glow in its colour, a trail in its manner at its own length, count, width and colour, and a ring for the heavy ones. Within a family the baby is small and pale, the plain one middling, the heavy one big, dark and ringed, so a missile is not a baby missile and a Death's Head is not a MIRV. The manners: a missile's exhaust, a nuke's pulsing green glow and falling sparks, a comet tail for the MIRV, the Leap Frog and the Death's Head, a Funky Bomb's rainbow (its bomblets spin it faster), a tracer's thin grey dots and no glow, a smoke tracer's grey puffs, sparks behind the rollers, pale wisps behind the riot bombs, shed clods behind the dirt shells and droplets behind liquid dirt, flickering fire and dripping embers on napalm and a blue-white flame on hot napalm, spinning arms of glint on the diggers and sandhogs
|
|
88
|
+
- **Scorched Yard's land is brighter.** The tanks and the land go through the same lamp; the tanks looked lit because their paint is bright. Each stratum is lifted a fifth to a quarter in value at the same saturation, so the front of the land sits where the front of a tank does
|
|
89
|
+
- **Scorched Yard: the mouse drag clicks.** The keys and the wheel clicked as the aim moved; dragging on the field was silent. It clicks on every whole degree and every ten of power it crosses, no more than every 45 ms, so a slow drag ticks and a fast one whirs
|
|
90
|
+
- **Fixed: Scorched Yard's panel showed the wrong tank's cash while you shopped.** A purchase always took the money; the "This turn" panel was showing the tank whose turn it was when the round ended, and when that was a computer player its cash sat there unmoved while yours went down in the shop's own header. Between rounds the panel shows the human, marked "shopping"
|
|
91
|
+
- **Scorched Yard: vibrant strata, and a lamp that no longer bleaches them.** The land's five strata were dust-and-shadow browns that read as tinted whatever the lamp did; they are the same strata at full saturation now — hot magma, slate rock with some blue in it, terracotta clay, golden soil, a green that is green. The lamp gain comes down from 2.15 to 1.7: the front face sits at about 1.1 of its own colour and the face turned away under 0.2, where the higher gain had pushed the front past the point a channel clips and a saturated colour goes pale, which was the wash that kept being reported
|
|
92
|
+
- **Fixed: tanks in the air and in the ground after a new Scorched Yard game.** The land canvas was redrawn only when the land's version number moved, and a fresh game restarts that count where the last one began, so a new game after changing the opponent count (or a restart before a shot) placed the new tanks over the old terrain. The cache is cleared on every new game and every new round. The placement itself was always right: a test now stands three, five and eight seats on their ground over forty seeds each
|
|
93
|
+
- **Scorched Yard: the air is a steady flow with currents.** Reborn particles used to re-enter at the upwind edge, so in a light wind the field was dense there and empty downwind, and the density itself read as a front rolling in; a particle that runs out of life is reborn anywhere now, and only one that leaves the field comes back at the edge. Each particle carries a tail, drawn as a ribbon that thins and fades, so what moves reads as carried rather than as dots. And the currents themselves are drawn: a few dozen streamlines traced through the same field, bending round the same eddies, animated by a dash offset that runs downwind at the wind's speed
|
|
94
|
+
- **Fixed: Scorched Yard's air rushed backwards through a change of wind.** The wind layer's wash and its eddies took the page's clock and multiplied it by a rate that depended on the wind, so on a page a day old the smallest change in the wind moved them by a day's worth of travel, and flipped them end to end when the direction turned. The air keeps its own clock now, integrated a frame at a time at the current wind's rate: a change of wind changes how fast it runs from there on, and nothing else. And the field no longer scrolls its two octaves against each other vertically, which read as motion against the wind: it morphs in place, and the wind's drift is the only travel there is
|
|
95
|
+
- **Scorched Yard: eight seats.** Computer players go up to seven, for the original's eight-tank table; two is still the shipped game. Eight distinct tank colours, and the field seats eight without overlap
|
|
96
|
+
- **Scorched Yard: cheat mode.** A switch on the panel and in Display settings draws the firing solution while you aim: the shell's own path under this round's wind and the game's gravity, clipped where it would meet the dirt, with a ring where it lands. It is recomputed every frame the aim moves, so the arc bends live under the wind. It is the rules' own trajectory, so what it draws is what the shot does
|
|
97
|
+
- **Scorched Yard: the air is a flow field.** The wind layer is no longer dashes told where to be at time t: it is particles advected through the curl of a drifting noise field, over a faint plasma wash of the same flow, so what moves is material being carried, bent by eddies on the way. The swirl is capped at a third of the base wind, so every particle nets downwind and no streak ever points upwind. A change of wind bends the flow into the new speed and direction over half a second instead of swapping layers
|
|
98
|
+
- **Scorched Yard: the wind's strength changes every turn, its direction once a round.** Holding both for a whole round made the wind something you read once and forgot; holding neither was the flip-flop that started this. The round draws a direction and keeps it, and every turn draws a fresh strength within it
|
|
99
|
+
- **Scorched Yard: the air runs at one steady speed.** The wind layer carried a gust — a slow wave that lengthened and quickened every streak together by a third either way. It never reversed (measured frame by frame, no streak ever moves upwind) but a stream that surges and eases while the gauge reads one number does not look like that number. The gust is gone: the streaks advance at exactly the rate the gauge says
|
|
100
|
+
- **Scorched Yard: a restart button.** A war is five rounds, and a player knocked out in round one had nothing to do but watch the computer finish it. **Restart** on the panel, or **F2**, starts a fresh war from round one at any moment, and a knocked-out player is told so
|
|
101
|
+
- **Scorched Yard: the wind changes by crossfade, and says which way it blows.** A new wind used to replace the old one between two frames, so every streak jumped. The old air thins away while the new air comes up over it, already at its own speed and in its own direction, over about half a second; the new one leads, so the direction is readable long before the old one is gone. A row of chevrons at the top of the field points downwind, as many as the wind is strong, brightest just after a change
|
|
102
|
+
- **Scorched Yard's wind holds for a round.** A new wind mode, **Once a round**, is how the game ships: the wind is drawn when the round starts and keeps its direction and its strength until the round ends, so the air blows one way while you read it and every shot in the round is judged against the same gauge. The original's every-turn wind is still there under Display settings → Scorched Yard → Wind, and it can still turn right around between two shots
|
|
103
|
+
- **Fixed: nothing could be bought in Scorched Yard's shop.** Every panel decided whether to redraw by comparing its new markup with `box.innerHTML`, which a browser hands back normalised, so the comparison never matched and the markup was rebuilt on every draw. That was harmless while the board only drew on events and fatal once the wind kept it drawing thirty times a second: a button replaced between the press and the release is never clicked. Each panel remembers what it wrote, and the shop keeps its scroll position when something is bought
|
|
104
|
+
- **Scorched Yard's controls, the first step of the rescoped plan.** A held arrow accelerates (one a step, then two, then five, so the whole arc is about a second and a half and the last degree is still one press); Shift is fine and Ctrl coarse, and the keys line says so; **, and .** nudge the power by one for bracketing; the **wheel** over the field changes power, and with Shift the angle; **click the angle or the power** on the panel and type it; **R** fires the last shot again
|
|
105
|
+
- **Scorched Yard's explosions are painted, not built out of tiles.** The renderer already knew how to draw a firework — a white core, a shockwave, sparks that curve and trail and twinkle, and smoke built from flat discs that add up to a soft cloud — and a shell landing now draws with the same machinery, through the board's own projection, so the fire is exactly over the crater it made. A tank going up takes its own colour, and the dirt's dust is a low puff. `details3d` gained one seam for it: a board may hand the renderer an `overlay` to paint after the cubes, with the projector and `softStops`
|
|
106
|
+
- **Scorched Yard: the aim gauge.** A protractor stands over the tank whose turn it is — ticks every fifteen degrees, the round numbers written in, a needle along the current angle whose length is the power, and the angle and power printed at its tip. It dims for a computer player's turn, so you can see what it is about to do
|
|
107
|
+
- **Scorched Yard is lit from the viewer.** The field was lit from straight overhead, which lit the tops of the cubes and left every face you actually look at on one flat shade. The lamp stands low and at the viewer now, so the front of the board carries the light and the strata separate
|
|
108
|
+
- **Scorched Yard, the wind is its own flat layer.** It used to be tiles in the 3D field: they bobbed as they crossed, they were drawn over the hills they should have passed behind, and a gust that eased off dragged them backwards (the wind appeared to change direction while you were thinking). The air is now a plain 2D plane between the sky and the land — level streaks whose length is the wind's speed, in three bands of depth, the land in front of them hiding whatever goes behind a hill. It keeps blowing while the board is idle, at its own rate, and only ever blows one way
|
|
109
|
+
- **Scorched Yard, the blast is made of blocks.** The fireball, the shockwave, the embers and the smoke were spheres, and the engine gives a sphere a rim and a glint, so an explosion was a heap of bubbles on the dirt. They are blocks now, like the land, the tanks and the shells: a fireball on the field's own grid, hot at the centre and dark at the rim, a ring racing out, embers thrown on ballistic paths, and smoke that rises, spreads, drifts downwind and thins by its alpha rather than shrinking away
|
|
110
|
+
- **Scorched Yard, attract mode** (M5): a **watch** switch on the game's panel (and Display settings → Scorched Yard → Attract mode) hands your chair to another computer player — every seat is a computer player, a round rolls into the next without waiting at the shop, and when one of them wins the war a fresh one begins. Nothing is written to the high-score table for a war nobody played
|
|
111
|
+
- **Scorched Yard**: the field runs to the frame's edges and its bottom (no sky under or beside the land); the wind is visible — motes of dust drift across the field at its speed and in its direction, a pennant on every turret streams downwind and lifts with the strength, and under the Living sky the clouds drift with the round's wind
|
|
112
|
+
- **Scorched Yard, the look** (M4): a shockwave ring and smoke that rises, grows and drifts on the wind after every blast; a tank's death as sparks in its colour and three pieces of hull tumbling; dust where fallen dirt lands; a tank's fall animated, by gravity or slowly under a drawn parachute; tracks under the hull; the tanks talk ("Nuke 'em!", "Ouch!", "Tell my wife…") in a bubble over the field; a march in D minor as the game's music; under the Living sky each round draws its own hour; music, talk and per-round-sky switches; a screenshot in the guide
|
|
113
|
+
- **Scorched Yard, the computer players** (M3): the manual's eight personalities — Moron, Shooter (straight shots), Poolshark (bank shots off rubber walls), Tosser (lobs, correcting by halves), Chooser (the best of the three), Spoiler (nearly perfect, from the wind and gravity), Cyborg (a Spoiler with a grudge for whoever hit it, the weakest, the leader), Unknown (drawn each round) — planning with a side-effect-free shot simulator that carries the walls, the dirt and the tanks; they use batteries and shields before firing and shop to their tastes; a setting fields a mix or one kind
|
|
114
|
+
- **Scorched Yard, the roster and the shop** (M2): the manual's thirty-three weapons at the manual's prices, packs and blast radii (SCORCH.DOC) with the original's behaviours — the four blasts, Leap Frog's three growing warheads, Funky Bomb, MIRV and the nine-head Death's Head, the tracers, three rollers, the riot charge and blast as wedges cut from the turret, the riot bombs, the dirt shells, liquid dirt that oozes and fills, the dirt charge, the earth disrupter, napalm that flows and burns, the diggers and sandhogs that bore, plasma thrown from the tank, the laser — and eleven accessories (Shield, Force and Heavy shields, Mag Deflector and Super Mag, parachute, battery, auto defense, fuel, contact trigger, heat guidance); the manual's six wall modes with none as the default; several shells in flight at once; cash for damage, kills and survival, interest between rounds, and the shop in the round-end overlay; the items line and cash on the HUD; keys to drive, heal, shield and arm; the computer players shop too; fire and beams on screen
|
|
115
|
+
- **Scorched Yard, the first cut** (docs/PLAN-SCORCHED-YARD.md, M1): Scorched Earth on the block engine, under Diversions. A 96×48 field of dirt cubes drawn as runs by stratum, tanks with a turning barrel, a shell that flies under gravity and wind with the original's angle and power, craters, dirt that falls and settles, fall damage, death and its blast, the four wall modes, four missiles, one human against two computer players (the Moron; more opponents and personalities to come), turns, a game of rounds, a HUD with the wind and every tank's health, the mouse to aim, a high-score table, and a settings group for the rules
|
|
116
|
+
|
|
117
|
+
## [0.1.0] — 2026-09-16
|
|
118
|
+
|
|
119
|
+
The first minor release, two days after the initial 0.0.9, and everything since it in one place:
|
|
120
|
+
the 0.0.10 that was prepared on 2026-09-15 was never published, and its changes ship here. Four
|
|
121
|
+
things shaped it. The **first outside review** of 0.0.9 on bitcointalk, which called out a monitor
|
|
122
|
+
that bound every interface with no sign-in: 0.1.0 ships hardened — this machine only, sign-in on,
|
|
123
|
+
HTTPS with a certificate it makes itself, and no outbound connection at all until the exchange
|
|
124
|
+
feed is switched on. A day of **use on a laptop screen**, which found every tab a scroll: every
|
|
125
|
+
page now packs to one screen at 1093×945, and the Mining tab follows mempool.space's dashboard
|
|
126
|
+
with its **View more** panels. **Appearance**: the layout's colours are a setting — light or
|
|
127
|
+
dark, five themes, or nine colours of your own. And the **DOS Diversions**: Wolfenstein 3D, DOOM
|
|
128
|
+
and Quake, unmodified shareware on a PC emulated in the browser, written here with no
|
|
129
|
+
dependencies, because "can it run DOOM?" deserved a straight answer. 945 tests, from 862.
|
|
130
|
+
|
|
131
|
+
Upgrading from 0.0.9: [docs/INSTALL.md §11](docs/INSTALL.md#11-updating) — the first start after
|
|
132
|
+
the update serves HTTPS, creates the `admin` account and prints its password once.
|
|
133
|
+
|
|
134
|
+
### Security
|
|
135
|
+
|
|
136
|
+
- **Hardened defaults** (after the first outside review of 0.0.9): the monitor binds `127.0.0.1`
|
|
137
|
+
and requires sign-in out of the box — the first start creates the `admin` account and prints its
|
|
138
|
+
password once (or takes `BLOCKYARD_ADMIN_PASSWORD`). Reach it from elsewhere over an SSH tunnel,
|
|
139
|
+
or bind a LAN address with `BLOCKYARD_BIND` / `server.hosts`; open read-only access is a choice
|
|
140
|
+
(`BLOCKYARD_AUTH=0`), announced at boot. The boot banner says how to reach a loopback-only
|
|
141
|
+
monitor. Existing installs keep whatever `config/local.json` says.
|
|
142
|
+
- **HTTPS by default.** Every listener serves HTTPS; with no certificate named, the first start
|
|
143
|
+
makes the monitor its own self-signed one under `<data>/tls/` — written without dependencies
|
|
144
|
+
(`server/tls/selfsigned.js`: a v3 X.509 certificate assembled in DER and signed with ECDSA P-256
|
|
145
|
+
over SHA-256), naming the bound hosts, this machine's addresses and hostname — and remakes it
|
|
146
|
+
near expiry or when a bound address is missing from it. `blockyard tls` remakes it by hand
|
|
147
|
+
(`--san` to add names, `--print` to export it). Your own certificate still replaces it;
|
|
148
|
+
`BLOCKYARD_TLS=0` serves plain HTTP behind a proxy. The installer's summary and port probe know
|
|
149
|
+
both schemes.
|
|
150
|
+
- **The installer asks twice before a non-loopback bind.** A LAN or wildcard address is written
|
|
151
|
+
only when the operator types it and confirms it; the default it offers is `127.0.0.1`.
|
|
152
|
+
- **Market polling is off by default** — a new checkbox, **Display settings → Markets & Price →
|
|
153
|
+
Enable market polling**, shared by every screen. A fresh install makes no outbound connection
|
|
154
|
+
but to the node: the Markets and Kiosk tabs say that polling is off and where the switch is,
|
|
155
|
+
Overview's price line stays hidden and the explorer shows no dollar figures. Ticking it takes
|
|
156
|
+
effect at once; unticking parks the feed at once. `BLOCKYARD_MARKETS=0` still removes the feed
|
|
157
|
+
so that the checkbox cannot turn it on. Existing installs tick the box once.
|
|
158
|
+
|
|
159
|
+
### Appearance
|
|
160
|
+
|
|
161
|
+
- **A first tab in Display settings for the colours of the layout.** A theme mode — Light, Dark,
|
|
162
|
+
or System, which follows the operating system and changes with it — and theme cards with swatch
|
|
163
|
+
strips of the face the mode picks: **BlockYard** (the shipped look, the default; its dark face
|
|
164
|
+
is value for value what the monitor drew before), **Mono** (clean grayscale), **Nous** (GitHub's
|
|
165
|
+
chrome with a Nous blue accent), **GitHub** (Light Default and Dark Default) and **Catppuccin**
|
|
166
|
+
(Latte and Mocha). **Custom** is nine colour pickers — page, panels, text, muted text, accent,
|
|
167
|
+
lines, good, warning, bad — with the rest of a face derived from them (a raised panel, the
|
|
168
|
+
softer rules, the fainter text, the darker accent of a pressed button), and whether Custom is
|
|
169
|
+
light or dark read off its page colour; **customise <theme>** copies the theme on screen into
|
|
170
|
+
the pickers so a custom scheme starts from a look. Saved on the server with the other settings,
|
|
171
|
+
so every screen of the monitor draws the same; the sign-in page draws in the theme the browser
|
|
172
|
+
last saw.
|
|
173
|
+
- The theme is applied through the CSSOM (the page's custom properties rewritten on `<html>`),
|
|
174
|
+
which the content-security policy permits where a style attribute is refused. The charts' axis
|
|
175
|
+
text, grid lines and tooltips, the order-book depth chart's two sides and the market charts'
|
|
176
|
+
grounds follow the theme — they were literals of the dark look, and a light theme would have
|
|
177
|
+
drawn grey-on-grey. The 3D boards stay space, and the Explorer's block and transaction pages
|
|
178
|
+
keep their own dark cards.
|
|
179
|
+
|
|
180
|
+
### Mining
|
|
181
|
+
|
|
182
|
+
- **The Mining tab has the network row**: reward stats over the last 144 blocks, the difficulty
|
|
183
|
+
period (blocks remaining, the estimated and the previous change, the next halving), a week of
|
|
184
|
+
pools with luck and counts, a year of hashrate with the difficulty's steps, and the last twelve
|
|
185
|
+
adjustments as a table — every figure from this node alone (`server/collect/network.js`:
|
|
186
|
+
`getblockstats` for the reward window, block headers for the periods and a daily sample, the
|
|
187
|
+
week's coinbases read in the background at the lowest RPC priority).
|
|
188
|
+
- **mempool.space's layout**: two columns in its order (reward stats, difficulty adjustment;
|
|
189
|
+
pools, hashrate; recent blocks, adjustments) under the block flow, our own panels beneath, and
|
|
190
|
+
**View more »** on four cards opening that card full screen — the whole week of pools as a
|
|
191
|
+
table, the year's chart large, the whole attributed window of blocks, a year of adjustments.
|
|
192
|
+
- **The pool chart is a labelled pie**: every pool named beside its slice and joined to it by a
|
|
193
|
+
leader in the slice's colour, the small ones stacked, slices under half a percent gathered as
|
|
194
|
+
"Other" — and the "Other" threshold rises until every label fits the card, so no name runs off
|
|
195
|
+
the bottom at any window height. The pie and the year chart size themselves to the window.
|
|
196
|
+
- **Dollar figures** on the reward stats while market polling is on, from a new `/api/price` that
|
|
197
|
+
answers the cached spot price and never starts the exchange polling itself.
|
|
198
|
+
- The Mempool space viewer left this page — it is on Overview, Block space and Mempool — and with
|
|
199
|
+
it the full-pool poll the page used to ask for. The reward window is exactly 144 blocks.
|
|
200
|
+
- At a narrow window the block flow spans the width and is thinner, and the packages table scrolls
|
|
201
|
+
inside its card instead of bleeding into the neighbour; the three stacks become two below 1400px.
|
|
202
|
+
- **A streak of stale drops of the full-pool poll is one story**: one warning event when it
|
|
203
|
+
starts, a counter on Node & RPC while it lasts, one event when the poll answers again with the
|
|
204
|
+
count and the span. On a day the node answered slowly for thirteen hours, each drop had been its
|
|
205
|
+
own event, 188 of the feed's 200 rows.
|
|
206
|
+
|
|
207
|
+
### Every tab on one screen
|
|
208
|
+
|
|
209
|
+
Measured at 1093×945 and 1600×1000 with a dead-height probe, page by page:
|
|
210
|
+
|
|
211
|
+
- **Globally**: tighter card padding and heading spacing, and a short card beside a tall one keeps
|
|
212
|
+
its own height instead of being stretched to match (Chain & Sync's drill-down card had a
|
|
213
|
+
thousand pixels of nothing under its input; Node & RPC's poll cadence and connection cards
|
|
214
|
+
hundreds).
|
|
215
|
+
- **Overview**: the block flow card a quarter shorter, and the Block space board capped to the
|
|
216
|
+
viewport (it set the whole right column's height), so the events are on the first screen.
|
|
217
|
+
- **Block space**: the card tighter and the board sized so the whole page, note included, fits the
|
|
218
|
+
viewport without a scroll.
|
|
219
|
+
- **Markets**: the board takes what the window leaves, and the exchange table and the order-book
|
|
220
|
+
depth sit side by side beneath it (under 1400px the table drops the pair, 24 h range and volume
|
|
221
|
+
columns; all still in the summary line and on the Kiosk) instead of the depth chart starting a
|
|
222
|
+
thousand pixels down.
|
|
223
|
+
- **Kiosk**: tighter heads and gaps, the price panel's padding trimmed, the Block flow strip a
|
|
224
|
+
quarter shorter, and the full-screen button in that strip's head instead of floating over its
|
|
225
|
+
cards.
|
|
226
|
+
- **Mempool**: keeps its two columns down to 900px (it stacked from 1100), and the room over goes
|
|
227
|
+
to its time-series charts, a fifth taller.
|
|
228
|
+
- **Explorer**: a smaller title, the block strip's padding and scrollbar band trimmed, tighter
|
|
229
|
+
table rows and the table reaching the window's bottom edge — three more blocks on the first
|
|
230
|
+
screen.
|
|
231
|
+
- **Peers**: a long onion or i2p address no longer makes the whole page scroll sideways (it clips
|
|
232
|
+
with an ellipsis and carries the full text as its title; a wide table scrolls inside its card),
|
|
233
|
+
rows and service badges tighter, the top strip's cards at their own heights.
|
|
234
|
+
- **Network**: Throughput beside a stack of Upload and Traffic accounting, the throughput chart
|
|
235
|
+
taller, and the sources table taking the rest of the window.
|
|
236
|
+
- **Events**: the feed reaches the window's bottom edge (it stopped a hundred pixels short).
|
|
237
|
+
- **Chain & Sync**: one-line notes under the block-size and tip charts (the longer sentences are
|
|
238
|
+
their tooltips), the transaction-rate figures as one wrapping line, values that keep to their
|
|
239
|
+
line, and a shorter uptime label — the first three rows sit level and the drill-down and indexes
|
|
240
|
+
reach the first screen.
|
|
241
|
+
- **Node & RPC**: two stacks (RPC etiquette with its figures in two columns, Data quality and Node
|
|
242
|
+
connection; Poll cadence, self-telemetry beside the log tail, Panel sources and the RPC
|
|
243
|
+
console) instead of grid rows that left holes beside the short cards.
|
|
244
|
+
- **Admin**: two stacks (Users over the audit log; Node actions over Change own password, whose
|
|
245
|
+
two fields share a row). **Sign-in** and **404**: the same tighter card.
|
|
246
|
+
- **Display settings**: the tabs in three labelled rows — Boards (Appearance, Block space, Sky,
|
|
247
|
+
Markets & Price), Effects, and the Diversions last; rows, note and groups tighter, the sheet a little wider so hints wrap
|
|
248
|
+
less, and on the two effects tabs the switches run two across with each hint as the row's
|
|
249
|
+
tooltip — the Space effects tab is under half the scrolling it was. The price line on Overview
|
|
250
|
+
switch sits directly under the polling switch it depends on.
|
|
251
|
+
- **About**: the sky runs to the bottom edge with the credit line at its foot, and the GitHub
|
|
252
|
+
link and the tip pill share a row.
|
|
253
|
+
- **The Diversions pages take the window**: the wells of Tetrust, Blockout and Blockanoid grow to
|
|
254
|
+
the window's height (they stopped at 600px), and the DOS screen is always 4:3 and as large as
|
|
255
|
+
the window allows — at a 1093px window the 320×200 picture had been drawn squashed into a
|
|
256
|
+
761×720 box.
|
|
257
|
+
|
|
258
|
+
### DOS Diversions
|
|
259
|
+
|
|
260
|
+
- **DOOM.** The shareware `DOOM.EXE` v1.9 and `DOOM1.WAD` from `games/doom_dos/`, unmodified,
|
|
261
|
+
running on a PC emulated in the browser with no dependencies: an i386 interpreter
|
|
262
|
+
(`public/js/x86.js`), the DOS/4GW machine around it — DOS, DPMI, BIOS, PIC, timer, keyboard and
|
|
263
|
+
a planar VGA (`dospc.js`) — and a Sound Blaster Pro 2 with an OPL3 for the effects and the music
|
|
264
|
+
(`soundcard.js`), in a worker. Demos, menus, savegames and ENDOOM all work; 35 frames a second.
|
|
265
|
+
Mouse capture, WASD keys by default (the switch rebinds the running game at once), smoothing,
|
|
266
|
+
full screen; pauses when you look away; savegames and DOOM's config stay in the browser.
|
|
267
|
+
- **Wolfenstein 3D.** The shareware `WOLF3D.EXE` v1.4 and its `.WL1` files from
|
|
268
|
+
`games/wolf3d_dos/`, unmodified, on the same emulated PC — which now also runs a 16-bit real-mode
|
|
269
|
+
DOS program: real mode in the CPU (segments times sixteen, a wrapping SP, 16-bit string
|
|
270
|
+
instructions and interrupt frames), a plain MZ loader with its relocations, DOS's memory
|
|
271
|
+
allocator, the interrupt vector table, and VGA write mode 1. Menus, demos, AdLib music,
|
|
272
|
+
digitised sound effects, savegames and high scores kept in the browser, at its full 70 frames a
|
|
273
|
+
second. It sits before DOOM and Quake in the Diversions menu.
|
|
274
|
+
- **Quake.** The shareware `QUAKE.EXE` v1.06 and `PAK0.PAK` from `games/quake_dos/`, unmodified,
|
|
275
|
+
on the same emulated PC — which now also plays the go32 stub and CWSDPMI for a DJGPP program:
|
|
276
|
+
segment bases and 16-bit code in the CPU, a COFF loader, a directory tree, DOS's system file
|
|
277
|
+
table, the BIOS tick count. Demos, menus, savegames, sound effects through the Sound Blaster,
|
|
278
|
+
and the order screen on quit. W A S D and mouse look on the first start, Quake's own bindings
|
|
279
|
+
after. Quake starts with a smaller view (`viewsize 80`); **−** and **=** change it and Quake
|
|
280
|
+
keeps the choice.
|
|
281
|
+
- **The emulated PC is fast.** Each instruction is decoded once and cached rather than decoded
|
|
282
|
+
every time it runs (writes into cached code clear what they overlap, because both games patch
|
|
283
|
+
their own drawing code), the arithmetic and the x87 forms Quake runs most have handlers of their
|
|
284
|
+
own, and memory addresses are formed inline: Quake from 77 to about 141 million instructions a
|
|
285
|
+
second, its `timedemo demo1` from 29.7 fps to over 50; in the browser Quake plays at 40–50
|
|
286
|
+
frames a second.
|
|
287
|
+
- **A way out of full screen**: an **exit full screen** button in the top corner while full
|
|
288
|
+
screen, and holding **Esc** for a second (a tap of Esc stays the game's menu, which is what the
|
|
289
|
+
keyboard lock is for); leaving unlocks the keyboard and releases the mouse.
|
|
290
|
+
- The game files are served at `/games/<game>/<path>` (`server/http/games.js`); the shareware
|
|
291
|
+
packages live under `games/` (DOOM's moved from `doom_dos/` at the repository root).
|
|
292
|
+
|
|
293
|
+
### Markets and the effects
|
|
294
|
+
|
|
295
|
+
- **Black hole**, a Markets effect (modelled on NASA's visualisation, svs.gsfc.nasa.gov/14576): a
|
|
296
|
+
point of darkness opens and grows to a horizon over 26 s, the price line bends round it as
|
|
297
|
+
through a lens (the Einstein-radius push), the candles it reaches stretch and lean toward it and
|
|
298
|
+
shrink away into it, and an accretion disk seen nearly edge-on — a thin band white-yellow at its
|
|
299
|
+
inner edge through orange to a dark red rim, five hundred fibres spiralling inward sheared by
|
|
300
|
+
the Keplerian flow, its far side lensed into an arch over the shadow and a smaller one beneath,
|
|
301
|
+
a photon ring hugging the horizon, starlight bent into arcs. **It crosses the board**: it opens
|
|
302
|
+
a fifth of the way in on one side and runs a straight line through the chart to a fifth from the
|
|
303
|
+
other, from one height to another, so the line is seen bending round it as it passes; the
|
|
304
|
+
candles' orbits ride along at a quarter of the first cut's speed. It finishes its crossing before
|
|
305
|
+
it lets go, and lets go evenly, every candle gliding home and growing back smoothly. It hovered
|
|
306
|
+
over Block space for a day and its cubes never came home cleanly enough, so it is a Markets
|
|
307
|
+
effect only.
|
|
308
|
+
- **Supernova** (the solar flare, renamed and remade on NASA Goddard's animation,
|
|
309
|
+
svs.gsfc.nasa.gov/20413): the star is a glint — halo, hot core, diffraction spikes — growing and
|
|
310
|
+
blue-shifting as it goes; the opening explosion is a **white-hot flash**, held and washing far
|
|
311
|
+
out, that throws **a hundred and twenty-eight plumes of white gas** in every direction, each
|
|
312
|
+
flying and growing on its own out to nine star radii and drifting on until the effect is nearly
|
|
313
|
+
done (drawn on a half-resolution layer to keep the frame cheap); the debris is a volume of gas in
|
|
314
|
+
three layers — a blue cloud out in front, a white one behind it into which **violet grows patch
|
|
315
|
+
by patch from a tenth of the run**, and a deep violet heart — with a soft shock band throwing
|
|
316
|
+
and shaking the candles it crosses; and as the cloud dims a **pulsar** beats seven times a
|
|
317
|
+
second at the centre, two thin beams sweeping round, inside a nebula of the same gas that holds
|
|
318
|
+
its violet weight until four fifths of the run. 16 s (24 on Markets).
|
|
319
|
+
- **Fireworks are a display**, on both boards: every shell drawn — the rocket's arc, a white flash
|
|
320
|
+
and a shockwave ring at the burst, seven shell kinds by turn (peony, chrysanthemum, willow, ring,
|
|
321
|
+
crossette, strobe and more), sixty to ninety sparks each a curved trail, a lens flare at every
|
|
322
|
+
burst, glitter rain, and a nebula of smoke that drifts up and lingers; up to ten shells on
|
|
323
|
+
Markets over 14 s (five on Block space), each lighting the candles under it in its own colour.
|
|
324
|
+
**Off by default** on both boards, kept for special occasions.
|
|
325
|
+
- **X-ray**, on both boards: a front sweeps the board and everything behind it goes x-ray — bodies
|
|
326
|
+
dimmed to glass, every edge lit, a raster of thin lines across each face — then develops back.
|
|
327
|
+
- **Breathe** and **Light saber**, on the price line: three slow swells from the plain wire to
|
|
328
|
+
white heat and back; and the line igniting from its left end, blue, green, red or purple by the
|
|
329
|
+
run, humming with a breathing glow, spitting sparks, retracting to the hilt.
|
|
330
|
+
- **The energy pulse is heat, not blue, and its head is a crackling ball of plasma**; **the scan
|
|
331
|
+
line is a light curtain** standing on the board floor to the chart's top; **ball lightning is a
|
|
332
|
+
light source**, its arcs discharges built by midpoint displacement rather than zigzags, a quarter
|
|
333
|
+
of its size and a third of its speed on Markets; the scanner's cone is dimmer on both boards.
|
|
334
|
+
- **The Markets board keeps its price fit across refreshes**: the last fit is kept while the data
|
|
335
|
+
still sits inside it and fills at least two-thirds of it, so a refresh no longer re-scales the
|
|
336
|
+
whole chart unanimated. Whatever a head pulls is painted last, nearest the head on top; a held
|
|
337
|
+
pool refresh waits a moment and a half after an idle effect ends, with the board whole and still.
|
|
338
|
+
- **Layered soft fills add up correctly** (`softStops`): each nested disc carries only its
|
|
339
|
+
increment, so a stop's cumulative opacity is exactly the stop's; measured on the Kiosk, the
|
|
340
|
+
supernova's peak opacity fell from about 0.9 to about 0.45 and the chart shows through it.
|
|
341
|
+
- **The no-repeat window holds from the first pick** on both boards: every effect plays once
|
|
342
|
+
before any repeats (a negative slice index had let one come round at the tenth pick). The
|
|
343
|
+
searchlight and the tractor beam, which fly the same saucer, share the window.
|
|
344
|
+
- **A Kiosk test suite** (`test/kiosk.test.js`): every Markets and Block space effect plays through
|
|
345
|
+
the frame loop on a Kiosk-sized panel; the supernova, the black hole and the fireworks are
|
|
346
|
+
bounded by the board's width so no panel is covered.
|
|
347
|
+
|
|
348
|
+
### Fixed
|
|
349
|
+
|
|
350
|
+
- **The donation QR shows on Safari.** It was an inline SVG of 800 module rects, and Safari on
|
|
351
|
+
the first Mac install painted its white ground and none of the rects. It is a PNG now, painted
|
|
352
|
+
the same everywhere.
|
|
353
|
+
- **A dead index worker fails the build instead of hanging it.** A worker killed outright (out of
|
|
354
|
+
memory, with four beside the node) left its job unanswered and the build sat at "scan 5,720 of
|
|
355
|
+
5,721, about 1 s left" for an hour and a half on the first Mac install. The run now rejects the
|
|
356
|
+
moment a worker exits or throws, naming the job and the fix (fewer `addressIndexWorkers`); the
|
|
357
|
+
progress flag says *no progress for N min* when nothing has moved.
|
|
358
|
+
- The 0.0.9 release notes' test count corrected (862, not 864).
|
|
359
|
+
|
|
360
|
+
### Documentation
|
|
361
|
+
|
|
362
|
+
- INSTALL, GETTING-STARTED, SECURITY, CONFIGURATION, API, TROUBLESHOOTING and the README describe
|
|
363
|
+
the hardened defaults, HTTPS and the polling switch; INSTALL §11 has the notes for updating a
|
|
364
|
+
0.0.9 install; the USER-GUIDE has the Appearance section, the Mining row and the packed layouts;
|
|
365
|
+
TROUBLESHOOTING explains a streak of stale pool-poll drops. Screenshots re-shot at 0.1.0, with a
|
|
366
|
+
Mining shot added. The announcement for the bitcointalk thread is in `docs/announcement/0.1.0/`.
|
|
10
367
|
|
|
11
368
|
## [0.0.9] — 2026-09-14
|
|
12
369
|
|
|
@@ -676,4 +1033,5 @@ are an original implementation (`public/js/blockpack.js`, `public/js/feepalette.
|
|
|
676
1033
|
Internal first version: multi-user monitor with charts, sync viewer, mempool view, peers and
|
|
677
1034
|
event feed.
|
|
678
1035
|
|
|
1036
|
+
[0.0.10]: https://github.com/BobClawblaw/blockyard/releases/tag/v0.0.10
|
|
679
1037
|
[0.0.9]: https://github.com/BobClawblaw/blockyard/releases/tag/v0.0.9
|
package/README.md
CHANGED
|
@@ -5,13 +5,13 @@ A live, multi-user web monitor and block explorer for
|
|
|
5
5
|
|
|
6
6
|
Point it at your node and open a browser: live charts, a 3D block-space viewer,
|
|
7
7
|
a block / transaction / address explorer, exchange prices with order-book depth, and a
|
|
8
|
-
kiosk view for a wall screen. No dependencies to install, no CDN, no telemetry,
|
|
9
|
-
read-only toward your node by default.
|
|
8
|
+
kiosk view for a wall screen. No dependencies to install, no CDN, no telemetry, no outbound
|
|
9
|
+
connection but to your node out of the box, and read-only toward your node by default.
|
|
10
10
|
|
|
11
11
|
**This is 100% machine-generated code, directed by a human operator.** Every line of the
|
|
12
12
|
server, the browser app, the 3D engine, the tests and these documents was written by an AI
|
|
13
13
|
under a human's direction, and all auditing has been performed by AI and is published in this
|
|
14
|
-
repository ([docs/SECURITY-AUDIT.md](docs/SECURITY-AUDIT.md), [docs/SECURITY-AUDIT-2026-09-14.md](docs/SECURITY-AUDIT-2026-09-14.md), [docs/DEFECTS.md](docs/DEFECTS.md),
|
|
14
|
+
repository ([docs/SECURITY-AUDIT.md](docs/SECURITY-AUDIT.md), [docs/SECURITY-AUDIT-2026-09-14.md](docs/SECURITY-AUDIT-2026-09-14.md), [docs/SECURITY-AUDIT-2026-09-16.md](docs/SECURITY-AUDIT-2026-09-16.md), [docs/DEFECTS.md](docs/DEFECTS.md),
|
|
15
15
|
[docs/MEASUREMENTS.md](docs/MEASUREMENTS.md)). It is **experimental pre-release software: expect
|
|
16
16
|
bugs.**
|
|
17
17
|
|
|
@@ -21,22 +21,23 @@ bugs.**
|
|
|
21
21
|
|
|
22
22
|
| | |
|
|
23
23
|
|---|---|
|
|
24
|
-
| **Block space, in 3D.** The next block's worth of the mempool as a board of glowing tiles: area is vbytes, colour is feerate. Refreshes are choreographed — blocks lift, travel in collision-free lanes and land under gravity — and the board comes alive at rest with **
|
|
25
|
-
| **A board you can tune.** Neon-tube blocks, a metallic sheen or a chrome finish that mirrors a horizon, a movable lamp, a touch of perspective, a spiral galaxy behind the board, and a switch for every one of the
|
|
24
|
+
| **Block space, in 3D.** The next block's worth of the mempool as a board of glowing tiles: area is vbytes, colour is feerate. Refreshes are choreographed — blocks lift, travel in collision-free lanes and land under gravity — and the board comes alive at rest with **34 idle effects**, from ripples and light cycles to a lightning ball, ball lightning, a UFO's tractor beam, Missile Command, fireworks, code rain and a demoscene plasma. Two viewer modes: **Simple** (the richest few hundred transactions as cubes) and **Detailed** (every transaction in the block). |  |
|
|
25
|
+
| **A board you can tune.** Neon-tube blocks, a metallic sheen or a chrome finish that mirrors a horizon, a movable lamp, a touch of perspective, a spiral galaxy behind the board, and a switch for every one of the 34 effects — in a tabbed settings panel. Stored on the server (`config/blockyard.json`), so every screen sees the same board; they change how things are *drawn*, never what is measured. |  |
|
|
26
26
|
| **An explorer that looks the part.** Search a height, block hash, txid or address. Transaction pages with fee, fee rate and dollar value, feature badges, a flow diagram from inputs to outputs, and links to where every coin came from and went. **Address pages with full history and balance** — Bitcoin Core has no address index, so BlockYard builds its own from the node's block files (**a few hours** on first start, 124 GB) and keeps it current as blocks arrive. |  |
|
|
27
|
-
| **Markets.** Five exchanges' public prices: a 3D candle chart with a neon price line, a precise flat candlestick chart, an exchange table, and a bitcoinity-style order-book depth chart with change bars.
|
|
27
|
+
| **Markets.** Five exchanges' public prices: a 3D candle chart with a neon price line, a precise flat candlestick chart, an exchange table, and a bitcoinity-style order-book depth chart with change bars. Off until you tick **Enable market polling** — it is the one thing that talks to anyone but your node — and, once on, fetched by the server only while someone is looking. |  |
|
|
28
28
|
| **Kiosk.** The 3D markets board, a price panel and the block-space board side by side, full screen with one click. |  |
|
|
29
|
-
| **Tetrust, Blockout and Blockanoid.** Three playable games built on the same 3D engine — trust, but verify. Tetrust is Tetris: the well is the block-space board and the music is synthesised in the browser. Blockout is Breakout, where the wall is made of block-space stones and the bat follows your mouse. Blockanoid is Arkanoid: a different wall every level, silver bricks that take more than one hit, gold that takes none, and capsules that fall out of what you break — laser, wide, catch, slow, three balls, a life. All three pause when you look away and keep high scores per browser. |  |
|
|
29
|
+
| **Tetrust, Blockout and Blockanoid.** Three playable games built on the same 3D engine — trust, but verify. Tetrust is Tetris: the well is the block-space board and the music is synthesised in the browser. Blockout is Breakout, where the wall is made of block-space stones and the bat follows your mouse. Blockanoid is Arkanoid: a different wall every level, silver bricks that take more than one hit, gold that takes none, and capsules that fall out of what you break — laser, wide, catch, slow, three balls, a life. All three pause when you look away and keep high scores per browser. **Scorched Yard** is Scorched Earth on the same engine: a landscape of dirt cubes that craters and falls, the original's thirty-three weapons and eleven accessories at the manual's prices, its eight computer personalities, cash and a shop between rounds, and the wind you can see. And **Wolfenstein 3D**, **DOOM** and **Quake**: the real shareware `WOLF3D.EXE` (1992), `DOOM.EXE` (1993) and `QUAKE.EXE` (1996), unmodified, on a PC emulated in the browser — processor in real and protected mode, FPU, DOS and both extenders, VGA and Sound Blaster written from scratch, still with no dependencies. So if anyone asks *"well, can it run DOOM?"*, the answer is an emphatic **"Naturally. What sort of AI slop generator do you take me for?"** |  |
|
|
30
30
|
|
|
31
31
|
Also on board: a sync viewer with an honest ETA, Block flow (projected blocks, the block
|
|
32
32
|
being built, recent blocks), mempool and fee charts, a peer table, bandwidth, the node's
|
|
33
33
|
event stream, a provenance table for every figure, a read-only RPC console behind a
|
|
34
34
|
default-deny allowlist, and a tabbed **Display settings** panel (the gear) that tunes every
|
|
35
|
-
board without a reload
|
|
35
|
+
board without a reload and picks the layout's colours — light or dark, the shipped look, Mono,
|
|
36
|
+
Nous, GitHub, Catppuccin, or nine colours of your own.
|
|
36
37
|
|
|
37
38
|
## Quick start
|
|
38
39
|
|
|
39
|
-
You need **Node.js 22 or newer** and a running **Bitcoin Core 25.0 or later** with `server=1`
|
|
40
|
+
You need **Node.js 22.2 or newer** and a running **Bitcoin Core 25.0 or later** with `server=1`
|
|
40
41
|
and `txindex=1`, **on the same machine** — BlockYard reads the node's block files to build the
|
|
41
42
|
explorer's address index, and a node on another machine is not supported. Without `txindex` the
|
|
42
43
|
explorer cannot look a confirmed transaction up by id; everything else works without it (see
|
|
@@ -46,9 +47,10 @@ top of the node's own ~875 GB of block files.
|
|
|
46
47
|
```bash
|
|
47
48
|
git clone https://github.com/BobClawblaw/blockyard.git
|
|
48
49
|
cd blockyard
|
|
49
|
-
npm test # optional:
|
|
50
|
+
npm test # optional: 1068 unit tests, all built in
|
|
50
51
|
npm run setup # reads the node's bitcoin.conf, checks the node, writes config/local.json
|
|
51
|
-
npm start # builds the address index in the background (a few hours); open
|
|
52
|
+
npm start # builds the address index in the background (a few hours); open https://127.0.0.1:21000
|
|
53
|
+
# and sign in as admin with the password the first start prints once
|
|
52
54
|
```
|
|
53
55
|
|
|
54
56
|
`npm run setup` asks for the node's data directory, reads its `bitcoin.conf` for the rest,
|
|
@@ -107,15 +109,23 @@ design rests on) and [docs/DEFECTS.md](docs/DEFECTS.md) (known limits).
|
|
|
107
109
|
|
|
108
110
|
## Security at a glance
|
|
109
111
|
|
|
110
|
-
- **
|
|
111
|
-
|
|
112
|
-
on
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
112
|
+
- **Hardened out of the box** — it listens on `127.0.0.1` only and requires sign-in: the
|
|
113
|
+
first start creates an `admin` account and prints its password once. Accounts, roles,
|
|
114
|
+
sessions, CSRF protection and a per-user audit trail are on. Reach it from another machine
|
|
115
|
+
over an SSH tunnel, or bind a LAN address (`BLOCKYARD_BIND`) when you decide the LAN may
|
|
116
|
+
see it; open, read-only access with no account is a choice (`BLOCKYARD_AUTH=0`), announced
|
|
117
|
+
at boot.
|
|
118
|
+
- **HTTPS by default** — the first start makes the monitor its own certificate (no
|
|
119
|
+
dependencies: the X.509 is written by hand), and every listener serves it; a certificate of
|
|
120
|
+
your own with `BLOCKYARD_TLS_CERT` / `BLOCKYARD_TLS_KEY`, or `BLOCKYARD_TLS=0` behind a
|
|
121
|
+
proxy that terminates TLS.
|
|
122
|
+
- **Where it listens is your decision** — `127.0.0.1`, a LAN address, a VPN address, or
|
|
123
|
+
several.
|
|
124
|
+
- **No outbound connections out of the box**: a fresh install talks to nothing but your node.
|
|
125
|
+
The one exception is opt-in — a checkbox, **Display settings → Markets & Price → Enable
|
|
126
|
+
market polling**, turns on the exchange feed for the Markets and Kiosk tabs, Overview's price
|
|
127
|
+
line and the explorer's dollar figures, and even then the server asks the exchanges only while
|
|
128
|
+
someone is looking. `BLOCKYARD_MARKETS=0` removes the feed so that no checkbox can turn it on.
|
|
119
129
|
|
|
120
130
|
Details in [docs/SECURITY.md](docs/SECURITY.md). To report a vulnerability, see
|
|
121
131
|
[SECURITY.md](SECURITY.md).
|
|
@@ -126,7 +136,7 @@ Details in [docs/SECURITY.md](docs/SECURITY.md). To report a vulnerability, see
|
|
|
126
136
|
npm run dev # fake node doing a simulated sync, port 18088
|
|
127
137
|
npm run setup # interactive install: read bitcoin.conf, check the node, write config/local.json
|
|
128
138
|
npm run check # the same checks (every call timed) against every configured node; exits 1 on a FAIL
|
|
129
|
-
npm test #
|
|
139
|
+
npm test # 1068 unit tests (node:test, no dependencies)
|
|
130
140
|
npm run smoke # boots the real server and checks the HTTP contract
|
|
131
141
|
npm run counts:fix # keep the documented test count in step with the suite
|
|
132
142
|
```
|
|
@@ -136,20 +146,31 @@ RPC etiquette) and [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) for how it fits
|
|
|
136
146
|
|
|
137
147
|
## Status
|
|
138
148
|
|
|
139
|
-
Version **0.
|
|
140
|
-
|
|
149
|
+
Version **0.1.1** (2026-09-17) — a hardening release after 0.1.0: the third security audit with
|
|
150
|
+
every finding fixed, a resumable address index build, and Scorched Yard. Pre-release software: the
|
|
151
|
+
word is meant literally. Releases are published on [npm](https://www.npmjs.com/package/blockyard)
|
|
152
|
+
as `blockyard`, as [GitHub releases](https://github.com/BobClawblaw/blockyard/releases),
|
|
153
|
+
and announced on
|
|
154
|
+
[bitcointalk](https://bitcointalk.org/index.php?topic=5594141.msg67144312) — questions, bug
|
|
155
|
+
reports and reviews are welcome there and in [issues](https://github.com/BobClawblaw/blockyard/issues).
|
|
156
|
+
It ships **hardened**: bound to this machine, sign-in on, HTTPS with a certificate it makes itself,
|
|
157
|
+
and **zero telemetry** — no outbound connection to anyone but your node until you tick the market
|
|
158
|
+
polling switch yourself.
|
|
159
|
+
The test suite is
|
|
160
|
+
comprehensive (1068 tests, plus a live smoke run), the monitoring side is solid, and the
|
|
141
161
|
explorer's biggest gap is closed: **address history and balances**, which Bitcoin Core cannot
|
|
142
162
|
answer at any setting, now come from an **address index BlockYard builds itself** from the
|
|
143
163
|
node's block and undo files and keeps current as blocks arrive. It is checked against the node
|
|
144
|
-
(every balance equal to `scantxoutset`, to the satoshi) and costs
|
|
145
|
-
124 GB of disk, built in the background the first time BlockYard starts and paced so the node's
|
|
164
|
+
(every balance equal to `scantxoutset`, to the satoshi) and costs a few hours on the default four
|
|
165
|
+
workers (~30 minutes on 16) and 124 GB of disk, built in the background the first time BlockYard starts and paced so the node's
|
|
146
166
|
RPC stays responsive; without one, the address page says *not indexed* rather than showing a
|
|
147
167
|
zero. An address's unspent outputs are listed too (for a history of up to 100 transactions).
|
|
148
168
|
What it does not yet have: an address's mempool transactions.
|
|
149
169
|
|
|
150
170
|
Everything here was written by an AI directed by a human, and audited by AI:
|
|
151
|
-
[docs/SECURITY-AUDIT.md](docs/SECURITY-AUDIT.md)
|
|
152
|
-
[docs/SECURITY-AUDIT-2026-09-14.md](docs/SECURITY-AUDIT-2026-09-14.md)
|
|
171
|
+
[docs/SECURITY-AUDIT.md](docs/SECURITY-AUDIT.md),
|
|
172
|
+
[docs/SECURITY-AUDIT-2026-09-14.md](docs/SECURITY-AUDIT-2026-09-14.md) and
|
|
173
|
+
[docs/SECURITY-AUDIT-2026-09-16.md](docs/SECURITY-AUDIT-2026-09-16.md) are the audits, findings
|
|
153
174
|
and remediation included. The test suite runs in CI on Ubuntu, macOS and Windows (Node 22 and 24);
|
|
154
175
|
a real install has been done on macOS (Core 29.1) and Linux, and Windows has only the test suite.
|
|
155
176
|
[docs/DEFECTS.md](docs/DEFECTS.md) lists five open items, honestly stated, with the
|
package/SECURITY.md
CHANGED
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
|
|
5
5
|
| version | supported |
|
|
6
6
|
|---|---|
|
|
7
|
-
| 0.
|
|
8
|
-
|
|
|
7
|
+
| 0.1.x | yes |
|
|
8
|
+
| 0.0.9 and earlier | no: upgrade. 0.0.9 shipped bound to every interface with no sign-in, and later audits fixed issues it still has |
|
|
9
9
|
|
|
10
10
|
## Reporting a vulnerability
|
|
11
11
|
|
package/bin/blockyard.js
CHANGED
|
@@ -27,11 +27,12 @@ const COMMANDS = {
|
|
|
27
27
|
start: 'server/main.js',
|
|
28
28
|
'index-build': 'scripts/index-build.js',
|
|
29
29
|
users: 'scripts/manage-users.js',
|
|
30
|
+
tls: 'scripts/tls.js',
|
|
30
31
|
};
|
|
31
32
|
const cmd = process.argv[2];
|
|
32
33
|
if (!COMMANDS[cmd]) {
|
|
33
34
|
const version = JSON.parse((await import('node:fs')).readFileSync(path.join(root, 'package.json'), 'utf8')).version;
|
|
34
|
-
process.stdout.write(`BlockYard ${version}\n\n blockyard setup ask where the node is, check it, write the config, build the index\n blockyard start run the monitor\n blockyard check the same checks as setup, any time\n blockyard index-build build the address index by hand (--out <dir> [--workers N])\n blockyard users manage accounts\n\nconfig ${process.env.BLOCKYARD_CONFIG}\ndata ${process.env.BLOCKYARD_DATA}\n`);
|
|
35
|
+
process.stdout.write(`BlockYard ${version}\n\n blockyard setup ask where the node is, check it, write the config, build the index\n blockyard start run the monitor\n blockyard check the same checks as setup, any time\n blockyard index-build build the address index by hand (--out <dir> [--workers N])\n blockyard users manage accounts\n blockyard tls remake this monitor's own HTTPS certificate (--san to add names)\n\nconfig ${process.env.BLOCKYARD_CONFIG}\ndata ${process.env.BLOCKYARD_DATA}\n`);
|
|
35
36
|
process.exit(cmd ? 2 : 0);
|
|
36
37
|
}
|
|
37
38
|
// the scripts decide "am I being run directly?" by comparing argv[1] to their own path, so hand
|