@paimaexample/evm-contracts 0.3.103 → 0.3.105

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -5,3 +5,265 @@ NPM package for EVM contracts for EffectStream and related utilities.
5
5
  See
6
6
  [the Paima documentation](https://docs.paimastudios.com/home/libraries/evm-contracts/introduction)
7
7
  for full documentation.
8
+
9
+ # Hardhat Config Builder
10
+
11
+ This package also provides a unified Hardhat configuration builder that consolidates common Hardhat setup logic used across e2e tests and templates.
12
+
13
+ ## Overview
14
+
15
+ The unified config builder provides three main functions:
16
+
17
+ 1. **`createHardhatConfig()`** - Creates a complete Hardhat configuration with automatic default networks
18
+ 2. **`createNodeTasks()`** - Creates custom Hardhat tasks for running local blockchain nodes
19
+ 3. **`initTelemetry()`** - Initializes OpenTelemetry for Hardhat
20
+
21
+ **Key Features:**
22
+ - **Automatic Default Networks**: Default networks (`evmMain`, `evmMainHttp`, `evmParallel`, `evmParallelHttp`) are included when `networks` is not specified.
23
+ - **Centralized Configuration**: All common Hardhat setup logic in one place
24
+ - **Type Safe**: Full TypeScript support with proper types
25
+ - **Flexible**: Supports both `@effectstream` and `@paimaexample` package namespaces
26
+
27
+ **Additional Utilities:**
28
+ - **`createDefaultNetworks()`** - Helper function to create default network configurations
29
+
30
+ ## Usage
31
+
32
+ ### Basic Example
33
+
34
+ ```typescript
35
+ import type { HardhatUserConfig } from "hardhat/config";
36
+ import {
37
+ createHardhatConfig,
38
+ createNodeTasks,
39
+ initTelemetry,
40
+ } from "@effectstream/evm-hardhat/hardhat-config-builder";
41
+ // or for templates:
42
+ // } from "@paimaexample/evm-hardhat/hardhat-config-builder";
43
+
44
+ import {
45
+ JsonRpcServerImplementation,
46
+ } from "@effectstream/evm-hardhat/json-rpc-server";
47
+ // or for templates:
48
+ // } from "@paimaexample/evm-hardhat/json-rpc-server";
49
+
50
+ import fs from "node:fs";
51
+ import waitOn from "wait-on";
52
+ import {
53
+ ComponentNames,
54
+ log,
55
+ SeverityNumber,
56
+ } from "@effectstream/log";
57
+ // or for templates:
58
+ // } from "@paimaexample/log";
59
+
60
+ const __dirname = import.meta.dirname;
61
+
62
+ // Initialize telemetry (optional)
63
+ // Note: logPackage parameter is kept for backward compatibility but ignored
64
+ initTelemetry("@effectstream/log", "./deno.json");
65
+ // or for templates:
66
+ // initTelemetry("@paimaexample/log", "./deno.json");
67
+
68
+ // Create node tasks (optional, only if you need local node functionality)
69
+ const nodeTasks = createNodeTasks({
70
+ JsonRpcServer: {} as unknown as never, // Type placeholder, optional and not used
71
+ JsonRpcServerImplementation,
72
+ ComponentNames,
73
+ log,
74
+ SeverityNumber,
75
+ waitOn,
76
+ fs,
77
+ });
78
+
79
+ // Create unified config with default networks
80
+ const config: HardhatUserConfig = createHardhatConfig({
81
+ sourcesDir: `${__dirname}/src/contracts`,
82
+ artifactsDir: `${__dirname}/build/artifacts/hardhat`,
83
+ cacheDir: `${__dirname}/build/cache/hardhat`,
84
+ // Default networks (evmMain, evmMainHttp, evmParallel, evmParallelHttp) are used automatically
85
+ tasks: nodeTasks, // Optional: only include if you created node tasks
86
+ solidityVersion: "0.8.30", // Optional: defaults to "0.8.30"
87
+ });
88
+
89
+ export default config;
90
+ ```
91
+
92
+ ## API Reference
93
+
94
+ ### `createDefaultNetworks(options?: DefaultNetworkOptions): Record<string, NetworkConfig>`
95
+
96
+ 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.
97
+
98
+ #### When to Use
99
+
100
+ - **Directly**: When you want to create default networks and pass them explicitly to `createHardhatConfig()`
101
+ - **Internally**: Automatically called by `createHardhatConfig()` when `networks` is not provided (default behavior)
102
+ - **Customization**: Use with `defaultNetworkOptions` in `createHardhatConfig()` to customize default network parameters
103
+
104
+ #### Parameters
105
+
106
+ - `options.evmMainPort` (optional): Base port for evmMain (defaults to `8545`)
107
+ - `options.evmParallelPort` (optional): Base port for evmParallel (defaults to `8546`)
108
+ - `options.evmMainChainId` (optional): Chain ID for evmMain (defaults to `31337`)
109
+ - `options.evmParallelChainId` (optional): Chain ID for evmParallel (defaults to `31338`)
110
+ - `options.evmMainInterval` (optional): Mining interval for evmMain in ms (defaults to `250`)
111
+ - `options.evmParallelInterval` (optional): Mining interval for evmParallel in ms (defaults to `1000`)
112
+
113
+ #### Returns
114
+
115
+ A network configuration object with:
116
+ - `evmMain`: Fast network (250ms block interval) on chainId 31337, port 8545
117
+ - `evmMainHttp`: HTTP wrapper for evmMain (used by Hardhat Ignition for deployments)
118
+ - `evmParallel`: Slower network (1s block interval) on chainId 31338, port 8546
119
+ - `evmParallelHttp`: HTTP wrapper for evmParallel (used by Hardhat Ignition for deployments)
120
+
121
+ #### Example
122
+
123
+ ```typescript
124
+ import { createDefaultNetworks } from "@effectstream/evm-contracts";
125
+
126
+ // Create default networks with custom ports
127
+ const networks = createDefaultNetworks({
128
+ evmMainPort: 8545,
129
+ evmParallelPort: 8546,
130
+ evmMainInterval: 500, // Slower than default
131
+ });
132
+
133
+ // Use in createHardhatConfig
134
+ const config = createHardhatConfig({
135
+ sourcesDir: `${__dirname}/src/contracts`,
136
+ artifactsDir: `${__dirname}/build/artifacts/hardhat`,
137
+ cacheDir: `${__dirname}/build/cache/hardhat`,
138
+ networks, // Explicitly pass networks
139
+ useDefaultNetworks: false, // Disable auto-creation since we're passing networks
140
+ });
141
+ ```
142
+
143
+ ### `createHardhatConfig(options: HardhatConfigOptions): HardhatUserConfig`
144
+
145
+ Creates a unified Hardhat configuration.
146
+
147
+ #### Parameters
148
+
149
+ - `options.sourcesDir` (required): Directory containing contract sources
150
+ - `options.artifactsDir` (required): Directory for compiled artifacts
151
+ - `options.cacheDir` (required): Directory for Hardhat cache
152
+ - `options.networks` (optional): Networks configuration object. **If not provided, default networks (`evmMain`, `evmMainHttp`, `evmParallel`, `evmParallelHttp`) will be automatically used**
153
+ - `options.useDefaultNetworks` (optional): Whether to use default networks (defaults to `true` if `networks` is not provided)
154
+ - `options.defaultNetworkOptions` (optional): Options for customizing default networks (only used if `useDefaultNetworks` is `true`)
155
+ - `options.tasks` (optional): Custom Hardhat tasks (e.g., from `createNodeTasks()`)
156
+ - `options.solidityVersion` (optional): Solidity compiler version (defaults to `"0.8.30"`)
157
+
158
+ #### Returns
159
+
160
+ A complete `HardhatUserConfig` object ready to export.
161
+ **Note:** The config will automatically include the default networks (`evmMain`, `evmMainHttp`, `evmParallel`, `evmParallelHttp`) when `networks` is not provided.
162
+
163
+ ### `createNodeTasks(deps: NodeTaskDependencies): HardhatUserConfig["tasks"]`
164
+
165
+ Creates custom Hardhat tasks for running local blockchain nodes. These tasks enable:
166
+ - Starting JSON-RPC servers for configured networks (`hardhat node`)
167
+ - Waiting for servers to be ready (`hardhat node:wait`)
168
+
169
+ #### Parameters
170
+
171
+ - `deps.JsonRpcServer` (optional): Type placeholder, not actually used (kept for type compatibility). Can be omitted or set to `{} as unknown as never`
172
+ - `deps.JsonRpcServerImplementation` (required): The JsonRpcServerImplementation class from `@effectstream/evm-hardhat/json-rpc-server` or `@paimaexample/evm-hardhat/json-rpc-server`
173
+ - `deps.ComponentNames` (required): Component names from the log package
174
+ - `deps.log` (required): Log utilities from the log package
175
+ - `deps.SeverityNumber` (required): Severity number constants from the log package
176
+ - `deps.waitOn` (required): The `wait-on` module for waiting on ports
177
+ - `deps.fs` (required): Node.js `fs` module for checking Docker environment
178
+
179
+ #### Returns
180
+
181
+ An array of Hardhat tasks that can be passed to `createHardhatConfig()`.
182
+
183
+ ### `initTelemetry(logPackage: string, denoJsonPath?: string): void`
184
+
185
+ Initializes OpenTelemetry for Hardhat. This should be called at the top level of your `hardhat.config.ts` file.
186
+
187
+ #### Parameters
188
+
189
+ - `logPackage` (required but ignored): Package name for log utilities - kept for backward compatibility but no longer used (uses static import instead)
190
+ - `denoJsonPath` (optional): Path to `deno.json` file for version detection (defaults to `"./deno.json"`)
191
+
192
+ ## Package Names
193
+
194
+ The unified config builder supports both package naming conventions:
195
+
196
+ - **E2E tests**: Use `@effectstream/evm-hardhat/hardhat-config-builder`, `@effectstream/evm-hardhat/json-rpc-server`, `@effectstream/log`
197
+ - **Templates**: Use `@paimaexample/evm-hardhat/hardhat-config-builder`, `@paimaexample/evm-hardhat/json-rpc-server`, `@paimaexample/log`
198
+
199
+ 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`.
200
+
201
+ ## Benefits
202
+
203
+ 1. **Centralized Configuration**: All common Hardhat setup logic in one place
204
+ 2. **Easier Maintenance**: Updates to Hardhat setup only need to be made once
205
+ 3. **Consistency**: All e2e tests and templates use the same configuration logic
206
+ 4. **Flexibility**: Still allows customization through parameters
207
+ 5. **Type Safety**: Full TypeScript support with proper types
208
+
209
+ ### Customizing Default Networks
210
+
211
+ You can customize the default networks by passing `defaultNetworkOptions`:
212
+
213
+ ```typescript
214
+ const config: HardhatUserConfig = createHardhatConfig({
215
+ sourcesDir: `${__dirname}/src/contracts`,
216
+ artifactsDir: `${__dirname}/build/artifacts/hardhat`,
217
+ cacheDir: `${__dirname}/build/cache/hardhat`,
218
+ defaultNetworkOptions: {
219
+ evmMainInterval: 500, // Customize main network interval
220
+ evmMainPort: 8545, // Customize port (defaults to 8545)
221
+ evmParallelPort: 8546, // Customize port (defaults to 8546)
222
+ },
223
+ tasks: nodeTasks,
224
+ solidityVersion: "0.8.30",
225
+ });
226
+ ```
227
+
228
+ ### Using Custom Networks
229
+
230
+ If you want to provide completely custom networks instead of using defaults:
231
+
232
+ ```typescript
233
+ const customNetworks = {
234
+ myCustomNetwork: {
235
+ type: "edr-simulated",
236
+ chainType: "l1",
237
+ chainId: 1337,
238
+ // ... custom config
239
+ },
240
+ };
241
+
242
+ const config: HardhatUserConfig = createHardhatConfig({
243
+ sourcesDir: `${__dirname}/src/contracts`,
244
+ artifactsDir: `${__dirname}/build/artifacts/hardhat`,
245
+ cacheDir: `${__dirname}/build/cache/hardhat`,
246
+ networks: customNetworks,
247
+ useDefaultNetworks: false, // Disable default networks
248
+ tasks: nodeTasks,
249
+ solidityVersion: "0.8.30",
250
+ });
251
+ ```
252
+
253
+ ## Migration Guide
254
+
255
+ If you have an existing `hardhat.config.ts` file, follow these steps:
256
+
257
+ 1. Import the unified builder functions
258
+ 2. Replace your custom `initTelemetry()` function with `initTelemetry()` from the builder
259
+ 3. Replace your custom node tasks with `createNodeTasks()`
260
+ 4. Remove the network definitions (they're now provided by default)
261
+ 5. Replace your config object with `createHardhatConfig()` (without the `networks` parameter)
262
+ 6. Remove duplicate code (network list helpers, task definitions, etc.)
263
+
264
+ See the examples in `e2e/shared/contracts/evm/hardhat.config.ts` and the template configs for reference implementations.
265
+
266
+ ## See Also
267
+
268
+ - [Hardhat Documentation](https://hardhat.org/docs)
269
+ - [Paima Engine Documentation](https://docs.paimastudios.com)
package/deno.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@paimaexample/evm-contracts",
3
- "version": "0.3.103",
3
+ "version": "0.3.105",
4
4
  "license": "MIT",
5
5
  "exports": {
6
6
  ".": "./mod.ts"
package/mod.ts CHANGED
@@ -6,7 +6,7 @@ export {
6
6
  type HardhatConfigOptions,
7
7
  type DefaultNetworkOptions,
8
8
  type NodeTaskDependencies,
9
- } from "./src/hardhatConfigBuilder.ts";
9
+ } from "@paimaexample/evm-hardhat/hardhat-config-builder";
10
10
 
11
11
  export { defaultHardhatConfig } from "./src/recommendedHardhat.ts";
12
12
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@paimaexample/evm-contracts",
3
- "version": "0.3.103",
3
+ "version": "0.3.105",
4
4
  "description": "Effectstream EVM default contracts.",
5
5
  "main": "index.js",
6
6
  "author": "Paima Studios",
@@ -1,262 +0,0 @@
1
- # Hardhat Config Builder
2
-
3
- This package provides a unified Hardhat configuration builder that consolidates common Hardhat setup logic used across e2e tests and templates. This eliminates code duplication and centralizes maintenance.
4
-
5
- ## Overview
6
-
7
- The unified config builder provides three main functions:
8
-
9
- 1. **`createHardhatConfig()`** - Creates a complete Hardhat configuration with automatic default networks
10
- 2. **`createNodeTasks()`** - Creates custom Hardhat tasks for running local blockchain nodes
11
- 3. **`initTelemetry()`** - Initializes OpenTelemetry for Hardhat
12
-
13
- **Key Features:**
14
- - **Automatic Default Networks**: If you don't specify `networks`, default networks (`evmMain`, `evmMainHttp`, `evmParallel`, `evmParallelHttp`) are automatically included
15
- - **Centralized Configuration**: All common Hardhat setup logic in one place
16
- - **Type Safe**: Full TypeScript support with proper types
17
- - **Flexible**: Supports both `@effectstream` and `@paimaexample` package namespaces
18
-
19
- **Additional Utilities:**
20
- - **`createDefaultNetworks()`** - Helper function to create default network configurations (used internally by `createHardhatConfig()`)
21
-
22
- ## Usage
23
-
24
- ### Basic Example
25
-
26
- ```typescript
27
- import type { HardhatUserConfig } from "hardhat/config";
28
- import {
29
- createHardhatConfig,
30
- createNodeTasks,
31
- initTelemetry,
32
- } from "@effectstream/evm-contracts";
33
- // or for templates:
34
- // } from "@paimaexample/evm-contracts";
35
-
36
- import {
37
- JsonRpcServerImplementation,
38
- } from "@effectstream/evm-hardhat/json-rpc-server";
39
- // or for templates:
40
- // } from "@paimaexample/evm-hardhat/json-rpc-server";
41
-
42
- import fs from "node:fs";
43
- import waitOn from "wait-on";
44
- import {
45
- ComponentNames,
46
- log,
47
- SeverityNumber,
48
- } from "@effectstream/log";
49
- // or for templates:
50
- // } from "@paimaexample/log";
51
-
52
- const __dirname = import.meta.dirname;
53
-
54
- // Initialize telemetry (optional)
55
- initTelemetry("@effectstream/log", "./deno.json");
56
- // or for templates:
57
- // initTelemetry("@paimaexample/log", "./deno.json");
58
-
59
- // Create node tasks (optional, only if you need local node functionality)
60
- const nodeTasks = createNodeTasks({
61
- JsonRpcServer: {} as unknown as never, // Type placeholder, optional and not used
62
- JsonRpcServerImplementation,
63
- ComponentNames,
64
- log,
65
- SeverityNumber,
66
- waitOn,
67
- fs,
68
- });
69
-
70
- // Create unified config with default networks
71
- const config: HardhatUserConfig = createHardhatConfig({
72
- sourcesDir: `${__dirname}/src/contracts`,
73
- artifactsDir: `${__dirname}/build/artifacts/hardhat`,
74
- cacheDir: `${__dirname}/build/cache/hardhat`,
75
- // Default networks (evmMain, evmMainHttp, evmParallel, evmParallelHttp) are used automatically
76
- tasks: nodeTasks, // Optional: only include if you created node tasks
77
- solidityVersion: "0.8.30", // Optional: defaults to "0.8.30"
78
- });
79
-
80
- export default config;
81
- ```
82
-
83
- ## API Reference
84
-
85
- ### `createDefaultNetworks(options?: DefaultNetworkOptions): Record<string, NetworkConfig>`
86
-
87
- Creates default network configurations commonly used in e2e tests and templates. This function is used internally by `createHardhatConfig()` when default networks are enabled, but can also be called directly if you need to create networks separately or customize them.
88
-
89
- #### When to Use
90
-
91
- - **Directly**: When you want to create default networks and pass them explicitly to `createHardhatConfig()`
92
- - **Internally**: Automatically called by `createHardhatConfig()` when `networks` is not provided (default behavior)
93
- - **Customization**: Use with `defaultNetworkOptions` in `createHardhatConfig()` to customize default network parameters
94
-
95
- #### Parameters
96
-
97
- - `options.evmMainPort` (optional): Base port for evmMain (defaults to `8545`)
98
- - `options.evmParallelPort` (optional): Base port for evmParallel (defaults to `8546`)
99
- - `options.evmMainChainId` (optional): Chain ID for evmMain (defaults to `31337`)
100
- - `options.evmParallelChainId` (optional): Chain ID for evmParallel (defaults to `31338`)
101
- - `options.evmMainInterval` (optional): Mining interval for evmMain in ms (defaults to `250`)
102
- - `options.evmParallelInterval` (optional): Mining interval for evmParallel in ms (defaults to `1000`)
103
-
104
- #### Returns
105
-
106
- A network configuration object with:
107
- - `evmMain`: Fast network (250ms block interval) on chainId 31337, port 8545
108
- - `evmMainHttp`: HTTP wrapper for evmMain (used by Hardhat Ignition for deployments)
109
- - `evmParallel`: Slower network (1s block interval) on chainId 31338, port 8546
110
- - `evmParallelHttp`: HTTP wrapper for evmParallel (used by Hardhat Ignition for deployments)
111
-
112
- #### Example
113
-
114
- ```typescript
115
- import { createDefaultNetworks } from "@effectstream/evm-contracts";
116
-
117
- // Create default networks with custom ports
118
- const networks = createDefaultNetworks({
119
- evmMainPort: 8545,
120
- evmParallelPort: 8546,
121
- evmMainInterval: 500, // Slower than default
122
- });
123
-
124
- // Use in createHardhatConfig
125
- const config = createHardhatConfig({
126
- sourcesDir: `${__dirname}/src/contracts`,
127
- artifactsDir: `${__dirname}/build/artifacts/hardhat`,
128
- cacheDir: `${__dirname}/build/cache/hardhat`,
129
- networks, // Explicitly pass networks
130
- useDefaultNetworks: false, // Disable auto-creation since we're passing networks
131
- });
132
- ```
133
-
134
- ### `createHardhatConfig(options: HardhatConfigOptions): HardhatUserConfig`
135
-
136
- Creates a unified Hardhat configuration.
137
-
138
- #### Parameters
139
-
140
- - `options.sourcesDir` (required): Directory containing contract sources
141
- - `options.artifactsDir` (required): Directory for compiled artifacts
142
- - `options.cacheDir` (required): Directory for Hardhat cache
143
- - `options.networks` (optional): Networks configuration object. **If not provided, default networks (`evmMain`, `evmMainHttp`, `evmParallel`, `evmParallelHttp`) will be automatically used**
144
- - `options.useDefaultNetworks` (optional): Whether to use default networks (defaults to `true` if `networks` is not provided)
145
- - `options.defaultNetworkOptions` (optional): Options for customizing default networks (only used if `useDefaultNetworks` is `true`)
146
- - `options.tasks` (optional): Custom Hardhat tasks (e.g., from `createNodeTasks()`)
147
- - `options.solidityVersion` (optional): Solidity compiler version (defaults to `"0.8.30"`)
148
-
149
- #### Returns
150
-
151
- A complete `HardhatUserConfig` object ready to export.
152
-
153
- **Note:** By default, if you don't provide `networks`, the config will automatically include the default networks (`evmMain`, `evmMainHttp`, `evmParallel`, `evmParallelHttp`). This eliminates the need to define networks manually in most cases.
154
-
155
- ### `createNodeTasks(deps: NodeTaskDependencies): HardhatUserConfig["tasks"]`
156
-
157
- Creates custom Hardhat tasks for running local blockchain nodes. These tasks enable:
158
- - Starting JSON-RPC servers for configured networks (`hardhat node`)
159
- - Waiting for servers to be ready (`hardhat node:wait`)
160
-
161
- #### Parameters
162
-
163
- - `deps.JsonRpcServer` (optional): Type placeholder, not actually used (kept for type compatibility). Can be omitted or set to `{} as unknown as never`
164
- - `deps.JsonRpcServerImplementation` (required): The JsonRpcServerImplementation class from `@effectstream/evm-hardhat/json-rpc-server` or `@paimaexample/evm-hardhat/json-rpc-server`
165
- - `deps.ComponentNames` (required): Component names from the log package
166
- - `deps.log` (required): Log utilities from the log package
167
- - `deps.SeverityNumber` (required): Severity number constants from the log package
168
- - `deps.waitOn` (required): The `wait-on` module for waiting on ports
169
- - `deps.fs` (required): Node.js `fs` module for checking Docker environment
170
-
171
- #### Returns
172
-
173
- An array of Hardhat tasks that can be passed to `createHardhatConfig()`.
174
-
175
- ### `initTelemetry(logPackage: string, denoJsonPath?: string): void`
176
-
177
- Initializes OpenTelemetry for Hardhat. This should be called at the top level of your `hardhat.config.ts` file.
178
-
179
- #### Parameters
180
-
181
- - `logPackage` (required): Package name for log utilities (e.g., `"@effectstream/log"` or `"@paimaexample/log"`)
182
- - `denoJsonPath` (optional): Path to `deno.json` file for version detection (defaults to `"./deno.json"`)
183
-
184
- ## Package Names
185
-
186
- The unified config builder supports both package naming conventions:
187
-
188
- - **E2E tests**: Use `@effectstream/evm-contracts`, `@effectstream/evm-hardhat`, `@effectstream/log`
189
- - **Templates**: Use `@paimaexample/evm-contracts`, `@paimaexample/evm-hardhat`, `@paimaexample/log`
190
-
191
- The functions work identically regardless of which package namespace you use.
192
-
193
- ## Benefits
194
-
195
- 1. **Eliminates Duplication**: Common Hardhat configuration logic is centralized in one place
196
- 2. **Easier Maintenance**: Updates to Hardhat setup only need to be made once
197
- 3. **Consistency**: All e2e tests and templates use the same configuration logic
198
- 4. **Flexibility**: Still allows customization through parameters
199
- 5. **Type Safety**: Full TypeScript support with proper types
200
-
201
- ### Customizing Default Networks
202
-
203
- You can customize the default networks by passing `defaultNetworkOptions`:
204
-
205
- ```typescript
206
- const config: HardhatUserConfig = createHardhatConfig({
207
- sourcesDir: `${__dirname}/src/contracts`,
208
- artifactsDir: `${__dirname}/build/artifacts/hardhat`,
209
- cacheDir: `${__dirname}/build/cache/hardhat`,
210
- defaultNetworkOptions: {
211
- evmMainInterval: 500, // Customize main network interval
212
- evmMainPort: 8545, // Customize port (defaults to 8545)
213
- evmParallelPort: 8546, // Customize port (defaults to 8546)
214
- },
215
- tasks: nodeTasks,
216
- solidityVersion: "0.8.30",
217
- });
218
- ```
219
-
220
- ### Using Custom Networks
221
-
222
- If you want to provide completely custom networks instead of using defaults:
223
-
224
- ```typescript
225
- const customNetworks = {
226
- myCustomNetwork: {
227
- type: "edr-simulated",
228
- chainType: "l1",
229
- chainId: 1337,
230
- // ... custom config
231
- },
232
- };
233
-
234
- const config: HardhatUserConfig = createHardhatConfig({
235
- sourcesDir: `${__dirname}/src/contracts`,
236
- artifactsDir: `${__dirname}/build/artifacts/hardhat`,
237
- cacheDir: `${__dirname}/build/cache/hardhat`,
238
- networks: customNetworks,
239
- useDefaultNetworks: false, // Disable default networks
240
- tasks: nodeTasks,
241
- solidityVersion: "0.8.30",
242
- });
243
- ```
244
-
245
- ## Migration Guide
246
-
247
- If you have an existing `hardhat.config.ts` file, follow these steps:
248
-
249
- 1. Import the unified builder functions
250
- 2. Replace your custom `initTelemetry()` function with `initTelemetry()` from the builder
251
- 3. Replace your custom node tasks with `createNodeTasks()`
252
- 4. Remove the network definitions (they're now provided by default)
253
- 5. Replace your config object with `createHardhatConfig()` (without the `networks` parameter)
254
- 6. Remove duplicate code (network list helpers, task definitions, etc.)
255
-
256
- See the examples in `e2e/shared/contracts/evm/hardhat.config.ts` and the template configs for reference implementations.
257
-
258
- ## See Also
259
-
260
- - [Hardhat Documentation](https://hardhat.org/docs)
261
- - [Paima Engine Documentation](https://docs.paimastudios.com)
262
-
@@ -1,398 +0,0 @@
1
- import type { HardhatUserConfig } from "hardhat/config";
2
- import type { NetworkConfig, TaskArguments } from "hardhat/types";
3
- import type { HardhatRuntimeEnvironment } from "hardhat/types";
4
- import HardhatViem from "@nomicfoundation/hardhat-viem";
5
- import { overrideTask, task } from "hardhat/config";
6
- import { ArgumentType } from "hardhat/types/arguments";
7
- import HardhatIgnitionViem from "@nomicfoundation/hardhat-ignition-viem";
8
-
9
- /**
10
- * Dependencies required for creating node tasks.
11
- * These should be imported in the calling code and passed to createNodeTasks.
12
- */
13
- export interface NodeTaskDependencies {
14
- /** JsonRpcServer type placeholder (not actually used, kept for type compatibility) */
15
- JsonRpcServer?: unknown;
16
- /** JsonRpcServerImplementation from evm-hardhat package */
17
- JsonRpcServerImplementation: new (
18
- options: { hostname: string; port: number; provider: any },
19
- logCallback: (msg: string) => void,
20
- ) => any;
21
- /** Log utilities from log package */
22
- ComponentNames: { HARDHAT: string };
23
- log: {
24
- remote: (
25
- component: string,
26
- tags: string[],
27
- severity: number,
28
- fn: (log: (...args: unknown[]) => void) => void,
29
- ) => void;
30
- };
31
- SeverityNumber: { INFO: number };
32
- /** wait-on module for waiting on ports */
33
- waitOn: (options: { resources: string[] }) => Promise<void>;
34
- /** fs module for checking Docker environment */
35
- fs: { existsSync: (path: string) => boolean };
36
- }
37
-
38
- /**
39
- * Options for creating default networks
40
- */
41
- export interface DefaultNetworkOptions {
42
- /** Base port for evmMain (defaults to 8545) */
43
- evmMainPort?: number;
44
- /** Base port for evmParallel (defaults to 8546) */
45
- evmParallelPort?: number;
46
- /** Chain ID for evmMain (defaults to 31337) */
47
- evmMainChainId?: number;
48
- /** Chain ID for evmParallel (defaults to 31338) */
49
- evmParallelChainId?: number;
50
- /** Mining interval for evmMain in ms (defaults to 250) */
51
- evmMainInterval?: number;
52
- /** Mining interval for evmParallel in ms (defaults to 1000) */
53
- evmParallelInterval?: number;
54
- }
55
-
56
- /**
57
- * Configuration options for creating a Hardhat config
58
- */
59
- export interface HardhatConfigOptions {
60
- /** Directory containing contract sources */
61
- sourcesDir: string;
62
- /** Directory for compiled artifacts */
63
- artifactsDir: string;
64
- /** Directory for Hardhat cache */
65
- cacheDir: string;
66
- /** Networks configuration - if not provided, default networks will be used */
67
- networks?: Record<string, NetworkConfig>;
68
- /** Whether to use default networks (defaults to true if networks is not provided) */
69
- useDefaultNetworks?: boolean;
70
- /** Options for default networks (only used if useDefaultNetworks is true) */
71
- defaultNetworkOptions?: DefaultNetworkOptions;
72
- /** Custom Hardhat tasks (e.g., from createNodeTasks) */
73
- tasks?: HardhatUserConfig["tasks"];
74
- /** Solidity compiler version */
75
- solidityVersion?: string;
76
- }
77
-
78
- /**
79
- * Creates node tasks for running local blockchain nodes.
80
- * These tasks allow starting JSON-RPC servers for configured networks.
81
- *
82
- * @param deps Dependencies required for the tasks (imported in calling code)
83
- * @returns Array of Hardhat tasks (node and node:wait)
84
- */
85
- export function createNodeTasks(
86
- deps: NodeTaskDependencies,
87
- ): HardhatUserConfig["tasks"] {
88
- const {
89
- JsonRpcServerImplementation,
90
- ComponentNames,
91
- log,
92
- SeverityNumber,
93
- waitOn,
94
- fs,
95
- } = deps;
96
-
97
- function logNetwork(networkName: string, ...msg: unknown[]) {
98
- log.remote(
99
- ComponentNames.HARDHAT,
100
- [networkName],
101
- SeverityNumber.INFO,
102
- (logFn) => logFn(...msg),
103
- );
104
- }
105
-
106
- function getNetworkList(networks: Record<string, NetworkConfig>) {
107
- const networkEntries = Object.entries(networks);
108
- // ensure we always run the `hardhat` network first
109
- networkEntries.sort((a, b) => {
110
- if (a[0] === "hardhat") return -1;
111
- if (b[0] === "hardhat") return 1;
112
- return 0;
113
- });
114
-
115
- return networkEntries.filter(([name, network]) =>
116
- // skip the builtin localhost network, since hardhat node is meant to explicitly not use it
117
- name !== "localhost" &&
118
- // hardhat network seems broken and the block number never advances on it
119
- name !== "hardhat" &&
120
- // if http type, then it already has a JSON-RPC server
121
- network.type !== "http"
122
- );
123
- }
124
-
125
- const nodeTask = overrideTask("node")
126
- .setAction(async () => ({
127
- default: async (
128
- args: TaskArguments,
129
- hre: HardhatRuntimeEnvironment,
130
- ): Promise<void> => {
131
- const hostname = (() => {
132
- if (args.hostname !== "127.0.0.1" && args.hostname !== "") {
133
- return args.hostname as string;
134
- }
135
- const insideDocker = fs.existsSync("/.dockerenv");
136
- return insideDocker ? "0.0.0.0" : "127.0.0.1";
137
- })();
138
- let port = args.port as number;
139
-
140
- const connections: any[] = [];
141
- const networkEntries = getNetworkList(hre.config.networks);
142
- for (const [name, network] of networkEntries) {
143
- // skip the builtin localhost network, since hardhat node is meant to explicitly not use it
144
- if (name === "localhost") {
145
- continue;
146
- }
147
- // hardhat network seems broken and the block number never advances on it
148
- if (name === "hardhat") {
149
- continue;
150
- }
151
- // if http type, then it already has a JSON-RPC server
152
- if (network.type === "http") {
153
- continue;
154
- }
155
-
156
- const connection = await hre.network.connect(name);
157
-
158
- const server = new JsonRpcServerImplementation(
159
- {
160
- hostname,
161
- port,
162
- provider: connection.provider,
163
- },
164
- (msg: string) => logNetwork(name, msg),
165
- );
166
- port++; // increase port so next network has a unique port number
167
- const publicClient = await connection.viem.getPublicClient();
168
- publicClient.watchBlocks(
169
- {
170
- onBlock: (block: any) => {
171
- // there seems to be a bug on block 0 where it triggers watchBlock in an infinite loop
172
- if (block.number === 0n) return;
173
-
174
- const txsMessage = block.transactions.length === 0
175
- ? ""
176
- : `\nTransactions:\n${
177
- block.transactions.map((tx: any) => tx.hash).join("\n\t")
178
- }`;
179
- logNetwork(
180
- name,
181
- `block ${block.number} (${block.hash})`,
182
- txsMessage,
183
- );
184
- },
185
- includeTransactions: true,
186
- },
187
- );
188
-
189
- const { port: actualPort, address } = await server.listen();
190
- logNetwork(
191
- name,
192
- `Started HTTP and WebSocket JSON-RPC server at ${address}:${actualPort}\n`,
193
- );
194
-
195
- connections.push(server);
196
-
197
- logNetwork(name, "Accounts for", name);
198
- logNetwork(name, "========");
199
- // we use this over network.genesisAccounts
200
- // since we don't have access to some of the hardhat v3 util functions otherwise
201
- const wallets = await connection.viem.getWalletClients();
202
- for (let i = 0; i < wallets.length; i++) {
203
- const weiBalance = await publicClient.getBalance({
204
- address: wallets[i].account.address,
205
- });
206
- const balance = (weiBalance / 10n ** 18n).toString(10);
207
- logNetwork(
208
- name,
209
- `Account #${i}: ${wallets[i].account.address} (${balance} ETH)`,
210
- );
211
- }
212
- }
213
- await Promise.all(
214
- connections.map((connection) => connection.waitUntilClosed()),
215
- );
216
- },
217
- }))
218
- .build();
219
-
220
- const nodeWaitTask = task(["node", "wait"])
221
- .addOption({
222
- name: "port",
223
- type: ArgumentType.INT,
224
- defaultValue: 8545,
225
- }).setAction(async () => ({
226
- default: async (
227
- args: TaskArguments,
228
- hre: HardhatRuntimeEnvironment,
229
- ): Promise<void> => {
230
- const networkEntries = getNetworkList(hre.config.networks);
231
- for (
232
- let port = args.port as number;
233
- port < (args.port as number) + networkEntries.length;
234
- port++
235
- ) {
236
- await waitOn({
237
- resources: [`tcp:${port}`],
238
- });
239
- port++;
240
- }
241
- },
242
- }))
243
- .build();
244
-
245
- return [nodeTask, nodeWaitTask];
246
- }
247
-
248
- /**
249
- * Creates default network configurations commonly used in e2e tests and templates.
250
- *
251
- * Returns networks:
252
- * - evmMain: Fast network (250ms block interval) on chainId 31337, port 8545
253
- * - evmMainHttp: HTTP wrapper for evmMain
254
- * - evmParallel: Slower network (1s block interval) on chainId 31338, port 8546
255
- * - evmParallelHttp: HTTP wrapper for evmParallel
256
- *
257
- * @param options Optional configuration to override defaults
258
- * @returns Network configuration object
259
- */
260
- export function createDefaultNetworks(
261
- options?: DefaultNetworkOptions,
262
- ): Record<string, NetworkConfig> {
263
- const {
264
- evmMainPort = 8545,
265
- evmParallelPort = 8546,
266
- evmMainChainId = 31337,
267
- evmParallelChainId = 31338,
268
- evmMainInterval = 250,
269
- evmParallelInterval = 1000,
270
- } = options || {};
271
-
272
- return {
273
- evmMain: {
274
- type: "edr-simulated",
275
- chainType: "l1",
276
- chainId: evmMainChainId,
277
- mining: {
278
- auto: true,
279
- interval: evmMainInterval, // Arbitrum (250ms)
280
- },
281
- allowBlocksWithSameTimestamp: true,
282
- },
283
- // This is a helper network to allow to hardhat/ignition to connect to the network.
284
- evmMainHttp: {
285
- type: "http",
286
- chainType: "l1",
287
- url: `http://0.0.0.0:${evmMainPort}`,
288
- },
289
- evmParallel: {
290
- type: "edr-simulated",
291
- chainType: "l1",
292
- chainId: evmParallelChainId,
293
- mining: {
294
- auto: true,
295
- interval: evmParallelInterval, // 1s
296
- },
297
- },
298
- // This is a helper network to allow to hardhat/ignition to connect to the network.
299
- evmParallelHttp: {
300
- type: "http",
301
- chainType: "l1",
302
- url: `http://0.0.0.0:${evmParallelPort}`,
303
- },
304
- };
305
- }
306
-
307
- /**
308
- * Initializes OpenTelemetry for Hardhat.
309
- * This should be called at the top level of your hardhat.config.ts file.
310
- *
311
- * Note: This function uses dynamic imports and executes asynchronously.
312
- * Errors are caught and logged as warnings to avoid breaking Hardhat initialization.
313
- *
314
- * @param logPackage Package name for log utilities (e.g., "@paimaexample/log" or "@paimaexample/log")
315
- * @param denoJsonPath Path to deno.json file for version detection
316
- */
317
- export function initTelemetry(
318
- logPackage: string,
319
- denoJsonPath: string = "./deno.json",
320
- ): void {
321
- // Dynamic import to support both @effectstream and @paimaexample packages
322
- // Execute asynchronously - errors won't break Hardhat initialization
323
- (async () => {
324
- try {
325
- const fs = await import("node:fs");
326
- const { parse } = await import("jsonc-parser");
327
- const { NodeSDK } = await import("@opentelemetry/sdk-node");
328
- const { defaultOtelSetup } = await import(logPackage);
329
-
330
- const DenoConfig = parse(fs.readFileSync(denoJsonPath, "utf8"));
331
- const sdk = new NodeSDK({
332
- ...defaultOtelSetup("hardhat", DenoConfig.version),
333
- });
334
- sdk.start();
335
- } catch (error) {
336
- console.warn("Failed to initialize telemetry:", error);
337
- }
338
- })();
339
- }
340
-
341
- /**
342
- * Creates a unified Hardhat configuration that can be used across e2e tests and templates.
343
- *
344
- * This function consolidates the common Hardhat setup including:
345
- * - Network configuration
346
- * - Path configuration
347
- * - Plugin setup
348
- * - Solidity compiler configuration
349
- *
350
- * For node tasks, use createNodeTasks() separately and pass the result in the tasks option.
351
- *
352
- * @param options Configuration options
353
- * @returns HardhatUserConfig object
354
- */
355
- export function createHardhatConfig(
356
- options: HardhatConfigOptions,
357
- ): HardhatUserConfig {
358
- const {
359
- sourcesDir,
360
- artifactsDir,
361
- cacheDir,
362
- networks,
363
- useDefaultNetworks = networks === undefined,
364
- defaultNetworkOptions,
365
- tasks,
366
- solidityVersion = "0.8.30",
367
- } = options;
368
-
369
- // Use default networks if none provided and useDefaultNetworks is true
370
- const finalNetworks = networks ||
371
- (useDefaultNetworks
372
- ? createDefaultNetworks(defaultNetworkOptions)
373
- : {});
374
-
375
- const config: HardhatUserConfig = {
376
- networks: finalNetworks,
377
- paths: {
378
- sources: [sourcesDir],
379
- artifacts: artifactsDir,
380
- cache: cacheDir,
381
- },
382
- tasks,
383
- plugins: [
384
- HardhatViem,
385
- HardhatIgnitionViem,
386
- ],
387
- solidity: {
388
- profiles: {
389
- default: {
390
- version: solidityVersion,
391
- },
392
- },
393
- },
394
- };
395
-
396
- return config;
397
- }
398
-