Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/publish-simplex-desktop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ jobs:
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "24.19.0"
node-version: "24.22.1"

- name: Setup pnpm
uses: pnpm/action-setup@v4
Expand Down Expand Up @@ -161,7 +161,7 @@ jobs:
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "24.19.0"
node-version: "24.22.1"

- name: Setup pnpm
uses: pnpm/action-setup@v4
Expand Down Expand Up @@ -368,7 +368,7 @@ jobs:
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "24.19.0"
node-version: "24.22.1"

- name: Setup pnpm
uses: pnpm/action-setup@v4
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/test-simplex-desktop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -80,14 +80,14 @@ jobs:

- name: Execute staged Node on Unix
if: runner.os != 'Windows'
run: test "$(packages/simplex-desktop/resources/node/${{ matrix.target }}/node --version)" = "v24.19.0"
run: test "$(packages/simplex-desktop/resources/node/${{ matrix.target }}/node --version)" = "v24.22.1"

- name: Execute staged Node on Windows
if: runner.os == 'Windows'
shell: pwsh
run: |
$version = & "packages/simplex-desktop/resources/node/win32-x64/node.exe" --version
if ($version -ne "v24.19.0") { throw "Expected v24.19.0, got $version" }
if ($version -ne "v24.22.1") { throw "Expected v24.22.1, got $version" }

desktop-e2e-artifacts:
name: Build Simplex desktop E2E artifacts
Expand Down
2 changes: 1 addition & 1 deletion docs/content/developers/evm/simplex/installation.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ simplex
```

The scope matters: the unscoped `simplex` package on npm is unrelated. The installed command is still
`simplex`. A global install needs Node.js 22.16 or newer; the desktop and Docker distributions bundle
`simplex`. A global install needs Node.js 22.23.4+, 24.22.1+ or 26.12.1+; the desktop and Docker distributions bundle
their own runtime.

## Building a config file
Expand Down
4 changes: 2 additions & 2 deletions docs/content/developers/sdk/api/simplex.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -878,8 +878,8 @@ it is.
directory written by the binary is picked up unchanged. Limit orders and operator state ride in
`bids.db` beside the bids, and implements `patch`; a `runtime-state.json` from an earlier version is imported once
and then removed. It is built on Node's
built-in `node:sqlite`, so there is no native module to install or compile — which is why the
package requires Node 22.16 or newer.
built-in `node:sqlite`, so there is no native module to install or compile. The package requires
Node 22.23.4+, 24.22.1+ or 26.12.1+.

**Example — a custom backend:**

Expand Down
4 changes: 2 additions & 2 deletions docs/content/developers/sdk/simplex.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ less work.
npm install @hyperbridge/simplex
```

Node.js 22.16 or later. The package ships ESM and CJS builds with bundled types.
Node.js 22.23.4+, 24.22.1+ or 26.12.1+. The package ships ESM and CJS builds with bundled types.

## Starting a solver

Expand Down Expand Up @@ -254,7 +254,7 @@ that is only reclaimable by retracting it, and the retraction sweep finds what t
querying the bid store. Lose those records and you leak deposits.

The bundled SQLite store is a separate entry point. It runs on Node's built-in `node:sqlite`, so
there is no native module to install or compile — the package just needs Node 22.16 or newer:
there is no native module to install or compile — the package just needs Node 22.23.4+, 24.22.1+ or 26.12.1+:

```ts lineNumbers
import { SqliteDataStore } from "@hyperbridge/simplex/sqlite"
Expand Down
2 changes: 1 addition & 1 deletion sdk/packages/simplex-desktop/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ without a separate trusted network boundary.
## Runtime resources

The staging script follows Node's binary-verification procedure: it verifies the signed
`SHASUMS256.txt.asc` with the pinned release key, verifies the selected Node 24.19.0 archive checksum,
`SHASUMS256.txt.asc` with the pinned release key, verifies the selected Node 24.22.1 archive checksum,
and installs only `node` or `node.exe`. `darwin-universal` verifies both macOS slices independently
before merging them with `lipo`.

Expand Down
2 changes: 1 addition & 1 deletion sdk/packages/simplex-desktop/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@hyperbridge/simplex-desktop",
"productName": "Simplex",
"version": "0.18.3",
"version": "0.18.4",
"private": true,
"description": "Native desktop shell for the Simplex intent solver",
"author": "Polytope Labs <hello@polytope.technology>",
Expand Down
2 changes: 1 addition & 1 deletion sdk/packages/simplex-desktop/scripts/stage-node.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { pipeline } from "node:stream/promises"
import * as openpgp from "openpgp"
import * as tar from "tar"

export const NODE_VERSION = "24.19.0"
export const NODE_VERSION = "24.22.1"
export const NODE_BASE_URL = `https://nodejs.org/dist/v${NODE_VERSION}`
export const NODE_RELEASE_KEY_FINGERPRINT = "5BE8A3F6C8A5C01D106C0AD820B1A390B168D356"
export const TARGETS = ["darwin-arm64", "darwin-x64", "darwin-universal", "linux-arm64", "linux-x64", "win32-x64"]
Expand Down
2 changes: 1 addition & 1 deletion sdk/packages/simplex/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Embed it in your own Node service, or run it as a ready-made app:
npm install @hyperbridge/simplex
```

Requires Node.js 22.16 or later.
Requires Node.js 22.23.4+, 24.22.1+ or 26.12.1+.

## Quick start

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# 2026-10-23 — Simplex runs on Node 24.22.1, and requires a Node with the Node2Shell fix

CVE-2026-111497 (Node2Shell) is an out-of-bounds write in the Brotli decoder bundled with Node. Any
Brotli data the process decompresses can trigger it, and that includes `fetch()` responses with
`Content-Encoding: br`. Simplex fetches from RPCs, the orderbook, the indexer and bundlers. A malicious
or compromised endpoint could send a crafted response and run code in the solver.

Remote access does not reach the decoder. The embedded SSH server only negotiates `zlib@openssh.com`
compression, and `UiServer` reads request bodies as raw bytes without decoding them. The exposure is
the runtime.

## Runtimes

- The Docker image's builder and runtime stages are on `node:24.22.1` and `node:24.22.1-slim`.
- The desktop app stages Node 24.22.1 (`NODE_VERSION` in `simplex-desktop/scripts/stage-node.mjs`).
The release is signed by the same key the script already pins.
- The desktop release workflow packages on Node 24.22.1, and the staging check expects `v24.22.1`.

## `engines.node`

`engines.node` is `^22.23.4 || ^24.22.1 || >=26.12.1`: the first patched release on each supported
line. Node 23 and 25 are end of life and never got the fix, so they are no longer in range. The
`node:sqlite` floor (22.16.0) is still the oldest version the store can run on. `engines` is only
advisory, so npm and pnpm warn on an older Node rather than refuse to install.

Electron has no release with the fix yet. The packaged solver runs on the staged Node, not
Electron's, so this does not change what the solver is exposed to.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@
Decided: `>=22.16.0`. That is the first release carrying *every* `node:sqlite` API this store
calls, which is a stricter bar than the first release where the module is unflagged.

Since 2026-10-23 the declared range is higher: `^22.23.4 || ^24.22.1 || >=26.12.1`, the first
release on each line with the Node2Shell fix (see
`changelog/2026-10-23-node-runtime-node2shell-fix.md`). The `node:sqlite` reasoning below still
sets the oldest version the store itself can run on.

The two dates differ. `node:sqlite` stopped needing `--experimental-sqlite` in v23.4.0 and
v22.13.0. But `database.isTransaction`, which `attachOrder`'s rollback branch reads, was added in
v24.0.0 and v22.16.0; `database.isOpen`, which `close()` reads, in v23.11.0 and v22.15.0. So
Expand Down
4 changes: 2 additions & 2 deletions sdk/packages/simplex/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@hyperbridge/simplex",
"version": "0.18.3",
"version": "0.18.4",
"license": "Apache-2.0",
"description": "Automated intent filler for the Hyperbridge IntentGateway — run it as a binary or embed it as a library",
"main": "dist/index.js",
Expand Down Expand Up @@ -114,7 +114,7 @@
"access": "public"
},
"engines": {
"node": ">=22.16.0"
"node": "^22.23.4 || ^24.22.1 || >=26.12.1"
},
"dependencies": {
"@base-ui/react": "^1.8.0",
Expand Down
4 changes: 2 additions & 2 deletions sdk/packages/simplex/scripts/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
# ---------------------------------------------------------------------------
# Builder — installs the toolchain, compiles protos, bundles the CLI and web UI.
# ---------------------------------------------------------------------------
FROM node:24.19.0 AS builder
FROM node:24.22.1 AS builder

# protoc is needed by packages/simplex/scripts/build.sh. There is deliberately no python3,
# make or g++ here: nothing in the tree compiles any more, so node-gyp has nothing to fall
Expand Down Expand Up @@ -52,7 +52,7 @@ RUN cd packages/simplex && pnpm build
# Runtime — slim base, no compiler toolchain. Keeps the pull small on Docker Desktop
# hosts, where every layer lands inside the Linux VM's disk image.
# ---------------------------------------------------------------------------
FROM node:24.19.0-slim AS runtime
FROM node:24.22.1-slim AS runtime

# Create non-root user
RUN groupadd -g 1001 simplex && \
Expand Down
5 changes: 3 additions & 2 deletions sdk/packages/simplex/src/data/sqlite/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,9 @@ export { SqliteStateStore } from "./state"
* Set through the PRAGMA rather than `DatabaseSync`'s `timeout` option on purpose.
* That option only exists in Node >=22.18 and >=24 (`@types/node` says 22.16, which
* is wrong — the version table on nodejs.org is authoritative), so it is silently
* ignored on 22.16, 22.17 and the whole 23 line, all of which `engines.node`
* admits. The PRAGMA is plain SQLite and works wherever `node:sqlite` does.
* ignored on 22.16, 22.17 and the whole 23 line. `engines.node` no longer admits
* those, but it is only advisory. The PRAGMA is plain SQLite and works wherever
* `node:sqlite` does.
*/
const BUSY_TIMEOUT_MS = 5_000

Expand Down
Loading