diff --git a/.github/workflows/build-lint-test.yml b/.github/workflows/build-lint-test.yml index 6ff43e28e..1bd0e9d3c 100644 --- a/.github/workflows/build-lint-test.yml +++ b/.github/workflows/build-lint-test.yml @@ -9,7 +9,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - node-version: [18.x, 20.x, 22.x] + node-version: [22.x, 24.x] steps: - name: Checkout and setup environment uses: MetaMask/action-checkout-and-setup@v1 @@ -77,7 +77,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - node-version: [18.x, 20.x, 22.x] + node-version: [22.x, 24.x] steps: - name: Checkout and setup environment uses: MetaMask/action-checkout-and-setup@v1 @@ -99,7 +99,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - node-version: [18.x, 20.x, 22.x] + node-version: [22.x, 24.x] steps: - name: Checkout and setup environment uses: MetaMask/action-checkout-and-setup@v1 diff --git a/CHANGELOG.md b/CHANGELOG.md index 6817943e3..96842f57b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- **BREAKING:** Drop support for Node 18 and 20 ([#328](https://github.com/MetaMask/utils/pull/328)) - Bump `@ethereumjs/tx` from `^4.2.0` to `^5.4.0` ([#321](https://github.com/MetaMask/utils/pull/321)) - The deprecated `Keyring.signTransaction` now returns `LegacyTxData` rather than `TxData`. These describe the same shape: `@ethereumjs/tx@5` repurposed the name `TxData` for a map keyed by transaction type and renamed the old meaning to `LegacyTxData`. Implementations do not need changing. - Bump `@metamask/scure-bip39` from `^2.0.3` to `^2.1.1` ([#311](https://github.com/MetaMask/utils/pull/311)) diff --git a/constraints.pro b/constraints.pro index 0bec58439..091746827 100644 --- a/constraints.pro +++ b/constraints.pro @@ -92,7 +92,7 @@ gen_enforced_dependency(WorkspaceCwd, DependencyIdent, null, DependencyType) :- DependencyType == 'devDependencies'. % The package must specify the expected minimum Node version. -gen_enforced_field(WorkspaceCwd, 'engines.node', '^18.18 || ^20.14 || >=22'). +gen_enforced_field(WorkspaceCwd, 'engines.node', '^22.14.0 || ^24'). % The package is public. gen_enforced_field(WorkspaceCwd, 'publishConfig.access', 'public'). diff --git a/eslint.config.mjs b/eslint.config.mjs index 31fd73988..3c6d970a8 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -82,9 +82,9 @@ const config = createConfig([ { files: ['**/*.test.{js,ts}'], rules: { - // These tests deliberately reach for `crypto` and `crypto.webcrypto`, - // and polyfill the global when running on Node 18. Flagging them as - // unsupported defeats the purpose of the polyfill they are testing. + // The rule treats the global `crypto` as experimental until Node 23, + // and the supported floor here is ^22.14.0. It is present and usable + // on 22, so the tests may use it. 'n/no-unsupported-features/node-builtins': 'off', }, }, diff --git a/package.json b/package.json index 6dce1a8f1..8e919e35d 100644 --- a/package.json +++ b/package.json @@ -88,7 +88,7 @@ "@ts-bridge/shims": "^0.1.1", "@types/jest": "^30.0.0", "@types/jest-when": "^3.5.3", - "@types/node": "~18.18.14", + "@types/node": "^22.13.14", "@types/semver": "^7", "@types/uuid": "^9.0.8", "eslint": "^9.39.1", @@ -121,7 +121,7 @@ "directory": "src" }, "engines": { - "node": "^18.18 || ^20.14 || >=22" + "node": "^22.14.0 || ^24" }, "packageManager": "yarn@4.16.0", "lavamoat": { diff --git a/src/hashing.test.ts b/src/hashing.test.ts index e418cd7be..473208f97 100644 --- a/src/hashing.test.ts +++ b/src/hashing.test.ts @@ -1,27 +1,13 @@ import * as nobleHashes256 from '@noble/hashes/sha256'; import * as nobleHashes512 from '@noble/hashes/sha512'; -import { webcrypto } from 'crypto'; -import { parse } from 'semver'; import { bytesToHex, stringToBytes } from './bytes'; import { sha256, sha512, sha384 } from './hashing'; describe('hash functions', () => { - const originalSubtle = globalThis.crypto?.subtle ?? webcrypto.subtle; + const originalSubtle = globalThis.crypto.subtle; const originalDigest = originalSubtle?.digest?.bind(originalSubtle); - beforeEach(() => { - const isNode18 = parse(process.version)?.major === 18; - - // The global does not exist in Node 18, so we must add it. - if (isNode18) { - Object.defineProperty(globalThis, 'crypto', { - value: webcrypto, - writable: true, - }); - } - }); - afterEach(() => { Object.defineProperty(globalThis.crypto, 'subtle', { value: originalSubtle, diff --git a/yarn.lock b/yarn.lock index 59d8a4107..e650b41d4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1212,7 +1212,7 @@ __metadata: "@types/jest": "npm:^30.0.0" "@types/jest-when": "npm:^3.5.3" "@types/lodash": "npm:^4.17.20" - "@types/node": "npm:~18.18.14" + "@types/node": "npm:^22.13.14" "@types/semver": "npm:^7" "@types/uuid": "npm:^9.0.8" debug: "npm:^4.3.4" @@ -2362,12 +2362,12 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:*, @types/node@npm:~18.18.14": - version: 18.18.14 - resolution: "@types/node@npm:18.18.14" +"@types/node@npm:*, @types/node@npm:^22.13.14": + version: 22.20.1 + resolution: "@types/node@npm:22.20.1" dependencies: - undici-types: "npm:~5.26.4" - checksum: 10/508e90549c2893ec3b8e5f133763a3983adf37b6c8cfb3f1ea066f63d45f57a7246cf6c23aa859417d41d5c0b3f76883d66a749d2f1aa1ca486a47231286a01f + undici-types: "npm:~6.21.0" + checksum: 10/0949e49d0383569ebd1222a2f65a9adb9328a6a6dbed459a02cdb37c61147755386c004c4ffbe436de59f5859df1774b1dd6bf168f7aeee46884bb190e0c384f languageName: node linkType: hard @@ -7769,10 +7769,10 @@ __metadata: languageName: node linkType: hard -"undici-types@npm:~5.26.4": - version: 5.26.5 - resolution: "undici-types@npm:5.26.5" - checksum: 10/0097779d94bc0fd26f0418b3a05472410408877279141ded2bd449167be1aed7ea5b76f756562cb3586a07f251b90799bab22d9019ceba49c037c76445f7cddd +"undici-types@npm:~6.21.0": + version: 6.21.0 + resolution: "undici-types@npm:6.21.0" + checksum: 10/ec8f41aa4359d50f9b59fa61fe3efce3477cc681908c8f84354d8567bb3701fafdddf36ef6bff307024d3feb42c837cf6f670314ba37fc8145e219560e473d14 languageName: node linkType: hard