UNPKG

hardhat

Version:

Hardhat is an extensible developer tool that helps smart contract developers increase productivity by reliably bringing together the tools they want.

96 lines (79 loc) 3.34 kB
import type { HookContext, NetworkHooks } from "../../../../types/hooks.js"; import type { ChainType, NetworkConnection, } from "../../../../types/network.js"; import type { JsonRpcRequest, JsonRpcResponse, } from "../../../../types/providers.js"; import type { RequestHandler } from "../request-handlers/types.js"; import { AsyncMutex } from "@nomicfoundation/hardhat-utils/synchronization"; import { isJsonRpcResponse } from "../json-rpc.js"; import { createHandlersArray } from "../request-handlers/handlers-array.js"; export default async (): Promise<Partial<NetworkHooks>> => { // This map is essential for managing multiple network connections in Hardhat V3. // Since Hardhat V3 supports multiple connections, we use this map to track each one // and associate it with the corresponding handlers array. // When a connection is closed, its associated handlers array is removed from the map. // See the "closeConnection" function at the end of the file for more details. const requestHandlersPerConnection: WeakMap< NetworkConnection<ChainType | string>, RequestHandler[] > = new WeakMap(); const initializationMutex = new AsyncMutex(); const handlers: Partial<NetworkHooks> = { async onRequest<ChainTypeT extends ChainType | string>( context: HookContext, networkConnection: NetworkConnection<ChainTypeT>, jsonRpcRequest: JsonRpcRequest, next: ( nextContext: HookContext, nextNetworkConnection: NetworkConnection<ChainTypeT>, nextJsonRpcRequest: JsonRpcRequest, ) => Promise<JsonRpcResponse>, ) { const requestHandlers = await initializationMutex.exclusiveRun( async () => { let handlersPerConnection = requestHandlersPerConnection.get(networkConnection); if (handlersPerConnection === undefined) { handlersPerConnection = await createHandlersArray(networkConnection); requestHandlersPerConnection.set( networkConnection, handlersPerConnection, ); } return handlersPerConnection; }, ); // We previously cloned here, but the performance impact is significant. // TODO: ensure the passed in request is not mutated by adapting the // handlers being applied here. See https://github.com/NomicFoundation/hardhat/issues/8090 let updatedRequest = jsonRpcRequest; for (const handler of requestHandlers) { const newRequestOrResponse = await handler.handle(updatedRequest); if (isJsonRpcResponse(newRequestOrResponse)) { return newRequestOrResponse; } updatedRequest = newRequestOrResponse; } return next(context, networkConnection, updatedRequest); }, async closeConnection<ChainTypeT extends ChainType | string>( context: HookContext, networkConnection: NetworkConnection<ChainTypeT>, next: ( nextContext: HookContext, nextNetworkConnection: NetworkConnection<ChainTypeT>, ) => Promise<void>, ): Promise<void> { if (requestHandlersPerConnection.has(networkConnection) === true) { requestHandlersPerConnection.delete(networkConnection); } return next(context, networkConnection); }, }; return handlers; };