Jun 12, 9-10 PM (5)
Jun 12, 10-11 PM (30)
Jun 12, 11-12 AM (6)
Jun 13, 12-1 AM (6)
Jun 13, 1-2 AM (2)
Jun 13, 2-3 AM (0)
Jun 13, 3-4 AM (3)
Jun 13, 4-5 AM (0)
Jun 13, 5-6 AM (3)
Jun 13, 6-7 AM (7)
Jun 13, 7-8 AM (5)
Jun 13, 8-9 AM (6)
Jun 13, 9-10 AM (14)
Jun 13, 10-11 AM (12)
Jun 13, 11-12 PM (2)
Jun 13, 12-1 PM (23)
Jun 13, 1-2 PM (21)
Jun 13, 2-3 PM (8)
Jun 13, 3-4 PM (1)
Jun 13, 4-5 PM (4)
Jun 13, 5-6 PM (4)
Jun 13, 6-7 PM (3)
Jun 13, 7-8 PM (3)
Jun 13, 8-9 PM (7)
Jun 13, 9-10 PM (16)
Jun 13, 10-11 PM (19)
Jun 13, 11-12 AM (24)
Jun 14, 12-1 AM (18)
Jun 14, 1-2 AM (0)
Jun 14, 2-3 AM (0)
Jun 14, 3-4 AM (0)
Jun 14, 4-5 AM (2)
Jun 14, 5-6 AM (0)
Jun 14, 6-7 AM (2)
Jun 14, 7-8 AM (3)
Jun 14, 8-9 AM (0)
Jun 14, 9-10 AM (1)
Jun 14, 10-11 AM (2)
Jun 14, 11-12 PM (10)
Jun 14, 12-1 PM (8)
Jun 14, 1-2 PM (4)
Jun 14, 2-3 PM (8)
Jun 14, 3-4 PM (2)
Jun 14, 4-5 PM (1)
Jun 14, 5-6 PM (1)
Jun 14, 6-7 PM (0)
Jun 14, 7-8 PM (11)
Jun 14, 8-9 PM (1)
Jun 14, 9-10 PM (13)
Jun 14, 10-11 PM (29)
Jun 14, 11-12 AM (23)
Jun 15, 12-1 AM (8)
Jun 15, 1-2 AM (10)
Jun 15, 2-3 AM (4)
Jun 15, 3-4 AM (4)
Jun 15, 4-5 AM (1)
Jun 15, 5-6 AM (4)
Jun 15, 6-7 AM (6)
Jun 15, 7-8 AM (41)
Jun 15, 8-9 AM (26)
Jun 15, 9-10 AM (11)
Jun 15, 10-11 AM (35)
Jun 15, 11-12 PM (25)
Jun 15, 12-1 PM (40)
Jun 15, 1-2 PM (26)
Jun 15, 2-3 PM (21)
Jun 15, 3-4 PM (24)
Jun 15, 4-5 PM (21)
Jun 15, 5-6 PM (13)
Jun 15, 6-7 PM (13)
Jun 15, 7-8 PM (7)
Jun 15, 8-9 PM (26)
Jun 15, 9-10 PM (20)
Jun 15, 10-11 PM (22)
Jun 15, 11-12 AM (39)
Jun 16, 12-1 AM (11)
Jun 16, 1-2 AM (5)
Jun 16, 2-3 AM (1)
Jun 16, 3-4 AM (9)
Jun 16, 4-5 AM (6)
Jun 16, 5-6 AM (1)
Jun 16, 6-7 AM (16)
Jun 16, 7-8 AM (81)
Jun 16, 8-9 AM (18)
Jun 16, 9-10 AM (28)
Jun 16, 10-11 AM (22)
Jun 16, 11-12 PM (31)
Jun 16, 12-1 PM (37)
Jun 16, 1-2 PM (49)
Jun 16, 2-3 PM (34)
Jun 16, 3-4 PM (28)
Jun 16, 4-5 PM (37)
Jun 16, 5-6 PM (17)
Jun 16, 6-7 PM (26)
Jun 16, 7-8 PM (9)
Jun 16, 8-9 PM (11)
Jun 16, 9-10 PM (4)
Jun 16, 10-11 PM (31)
Jun 16, 11-12 AM (9)
Jun 17, 12-1 AM (8)
Jun 17, 1-2 AM (8)
Jun 17, 2-3 AM (11)
Jun 17, 3-4 AM (4)
Jun 17, 4-5 AM (1)
Jun 17, 5-6 AM (6)
Jun 17, 6-7 AM (99)
Jun 17, 7-8 AM (33)
Jun 17, 8-9 AM (22)
Jun 17, 9-10 AM (56)
Jun 17, 10-11 AM (18)
Jun 17, 11-12 PM (19)
Jun 17, 12-1 PM (57)
Jun 17, 1-2 PM (28)
Jun 17, 2-3 PM (37)
Jun 17, 3-4 PM (26)
Jun 17, 4-5 PM (19)
Jun 17, 5-6 PM (16)
Jun 17, 6-7 PM (10)
Jun 17, 7-8 PM (14)
Jun 17, 8-9 PM (12)
Jun 17, 9-10 PM (37)
Jun 17, 10-11 PM (29)
Jun 17, 11-12 AM (14)
Jun 18, 12-1 AM (12)
Jun 18, 1-2 AM (8)
Jun 18, 2-3 AM (5)
Jun 18, 3-4 AM (11)
Jun 18, 4-5 AM (11)
Jun 18, 5-6 AM (11)
Jun 18, 6-7 AM (9)
Jun 18, 7-8 AM (19)
Jun 18, 8-9 AM (83)
Jun 18, 9-10 AM (45)
Jun 18, 10-11 AM (51)
Jun 18, 11-12 PM (23)
Jun 18, 12-1 PM (67)
Jun 18, 1-2 PM (14)
Jun 18, 2-3 PM (53)
Jun 18, 3-4 PM (44)
Jun 18, 4-5 PM (64)
Jun 18, 5-6 PM (24)
Jun 18, 6-7 PM (21)
Jun 18, 7-8 PM (13)
Jun 18, 8-9 PM (17)
Jun 18, 9-10 PM (23)
Jun 18, 10-11 PM (30)
Jun 18, 11-12 AM (26)
Jun 19, 12-1 AM (13)
Jun 19, 1-2 AM (9)
Jun 19, 2-3 AM (5)
Jun 19, 3-4 AM (2)
Jun 19, 4-5 AM (11)
Jun 19, 5-6 AM (4)
Jun 19, 6-7 AM (92)
Jun 19, 7-8 AM (18)
Jun 19, 8-9 AM (37)
Jun 19, 9-10 AM (39)
Jun 19, 10-11 AM (27)
Jun 19, 11-12 PM (30)
Jun 19, 12-1 PM (53)
Jun 19, 1-2 PM (66)
Jun 19, 2-3 PM (32)
Jun 19, 3-4 PM (61)
Jun 19, 4-5 PM (9)
Jun 19, 5-6 PM (4)
Jun 19, 6-7 PM (17)
Jun 19, 7-8 PM (15)
Jun 19, 8-9 PM (1)
Jun 19, 9-10 PM (5)
3,156 commits this week Jun 12, 2026 - Jun 19, 2026
chore(deps): bump express-openapi-validator to ^5.6.2 (pulls multer 2.x)
Bumps express-openapi-validator in cardano-services from ^4.13.8 to ^5.6.2,
which depends on multer ^2.0.2 — clearing the multer high-severity advisory
(< 2.x). The validation middleware options we pass (apiSpec, ignoreUndocumented,
validateRequests, validateResponses) are unchanged in v5.

v5 type rename fix: OpenAPIV3.Document -> OpenAPIV3.DocumentV3 (src + test).

Validated: cardano-services builds clean; openApi unit test passes; no new test
failures (the StakePoolBuilder DB test and TxSubmit are the pre-existing Node 22
baseline, unrelated). HTTP request/response validation behaviour is exercised by
CI's cardano-services HTTP suite.

Resolves #1705.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
chore(deps): relock axios to 1.18.0
Refreshes the lockfile so the `^1.7.4` axios consumers (cardano-services,
cardano-services-client, util-dev) resolve to 1.18.0 — clears the axios 1.x
advisories (SSRF/credential-leak/DoS family, < 1.16.x). In-range relock, no
manifest change. Now viable on the Node 22 base (#1719).

A legacy axios `0.25.0` copy remains via an old transitive (axios 0.x -> 1.x is
a major for that parent) — tracked in #1704.

Validated: full clean build green on axios 1.18 (type-level). HTTP runtime
behaviour (HttpProvider) is exercised by CI; the local sandbox can't run the
in-process socket tests.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
chore(deps): bump ip-address to ^10.2.0 in core
Bumps the direct `ip-address` dependency in @cardano-sdk/core from ^9.0.5 to
^10.2.0 (advisory GHSA for ip-address < 10.1.1; ip-address@10 requires only
node >= 12). core's usage (Address4/Address6 isValid, toUnsignedByteArray,
fromUnsignedByteArray, canonicalForm in ipUtils) is unchanged across the major.

Closes the core direct-manifest alert. A transitive `[email protected]` remains
via `socks` (build/dev tooling: chromedriver/webdriverio proxy chain) and would
need that parent bumped — build-context only, tracked in #1707.

Validated: core builds; core suite 992/992 (covers ipUtils).

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
chore: target Node 22 LTS (drop EOL Node 18) + required compat fixes
The project was pinned to the now-EOL Node 18.12.0 (.nvmrc + all CI workflows)
with a stale `engines: >=16.20.2`. Move to the Node 22 LTS line, tracked by
major so it doesn't go stale again:

- .nvmrc: 22 · all 9 CI workflows: node-version 22 · engines.node: >=22 (all manifests)
- @types/node: ^18 -> ^22

Node 22 / @types/node 22 compatibility fixes (folded in so every commit builds):
- cardano-services WsServer + projection/e2e tests: type interval handles as
  NodeJS.Timeout (setInterval no longer returns the legacy NodeJS.Timer)
- e2e measurement-util (src + test): PerformanceEntry no longer carries `detail`
- shared jest base config: fakeTimers `doNotFake: ['performance']` (Node 22's
  read-only global `performance` can't be replaced by the fake-timers impl), and
  a setupFile disabling http(s).globalAgent keepAlive — Node 19+ defaults it to
  true, so HTTP tests that restart servers between cases reused stale sockets
  ("socket hang up" / AxiosError in HttpProvider + TxSubmit suites)
- cardano-services-client test: --runInBand (avoids a jest-worker circular-JSON
  IPC crash on a follow-redirects object)
- TypeormStakePoolProvider util test: assert toThrow(SyntaxError) (V8 JSON
  message wording differs across Node versions)

Docker: NODEJS_MAJOR_VERSION=22, plus a multi-stage `deps-builder` that installs
the build toolchain (build-essential/python3/libudev-dev/libusb/pkg-config) to
compile native modules — Node 22 has no prebuilds for some older native deps
(cpu-features, chacha-native, node-hid/usb). Toolchain stays in the builder;
runtime images copy the compiled node_modules and stay lean.

Unblocks the Node-20+ dependency majors that couldn't pass CI on Node 18.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
chore: target Node 22 LTS (drop EOL Node 18) + required compat fixes
The project was pinned to the now-EOL Node 18.12.0 (.nvmrc + all CI workflows)
with a stale `engines: >=16.20.2`. Move to the Node 22 LTS line, tracked by
major so it doesn't go stale again:

- .nvmrc: 22 · all 9 CI workflows: node-version 22 · engines.node: >=22 (all manifests)
- @types/node: ^18 -> ^22

Node 22 / @types/node 22 compatibility fixes (folded in so every commit builds):
- cardano-services WsServer + projection/e2e tests: type interval handles as
  NodeJS.Timeout (setInterval no longer returns the legacy NodeJS.Timer)
- e2e measurement-util (src + test): PerformanceEntry no longer carries `detail`
- shared jest base config: fakeTimers `doNotFake: ['performance']` — Node 22's
  read-only global `performance` cannot be replaced by the fake-timers impl
- TypeormStakePoolProvider util test: assert toThrow(SyntaxError) (V8 JSON
  message wording differs across Node versions)

Docker: NODEJS_MAJOR_VERSION=22, and a multi-stage `deps-builder` that installs
the build toolchain (build-essential/python3/libudev-dev/libusb/pkg-config) to
compile native modules from source — Node 22 has no prebuilds for some older
native deps (cpu-features, chacha-native, node-hid/usb). The toolchain stays in
the builder; the runtime images copy the compiled node_modules and remain lean.

Unblocks the Node-20+ dependency majors that couldn't pass CI on Node 18.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
chore: target Node 22 LTS (drop EOL Node 18) + required compat fixes
The project was pinned to the now-EOL Node 18.12.0 (.nvmrc + all CI workflows)
with a stale `engines: >=16.20.2`. Move to the Node 22 LTS line, tracked by
major so it doesn't go stale again:

- .nvmrc: 22 · all 9 CI workflows: node-version 22 · Dockerfile: NODEJS_MAJOR_VERSION=22
- engines.node: >=22 across root + every workspace manifest
- @types/node: ^18 -> ^22

Node 22 / @types/node 22 compatibility fixes (folded in so every commit builds):
- cardano-services WsServer: type heartbeat/stake intervals as NodeJS.Timeout
  (setInterval no longer returns the legacy NodeJS.Timer; clearInterval rejects it)
- e2e measurement-util: PerformanceEntry no longer carries `detail` (now on
  PerformanceMark/Measure) — cast the entry and narrow the mark filter
- shared jest base config: fakeTimers `doNotFake: ['performance']` — Node 22's
  read-only global `performance` cannot be replaced by the fake-timers impl
  (was crashing many suites across cardano-services/ogmios/web-extension/etc.)
- TypeormStakePoolProvider util test: assert `toThrow(SyntaxError)` instead of a
  V8 JSON.parse message string that differs across Node versions

Unblocks the Node-20+ dependency majors that couldn't pass CI on Node 18.

Validated: clean full build green on @types/node 22 (all 21 workspaces);
core/crypto/key-management + cardano-services unit suites green except
DB-backed tests (no local DB) and the in-process HTTP TxSubmit tests (local
sockets) — both validated by CI.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
fix(bootstrap): download snapshots via ranged ring buffer
Bootstrapping from the Cloudflare R2 snapshot bucket intermittently failed
with "error decoding response body / operation timed out" while unpacking a
segment. The old path streamed a single HTTP response directly into the tar
extractor, so the connection stayed open for the entire multi-GB transfer and
its lifetime was coupled to disk-write backpressure. R2 tears down such
long-lived, slowly-drained responses where S3 tolerated them, and any
transient stall on that one connection was fatal and unrecoverable.

Replace the single stream with a ranged ring buffer (new `ranged` module):

- A background thread downloads the snapshot in bounded 64 MiB byte ranges,
  staging a small fixed-size window (4 chunks, ~256 MiB) on disk ahead of the
  extractor. Backpressure is applied *before* a request is issued (via a permit
  pool), so the server never sees an idle/slow-drained connection.
- Each chunk is short-lived and retried with exponential backoff on failure,
  making transient stalls recoverable instead of fatal.
- A HEAD probe selects the ranged path when the endpoint advertises
  `Accept-Ranges: bytes`; otherwise it falls back to the original single-stream
  download (with its own untimed client, since an overall timeout must not cap
  a full-body stream).

Verified end-to-end against the live R2 endpoint with an ignored integration
test that downloads a prefix through the ring buffer and asserts byte-exactness
versus a direct ranged fetch, plus window backpressure and staging cleanup.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>