CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-hardhat

Extensible developer tool that helps smart contract developers increase productivity by reliably bringing together the tools they want.

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

plugin-system.mddocs/

Plugin System

Hardhat's plugin system provides a modular architecture for extending functionality through plugins with dependency management, lifecycle hooks, and type-safe extensions.

Capabilities

Plugin Definition

Core interface for defining Hardhat plugins with metadata and functionality.

interface HardhatPlugin {
  /** Unique plugin identifier */
  id: string;
  
  /** NPM package name containing the plugin */
  npmPackage: string;
  
  /** Hook handlers provided by the plugin */
  hookHandlers?: Partial<HardhatPluginHookHandlers>;
  
  /** Global CLI options added by the plugin */
  globalOptions?: GlobalOptionDefinition[];
  
  /** Plugin dependencies (lazy-loaded) */
  dependencies?: () => Promise<HardhatPlugin>[];
  
  /** Plugin initialization function */
  init?: (hre: HardhatRuntimeEnvironment) => Promise<void>;
}

Usage Examples:

import type { HardhatPlugin } from "hardhat/types";

const myPlugin: HardhatPlugin = {
  id: "my-custom-plugin",
  npmPackage: "hardhat-my-plugin",
  hookHandlers: {
    hre: () => import("./hre-hooks.js"),
    config: () => import("./config-hooks.js")
  },
  globalOptions: [
    {
      name: "my-option",
      description: "Custom plugin option",
      type: ArgumentType.STRING,
      defaultValue: "default"
    }
  ],
  dependencies: () => [
    import("hardhat-dependency-plugin")
  ],
  init: async (hre) => {
    // Plugin initialization logic
    console.log(`Initializing plugin on network: ${hre.network.name}`);
  }
};

export default myPlugin;

Plugin Hook Handlers

Hook handler definitions that plugins can implement.

interface HardhatPluginHookHandlers {
  /** Configuration-related hook handlers */
  config?: () => Promise<ConfigHookHandlers>;
  
  /** HRE lifecycle hook handlers */
  hre?: () => Promise<HreHookHandlers>;
  
  /** Configuration variable hook handlers */
  configurationVariables?: () => Promise<ConfigVarHookHandlers>;
  
  /** User interruption hook handlers */
  userInterruptions?: () => Promise<UserInterruptionHookHandlers>;
}

interface ConfigHookHandlers {
  resolveUserConfig?: (
    userConfig: HardhatUserConfig,
    context: ConfigHookContext
  ) => Promise<HardhatUserConfig>;
  
  configResolved?: (
    config: HardhatConfig,
    context: ConfigHookContext
  ) => Promise<void>;
  
  validateConfig?: (
    config: HardhatConfig,
    context: ConfigHookContext
  ) => Promise<void>;
}

interface HreHookHandlers {
  initialized?: (
    hre: HardhatRuntimeEnvironment,
    context: HookContext
  ) => Promise<void>;
  
  beforeTaskRun?: (
    taskName: string,
    taskArguments: TaskArguments,
    context: HookContext
  ) => Promise<void>;
  
  afterTaskRun?: (
    taskName: string,
    taskArguments: TaskArguments,
    result: any,
    context: HookContext
  ) => Promise<void>;
  
  taskFailed?: (
    taskName: string,
    taskArguments: TaskArguments,
    error: Error,
    context: HookContext
  ) => Promise<void>;
}

Global Options

Plugin-defined global CLI options that extend Hardhat's command-line interface.

interface GlobalOptionDefinition {
  /** Option name (without dashes) */
  name: string;
  
  /** Option description for help text */
  description: string;
  
  /** Argument type */
  type: ArgumentType;
  
  /** Default value */
  defaultValue?: ArgumentTypeToValueType[ArgumentType];
  
  /** Short flag name */
  shortName?: string;
  
  /** Whether the option is a flag (boolean) */
  isFlag?: boolean;
  
  /** Whether the option is required */
  isRequired?: boolean;
}

/**
 * Creates a global option definition
 * @param definition - The option definition
 */
function globalOption(definition: GlobalOptionDefinition): void;

Usage Examples:

import { globalOption, ArgumentType } from "hardhat/config";

// Add a string option
globalOption({
  name: "api-key",
  description: "API key for external service",
  type: ArgumentType.STRING,
  defaultValue: undefined
});

// Add a boolean flag
globalOption({
  name: "verbose-logging",
  description: "Enable verbose logging",
  type: ArgumentType.BOOLEAN,
  defaultValue: false,
  isFlag: true
});

// Add a number option with short name
globalOption({
  name: "max-retries",
  shortName: "r",
  description: "Maximum number of retries",
  type: ArgumentType.INT,
  defaultValue: 3
});

Plugin Dependencies

System for managing plugin dependencies and load order.

type PluginDependency = 
  | string 
  | { name: string; optional?: boolean }
  | (() => Promise<HardhatPlugin>);

interface PluginDependencyInfo {
  /** Plugin name or identifier */
  name: string;
  
  /** Whether the dependency is optional */
  optional: boolean;
  
  /** Resolved plugin instance */
  plugin?: HardhatPlugin;
  
  /** Load status */
  status: "pending" | "loading" | "loaded" | "failed";
  
  /** Load error if failed */
  error?: Error;
}

Plugin Registry

System for registering and managing plugins.

interface PluginRegistry {
  /** Register a plugin */
  register(plugin: HardhatPlugin): void;
  
  /** Get a registered plugin by ID */
  get(pluginId: string): HardhatPlugin | undefined;
  
  /** Check if a plugin is registered */
  has(pluginId: string): boolean;
  
  /** Get all registered plugin IDs */
  getPluginIds(): string[];
  
  /** Load and initialize all plugins */
  loadAll(hre: HardhatRuntimeEnvironment): Promise<void>;
  
  /** Get plugin dependency graph */
  getDependencyGraph(): Map<string, string[]>;
}

Plugin Error Handling

Specialized error handling for plugin-related issues.

class HardhatPluginError extends Error {
  /** Plugin name that caused the error */
  readonly pluginName: string;
  
  /** Original error if this wraps another error */
  readonly parent?: Error;
  
  constructor(
    pluginName: string,
    message: string,
    parent?: Error
  );
}

interface PluginLoadError extends Error {
  /** Plugin ID that failed to load */
  pluginId: string;
  
  /** Type of load error */
  errorType: "missing" | "invalid" | "dependency" | "initialization";
  
  /** Additional error context */
  context?: any;
}

Usage Examples:

import { HardhatPluginError } from "hardhat/plugins";

// In plugin code, throw plugin-specific errors
throw new HardhatPluginError(
  "my-plugin",
  "Failed to connect to external service",
  originalError
);

// Handle plugin errors
try {
  await hre.run("my-plugin-task");
} catch (error) {
  if (error instanceof HardhatPluginError) {
    console.log(`Plugin error in ${error.pluginName}: ${error.message}`);
  }
}

Type Extensions

Plugins can extend Hardhat's type system through module augmentation.

Usage Examples:

// In plugin's type extension file
declare module "hardhat/types/hre" {
  interface HardhatRuntimeEnvironment {
    myPlugin: {
      doSomething(): Promise<void>;
      getSomething(): string;
    };
  }
}

declare module "hardhat/types/config" {
  interface HardhatUserConfig {
    myPlugin?: {
      enabled?: boolean;
      apiKey?: string;
    };
  }
  
  interface HardhatConfig {
    myPlugin: {
      enabled: boolean;
      apiKey?: string;
    };
  }
}

// In plugin implementation
export async function initialized(hre, context) {
  hre.myPlugin = {
    doSomething: async () => {
      console.log("Doing something...");
    },
    getSomething: () => "something"
  };
}

Plugin Lifecycle

Plugins follow a specific lifecycle during loading and execution.

interface PluginLifecycle {
  /** Phase 1: Plugin registration */
  register: () => void;
  
  /** Phase 2: Dependency resolution */
  resolveDependencies: () => Promise<void>;
  
  /** Phase 3: Plugin initialization */
  initialize: (hre: HardhatRuntimeEnvironment) => Promise<void>;
  
  /** Phase 4: Hook handler registration */
  registerHooks: (hre: HardhatRuntimeEnvironment) => Promise<void>;
  
  /** Phase 5: Plugin ready for use */
  ready: () => void;
}

docs

artifact-management.md

configuration.md

hook-system.md

index.md

network-management.md

plugin-system.md

solidity-build-system.md

task-management.md

utilities.md

tile.json