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
11 changes: 11 additions & 0 deletions .changeset/fix-create-sei-bun-brotli.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
'@sei-js/create-sei': patch
---

Require Bun 1.4.4 for generated applications, the first Bun release outside the Brotli decoder advisory `GHSA-9v8h-qqgm-4m35` (CVE-2026-111497).

Bun vendors Google's Brotli library for `node:zlib` and for decompressing `fetch` responses. The `1.3.14` the template pinned ships Brotli 1.1.0, and Bun 1.4.3 still ships 1.2.0, both inside the advisory's 1.0.3 through 1.2.0 range. Bun 1.4.4 ships Brotli 1.2.1, and there is no fixed 1.3.x release.

The template's `packageManager` moves from `bun@1.3.14` to `bun@1.4.4`, and the generated README and this package's README name 1.4.4 as the minimum. The release smoke now runs on Bun 1.4.4, so that is the version the template's overrides are validated with.

No published dependency or peer range changes.
15 changes: 15 additions & 0 deletions .changeset/fix-mcp-server-brotli-node-floor.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
'@sei-js/mcp-server': patch
---

Raise the supported Node.js range to the releases that patch the Brotli decoder advisory `GHSA-9v8h-qqgm-4m35` (CVE-2026-111497).

**This drops support for Node.js 20, and for 22.x, 24.x, and 26.x releases before 22.23.4, 24.22.1, and 26.12.1.** npm only warns about the engine mismatch, but Yarn 1, and npm with `engine-strict` set, refuse to install this release on them.

Node.js bundles Google's Brotli library, and the decoder in Brotli 1.0.3 through 1.2.0 can be driven into an out-of-bounds write by a crafted compressed stream. Node fixed it in the [October 21, 2026 security releases](https://nodejs.org/en/blog/vulnerability/october-2026-security-releases): 22.23.4, 24.22.1, and 26.12.1. Node 20 is end-of-life and gets no fix.

The server reaches that decoder through `fetch`, which decompresses Brotli-encoded responses automatically: viem's HTTP transport for the configured RPC endpoints, and the docs client for `https://docs.sei.io/mcp`. Its own HTTP transports do not, because Express 4's body parser only inflates gzip and deflate request bodies and rejects `Content-Encoding: br` with a 415.

`engines.node` moves from `>=20.0.0` to `^22.23.4 || ^24.22.1 || >=26.12.1`, and the README's requirement matches.

No dependency or peer range changes.
2 changes: 1 addition & 1 deletion .github/workflows/checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:

- uses: oven-sh/setup-bun@v2
with:
bun-version: '1.3.14'
bun-version: '1.4.4'

- name: Install system dependencies
run: sudo apt-get update && sudo apt-get install -y rsync
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ jobs:

- uses: oven-sh/setup-bun@v2
with:
bun-version: '1.3.14'
bun-version: '1.4.4'

- name: Install dependencies
run: bun install --frozen-lockfile
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/create-sei-smoke.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ jobs:
- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: '1.3.14'
bun-version: '1.4.4'

- name: Install system dependencies
run: sudo apt-get update && sudo apt-get install -y rsync
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ jobs:

- uses: oven-sh/setup-bun@v2
with:
bun-version: '1.3.14'
bun-version: '1.4.4'

- name: Install system dependencies
run: sudo apt-get update && sudo apt-get install -y rsync
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/sei-global-wallet-smoke.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ jobs:
- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: '1.3.14'
bun-version: '1.4.4'

- name: Install workspace dependencies
run: bun install --frozen-lockfile
Expand Down
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
24
24.22.1
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ This project uses [Bun](https://bun.sh) for package management, tests, and scrip

### Prerequisites

Install Bun 1.3.14: https://bun.sh/docs/installation
Install Bun 1.4.4: https://bun.sh/docs/installation

Node.js 24 is pinned in `.nvmrc` for npm package validation and OIDC publishing; Bun remains the workspace package manager and test runner.
Node.js 24.22.1 is pinned in `.nvmrc` for npm package validation and OIDC publishing; Bun remains the workspace package manager and test runner.

### Install, build, test

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,5 +46,5 @@
"publint": "0.3.23",
"typescript": "^5.8.2"
},
"packageManager": "bun@1.3.14"
"packageManager": "bun@1.4.4"
}
2 changes: 1 addition & 1 deletion packages/create-sei/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
npx @sei-js/create-sei app -n my-sei-app
```

Generated applications require Bun 1.3.14 or newer. Their dependency overrides and smoke coverage are Bun-specific; using npm, Yarn, or pnpm can resolve a different, unverified security graph.
Generated applications require Bun 1.4.4 or newer. Their dependency overrides and smoke coverage are Bun-specific; using npm, Yarn, or pnpm can resolve a different, unverified security graph.

## Release verification

Expand Down
2 changes: 1 addition & 1 deletion packages/create-sei/templates/next-template/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ This app was generated by `@sei-js/create-sei`. It uses Next.js, Wagmi, Viem, Ra

## Package manager

Bun 1.3.14 or newer is required for this starter. Its security overrides and release smoke are validated with Bun; npm, Yarn, and pnpm do not share one override contract and may silently resolve a different dependency graph.
Bun 1.4.4 or newer is required for this starter. Its security overrides and release smoke are validated with Bun; npm, Yarn, and pnpm do not share one override contract and may silently resolve a different dependency graph.

The generated project intentionally does not ship a lockfile. Exact direct pins reduce drift, but transitive dependencies are resolved when you run `bun install`; the dedicated smoke validates the current graph rather than claiming every future install is byte-for-byte reproducible. Commit the resulting `bun.lock` after your first reviewed install.

Expand Down
2 changes: 1 addition & 1 deletion packages/create-sei/templates/next-template/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,5 +51,5 @@
"uuid": "11.1.1",
"ws": "8.21.3"
},
"packageManager": "bun@1.3.14"
"packageManager": "bun@1.4.4"
}
2 changes: 1 addition & 1 deletion packages/mcp-server/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

## Requirements

Node.js 20 or newer.
Node.js 22.23.4 or a later 22.x release, 24.22.1 or a later 24.x release, or 26.12.1 and newer. Earlier releases ship a Brotli decoder affected by [CVE-2026-111497](https://nodejs.org/en/blog/vulnerability/october-2026-security-releases), which `fetch` uses to decompress the RPC and docs responses this server reads.

## Quick Start

Expand Down
2 changes: 1 addition & 1 deletion packages/mcp-server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
"author": "@codebycarson",
"license": "MIT",
"engines": {
"node": ">=20.0.0"
"node": "^22.23.4 || ^24.22.1 || >=26.12.1"
},
"repository": {
"type": "git",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -387,7 +387,12 @@ describe('StreamableHttpTransport', () => {
}).catch(() => undefined);
await withTimeout(started, 'request startup');

await expect(transport.stop()).rejects.toBeInstanceOf(AggregateError);
// Under Bun 1.4, `expect(...).rejects` never settles a stop() that has to close a live request.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nit] This workaround is fine, and if stop() resolves, stopError is undefined and toBeInstanceOf still fails, so the assertion stays meaningful. Consider linking an upstream Bun issue in the comment so the workaround can be reverted to .rejects once Bun fixes it.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nit] The workaround is sound: if stop() resolves, stopError is undefined and the assertion still fails. Consider linking an upstream Bun issue (or adding a TODO) so this can go back to expect(...).rejects once Bun fixes it.

const stopError = await transport.stop().then(
() => undefined,
(error: unknown) => error
);
expect(stopError).toBeInstanceOf(AggregateError);
expect(requestTransport.close).toHaveBeenCalledTimes(1);
expect(requestServer.close).toHaveBeenCalledTimes(1);
await expect(transport.stop()).resolves.toBeUndefined();
Expand Down
12 changes: 8 additions & 4 deletions scripts/check-sei-global-wallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -631,10 +631,14 @@
filename: bundlePath,
timeout: 10_000
});
assert.deepEqual(context.__edgeCheck, {
aliases: true,
entrypoints: true
});
// The result object belongs to the vm realm, and a strict deep comparison rejects its foreign prototype.
assert.deepEqual(
{ ...(context.__edgeCheck as Record<string, unknown>) },

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nit] The shallow spread works here because both values are primitives. If __edgeCheck ever gains nested objects, those would still carry vm-realm prototypes and hit the same strict-compare failure; something like structuredClone or a JSON round-trip would cover that case too. If __edgeCheck is undefined, spreading it gives {}, and the comparison still fails as it should.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nit] Spreading into a main-realm object still catches missing or extra own keys, and an undefined __edgeCheck spreads to {}, which fails as it should. Non-enumerable or inherited props are now ignored, which is fine for this check.

{
aliases: true,
entrypoints: true
}
);
};

/**
Expand All @@ -651,7 +655,7 @@
};

const assertAuditClean = (report: AuditReport, label: string) => {
assert.equal(report.metadata?.vulnerabilities?.total, 0, `${label} audit was not clean: ${describeAuditFindings(report).join('; ')}`);

Check failure on line 658 in scripts/check-sei-global-wallet.ts

View workflow job for this annotation

GitHub Actions / npm, Bun, edge, and browser consumers

AssertionError: Waived npm consumer audit was not clean: @dynamic-labs/ethereum-aa-core; @dynamic-labs/ethereum-aa-zksync; @dynamic-labs/ethereum-core; @dynamic-labs/global-wallet-client; @dynamic-labs/iconic; @dynamic-labs/wallet-book; @dynamic-labs/wallet-connector-core; @sei-js/sei-global-wallet; sharp (https://github.com/advisories/GHSA-wq5f-xc86-pv6w)

9 !== 0 at assertAuditClean (/home/runner/work/sei-js/sei-js/scripts/check-sei-global-wallet.ts:658:9)
};

const assertWithinWaiver = (reported: readonly string[], accepted: readonly string[], label: string) => {
Expand Down
Loading