Skip to content

Add @nomicfoundation/hardhat-solx plugin#8034

Merged
kanej merged 15 commits intomainfrom
feat/solx-step3-hardhat-solx-plugin
Apr 2, 2026
Merged

Add @nomicfoundation/hardhat-solx plugin#8034
kanej merged 15 commits intomainfrom
feat/solx-step3-hardhat-solx-plugin

Conversation

@marianfe
Copy link
Copy Markdown
Contributor

@marianfe marianfe commented Mar 6, 2026

Summary

Adds @nomicfoundation/hardhat-solx plugin that enables adding solx for test builds in Hardhat 3.
The plugin extends SolidityCompilerType, SolidityCompilerConfig adding solx types, and hooks into validateUserConfig, downloadCompilers and getCompiler to orchestrate the compilation flow for solx.

The plugin handles supported versions and supported EVM versions, and validates solx configs.
It requires adding a solx build profile that can be used when running build or tests.

Downloads from solx-releases-mirror.hardhat.org with retry logic matching the solc downloader pattern

Built on top of #8008 and #8009.

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Mar 6, 2026

🦋 Changeset detected

Latest commit: eaef43d

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 2 packages
Name Type
@nomicfoundation/hardhat-solx Major
@nomicfoundation/hardhat-errors Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@marianfe marianfe added the no docs needed This PR doesn't require links to documentation label Mar 6, 2026
@marianfe marianfe changed the title Add @nomicfoundation/hardhat-solx extension plugin Add @nomicfoundation/hardhat-solx plugin Mar 6, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Mar 6, 2026

hardhat

Total size of the bundle: 246M
Total number of dependencies (including transitive): 48

List of dependencies (sorted by size)
238M	total
37M	@nomicfoundation/edr-linux-x64-musl
37M	@nomicfoundation/edr-linux-x64-gnu
34M	@nomicfoundation/edr-linux-arm64-musl
34M	@nomicfoundation/edr-linux-arm64-gnu
25M	@nomicfoundation/edr-darwin-x64
24M	@nomicfoundation/edr-win32-x64-msvc
21M	@nomicfoundation/edr-darwin-arm64
7.3M	@sentry/core
5.2M	zod
2.7M	micro-eth-signer
1.9M	@noble/curves
1.7M	undici
1.2M	@noble/hashes
1.1M	@nomicfoundation/hardhat-utils
884K	@nomicfoundation/hardhat-vendored
864K	@streamparser/json
624K	micro-packed
592K	tsx
588K	@nomicfoundation/hardhat-errors
492K	@scure/bip39
476K	@nomicfoundation/edr
408K	json-stream-stringify
368K	ethereum-cryptography
344K	fast-equals
332K	@streamparser/json-node
320K	enquirer
320K	@nomicfoundation/hardhat-zod-utils
288K	semver
200K	ws
180K	chokidar
176K	get-tsconfig
168K	esbuild
168K	@scure/base
136K	adm-zip
96K	@scure/bip32
92K	chalk
72K	@nomicfoundation/solidity-analyzer
68K	debug
60K	readdirp
56K	rfdc
48K	ansi-colors
44K	resolve.exports
40K	resolve-pkg-maps
36K	p-map
24K	strip-ansi
24K	env-paths
24K	ansi-regex
20K	ms

Comment thread packages/hardhat-errors/src/descriptors.ts
Comment thread v-next/hardhat-solx/src/internal/downloader.ts Outdated
Comment thread v-next/hardhat-solx/src/internal/downloader.ts Outdated
Comment thread v-next/hardhat-solx/package.json Outdated
Comment thread .changeset/warm-solx-plugin.md Outdated
Comment thread .changeset/warm-solx-plugin.md Outdated
Comment thread v-next/hardhat-solx/README.md Outdated
Comment thread packages/hardhat-solx/src/internal/solx-compiler.ts
Comment thread packages/hardhat-solx/src/internal/solx-compiler.ts
Comment thread packages/hardhat-solx/src/internal/hook-handlers/solidity.ts
...input,
settings: {
...input.settings,
...this.#extraSettings,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I don't know where to validate this: are the extra settings top-level like this?

Comment thread v-next/hardhat-solx/test/integration.ts Outdated
Comment thread v-next/hardhat-solx/src/internal/hook-handlers/config.ts Outdated
Comment thread v-next/hardhat-solx/src/internal/hook-handlers/config.ts Outdated
Comment thread v-next/hardhat-solx/src/internal/hook-handlers/config.ts Outdated
Comment thread v-next/hardhat-solx/src/internal/hook-handlers/config.ts Outdated
Comment thread v-next/hardhat-solx/src/internal/hook-handlers/config.ts Outdated
Comment thread packages/hardhat-solx/test/hook-handlers/solidity.ts
Comment thread v-next/hardhat-solx/src/internal/hook-handlers/config.ts Outdated
@kanej kanej removed their request for review March 9, 2026 09:39
Copilot AI review requested due to automatic review settings March 25, 2026 12:40
@marianfe marianfe force-pushed the feat/solx-step3-hardhat-solx-plugin branch from adc48a5 to 7056461 Compare March 25, 2026 12:40
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds a new @nomicfoundation/hardhat-solx plugin package to enable using the experimental solx compiler (via a dedicated build profile) in Hardhat 3, including config/type extensions, download orchestration, and tests/docs.

Changes:

  • Introduce the hardhat-solx plugin with config + solidity hook handlers, a solx compiler wrapper, and a binary downloader.
  • Extend Hardhat config/types to register solx as a compiler type and add solx plugin configuration.
  • Add unit/integration tests, fixture project, and documentation; add new hardhat-errors descriptors for solx-related errors.

Reviewed changes

Copilot reviewed 26 out of 27 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
v-next/hardhat-solx/tsconfig.json New TS project config for the plugin package build.
v-next/hardhat-solx/test/solx-compiler.ts Unit tests for the SolxCompiler wrapper behavior.
v-next/hardhat-solx/test/platform.ts Unit tests for platform/asset naming helpers.
v-next/hardhat-solx/test/integration.ts Basic integration coverage via creating an HRE with the plugin.
v-next/hardhat-solx/test/hook-handlers/solidity.ts Tests for solidity hook handler behavior (download/getCompiler).
v-next/hardhat-solx/test/fixture-projects/simple/package.json Fixture project package metadata for integration tests.
v-next/hardhat-solx/test/fixture-projects/simple/hardhat.config.ts Fixture Hardhat config using a solx build profile.
v-next/hardhat-solx/test/fixture-projects/simple/contracts/Greeter.sol Simple Solidity contract for fixture compilation context.
v-next/hardhat-solx/test/config.ts Tests for plugin config validation/resolution behavior.
v-next/hardhat-solx/src/type-extensions.ts Module augmentation adding solx compiler type + plugin config typing.
v-next/hardhat-solx/src/internal/solx-compiler.ts Compiler implementation calling spawnCompile with solx binary.
v-next/hardhat-solx/src/internal/platform.ts Platform/arch -> solx asset naming and unsupported-platform error.
v-next/hardhat-solx/src/internal/hook-handlers/solidity.ts Hook handlers to download solx binaries and provide a solx Compiler.
v-next/hardhat-solx/src/internal/hook-handlers/config.ts Hook handlers to validate/resolve config and enforce solx profile rules.
v-next/hardhat-solx/src/internal/downloader.ts Binary cache path + download-with-retries implementation.
v-next/hardhat-solx/src/internal/constants.ts Solx constants: supported versions/EVMs, defaults, and version map.
v-next/hardhat-solx/src/index.ts Plugin entrypoint registering hook handlers and type extensions.
v-next/hardhat-solx/package.json New publishable package manifest, scripts, and dependencies.
v-next/hardhat-solx/eslint.config.js Package-level ESLint configuration wiring to repo config.
v-next/hardhat-solx/README.md User documentation for installation/configuration/usage.
v-next/hardhat-solx/LICENSE License for the new package.
v-next/hardhat-solx/.prettierignore Prettier ignore rules for generated outputs and fixtures.
v-next/hardhat-solx/.gitignore Git ignore rules for build/test outputs and fixtures.
v-next/hardhat-errors/src/descriptors.ts New HARDHAT_SOLX error category + errors for platform/download failures.
pnpm-lock.yaml Workspace lockfile updates adding the new package dependencies.
.peer-bumps.json Record that the new plugin depends on new Hardhat hook APIs.
.changeset/warm-solx-plugin.md Changeset publishing hardhat-solx and bumping hardhat-errors.
Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported

Comment thread packages/hardhat-solx/src/internal/hook-handlers/solidity.ts
Comment thread packages/hardhat-solx/src/internal/platform.ts
Comment thread packages/hardhat-solx/src/internal/downloader.ts
Comment thread v-next/hardhat-solx/src/internal/downloader.ts Outdated
Comment on lines +112 to +116
try {
await hooks.downloadCompilers!(context, configs, true);
} catch {
// Expected — download fails in test environment
}
Copy link

Copilot AI Mar 25, 2026

Choose a reason for hiding this comment

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

This test calls hooks.downloadCompilers with a solx config, which triggers a real network download attempt (3 retries + request timeouts) and then swallows the error. This will make CI flaky/slow and may even download binaries during tests. Prefer mocking downloadSolx/download (e.g. via dependency injection or an undici MockAgent) so the test is deterministic and offline.

Suggested change
try {
await hooks.downloadCompilers!(context, configs, true);
} catch {
// Expected — download fails in test environment
}
await assert.rejects(
hooks.downloadCompilers!(context, configs, true),
);

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

will look at fixing this where it makes sense, to follow the same pattern like solc downloader tests.

Comment thread packages/hardhat-solx/src/internal/hook-handlers/config.ts
Comment on lines +170 to +177
return {
...resolvedConfig,
solidity: {
...resolvedConfig.solidity,
registeredCompilerTypes: [
...resolvedConfig.solidity.registeredCompilerTypes,
SOLX_COMPILER_TYPE,
],
Copy link

Copilot AI Mar 25, 2026

Choose a reason for hiding this comment

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

registeredCompilerTypes is always appended with "solx" here, which can introduce duplicates if the plugin is registered more than once (or if another plugin also registers the same type). Consider deduping (e.g. check includes first or build a Set) before returning the resolved config.

Suggested change
return {
...resolvedConfig,
solidity: {
...resolvedConfig.solidity,
registeredCompilerTypes: [
...resolvedConfig.solidity.registeredCompilerTypes,
SOLX_COMPILER_TYPE,
],
const registeredCompilerTypes = resolvedConfig.solidity
.registeredCompilerTypes.includes(SOLX_COMPILER_TYPE)
? resolvedConfig.solidity.registeredCompilerTypes
: [
...resolvedConfig.solidity.registeredCompilerTypes,
SOLX_COMPILER_TYPE,
];
return {
...resolvedConfig,
solidity: {
...resolvedConfig.solidity,
registeredCompilerTypes,

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

i can take a look at fixing this.

Comment thread packages/hardhat-solx/src/internal/hook-handlers/config.ts
@marianfe marianfe force-pushed the feat/solx-step3-hardhat-solx-plugin branch from 7056461 to 12e7a3e Compare March 25, 2026 19:16
@marianfe marianfe requested a review from alcuadrado March 25, 2026 19:34
Copilot AI review requested due to automatic review settings March 26, 2026 14:38
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 26 out of 27 changed files in this pull request and generated 3 comments.

Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported

Comment on lines +53 to +59
.refine(
(data) => "path" in data || SUPPORTED_VERSIONS.includes(data.version),
{
message: `Solx only supports versions: ${SUPPORTED_VERSIONS.join(", ")}`,
path: ["version"],
},
);
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

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

The solx compiler version validation can be bypassed by setting a path property that is present but undefined (e.g. path: process.env.SOLX_PATH when the env var isn’t set). Because the refine uses "path" in data, any config with a path key will skip the supported-version check, which can lead to an unsupported Solidity version making it past validation and later triggering an internal invariant in the Solidity hook handler. Consider changing this refine to require a non-empty string path (e.g. typeof data.path === "string" && data.path.length > 0) before skipping the supported-versions check.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I thin this doesn't make a ton of sense

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I actually went ahead and implemented this suggestion, i'll explain below on your other comment why i think this makes sense.

Comment on lines +90 to +93
assertHardhatInvariant(
await exists(compilerConfig.path),
`solx binary not found at ${compilerConfig.path} — the configured path does not exist`,
);
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

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

Missing/invalid compilerConfig.path is a user configuration error, but it’s currently reported via assertHardhatInvariant, which surfaces as a CORE.INTERNAL.ASSERTION_ERROR. This makes a common misconfiguration look like an internal bug. Prefer throwing a dedicated HardhatError (ideally under HARDHAT_SOLX) or returning a resolved-config validation error so the user gets a proper config error category.

Suggested change
assertHardhatInvariant(
await exists(compilerConfig.path),
`solx binary not found at ${compilerConfig.path} — the configured path does not exist`,
);
const pathExists = await exists(compilerConfig.path);
if (!pathExists) {
throw new Error(
`solx binary not found at ${compilerConfig.path} — the configured path does not exist`,
);
}

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Agreed with this comment, this should throw a HardhatError, as it can be a user mistake, more than an assertion violation.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

fixed

Comment on lines +3046 to +3048
websiteDescription: `The solx compiler binary could not be downloaded from GitHub releases.

Check your internet connection and verify that the requested solx version exists.`,
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

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

The HARDHAT_SOLX.GENERAL.DOWNLOAD_FAILED website description says the binary couldn’t be downloaded from GitHub releases, but the implementation downloads from https://solx-releases-mirror.hardhat.org. Updating this text would avoid sending users to the wrong place when troubleshooting download failures.

Suggested change
websiteDescription: `The solx compiler binary could not be downloaded from GitHub releases.
Check your internet connection and verify that the requested solx version exists.`,
websiteDescription: `The solx compiler binary could not be downloaded from the solx releases server used by Hardhat.
Check your internet connection, ensure that the solx releases mirror (https://solx-releases-mirror.hardhat.org) is reachable from your environment, and verify that the requested solx version exists.`,

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

fixed

version: solxVersion,
attempts: DOWNLOAD_RETRY_COUNT.toString(),
reason: lastError?.message ?? "unknown error",
},
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
},
},
lastError,

this keeps the error.cause chain, making errors easier to debug

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

fixed!

})
.passthrough()
.refine(
(data) => "path" in data || SUPPORTED_VERSIONS.includes(data.version),
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
(data) => "path" in data || SUPPORTED_VERSIONS.includes(data.version),
(data) => SUPPORTED_VERSIONS.includes(data.version),

I believe this is what you wanted, because later you have code to explicitly handle the custom path.

Copy link
Copy Markdown
Contributor Author

@marianfe marianfe Apr 2, 2026

Choose a reason for hiding this comment

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

I actually intentionally want us to not check supported versions when the compiler custom path is used , and i've added an additional check to make sure the path is not a string.Empty path . the reason is that for custom paths, users might be using a latest nightly build which supports a higher solidity version than the current solx plugin map. e.g. while 0.8.35 is in development in the nightly build and not released yet. i actually have unit tests specifically checking that this works, i think it is a legit use case (using a custom path to a compiler that supports a solidity version that's not officially in the supported map). thoughts?

Copy link
Copy Markdown
Member

@alcuadrado alcuadrado left a comment

Choose a reason for hiding this comment

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

I left some minor comments, but LGTM

@marianfe marianfe added this pull request to the merge queue Apr 2, 2026
@github-merge-queue github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Apr 2, 2026
Copilot AI review requested due to automatic review settings April 2, 2026 14:24
@kanej kanej enabled auto-merge April 2, 2026 14:25
@kanej kanej added this pull request to the merge queue Apr 2, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 27 out of 28 changed files in this pull request and generated 5 comments.

Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported

Comment thread scripts/lib/packages.ts
Comment on lines 9 to 17
const allPackageNames = (await readdir(packagesDir)).filter(
(file) =>
![
"config",
"example-project",
"template-package",
"hardhat-test-utils",
"hardhat-solx",
].includes(file),
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

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

readAllReleasablePackages is documented as returning packages that are released to npm, but this change adds hardhat-solx to the explicit exclusion list. That makes it impossible for release tooling that relies on this list to detect/version/publish the new plugin. If @nomicfoundation/hardhat-solx is intended to be published, remove it from this exclusion list; if it’s intended to stay internal, consider removing the changeset/peer-bump entry and updating the README installation instructions accordingly.

Copilot uses AI. Check for mistakes.
Comment on lines +1 to +6
{
"name": "@nomicfoundation/hardhat-solx",
"private": true,
"version": "2.0.0",
"description": "Hardhat plugin for using solx compiler in test builds",
"homepage": "https://github.com/NomicFoundation/hardhat/tree/main/packages/hardhat-solx",
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

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

This package is marked "private": true, which prevents publishing to npm, but the PR introduces a changeset and README instructions for npm install --save-dev @nomicfoundation/hardhat-solx. Please align these: either remove private (and ensure release tooling includes the package), or adjust docs/changesets to reflect that the plugin is not meant to be installed from npm.

Copilot uses AI. Check for mistakes.
Comment on lines +9 to +17
```bash
npm install --save-dev @nomicfoundation/hardhat-solx
```

Then add the plugin to your `hardhat.config.ts` and create a `solx` build profile. You must use the build profiles config format, which requires both a `default` and a `solx` profile:

```typescript
import { defineConfig } from "hardhat/config";
import hardhatSolx from "@nomicfoundation/hardhat-solx";
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

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

The Installation section suggests installing @nomicfoundation/hardhat-solx from npm, but the new package is currently marked private and is excluded from release tooling (scripts/lib/packages.ts). Either make the package publishable, or update these instructions to match the intended distribution method.

Suggested change
```bash
npm install --save-dev @nomicfoundation/hardhat-solx
```
Then add the plugin to your `hardhat.config.ts` and create a `solx` build profile. You must use the build profiles config format, which requires both a `default` and a `solx` profile:
```typescript
import { defineConfig } from "hardhat/config";
import hardhatSolx from "@nomicfoundation/hardhat-solx";
This plugin is currently experimental and is not published to npm. It is intended to be used from within the Hardhat monorepo or from source.
Once the plugin is available in your project, add it to your `hardhat.config.ts` and create a `solx` build profile. You must use the build profiles config format, which requires both a `default` and a `solx` profile:
```typescript
import { defineConfig } from "hardhat/config";
import hardhatSolx from "@nomicfoundation/hardhat-solx";
import { defineConfig } from "hardhat/config";
import hardhatSolx from "@nomicfoundation/hardhat-solx";

Copilot uses AI. Check for mistakes.
Comment on lines +122 to +152

it("does not mutate compiler config paths", async () => {
const hookHandlerModule = await import(
"../../src/internal/hook-handlers/solidity.js"
);
const hooks = await hookHandlerModule.default();

const context = { config: {} } as any;

const configs: SolidityCompilerConfig[] = [
createSolidityCompilerConfig({ type: "solx", version: "0.8.33" }),
];

// This will fail to download (no network in tests), but we can
// verify via the error that it tries and that path is not mutated.
// For a true unit test we'd mock downloadSolx, but for now just
// check the path isn't set before the download attempt.
const originalPath = configs[0].path;

try {
await hooks.downloadCompilers!(context, configs, true);
} catch {
// Expected — download fails in test environment
}

assert.equal(
configs[0].path,
originalPath,
"compiler config path should not be mutated",
);
});
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

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

This test triggers a real downloadCompilers run for a solx config (which attempts network downloads with retries) and then swallows any error. That makes the test suite slow/flaky and can unexpectedly download binaries in CI. Prefer mocking downloadSolx/download (e.g. via dependency injection or a request MockAgent) and asserting on the expected behavior without doing real I/O.

Suggested change
it("does not mutate compiler config paths", async () => {
const hookHandlerModule = await import(
"../../src/internal/hook-handlers/solidity.js"
);
const hooks = await hookHandlerModule.default();
const context = { config: {} } as any;
const configs: SolidityCompilerConfig[] = [
createSolidityCompilerConfig({ type: "solx", version: "0.8.33" }),
];
// This will fail to download (no network in tests), but we can
// verify via the error that it tries and that path is not mutated.
// For a true unit test we'd mock downloadSolx, but for now just
// check the path isn't set before the download attempt.
const originalPath = configs[0].path;
try {
await hooks.downloadCompilers!(context, configs, true);
} catch {
// Expected — download fails in test environment
}
assert.equal(
configs[0].path,
originalPath,
"compiler config path should not be mutated",
);
});

Copilot uses AI. Check for mistakes.
Comment on lines +257 to +294
const { getSolxBinaryPath } = await import(
"../../src/internal/downloader.js"
);
const { exists } = await import("@nomicfoundation/hardhat-utils/fs");

// Use the cached solx binary if available, skip otherwise
const cachedPath = await getSolxBinaryPath("0.1.3");
if (!(await exists(cachedPath))) {
return;
}

const hookHandlerModule = await import(
"../../src/internal/hook-handlers/solidity.js"
);
const hooks = await hookHandlerModule.default();

const context = { config: {} } as any;
const compilerConfig = createSolidityCompilerConfig({
type: "solx",
version: "0.8.33",
path: cachedPath,
});
const mockNext = createGetCompilerMockNext();

const compiler = await hooks.getCompiler!(
context,
compilerConfig,
mockNext.next,
);

assert.ok(
!mockNext.wasCalled(),
"next should NOT have been called for solx type",
);
assert.equal(compiler.compilerPath, cachedPath);
// Version should be parsed from the binary, not from config
assert.equal(compiler.version, "0.1.3");
assert.equal(compiler.longVersion, "0.1.3+solx");
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

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

This test becomes a no-op when the solx binary isn’t already present in the global cache (return if the cached path doesn’t exist), which means CI may not exercise the custom-path code path at all. Consider making the test deterministic by stubbing exists/execFile (or injecting a version lookup function) so it always validates the behavior without relying on external cache state.

Suggested change
const { getSolxBinaryPath } = await import(
"../../src/internal/downloader.js"
);
const { exists } = await import("@nomicfoundation/hardhat-utils/fs");
// Use the cached solx binary if available, skip otherwise
const cachedPath = await getSolxBinaryPath("0.1.3");
if (!(await exists(cachedPath))) {
return;
}
const hookHandlerModule = await import(
"../../src/internal/hook-handlers/solidity.js"
);
const hooks = await hookHandlerModule.default();
const context = { config: {} } as any;
const compilerConfig = createSolidityCompilerConfig({
type: "solx",
version: "0.8.33",
path: cachedPath,
});
const mockNext = createGetCompilerMockNext();
const compiler = await hooks.getCompiler!(
context,
compilerConfig,
mockNext.next,
);
assert.ok(
!mockNext.wasCalled(),
"next should NOT have been called for solx type",
);
assert.equal(compiler.compilerPath, cachedPath);
// Version should be parsed from the binary, not from config
assert.equal(compiler.version, "0.1.3");
assert.equal(compiler.longVersion, "0.1.3+solx");
const downloaderModule = await import(
"../../src/internal/downloader.js"
);
const fsModule = await import("@nomicfoundation/hardhat-utils/fs");
const childProcessModule = await import("node:child_process");
const originalGetSolxBinaryPath = (downloaderModule as any)
.getSolxBinaryPath;
const originalExists = (fsModule as any).exists;
const originalExecFile = (childProcessModule as any).execFile;
const fakePath = "/fake/path/to/solx";
(downloaderModule as any).getSolxBinaryPath = async () => fakePath;
(fsModule as any).exists = async () => true;
(childProcessModule as any).execFile = (
_file: string,
_args: string[] | undefined,
callback: (error: Error | null, stdout: string, stderr: string) => void,
) => {
callback(null, "0.1.3+solx", "");
};
try {
const hookHandlerModule = await import(
"../../src/internal/hook-handlers/solidity.js"
);
const hooks = await hookHandlerModule.default();
const context = { config: {} } as any;
const compilerConfig = createSolidityCompilerConfig({
type: "solx",
version: "0.8.33",
path: fakePath,
});
const mockNext = createGetCompilerMockNext();
const compiler = await hooks.getCompiler!(
context,
compilerConfig,
mockNext.next,
);
assert.ok(
!mockNext.wasCalled(),
"next should NOT have been called for solx type",
);
assert.equal(compiler.compilerPath, fakePath);
// Version should be parsed from the binary, not from config
assert.equal(compiler.version, "0.1.3");
assert.equal(compiler.longVersion, "0.1.3+solx");
} finally {
(downloaderModule as any).getSolxBinaryPath = originalGetSolxBinaryPath;
(fsModule as any).exists = originalExists;
(childProcessModule as any).execFile = originalExecFile;
}

Copilot uses AI. Check for mistakes.
Merged via the queue into main with commit 6a946f4 Apr 2, 2026
300 checks passed
@kanej kanej deleted the feat/solx-step3-hardhat-solx-plugin branch April 2, 2026 14:35
@github-actions github-actions Bot mentioned this pull request Apr 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

no docs needed This PR doesn't require links to documentation status:triaging

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants