@paimaexample/evm-contracts
v0.3.120
Published
Effectstream EVM default contracts.
Readme
EffectStream EVM contracts
NPM package for EVM contracts for EffectStream and related utilities.
See the Paima documentation for full documentation.
Hardhat Config Builder
This package also provides a unified Hardhat configuration builder that consolidates common Hardhat setup logic used across e2e tests and templates.
Overview
The unified config builder provides three main functions:
createHardhatConfig()- Creates a complete Hardhat configuration with automatic default networkscreateNodeTasks()- Creates custom Hardhat tasks for running local blockchain nodesinitTelemetry()- Initializes OpenTelemetry for Hardhat
Key Features:
- Automatic Default Networks: Default networks (
evmMain,evmMainHttp,evmParallel,evmParallelHttp) are included whennetworksis not specified. - Centralized Configuration: All common Hardhat setup logic in one place
- Type Safe: Full TypeScript support with proper types
- Flexible: Supports both
@effectstreamand@paimaexamplepackage namespaces
Additional Utilities:
createDefaultNetworks()- Helper function to create default network configurations
Usage
Basic Example
import type { HardhatUserConfig } from "hardhat/config";
import {
createHardhatConfig,
createNodeTasks,
initTelemetry,
} from "@effectstream/evm-hardhat/hardhat-config-builder";
// or for templates:
// } from "@paimaexample/evm-hardhat/hardhat-config-builder";
import {
JsonRpcServerImplementation,
} from "@effectstream/evm-hardhat/json-rpc-server";
// or for templates:
// } from "@paimaexample/evm-hardhat/json-rpc-server";
import fs from "node:fs";
import waitOn from "wait-on";
import {
ComponentNames,
log,
SeverityNumber,
} from "@effectstream/log";
// or for templates:
// } from "@paimaexample/log";
const __dirname = import.meta.dirname;
// Initialize telemetry (optional)
// Note: logPackage parameter is kept for backward compatibility but ignored
initTelemetry("@effectstream/log", "./deno.json");
// or for templates:
// initTelemetry("@paimaexample/log", "./deno.json");
// Create node tasks (optional, only if you need local node functionality)
const nodeTasks = createNodeTasks({
JsonRpcServer: {} as unknown as never, // Type placeholder, optional and not used
JsonRpcServerImplementation,
ComponentNames,
log,
SeverityNumber,
waitOn,
fs,
});
// Create unified config with default networks
const config: HardhatUserConfig = createHardhatConfig({
sourcesDir: `${__dirname}/src/contracts`,
artifactsDir: `${__dirname}/build/artifacts/hardhat`,
cacheDir: `${__dirname}/build/cache/hardhat`,
// Default networks (evmMain, evmMainHttp, evmParallel, evmParallelHttp) are used automatically
tasks: nodeTasks, // Optional: only include if you created node tasks
solidityVersion: "0.8.30", // Optional: defaults to "0.8.30"
});
export default config;API Reference
createDefaultNetworks(options?: DefaultNetworkOptions): Record<string, NetworkConfig>
Creates default network configurations commonly used in e2e tests and templates. This function is used by createHardhatConfig() when default networks are enabled, but can also be called directly if you need to create networks separately or customize them.
When to Use
- Directly: When you want to create default networks and pass them explicitly to
createHardhatConfig() - Internally: Automatically called by
createHardhatConfig()whennetworksis not provided (default behavior) - Customization: Use with
defaultNetworkOptionsincreateHardhatConfig()to customize default network parameters
Parameters
options.evmMainPort(optional): Base port for evmMain (defaults to8545)options.evmParallelPort(optional): Base port for evmParallel (defaults to8546)options.evmMainChainId(optional): Chain ID for evmMain (defaults to31337)options.evmParallelChainId(optional): Chain ID for evmParallel (defaults to31338)options.evmMainInterval(optional): Mining interval for evmMain in ms (defaults to250)options.evmParallelInterval(optional): Mining interval for evmParallel in ms (defaults to1000)
Returns
A network configuration object with:
evmMain: Fast network (250ms block interval) on chainId 31337, port 8545evmMainHttp: HTTP wrapper for evmMain (used by Hardhat Ignition for deployments)evmParallel: Slower network (1s block interval) on chainId 31338, port 8546evmParallelHttp: HTTP wrapper for evmParallel (used by Hardhat Ignition for deployments)
Example
import { createDefaultNetworks } from "@effectstream/evm-contracts";
// Create default networks with custom ports
const networks = createDefaultNetworks({
evmMainPort: 8545,
evmParallelPort: 8546,
evmMainInterval: 500, // Slower than default
});
// Use in createHardhatConfig
const config = createHardhatConfig({
sourcesDir: `${__dirname}/src/contracts`,
artifactsDir: `${__dirname}/build/artifacts/hardhat`,
cacheDir: `${__dirname}/build/cache/hardhat`,
networks, // Explicitly pass networks
useDefaultNetworks: false, // Disable auto-creation since we're passing networks
});createHardhatConfig(options: HardhatConfigOptions): HardhatUserConfig
Creates a unified Hardhat configuration.
Parameters
options.sourcesDir(required): Directory containing contract sourcesoptions.artifactsDir(required): Directory for compiled artifactsoptions.cacheDir(required): Directory for Hardhat cacheoptions.networks(optional): Networks configuration object. If not provided, default networks (evmMain,evmMainHttp,evmParallel,evmParallelHttp) will be automatically usedoptions.useDefaultNetworks(optional): Whether to use default networks (defaults totrueifnetworksis not provided)options.defaultNetworkOptions(optional): Options for customizing default networks (only used ifuseDefaultNetworksistrue)options.tasks(optional): Custom Hardhat tasks (e.g., fromcreateNodeTasks())options.solidityVersion(optional): Solidity compiler version (defaults to"0.8.30")
Returns
A complete HardhatUserConfig object ready to export.
Note: The config will automatically include the default networks (evmMain, evmMainHttp, evmParallel, evmParallelHttp) when networks is not provided.
createNodeTasks(deps: NodeTaskDependencies): HardhatUserConfig["tasks"]
Creates custom Hardhat tasks for running local blockchain nodes. These tasks enable:
- Starting JSON-RPC servers for configured networks (
hardhat node) - Waiting for servers to be ready (
hardhat node:wait)
Parameters
deps.JsonRpcServer(optional): Type placeholder, not actually used (kept for type compatibility). Can be omitted or set to{} as unknown as neverdeps.JsonRpcServerImplementation(required): The JsonRpcServerImplementation class from@effectstream/evm-hardhat/json-rpc-serveror@paimaexample/evm-hardhat/json-rpc-serverdeps.ComponentNames(required): Component names from the log packagedeps.log(required): Log utilities from the log packagedeps.SeverityNumber(required): Severity number constants from the log packagedeps.waitOn(required): Thewait-onmodule for waiting on portsdeps.fs(required): Node.jsfsmodule for checking Docker environment
Returns
An array of Hardhat tasks that can be passed to createHardhatConfig().
initTelemetry(logPackage: string, denoJsonPath?: string): void
Initializes OpenTelemetry for Hardhat. This should be called at the top level of your hardhat.config.ts file.
Parameters
logPackage(required but ignored): Package name for log utilities - kept for backward compatibility but no longer used (uses static import instead)denoJsonPath(optional): Path todeno.jsonfile for version detection (defaults to"./deno.json")
Package Names
The unified config builder supports both package naming conventions:
- E2E tests: Use
@effectstream/evm-hardhat/hardhat-config-builder,@effectstream/evm-hardhat/json-rpc-server,@effectstream/log - Templates: Use
@paimaexample/evm-hardhat/hardhat-config-builder,@paimaexample/evm-hardhat/json-rpc-server,@paimaexample/log
Note: The functions are now exported from evm-hardhat package. The evm-contracts package re-exports them for backward compatibility, but new code should import directly from evm-hardhat.
Benefits
- Centralized Configuration: All common Hardhat setup logic in one place
- Easier Maintenance: Updates to Hardhat setup only need to be made once
- Consistency: All e2e tests and templates use the same configuration logic
- Flexibility: Still allows customization through parameters
- Type Safety: Full TypeScript support with proper types
Customizing Default Networks
You can customize the default networks by passing defaultNetworkOptions:
const config: HardhatUserConfig = createHardhatConfig({
sourcesDir: `${__dirname}/src/contracts`,
artifactsDir: `${__dirname}/build/artifacts/hardhat`,
cacheDir: `${__dirname}/build/cache/hardhat`,
defaultNetworkOptions: {
evmMainInterval: 500, // Customize main network interval
evmMainPort: 8545, // Customize port (defaults to 8545)
evmParallelPort: 8546, // Customize port (defaults to 8546)
},
tasks: nodeTasks,
solidityVersion: "0.8.30",
});Using Custom Networks
If you want to provide completely custom networks instead of using defaults:
const customNetworks = {
myCustomNetwork: {
type: "edr-simulated",
chainType: "l1",
chainId: 1337,
// ... custom config
},
};
const config: HardhatUserConfig = createHardhatConfig({
sourcesDir: `${__dirname}/src/contracts`,
artifactsDir: `${__dirname}/build/artifacts/hardhat`,
cacheDir: `${__dirname}/build/cache/hardhat`,
networks: customNetworks,
useDefaultNetworks: false, // Disable default networks
tasks: nodeTasks,
solidityVersion: "0.8.30",
});Migration Guide
If you have an existing hardhat.config.ts file, follow these steps:
- Import the unified builder functions
- Replace your custom
initTelemetry()function withinitTelemetry()from the builder - Replace your custom node tasks with
createNodeTasks() - Remove the network definitions (they're now provided by default)
- Replace your config object with
createHardhatConfig()(without thenetworksparameter) - Remove duplicate code (network list helpers, task definitions, etc.)
See the examples in e2e/shared/contracts/evm/hardhat.config.ts and the template configs for reference implementations.
