diff --git a/.changeset/cyan-dogs-ask.md b/.changeset/cyan-dogs-ask.md new file mode 100644 index 00000000000..5b0cf1d854e --- /dev/null +++ b/.changeset/cyan-dogs-ask.md @@ -0,0 +1,5 @@ +--- +"hardhat": patch +--- + +Updated `network.createServer` signature to type non-generic chainTypes diff --git a/.changeset/petite-teams-slide.md b/.changeset/petite-teams-slide.md new file mode 100644 index 00000000000..1fb1ecdf332 --- /dev/null +++ b/.changeset/petite-teams-slide.md @@ -0,0 +1,6 @@ +--- +"@nomicfoundation/hardhat-errors": patch +"hardhat": patch +--- + +Added guard against `http` network configs in `network.createServer(...)` diff --git a/v-next/hardhat-errors/src/descriptors.ts b/v-next/hardhat-errors/src/descriptors.ts index 67a561efd3d..ef2030aae41 100644 --- a/v-next/hardhat-errors/src/descriptors.ts +++ b/v-next/hardhat-errors/src/descriptors.ts @@ -1050,6 +1050,14 @@ account, and its parameters are incompatible. You sent both gasPrice and authori Please double check your transactions' parameters.`, }, + CREATE_SERVER_UNSUPPORTED_NETWORK_TYPE: { + number: 724, + messageTemplate: + 'Cannot create a server for network "{networkName}" because it has type "{networkType}". Only "edr-simulated" networks are supported.', + websiteTitle: "Unsupported network type for createServer", + websiteDescription: + "The createServer method only supports 'edr-simulated' networks. HTTP networks cannot be used to create a local JSON-RPC server.", + }, }, SOLIDITY_TESTS: { BUILD_INFO_NOT_FOUND_FOR_CONTRACT: { diff --git a/v-next/hardhat/src/internal/builtin-plugins/network-manager/network-manager.ts b/v-next/hardhat/src/internal/builtin-plugins/network-manager/network-manager.ts index 1bb2b7fcb55..06829590205 100644 --- a/v-next/hardhat/src/internal/builtin-plugins/network-manager/network-manager.ts +++ b/v-next/hardhat/src/internal/builtin-plugins/network-manager/network-manager.ts @@ -110,11 +110,15 @@ export class NetworkManagerImplementation implements NetworkManager { return networkConnection as NetworkConnection; } - public async createServer( - networkOrParams: NetworkConnectionParams | string = "default", + public async createServer< + ChainTypeT extends ChainType | string = DefaultChainType, + >( + networkOrParams?: NetworkConnectionParams | string, _hostname?: string, port?: number, ): Promise { + this.#ensureNetworkOrParamsIsNotHttpNetworkConfig(networkOrParams); + const insideDocker = await exists("/.dockerenv"); const hostname = _hostname ?? (insideDocker ? "0.0.0.0" : "127.0.0.1"); @@ -434,4 +438,27 @@ export class NetworkManagerImplementation implements NetworkManager { return path; } + + #ensureNetworkOrParamsIsNotHttpNetworkConfig( + networkOrParams?: NetworkConnectionParams | string, + ) { + const networkName = + typeof networkOrParams === "string" + ? networkOrParams + : networkOrParams?.network ?? this.#defaultNetwork; + + const networkConfig = this.#networkConfigs[networkName]; + + if (networkConfig === undefined || networkConfig.type === "edr-simulated") { + return; + } + + throw new HardhatError( + HardhatError.ERRORS.CORE.NETWORK.CREATE_SERVER_UNSUPPORTED_NETWORK_TYPE, + { + networkName, + networkType: networkConfig.type, + }, + ); + } } diff --git a/v-next/hardhat/src/types/network.ts b/v-next/hardhat/src/types/network.ts index f45dfac1015..43a26a4ed50 100644 --- a/v-next/hardhat/src/types/network.ts +++ b/v-next/hardhat/src/types/network.ts @@ -62,8 +62,8 @@ export interface NetworkManager { * * @return A `JsonRpcServer` instance that can be started with {@link JsonRpcServer.listen}. */ - createServer( - networkOrParams?: NetworkConnectionParams | string, + createServer( + networkOrParams?: NetworkConnectionParams | string, hostname?: string, port?: number, ): Promise; diff --git a/v-next/hardhat/test/internal/builtin-plugins/network-manager/network-manager.ts b/v-next/hardhat/test/internal/builtin-plugins/network-manager/network-manager.ts index c6670a2789b..5bfa9ca7c73 100644 --- a/v-next/hardhat/test/internal/builtin-plugins/network-manager/network-manager.ts +++ b/v-next/hardhat/test/internal/builtin-plugins/network-manager/network-manager.ts @@ -846,17 +846,55 @@ describe("NetworkManagerImplementation", () => { }); describe("createServer", function () { + it("should throw an error if the network type is not edr-simulated", async () => { + await assertRejectsWithHardhatError( + networkManager.createServer("localhost"), + HardhatError.ERRORS.CORE.NETWORK.CREATE_SERVER_UNSUPPORTED_NETWORK_TYPE, + { networkName: "localhost", networkType: "http" }, + ); + }); + + it("should throw an error if network parameters specify an http network", async () => { + await assertRejectsWithHardhatError( + networkManager.createServer({ network: "localhost" }), + HardhatError.ERRORS.CORE.NETWORK.CREATE_SERVER_UNSUPPORTED_NETWORK_TYPE, + { networkName: "localhost", networkType: "http" }, + ); + }); + it("connects to a network and returns a JsonRpcServer that wraps around it", async () => { const server = await networkManager.createServer( "edrNetwork", "127.0.0.1", ); + + const { address, port } = await server.listen(); + + try { + const { provider } = await networkManager.connect({ + network: "localhost", + override: { url: `http://${address}:${port}` }, + }); + await provider.request({ method: "eth_chainId" }); + } finally { + await server.close(); + } + }); + + it("connects to a network based on network parameters and returns a JsonRpcServer that wraps around it", async () => { + const server = await networkManager.createServer( + { network: "edrNetwork", chainType: "op" }, + "127.0.0.1", + ); + const { address, port } = await server.listen(); + try { const { provider } = await networkManager.connect({ network: "localhost", override: { url: `http://${address}:${port}` }, }); + await provider.request({ method: "eth_chainId" }); } finally { await server.close();