Extensible developer tool that helps smart contract developers increase productivity by reliably bringing together the tools they want.
npx @tessl/cli install tessl/npm-hardhat@3.0.0Hardhat is an extensible developer tool that helps smart contract developers increase productivity by reliably bringing together the tools they want. It provides a comprehensive Ethereum development environment with testing, compilation, deployment, and debugging capabilities for smart contracts.
npm install hardhatimport { config, tasks, network, artifacts, solidity } from "hardhat";Note: network, artifacts, and solidity are provided by builtin plugins that are automatically loaded with the Hardhat runtime environment.
For configuration and task definition:
import {
task,
emptyTask,
overrideTask,
configVariable,
globalOption,
globalFlag,
globalLevel
} from "hardhat/config";For programmatic HRE creation and configuration loading:
import {
createHardhatRuntimeEnvironment,
importUserConfig,
resolveHardhatConfigPath
} from "hardhat/hre";For utilities and plugin development:
import {
getFullyQualifiedName,
parseFullyQualifiedName
} from "hardhat/utils/contract-names";
import { HardhatPluginError } from "hardhat/plugins";For Solidity debugging:
import "hardhat/console.sol";CommonJS:
const { config, tasks, network, artifacts, solidity } = require("hardhat");import { config, tasks, network, artifacts } from "hardhat";
// Access configuration
console.log("Project root:", config.paths.root);
console.log("Cache directory:", config.paths.cache);
// Get contract artifacts
const artifact = await artifacts.readArtifact("MyContract");
// Connect to network
const provider = network.provider;
const [signer] = await network.provider.request({
method: "eth_accounts",
params: []
});
// Run a task programmatically
await tasks.run("compile");Hardhat is built around several key architectural components:
Configuration system supporting both user-defined settings and runtime configuration variables with validation and type safety.
interface HardhatConfig {
paths: ProjectPathsConfig;
}
interface ProjectPathsConfig {
root: string;
config?: string;
cache: string;
artifacts: string;
tests: TestPathsConfig;
sources: SourcePathsConfig;
}
function configVariable(
name: string,
format?: string
): ConfigurationVariable;Extensible task system for defining, overriding, and executing development operations with argument parsing and validation.
function task(
id: string | string[],
description?: string
): NewTaskDefinitionBuilder;
function overrideTask(
id: string | string[],
description?: string
): TaskOverrideDefinitionBuilder;
interface TaskManager {
run(taskName: string, taskArguments?: TaskArguments): Promise<any>;
get(taskName: string): TaskDefinition | undefined;
}Network connection and provider management with support for multiple networks, custom providers, and network switching.
interface NetworkManager {
readonly name: string;
readonly config: NetworkConfig;
readonly provider: HardhatProvider;
}
interface HardhatProvider {
request(args: { method: string; params?: any[] }): Promise<any>;
send(method: string, params?: any[]): Promise<any>;
}Contract artifact reading, writing, and management with build info tracking and dependency resolution.
interface ArtifactManager {
readArtifact(name: string): Promise<Artifact>;
readArtifactSync(name: string): Artifact;
artifactExists(name: string): Promise<boolean>;
getAllFullyQualifiedNames(): Promise<string[]>;
getBuildInfo(fullyQualifiedName: string): Promise<BuildInfo | undefined>;
}
interface Artifact {
contractName: string;
sourceName: string;
abi: any[];
bytecode: string;
deployedBytecode: string;
linkReferences: any;
deployedLinkReferences: any;
}Integrated Solidity compilation with dependency resolution, version management, and incremental builds.
interface SolidityBuildSystem {
compile(): Promise<void>;
getCompilerVersion(): string;
getSourceNames(): Promise<string[]>;
getDependencyGraph(): Promise<DependencyGraph>;
}Event-driven plugin system for lifecycle management and customization with type-safe hook definitions.
interface HookManager {
addHookHandler<T extends keyof HardhatHooks>(
hookName: T,
handler: HookHandler<T>
): void;
runHook<T extends keyof HardhatHooks>(
hookName: T,
...args: Parameters<HardhatHooks[T]>
): Promise<any>;
}
interface HardhatHooks {
config: ConfigHooks;
userInterruptions: UserInterruptionHooks;
configurationVariables: ConfigurationVariableHooks;
hre: HardhatRuntimeEnvironmentHooks;
}Modular plugin architecture for extending Hardhat functionality with dependency management and lifecycle hooks.
interface HardhatPlugin {
id: string;
npmPackage: string;
hookHandlers?: Partial<HardhatPluginHookHandlers>;
globalOptions?: GlobalOptionDefinition[];
dependencies?: () => Promise<HardhatPlugin>[];
}Comprehensive error system with structured error types and detailed error reporting for plugins and core functionality.
class HardhatPluginError extends Error {
constructor(
pluginName: string,
message: string,
parent?: Error
);
/** Plugin name that threw the error */
readonly pluginName: string;
/** Original error if this wraps another error */
readonly parent?: Error;
}
// Error types are exported from @nomicfoundation/hardhat-errors
// and can be used for error handling and type checkingUsage Examples:
import { HardhatPluginError } from "hardhat/plugins";
// In plugin development
try {
// Plugin operation that might fail
await riskyOperation();
} catch (error) {
throw new HardhatPluginError(
"my-plugin",
"Failed to perform operation",
error
);
}Hardhat provides a comprehensive command-line interface for project initialization, task execution, and development workflows.
// CLI is accessed via the hardhat binary:
// npx hardhat <task-name> [options]
// npx hardhat --init // Project initialization
// npx hardhat compile // Run compile task
// npx hardhat test // Run test task
interface GlobalOptions {
network?: string;
verbose?: boolean;
version?: boolean;
help?: boolean;
}Common CLI Commands:
# Initialize a new Hardhat project
npx hardhat --init
# Compile smart contracts
npx hardhat compile
# Run tests
npx hardhat test
# Deploy contracts (with custom task)
npx hardhat deploy --network goerli
# Get help
npx hardhat help
npx hardhat help <task-name>Contract name parsing and fully qualified name utilities for working with Solidity contracts.
function getFullyQualifiedName(
sourceName: string,
contractName: string
): string;
function parseFullyQualifiedName(fullyQualifiedName: string): {
sourceName: string;
contractName: string;
};interface HardhatRuntimeEnvironment {
readonly config: HardhatConfig;
readonly userConfig: HardhatUserConfig;
readonly globalOptions: GlobalOptions;
readonly tasks: TaskManager;
readonly hooks: HookManager;
readonly interruptions: UserInterruptionManager;
readonly network: NetworkManager;
readonly artifacts: ArtifactManager;
readonly solidity: SolidityBuildSystem;
}
interface GlobalOptions {
network?: string;
verbose?: boolean;
version?: boolean;
help?: boolean;
}
type TaskArguments = Record<string, any>;
type NewTaskActionFunction<
TaskArgumentsT extends TaskArguments = TaskArguments
> = (taskArguments: TaskArgumentsT, hre: HardhatRuntimeEnvironment) => any;
// Utility types for parameter manipulation (from hardhat/types/utils)
type ParametersExceptFirst<T extends (...args: any) => any> =
T extends (arg: any, ...rest: infer R) => any ? R : never;
type ParametersExceptLast<T extends (...args: any) => any> =
T extends (...args: [...infer R, any]) => any ? R : never;
type ParametersExceptFirstAndLast<T extends (...args: any) => any> =
ParametersExceptLast<ParametersExceptFirst<T>>;
type LastParameter<T extends (...args: any) => any> =
T extends (...args: [...any, infer L]) => any ? L : never;
type Params<T extends (...args: any) => any> = Parameters<T>;
type Return<T extends (...args: any) => any> = ReturnType<T>;
// Helper type for making fields required
type RequireField<T, K extends keyof T> = T & Required<Pick<T, K>>;