blockyard 0.0.9 → 0.1.0
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 +251 -1
- package/README.md +42 -23
- package/bin/blockyard.js +2 -1
- package/docs/API.md +16 -14
- package/docs/ARCHITECTURE.md +92 -5
- package/docs/CONFIGURATION.md +33 -26
- package/docs/GETTING-STARTED.md +5 -2
- package/docs/INSTALL.md +90 -33
- package/docs/MEASUREMENTS.md +147 -0
- package/docs/SECURITY.md +32 -15
- package/docs/TROUBLESHOOTING.md +35 -1
- package/docs/USER-GUIDE.md +266 -26
- package/package.json +1 -1
- package/public/404.html +1 -1
- package/public/css/app.css +306 -82
- package/public/donate-qr.png +0 -0
- package/public/index.html +295 -103
- package/public/js/agents.js +228 -51
- package/public/js/app.js +82 -8
- package/public/js/blockscene3d.js +179 -27
- package/public/js/charts.js +21 -21
- package/public/js/depthchart.js +31 -27
- package/public/js/details3d.js +1456 -71
- 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/login.js +5 -0
- package/public/js/markets.js +46 -8
- package/public/js/mining.js +310 -32
- package/public/js/panels.js +14 -10
- package/public/js/pricechart.js +14 -13
- package/public/js/quake.js +20 -0
- package/public/js/settings.js +103 -21
- package/public/js/soundcard.js +459 -0
- package/public/js/theme.js +235 -0
- package/public/js/wolf3d.js +22 -0
- package/public/js/x86.js +1978 -0
- package/scripts/donate-qr.py +12 -9
- package/scripts/dos-bench.js +56 -0
- package/scripts/setup.js +34 -12
- package/scripts/shots.mjs +6 -0
- package/scripts/smoke.sh +1 -1
- package/scripts/tls.js +31 -0
- package/server/chain/index/build.js +21 -4
- package/server/collect/monitor.js +30 -1
- package/server/collect/network.js +295 -0
- package/server/config.js +46 -22
- package/server/http/api.js +49 -5
- package/server/http/games.js +77 -0
- package/server/http/server.js +8 -0
- package/server/main.js +53 -8
- package/server/tls/selfsigned.js +160 -0
- package/systemd/blockyard.service +7 -5
- package/docs/PRIVATE-LEADERBOARD.md +0 -230
- package/docs/STATE-2026-09-09.md +0 -200
package/CHANGELOG.md
CHANGED
|
@@ -6,7 +6,256 @@ All notable changes to this project are documented here. The format follows
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
## [0.1.0] — 2026-09-16
|
|
10
|
+
|
|
11
|
+
The first minor release, two days after the initial 0.0.9, and everything since it in one place:
|
|
12
|
+
the 0.0.10 that was prepared on 2026-09-15 was never published, and its changes ship here. Four
|
|
13
|
+
things shaped it. The **first outside review** of 0.0.9 on bitcointalk, which called out a monitor
|
|
14
|
+
that bound every interface with no sign-in: 0.1.0 ships hardened — this machine only, sign-in on,
|
|
15
|
+
HTTPS with a certificate it makes itself, and no outbound connection at all until the exchange
|
|
16
|
+
feed is switched on. A day of **use on a laptop screen**, which found every tab a scroll: every
|
|
17
|
+
page now packs to one screen at 1093×945, and the Mining tab follows mempool.space's dashboard
|
|
18
|
+
with its **View more** panels. **Appearance**: the layout's colours are a setting — light or
|
|
19
|
+
dark, five themes, or nine colours of your own. And the **DOS Diversions**: Wolfenstein 3D, DOOM
|
|
20
|
+
and Quake, unmodified shareware on a PC emulated in the browser, written here with no
|
|
21
|
+
dependencies, because "can it run DOOM?" deserved a straight answer. 945 tests, from 862.
|
|
22
|
+
|
|
23
|
+
Upgrading from 0.0.9: [docs/INSTALL.md §11](docs/INSTALL.md#11-updating) — the first start after
|
|
24
|
+
the update serves HTTPS, creates the `admin` account and prints its password once.
|
|
25
|
+
|
|
26
|
+
### Security
|
|
27
|
+
|
|
28
|
+
- **Hardened defaults** (after the first outside review of 0.0.9): the monitor binds `127.0.0.1`
|
|
29
|
+
and requires sign-in out of the box — the first start creates the `admin` account and prints its
|
|
30
|
+
password once (or takes `BLOCKYARD_ADMIN_PASSWORD`). Reach it from elsewhere over an SSH tunnel,
|
|
31
|
+
or bind a LAN address with `BLOCKYARD_BIND` / `server.hosts`; open read-only access is a choice
|
|
32
|
+
(`BLOCKYARD_AUTH=0`), announced at boot. The boot banner says how to reach a loopback-only
|
|
33
|
+
monitor. Existing installs keep whatever `config/local.json` says.
|
|
34
|
+
- **HTTPS by default.** Every listener serves HTTPS; with no certificate named, the first start
|
|
35
|
+
makes the monitor its own self-signed one under `<data>/tls/` — written without dependencies
|
|
36
|
+
(`server/tls/selfsigned.js`: a v3 X.509 certificate assembled in DER and signed with ECDSA P-256
|
|
37
|
+
over SHA-256), naming the bound hosts, this machine's addresses and hostname — and remakes it
|
|
38
|
+
near expiry or when a bound address is missing from it. `blockyard tls` remakes it by hand
|
|
39
|
+
(`--san` to add names, `--print` to export it). Your own certificate still replaces it;
|
|
40
|
+
`BLOCKYARD_TLS=0` serves plain HTTP behind a proxy. The installer's summary and port probe know
|
|
41
|
+
both schemes.
|
|
42
|
+
- **The installer asks twice before a non-loopback bind.** A LAN or wildcard address is written
|
|
43
|
+
only when the operator types it and confirms it; the default it offers is `127.0.0.1`.
|
|
44
|
+
- **Market polling is off by default** — a new checkbox, **Display settings → Markets & Price →
|
|
45
|
+
Enable market polling**, shared by every screen. A fresh install makes no outbound connection
|
|
46
|
+
but to the node: the Markets and Kiosk tabs say that polling is off and where the switch is,
|
|
47
|
+
Overview's price line stays hidden and the explorer shows no dollar figures. Ticking it takes
|
|
48
|
+
effect at once; unticking parks the feed at once. `BLOCKYARD_MARKETS=0` still removes the feed
|
|
49
|
+
so that the checkbox cannot turn it on. Existing installs tick the box once.
|
|
50
|
+
|
|
51
|
+
### Appearance
|
|
52
|
+
|
|
53
|
+
- **A first tab in Display settings for the colours of the layout.** A theme mode — Light, Dark,
|
|
54
|
+
or System, which follows the operating system and changes with it — and theme cards with swatch
|
|
55
|
+
strips of the face the mode picks: **BlockYard** (the shipped look, the default; its dark face
|
|
56
|
+
is value for value what the monitor drew before), **Mono** (clean grayscale), **Nous** (GitHub's
|
|
57
|
+
chrome with a Nous blue accent), **GitHub** (Light Default and Dark Default) and **Catppuccin**
|
|
58
|
+
(Latte and Mocha). **Custom** is nine colour pickers — page, panels, text, muted text, accent,
|
|
59
|
+
lines, good, warning, bad — with the rest of a face derived from them (a raised panel, the
|
|
60
|
+
softer rules, the fainter text, the darker accent of a pressed button), and whether Custom is
|
|
61
|
+
light or dark read off its page colour; **customise <theme>** copies the theme on screen into
|
|
62
|
+
the pickers so a custom scheme starts from a look. Saved on the server with the other settings,
|
|
63
|
+
so every screen of the monitor draws the same; the sign-in page draws in the theme the browser
|
|
64
|
+
last saw.
|
|
65
|
+
- The theme is applied through the CSSOM (the page's custom properties rewritten on `<html>`),
|
|
66
|
+
which the content-security policy permits where a style attribute is refused. The charts' axis
|
|
67
|
+
text, grid lines and tooltips, the order-book depth chart's two sides and the market charts'
|
|
68
|
+
grounds follow the theme — they were literals of the dark look, and a light theme would have
|
|
69
|
+
drawn grey-on-grey. The 3D boards stay space, and the Explorer's block and transaction pages
|
|
70
|
+
keep their own dark cards.
|
|
71
|
+
|
|
72
|
+
### Mining
|
|
73
|
+
|
|
74
|
+
- **The Mining tab has the network row**: reward stats over the last 144 blocks, the difficulty
|
|
75
|
+
period (blocks remaining, the estimated and the previous change, the next halving), a week of
|
|
76
|
+
pools with luck and counts, a year of hashrate with the difficulty's steps, and the last twelve
|
|
77
|
+
adjustments as a table — every figure from this node alone (`server/collect/network.js`:
|
|
78
|
+
`getblockstats` for the reward window, block headers for the periods and a daily sample, the
|
|
79
|
+
week's coinbases read in the background at the lowest RPC priority).
|
|
80
|
+
- **mempool.space's layout**: two columns in its order (reward stats, difficulty adjustment;
|
|
81
|
+
pools, hashrate; recent blocks, adjustments) under the block flow, our own panels beneath, and
|
|
82
|
+
**View more »** on four cards opening that card full screen — the whole week of pools as a
|
|
83
|
+
table, the year's chart large, the whole attributed window of blocks, a year of adjustments.
|
|
84
|
+
- **The pool chart is a labelled pie**: every pool named beside its slice and joined to it by a
|
|
85
|
+
leader in the slice's colour, the small ones stacked, slices under half a percent gathered as
|
|
86
|
+
"Other" — and the "Other" threshold rises until every label fits the card, so no name runs off
|
|
87
|
+
the bottom at any window height. The pie and the year chart size themselves to the window.
|
|
88
|
+
- **Dollar figures** on the reward stats while market polling is on, from a new `/api/price` that
|
|
89
|
+
answers the cached spot price and never starts the exchange polling itself.
|
|
90
|
+
- The Mempool space viewer left this page — it is on Overview, Block space and Mempool — and with
|
|
91
|
+
it the full-pool poll the page used to ask for. The reward window is exactly 144 blocks.
|
|
92
|
+
- At a narrow window the block flow spans the width and is thinner, and the packages table scrolls
|
|
93
|
+
inside its card instead of bleeding into the neighbour; the three stacks become two below 1400px.
|
|
94
|
+
- **A streak of stale drops of the full-pool poll is one story**: one warning event when it
|
|
95
|
+
starts, a counter on Node & RPC while it lasts, one event when the poll answers again with the
|
|
96
|
+
count and the span. On a day the node answered slowly for thirteen hours, each drop had been its
|
|
97
|
+
own event, 188 of the feed's 200 rows.
|
|
98
|
+
|
|
99
|
+
### Every tab on one screen
|
|
100
|
+
|
|
101
|
+
Measured at 1093×945 and 1600×1000 with a dead-height probe, page by page:
|
|
102
|
+
|
|
103
|
+
- **Globally**: tighter card padding and heading spacing, and a short card beside a tall one keeps
|
|
104
|
+
its own height instead of being stretched to match (Chain & Sync's drill-down card had a
|
|
105
|
+
thousand pixels of nothing under its input; Node & RPC's poll cadence and connection cards
|
|
106
|
+
hundreds).
|
|
107
|
+
- **Overview**: the block flow card a quarter shorter, and the Block space board capped to the
|
|
108
|
+
viewport (it set the whole right column's height), so the events are on the first screen.
|
|
109
|
+
- **Block space**: the card tighter and the board sized so the whole page, note included, fits the
|
|
110
|
+
viewport without a scroll.
|
|
111
|
+
- **Markets**: the board takes what the window leaves, and the exchange table and the order-book
|
|
112
|
+
depth sit side by side beneath it (under 1400px the table drops the pair, 24 h range and volume
|
|
113
|
+
columns; all still in the summary line and on the Kiosk) instead of the depth chart starting a
|
|
114
|
+
thousand pixels down.
|
|
115
|
+
- **Kiosk**: tighter heads and gaps, the price panel's padding trimmed, the Block flow strip a
|
|
116
|
+
quarter shorter, and the full-screen button in that strip's head instead of floating over its
|
|
117
|
+
cards.
|
|
118
|
+
- **Mempool**: keeps its two columns down to 900px (it stacked from 1100), and the room over goes
|
|
119
|
+
to its time-series charts, a fifth taller.
|
|
120
|
+
- **Explorer**: a smaller title, the block strip's padding and scrollbar band trimmed, tighter
|
|
121
|
+
table rows and the table reaching the window's bottom edge — three more blocks on the first
|
|
122
|
+
screen.
|
|
123
|
+
- **Peers**: a long onion or i2p address no longer makes the whole page scroll sideways (it clips
|
|
124
|
+
with an ellipsis and carries the full text as its title; a wide table scrolls inside its card),
|
|
125
|
+
rows and service badges tighter, the top strip's cards at their own heights.
|
|
126
|
+
- **Network**: Throughput beside a stack of Upload and Traffic accounting, the throughput chart
|
|
127
|
+
taller, and the sources table taking the rest of the window.
|
|
128
|
+
- **Events**: the feed reaches the window's bottom edge (it stopped a hundred pixels short).
|
|
129
|
+
- **Chain & Sync**: one-line notes under the block-size and tip charts (the longer sentences are
|
|
130
|
+
their tooltips), the transaction-rate figures as one wrapping line, values that keep to their
|
|
131
|
+
line, and a shorter uptime label — the first three rows sit level and the drill-down and indexes
|
|
132
|
+
reach the first screen.
|
|
133
|
+
- **Node & RPC**: two stacks (RPC etiquette with its figures in two columns, Data quality and Node
|
|
134
|
+
connection; Poll cadence, self-telemetry beside the log tail, Panel sources and the RPC
|
|
135
|
+
console) instead of grid rows that left holes beside the short cards.
|
|
136
|
+
- **Admin**: two stacks (Users over the audit log; Node actions over Change own password, whose
|
|
137
|
+
two fields share a row). **Sign-in** and **404**: the same tighter card.
|
|
138
|
+
- **Display settings**: the tabs in three labelled rows — Boards (Appearance, Block space, Sky,
|
|
139
|
+
Markets & Price), Effects, and the Diversions last; rows, note and groups tighter, the sheet a little wider so hints wrap
|
|
140
|
+
less, and on the two effects tabs the switches run two across with each hint as the row's
|
|
141
|
+
tooltip — the Space effects tab is under half the scrolling it was. The price line on Overview
|
|
142
|
+
switch sits directly under the polling switch it depends on.
|
|
143
|
+
- **About**: the sky runs to the bottom edge with the credit line at its foot, and the GitHub
|
|
144
|
+
link and the tip pill share a row.
|
|
145
|
+
- **The Diversions pages take the window**: the wells of Tetrust, Blockout and Blockanoid grow to
|
|
146
|
+
the window's height (they stopped at 600px), and the DOS screen is always 4:3 and as large as
|
|
147
|
+
the window allows — at a 1093px window the 320×200 picture had been drawn squashed into a
|
|
148
|
+
761×720 box.
|
|
149
|
+
|
|
150
|
+
### DOS Diversions
|
|
151
|
+
|
|
152
|
+
- **DOOM.** The shareware `DOOM.EXE` v1.9 and `DOOM1.WAD` from `games/doom_dos/`, unmodified,
|
|
153
|
+
running on a PC emulated in the browser with no dependencies: an i386 interpreter
|
|
154
|
+
(`public/js/x86.js`), the DOS/4GW machine around it — DOS, DPMI, BIOS, PIC, timer, keyboard and
|
|
155
|
+
a planar VGA (`dospc.js`) — and a Sound Blaster Pro 2 with an OPL3 for the effects and the music
|
|
156
|
+
(`soundcard.js`), in a worker. Demos, menus, savegames and ENDOOM all work; 35 frames a second.
|
|
157
|
+
Mouse capture, WASD keys by default (the switch rebinds the running game at once), smoothing,
|
|
158
|
+
full screen; pauses when you look away; savegames and DOOM's config stay in the browser.
|
|
159
|
+
- **Wolfenstein 3D.** The shareware `WOLF3D.EXE` v1.4 and its `.WL1` files from
|
|
160
|
+
`games/wolf3d_dos/`, unmodified, on the same emulated PC — which now also runs a 16-bit real-mode
|
|
161
|
+
DOS program: real mode in the CPU (segments times sixteen, a wrapping SP, 16-bit string
|
|
162
|
+
instructions and interrupt frames), a plain MZ loader with its relocations, DOS's memory
|
|
163
|
+
allocator, the interrupt vector table, and VGA write mode 1. Menus, demos, AdLib music,
|
|
164
|
+
digitised sound effects, savegames and high scores kept in the browser, at its full 70 frames a
|
|
165
|
+
second. It sits before DOOM and Quake in the Diversions menu.
|
|
166
|
+
- **Quake.** The shareware `QUAKE.EXE` v1.06 and `PAK0.PAK` from `games/quake_dos/`, unmodified,
|
|
167
|
+
on the same emulated PC — which now also plays the go32 stub and CWSDPMI for a DJGPP program:
|
|
168
|
+
segment bases and 16-bit code in the CPU, a COFF loader, a directory tree, DOS's system file
|
|
169
|
+
table, the BIOS tick count. Demos, menus, savegames, sound effects through the Sound Blaster,
|
|
170
|
+
and the order screen on quit. W A S D and mouse look on the first start, Quake's own bindings
|
|
171
|
+
after. Quake starts with a smaller view (`viewsize 80`); **−** and **=** change it and Quake
|
|
172
|
+
keeps the choice.
|
|
173
|
+
- **The emulated PC is fast.** Each instruction is decoded once and cached rather than decoded
|
|
174
|
+
every time it runs (writes into cached code clear what they overlap, because both games patch
|
|
175
|
+
their own drawing code), the arithmetic and the x87 forms Quake runs most have handlers of their
|
|
176
|
+
own, and memory addresses are formed inline: Quake from 77 to about 141 million instructions a
|
|
177
|
+
second, its `timedemo demo1` from 29.7 fps to over 50; in the browser Quake plays at 40–50
|
|
178
|
+
frames a second.
|
|
179
|
+
- **A way out of full screen**: an **exit full screen** button in the top corner while full
|
|
180
|
+
screen, and holding **Esc** for a second (a tap of Esc stays the game's menu, which is what the
|
|
181
|
+
keyboard lock is for); leaving unlocks the keyboard and releases the mouse.
|
|
182
|
+
- The game files are served at `/games/<game>/<path>` (`server/http/games.js`); the shareware
|
|
183
|
+
packages live under `games/` (DOOM's moved from `doom_dos/` at the repository root).
|
|
184
|
+
|
|
185
|
+
### Markets and the effects
|
|
186
|
+
|
|
187
|
+
- **Black hole**, a Markets effect (modelled on NASA's visualisation, svs.gsfc.nasa.gov/14576): a
|
|
188
|
+
point of darkness opens and grows to a horizon over 26 s, the price line bends round it as
|
|
189
|
+
through a lens (the Einstein-radius push), the candles it reaches stretch and lean toward it and
|
|
190
|
+
shrink away into it, and an accretion disk seen nearly edge-on — a thin band white-yellow at its
|
|
191
|
+
inner edge through orange to a dark red rim, five hundred fibres spiralling inward sheared by
|
|
192
|
+
the Keplerian flow, its far side lensed into an arch over the shadow and a smaller one beneath,
|
|
193
|
+
a photon ring hugging the horizon, starlight bent into arcs. **It crosses the board**: it opens
|
|
194
|
+
a fifth of the way in on one side and runs a straight line through the chart to a fifth from the
|
|
195
|
+
other, from one height to another, so the line is seen bending round it as it passes; the
|
|
196
|
+
candles' orbits ride along at a quarter of the first cut's speed. It finishes its crossing before
|
|
197
|
+
it lets go, and lets go evenly, every candle gliding home and growing back smoothly. It hovered
|
|
198
|
+
over Block space for a day and its cubes never came home cleanly enough, so it is a Markets
|
|
199
|
+
effect only.
|
|
200
|
+
- **Supernova** (the solar flare, renamed and remade on NASA Goddard's animation,
|
|
201
|
+
svs.gsfc.nasa.gov/20413): the star is a glint — halo, hot core, diffraction spikes — growing and
|
|
202
|
+
blue-shifting as it goes; the opening explosion is a **white-hot flash**, held and washing far
|
|
203
|
+
out, that throws **a hundred and twenty-eight plumes of white gas** in every direction, each
|
|
204
|
+
flying and growing on its own out to nine star radii and drifting on until the effect is nearly
|
|
205
|
+
done (drawn on a half-resolution layer to keep the frame cheap); the debris is a volume of gas in
|
|
206
|
+
three layers — a blue cloud out in front, a white one behind it into which **violet grows patch
|
|
207
|
+
by patch from a tenth of the run**, and a deep violet heart — with a soft shock band throwing
|
|
208
|
+
and shaking the candles it crosses; and as the cloud dims a **pulsar** beats seven times a
|
|
209
|
+
second at the centre, two thin beams sweeping round, inside a nebula of the same gas that holds
|
|
210
|
+
its violet weight until four fifths of the run. 16 s (24 on Markets).
|
|
211
|
+
- **Fireworks are a display**, on both boards: every shell drawn — the rocket's arc, a white flash
|
|
212
|
+
and a shockwave ring at the burst, seven shell kinds by turn (peony, chrysanthemum, willow, ring,
|
|
213
|
+
crossette, strobe and more), sixty to ninety sparks each a curved trail, a lens flare at every
|
|
214
|
+
burst, glitter rain, and a nebula of smoke that drifts up and lingers; up to ten shells on
|
|
215
|
+
Markets over 14 s (five on Block space), each lighting the candles under it in its own colour.
|
|
216
|
+
**Off by default** on both boards, kept for special occasions.
|
|
217
|
+
- **X-ray**, on both boards: a front sweeps the board and everything behind it goes x-ray — bodies
|
|
218
|
+
dimmed to glass, every edge lit, a raster of thin lines across each face — then develops back.
|
|
219
|
+
- **Breathe** and **Light saber**, on the price line: three slow swells from the plain wire to
|
|
220
|
+
white heat and back; and the line igniting from its left end, blue, green, red or purple by the
|
|
221
|
+
run, humming with a breathing glow, spitting sparks, retracting to the hilt.
|
|
222
|
+
- **The energy pulse is heat, not blue, and its head is a crackling ball of plasma**; **the scan
|
|
223
|
+
line is a light curtain** standing on the board floor to the chart's top; **ball lightning is a
|
|
224
|
+
light source**, its arcs discharges built by midpoint displacement rather than zigzags, a quarter
|
|
225
|
+
of its size and a third of its speed on Markets; the scanner's cone is dimmer on both boards.
|
|
226
|
+
- **The Markets board keeps its price fit across refreshes**: the last fit is kept while the data
|
|
227
|
+
still sits inside it and fills at least two-thirds of it, so a refresh no longer re-scales the
|
|
228
|
+
whole chart unanimated. Whatever a head pulls is painted last, nearest the head on top; a held
|
|
229
|
+
pool refresh waits a moment and a half after an idle effect ends, with the board whole and still.
|
|
230
|
+
- **Layered soft fills add up correctly** (`softStops`): each nested disc carries only its
|
|
231
|
+
increment, so a stop's cumulative opacity is exactly the stop's; measured on the Kiosk, the
|
|
232
|
+
supernova's peak opacity fell from about 0.9 to about 0.45 and the chart shows through it.
|
|
233
|
+
- **The no-repeat window holds from the first pick** on both boards: every effect plays once
|
|
234
|
+
before any repeats (a negative slice index had let one come round at the tenth pick). The
|
|
235
|
+
searchlight and the tractor beam, which fly the same saucer, share the window.
|
|
236
|
+
- **A Kiosk test suite** (`test/kiosk.test.js`): every Markets and Block space effect plays through
|
|
237
|
+
the frame loop on a Kiosk-sized panel; the supernova, the black hole and the fireworks are
|
|
238
|
+
bounded by the board's width so no panel is covered.
|
|
239
|
+
|
|
240
|
+
### Fixed
|
|
241
|
+
|
|
242
|
+
- **The donation QR shows on Safari.** It was an inline SVG of 800 module rects, and Safari on
|
|
243
|
+
the first Mac install painted its white ground and none of the rects. It is a PNG now, painted
|
|
244
|
+
the same everywhere.
|
|
245
|
+
- **A dead index worker fails the build instead of hanging it.** A worker killed outright (out of
|
|
246
|
+
memory, with four beside the node) left its job unanswered and the build sat at "scan 5,720 of
|
|
247
|
+
5,721, about 1 s left" for an hour and a half on the first Mac install. The run now rejects the
|
|
248
|
+
moment a worker exits or throws, naming the job and the fix (fewer `addressIndexWorkers`); the
|
|
249
|
+
progress flag says *no progress for N min* when nothing has moved.
|
|
250
|
+
- The 0.0.9 release notes' test count corrected (862, not 864).
|
|
251
|
+
|
|
252
|
+
### Documentation
|
|
253
|
+
|
|
254
|
+
- INSTALL, GETTING-STARTED, SECURITY, CONFIGURATION, API, TROUBLESHOOTING and the README describe
|
|
255
|
+
the hardened defaults, HTTPS and the polling switch; INSTALL §11 has the notes for updating a
|
|
256
|
+
0.0.9 install; the USER-GUIDE has the Appearance section, the Mining row and the packed layouts;
|
|
257
|
+
TROUBLESHOOTING explains a streak of stale pool-poll drops. Screenshots re-shot at 0.1.0, with a
|
|
258
|
+
Mining shot added. The announcement for the bitcointalk thread is in `docs/announcement/0.1.0/`.
|
|
10
259
|
|
|
11
260
|
## [0.0.9] — 2026-09-14
|
|
12
261
|
|
|
@@ -676,4 +925,5 @@ are an original implementation (`public/js/blockpack.js`, `public/js/feepalette.
|
|
|
676
925
|
Internal first version: multi-user monitor with charts, sync viewer, mempool view, peers and
|
|
677
926
|
event feed.
|
|
678
927
|
|
|
928
|
+
[0.0.10]: https://github.com/BobClawblaw/blockyard/releases/tag/v0.0.10
|
|
679
929
|
[0.0.9]: https://github.com/BobClawblaw/blockyard/releases/tag/v0.0.9
|
package/README.md
CHANGED
|
@@ -5,8 +5,8 @@ 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
|
|
@@ -21,18 +21,19 @@ 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. 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
|
|
|
@@ -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: 945 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 # 945 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,13 +146,22 @@ RPC etiquette) and [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) for how it fits
|
|
|
136
146
|
|
|
137
147
|
## Status
|
|
138
148
|
|
|
139
|
-
Version **0.0
|
|
140
|
-
|
|
149
|
+
Version **0.1.0** — the first minor release, two days after the initial 0.0.9, and pre-release
|
|
150
|
+
software: the word is meant literally. Published 2026-09-16: on [npm](https://www.npmjs.com/package/blockyard)
|
|
151
|
+
as `blockyard`, as a [GitHub release](https://github.com/BobClawblaw/blockyard/releases/tag/v0.1.0),
|
|
152
|
+
and announced on
|
|
153
|
+
[bitcointalk](https://bitcointalk.org/index.php?topic=5594141.msg67144312) — questions, bug
|
|
154
|
+
reports and reviews are welcome there and in [issues](https://github.com/BobClawblaw/blockyard/issues).
|
|
155
|
+
It ships **hardened**: bound to this machine, sign-in on, HTTPS with a certificate it makes itself,
|
|
156
|
+
and **zero telemetry** — no outbound connection to anyone but your node until you tick the market
|
|
157
|
+
polling switch yourself.
|
|
158
|
+
The test suite is
|
|
159
|
+
comprehensive (945 tests, plus a live smoke run), the monitoring side is solid, and the
|
|
141
160
|
explorer's biggest gap is closed: **address history and balances**, which Bitcoin Core cannot
|
|
142
161
|
answer at any setting, now come from an **address index BlockYard builds itself** from the
|
|
143
162
|
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
|
|
163
|
+
(every balance equal to `scantxoutset`, to the satoshi) and costs a few hours on the default four
|
|
164
|
+
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
165
|
RPC stays responsive; without one, the address page says *not indexed* rather than showing a
|
|
147
166
|
zero. An address's unspent outputs are listed too (for a history of up to 100 transactions).
|
|
148
167
|
What it does not yet have: an address's mempool transactions.
|
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
|
package/docs/API.md
CHANGED
|
@@ -89,7 +89,7 @@ Other statuses: `204` for `OPTIONS` on any path (`Allow: GET,POST,DELETE,HEAD`).
|
|
|
89
89
|
|
|
90
90
|
Each route in the table has one of three auth levels:
|
|
91
91
|
|
|
92
|
-
| Level | Accounts off (
|
|
92
|
+
| Level | Accounts off (`BLOCKYARD_AUTH=0`) | Accounts on (the default) |
|
|
93
93
|
|---|---|---|
|
|
94
94
|
| `none` | Open. | Open. No session needed. |
|
|
95
95
|
| `any` | Served as the built-in anonymous user (`role: "viewer"`). | Any valid, non-disabled session. Without one: `401`. |
|
|
@@ -97,14 +97,14 @@ Each route in the table has one of three auth levels:
|
|
|
97
97
|
|
|
98
98
|
The roles are `viewer` < `operator` < `admin`. No route in the table requires `viewer` or `operator` by itself. Those two roles matter in two places only: each node action names a minimum role (section 14), and `POST /api/password` needs `admin` to change *another* user's password.
|
|
99
99
|
|
|
100
|
-
**Open mode (
|
|
100
|
+
**Open mode (`auth.enabled=false`, a choice; the default is accounts on).** No sign-in. Anyone who can reach the port can read everything (state, charts, events, peers, mempool, explorer, markets, the read-only RPC console) as `viewer`. The ceiling is fixed and nothing can raise it. As a result:
|
|
101
101
|
|
|
102
102
|
- user administration, `/api/audit` and password changes are closed;
|
|
103
103
|
- node writes (`/api/action`) are refused unless `BLOCKYARD_ALLOW_WRITES_WITHOUT_AUTH=1` was set deliberately;
|
|
104
104
|
- `/api/login` answers `403 accounts_disabled`;
|
|
105
105
|
- `GET /login` redirects (`302`) to `/`.
|
|
106
106
|
|
|
107
|
-
**Accounts mode (
|
|
107
|
+
**Accounts mode (the default).** Sign-in, roles, sessions, CSRF protection and a per-user audit trail. On first start with no users, an `admin` account is created. Its password comes from `BLOCKYARD_ADMIN_PASSWORD`, or is generated and printed once to the server log.
|
|
108
108
|
|
|
109
109
|
### Session cookie
|
|
110
110
|
|
|
@@ -224,8 +224,8 @@ Auth `none`, not rate limited. Built for uptime probes. `ok` is `true` when at l
|
|
|
224
224
|
{
|
|
225
225
|
"ok": true,
|
|
226
226
|
"degraded": [],
|
|
227
|
-
"version": "0.0
|
|
228
|
-
"build": "0.0
|
|
227
|
+
"version": "0.1.0",
|
|
228
|
+
"build": "0.1.0-fd620adc52",
|
|
229
229
|
"scheme": "http",
|
|
230
230
|
"tls": false,
|
|
231
231
|
"uptimeSec": 1519,
|
|
@@ -242,7 +242,7 @@ Auth `none`, not rate limited. Built for uptime probes. `ok` is `true` when at l
|
|
|
242
242
|
What the About page shows: the monitor's version and live build, and the **shape** of the machine it runs on.
|
|
243
243
|
|
|
244
244
|
```json
|
|
245
|
-
{ "version": "0.0
|
|
245
|
+
{ "version": "0.1.0", "build": "0.1.0-a6ecedff3c", "platform": "linux", "release": "7.0.0-31-generic",
|
|
246
246
|
"arch": "x64", "cpus": 32, "cpuModel": "AMD Ryzen 9 9950X3D 16-Core Processor",
|
|
247
247
|
"totalMemGb": 132.3, "node": "v22.23.2", "uptimeSec": 2355 }
|
|
248
248
|
```
|
|
@@ -261,9 +261,9 @@ Auth `none`. Answers "is the code in my tab the code on disk?" The build id is `
|
|
|
261
261
|
|
|
262
262
|
```json
|
|
263
263
|
{
|
|
264
|
-
"version": "0.0
|
|
265
|
-
"build": "0.0
|
|
266
|
-
"bootBuild": "0.0
|
|
264
|
+
"version": "0.1.0",
|
|
265
|
+
"build": "0.1.0-5223f98d84",
|
|
266
|
+
"bootBuild": "0.1.0-fd620adc52",
|
|
267
267
|
"matchesClient": null,
|
|
268
268
|
"scheme": "http",
|
|
269
269
|
"tls": false,
|
|
@@ -295,6 +295,7 @@ Top-level keys:
|
|
|
295
295
|
```
|
|
296
296
|
id label color online chain ibd tip sync progress warnings difficulty hashrateEstEh hashrateNote
|
|
297
297
|
avgBlockGapSec sizeOnDisk pruned chainwork uptimeSec network mempool peers net attribution blocks
|
|
298
|
+
network (the Mining tab's network row: rewards over 144 blocks, adjustment, halving, adjustments[], hashrate { networkHashPs, series[] }, pools { blocks, luckPct, pools[], filled, todo }; collect/network.js)
|
|
298
299
|
fees mining utxo chaintxstats indexes tips deployments rpcInfo log health series app user seq
|
|
299
300
|
```
|
|
300
301
|
|
|
@@ -331,7 +332,7 @@ Trimmed example:
|
|
|
331
332
|
"health": { "rpc": { "online": true, "...": "..." }, "cadence": { "fast": { "configuredMs": 4000,
|
|
332
333
|
"effectiveMs": 4000, "stretched": false, "lastRunMs": 120 } }, "quality": [] },
|
|
333
334
|
"series": { "mempool": { "hour": [ { "t": 1789154820000, "v": 18780 } ], "...": "..." } },
|
|
334
|
-
"app": { "version": "0.0
|
|
335
|
+
"app": { "version": "0.1.0", "build": "0.1.0-fd620adc52", "scheme": "http", "uptimeSec": 1536,
|
|
335
336
|
"sseClients": 5, "self": { "rssMb": 175.6, "heapMb": 42.8, "cpuPct": 2.71 }, "serverTime": 1789155688322 },
|
|
336
337
|
"user": { "username": "anonymous", "role": "viewer", "id": "anonymous", "disabled": false, "lastLoginAt": null },
|
|
337
338
|
"seq": 406
|
|
@@ -1029,8 +1030,9 @@ To poll incrementally, keep `maxSeq` and pass it back as `since`. The filters ar
|
|
|
1029
1030
|
|
|
1030
1031
|
Exchange prices from the public REST APIs of Coinbase, Kraken, Bitstamp, Bitfinex and OKX. **This is the only outbound connection BlockYard makes that is not to the node.** It runs server-side, because the page's CSP allows `connect-src 'self'` only.
|
|
1031
1032
|
|
|
1032
|
-
- **
|
|
1033
|
-
- `BLOCKYARD_MARKETS=0` (or `markets.enabled=false`)
|
|
1033
|
+
- **Off by default.** Polling runs only while the Display setting **Markets & Price → Enable market polling** is on (`markets.polling` in the shared settings file, read per request). With it off, both endpoints answer `{ "ok": true, "enabled": false, "polling": false, "note": "market polling is off ..." }`, the call parks the feed, and the monitor makes no outbound connection but to the node.
|
|
1034
|
+
- `BLOCKYARD_MARKETS=0` (or `markets.enabled=false`) removes the feed altogether; both endpoints then answer `{ "ok": true, "enabled": false, "note": "market data is off on this server ..." }` whatever the setting.
|
|
1035
|
+
- **On demand.** With polling on, nothing is fetched until someone calls `/api/markets` or `/api/markets/depth`. Each call "touches" the feed. The dashboard's Overview makes that call by default (Display settings → Markets & Price → Price line on Overview), so a monitor with anyone on its landing page is polling. While touched, it polls tickers every 15 s, hourly candles every 5 min and order books every 30 s. It stops 10 minutes after the last touch.
|
|
1034
1036
|
- An exchange that fails keeps its last data and reports `error`. It is never dropped or zero-filled.
|
|
1035
1037
|
|
|
1036
1038
|
### `GET /api/markets`
|
|
@@ -1222,7 +1224,7 @@ If the node refuses, the answer is `200` with `{ "ok": false, "action", "method"
|
|
|
1222
1224
|
|
|
1223
1225
|
## 15. Accounts, sessions, users and audit
|
|
1224
1226
|
|
|
1225
|
-
These routes are meaningful only with
|
|
1227
|
+
These routes are meaningful only with accounts on (the default). In open mode they answer as noted.
|
|
1226
1228
|
|
|
1227
1229
|
The user object returned by these routes (`publicUser`):
|
|
1228
1230
|
|
|
@@ -1378,7 +1380,7 @@ The monitor's own health: process, RPC client, log tail, stream clients and the
|
|
|
1378
1380
|
```json
|
|
1379
1381
|
{
|
|
1380
1382
|
"self": { "t": 1789155700000, "rssMb": 175.6, "heapMb": 42.8, "sseClients": 5, "usersActive": 0,
|
|
1381
|
-
"cpuPct": 2.71, "eventRate": 0, "build": "0.0
|
|
1383
|
+
"cpuPct": 2.71, "eventRate": 0, "build": "0.1.0-fd620adc52" },
|
|
1382
1384
|
"nodes": [
|
|
1383
1385
|
{ "id": "main",
|
|
1384
1386
|
"rpc": { "nodeId": "main", "url": "http://127.0.0.1:8332", "cookieSource": "...", "online": true,
|