hardhat 3.16.0 → 3.17.0

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.
Files changed (80) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/dist/src/internal/builtin-plugins/network-manager/accounts/derive-private-keys.d.ts.map +1 -1
  3. package/dist/src/internal/builtin-plugins/network-manager/accounts/derive-private-keys.js +0 -1
  4. package/dist/src/internal/builtin-plugins/network-manager/accounts/derive-private-keys.js.map +1 -1
  5. package/dist/src/internal/builtin-plugins/network-manager/config-resolution.d.ts.map +1 -1
  6. package/dist/src/internal/builtin-plugins/network-manager/config-resolution.js +1 -0
  7. package/dist/src/internal/builtin-plugins/network-manager/config-resolution.js.map +1 -1
  8. package/dist/src/internal/builtin-plugins/network-manager/edr/edr-constants.d.ts +1 -0
  9. package/dist/src/internal/builtin-plugins/network-manager/edr/edr-constants.d.ts.map +1 -1
  10. package/dist/src/internal/builtin-plugins/network-manager/edr/edr-constants.js +2 -0
  11. package/dist/src/internal/builtin-plugins/network-manager/edr/edr-constants.js.map +1 -1
  12. package/dist/src/internal/builtin-plugins/network-manager/edr/edr-provider.d.ts +15 -0
  13. package/dist/src/internal/builtin-plugins/network-manager/edr/edr-provider.d.ts.map +1 -1
  14. package/dist/src/internal/builtin-plugins/network-manager/edr/edr-provider.js +43 -5
  15. package/dist/src/internal/builtin-plugins/network-manager/edr/edr-provider.js.map +1 -1
  16. package/dist/src/internal/builtin-plugins/network-manager/edr/genesis-state.js +4 -4
  17. package/dist/src/internal/builtin-plugins/network-manager/edr/genesis-state.js.map +1 -1
  18. package/dist/src/internal/builtin-plugins/network-manager/edr/utils/convert-to-edr.d.ts +3 -2
  19. package/dist/src/internal/builtin-plugins/network-manager/edr/utils/convert-to-edr.d.ts.map +1 -1
  20. package/dist/src/internal/builtin-plugins/network-manager/edr/utils/convert-to-edr.js +13 -5
  21. package/dist/src/internal/builtin-plugins/network-manager/edr/utils/convert-to-edr.js.map +1 -1
  22. package/dist/src/internal/builtin-plugins/network-manager/http-provider.js +1 -1
  23. package/dist/src/internal/builtin-plugins/network-manager/http-provider.js.map +1 -1
  24. package/dist/src/internal/builtin-plugins/network-manager/provider-errors.d.ts +20 -0
  25. package/dist/src/internal/builtin-plugins/network-manager/provider-errors.d.ts.map +1 -1
  26. package/dist/src/internal/builtin-plugins/network-manager/provider-errors.js +24 -0
  27. package/dist/src/internal/builtin-plugins/network-manager/provider-errors.js.map +1 -1
  28. package/dist/src/internal/builtin-plugins/network-manager/request-handlers/handlers/accounts/local-accounts.d.ts.map +1 -1
  29. package/dist/src/internal/builtin-plugins/network-manager/request-handlers/handlers/accounts/local-accounts.js +10 -13
  30. package/dist/src/internal/builtin-plugins/network-manager/request-handlers/handlers/accounts/local-accounts.js.map +1 -1
  31. package/dist/src/internal/builtin-plugins/network-manager/request-handlers/handlers/gas/automatic-gas-handler.d.ts +1 -1
  32. package/dist/src/internal/builtin-plugins/network-manager/request-handlers/handlers/gas/automatic-gas-handler.d.ts.map +1 -1
  33. package/dist/src/internal/builtin-plugins/network-manager/request-handlers/handlers/gas/automatic-gas-handler.js +2 -2
  34. package/dist/src/internal/builtin-plugins/network-manager/request-handlers/handlers/gas/automatic-gas-handler.js.map +1 -1
  35. package/dist/src/internal/builtin-plugins/network-manager/request-handlers/handlers/gas/multiplied-gas-estimation.d.ts +11 -3
  36. package/dist/src/internal/builtin-plugins/network-manager/request-handlers/handlers/gas/multiplied-gas-estimation.d.ts.map +1 -1
  37. package/dist/src/internal/builtin-plugins/network-manager/request-handlers/handlers/gas/multiplied-gas-estimation.js +53 -13
  38. package/dist/src/internal/builtin-plugins/network-manager/request-handlers/handlers/gas/multiplied-gas-estimation.js.map +1 -1
  39. package/dist/src/internal/builtin-plugins/network-manager/request-handlers/handlers-array.d.ts.map +1 -1
  40. package/dist/src/internal/builtin-plugins/network-manager/request-handlers/handlers-array.js +19 -1
  41. package/dist/src/internal/builtin-plugins/network-manager/request-handlers/handlers-array.js.map +1 -1
  42. package/dist/src/internal/builtin-plugins/network-manager/type-extensions/config.d.ts +2 -0
  43. package/dist/src/internal/builtin-plugins/network-manager/type-extensions/config.d.ts.map +1 -1
  44. package/dist/src/internal/builtin-plugins/network-manager/type-validation.d.ts.map +1 -1
  45. package/dist/src/internal/builtin-plugins/network-manager/type-validation.js +1 -0
  46. package/dist/src/internal/builtin-plugins/network-manager/type-validation.js.map +1 -1
  47. package/dist/src/internal/builtin-plugins/node/json-rpc/handler.js +12 -1
  48. package/dist/src/internal/builtin-plugins/node/json-rpc/handler.js.map +1 -1
  49. package/dist/src/internal/builtin-plugins/solidity-test/formatters.js +10 -2
  50. package/dist/src/internal/builtin-plugins/solidity-test/formatters.js.map +1 -1
  51. package/dist/src/internal/core/configuration-variables.d.ts +8 -0
  52. package/dist/src/internal/core/configuration-variables.d.ts.map +1 -1
  53. package/dist/src/internal/core/configuration-variables.js +9 -9
  54. package/dist/src/internal/core/configuration-variables.js.map +1 -1
  55. package/dist/src/internal/edr/exports.d.ts +2 -0
  56. package/dist/src/internal/edr/exports.d.ts.map +1 -0
  57. package/dist/src/internal/edr/exports.js +2 -0
  58. package/dist/src/internal/edr/exports.js.map +1 -0
  59. package/package.json +6 -5
  60. package/src/internal/builtin-plugins/network-manager/accounts/derive-private-keys.ts +0 -1
  61. package/src/internal/builtin-plugins/network-manager/config-resolution.ts +1 -0
  62. package/src/internal/builtin-plugins/network-manager/edr/edr-constants.ts +3 -0
  63. package/src/internal/builtin-plugins/network-manager/edr/edr-provider.ts +52 -1
  64. package/src/internal/builtin-plugins/network-manager/edr/genesis-state.ts +5 -5
  65. package/src/internal/builtin-plugins/network-manager/edr/utils/convert-to-edr.ts +17 -3
  66. package/src/internal/builtin-plugins/network-manager/http-provider.ts +1 -1
  67. package/src/internal/builtin-plugins/network-manager/provider-errors.ts +30 -0
  68. package/src/internal/builtin-plugins/network-manager/request-handlers/handlers/accounts/local-accounts.ts +10 -26
  69. package/src/internal/builtin-plugins/network-manager/request-handlers/handlers/gas/automatic-gas-handler.ts +3 -1
  70. package/src/internal/builtin-plugins/network-manager/request-handlers/handlers/gas/multiplied-gas-estimation.ts +73 -18
  71. package/src/internal/builtin-plugins/network-manager/request-handlers/handlers-array.ts +24 -0
  72. package/src/internal/builtin-plugins/network-manager/type-extensions/config.ts +2 -0
  73. package/src/internal/builtin-plugins/network-manager/type-validation.ts +6 -0
  74. package/src/internal/builtin-plugins/node/json-rpc/handler.ts +15 -1
  75. package/src/internal/builtin-plugins/solidity-test/formatters.ts +14 -2
  76. package/src/internal/core/configuration-variables.ts +25 -10
  77. package/src/internal/edr/exports.ts +1 -0
  78. package/templates/01-node-test-runner-viem/package.json +1 -1
  79. package/templates/02-mocha-ethers/package.json +2 -2
  80. package/templates/03-minimal/package.json +1 -1
@@ -1,27 +1,48 @@
1
1
  import type { EthereumProvider } from "../../../../../../types/providers.js";
2
2
 
3
3
  import { assertHardhatInvariant } from "@nomicfoundation/hardhat-errors";
4
+ import { min } from "@nomicfoundation/hardhat-utils/bigint";
4
5
  import { ensureError } from "@nomicfoundation/hardhat-utils/error";
5
6
  import {
6
7
  hexStringToNumber,
7
8
  numberToHexString,
8
9
  } from "@nomicfoundation/hardhat-utils/hex";
9
10
 
11
+ import { InternalCallOutOfGasError } from "../../../provider-errors.js";
12
+
13
+ /**
14
+ * The fraction of the observed block gas limit that gets cached and used as the
15
+ * gas limit ceiling. The cached value is deliberately lower than what the
16
+ * latest block reported, to leave room for the block gas limit varying
17
+ * slightly between blocks after we cached it.
18
+ */
19
+ export const BLOCK_GAS_LIMIT_SAFETY_FACTOR = 0.95;
20
+
10
21
  /**
11
22
  * This class handles gas estimation for transactions by applying a multiplier to the estimated gas value.
12
23
  * It requests a gas estimation from the provider and multiplies it by a predefined gas multiplier, ensuring the gas does not exceed the block's gas limit.
13
- * If an execution error occurs, the method returns the block's gas limit instead.
14
- * The block gas limit is cached after the first retrieval to optimize performance.
24
+ * If the estimation fails because an internal call runs out of gas regardless of the gas limit, the method returns the fallback gas limit, capped to the current block gas limit on networks that enforce one, or rethrows when no fallback gas limit is known.
25
+ * If any other error whose message contains "execution error" occurs, the method returns the capped block gas limit instead. Every other error is rethrown.
26
+ * The capped block gas limit is the latest block's gas limit scaled by `BLOCK_GAS_LIMIT_SAFETY_FACTOR`, cached after the first retrieval to optimize performance, except when capping the fallback gas limit, which reads the pending block's unscaled one.
15
27
  */
16
28
  export abstract class MultipliedGasEstimation {
17
29
  readonly #provider: EthereumProvider;
18
30
  readonly #gasMultiplier: number;
31
+ readonly #fallbackGas: bigint | undefined;
32
+ readonly #isBlockGasLimitEnforced: () => boolean;
19
33
 
20
34
  #blockGasLimit: number | undefined;
21
35
 
22
- constructor(provider: EthereumProvider, gasMultiplier: number) {
36
+ constructor(
37
+ provider: EthereumProvider,
38
+ gasMultiplier: number,
39
+ fallbackGas?: bigint,
40
+ isBlockGasLimitEnforced: () => boolean = () => true,
41
+ ) {
23
42
  this.#provider = provider;
24
43
  this.#gasMultiplier = gasMultiplier;
44
+ this.#fallbackGas = fallbackGas;
45
+ this.#isBlockGasLimitEnforced = isBlockGasLimitEnforced;
25
46
  }
26
47
 
27
48
  protected async getMultipliedGasEstimation(params: any[]): Promise<string> {
@@ -52,6 +73,34 @@ export abstract class MultipliedGasEstimation {
52
73
  } catch (error) {
53
74
  ensureError(error);
54
75
 
76
+ // We fall back instead of failing the transaction, because the user
77
+ // never asked for this estimation. The fallback is the gas limit the
78
+ // network itself uses for requests with no gas field. Connections that
79
+ // don't expose it (e.g. an http connection to a `hardhat node` server)
80
+ // get no fallback, and the estimation error reaches the user instead of
81
+ // a guessed limit that may not suit the remote network: the error names
82
+ // both remedies, an explicit gas limit or the topLevelSuccess mode.
83
+ //
84
+ // The cap reads the pending block's limit fresh rather than the cache:
85
+ // evm_setBlockGasLimit may have lowered it, and only the pending block
86
+ // reflects that before the next block is mined.
87
+ //
88
+ // Networks that don't enforce a block gas limit are exempt: their
89
+ // headers still report one, so capping would shrink the fallback to a
90
+ // limit nothing rejects it for.
91
+ if (
92
+ error instanceof InternalCallOutOfGasError &&
93
+ this.#fallbackGas !== undefined
94
+ ) {
95
+ if (!this.#isBlockGasLimitEnforced()) {
96
+ return numberToHexString(this.#fallbackGas);
97
+ }
98
+
99
+ const blockGasLimit = BigInt(await this.#fetchBlockGasLimit("pending"));
100
+
101
+ return numberToHexString(min(this.#fallbackGas, blockGasLimit));
102
+ }
103
+
55
104
  if (error.message.toLowerCase().includes("execution error")) {
56
105
  const blockGasLimitTmp = await this.#getBlockGasLimit();
57
106
  return numberToHexString(blockGasLimitTmp);
@@ -63,25 +112,31 @@ export abstract class MultipliedGasEstimation {
63
112
 
64
113
  async #getBlockGasLimit(): Promise<number> {
65
114
  if (this.#blockGasLimit === undefined) {
66
- const latestBlock = await this.#provider.request({
67
- method: "eth_getBlockByNumber",
68
- params: ["latest", false],
69
- });
70
-
71
- assertHardhatInvariant(
72
- typeof latestBlock === "object" &&
73
- latestBlock !== null &&
74
- "gasLimit" in latestBlock &&
75
- typeof latestBlock.gasLimit === "string",
76
- "latestBlock should have a gasLimit",
77
- );
78
-
79
- const fetchedGasLimit = hexStringToNumber(latestBlock.gasLimit);
115
+ const fetchedGasLimit = await this.#fetchBlockGasLimit("latest");
80
116
 
81
117
  // We store a lower value in case the gas limit varies slightly
82
- this.#blockGasLimit = Math.floor(fetchedGasLimit * 0.95);
118
+ this.#blockGasLimit = Math.floor(
119
+ fetchedGasLimit * BLOCK_GAS_LIMIT_SAFETY_FACTOR,
120
+ );
83
121
  }
84
122
 
85
123
  return this.#blockGasLimit;
86
124
  }
125
+
126
+ async #fetchBlockGasLimit(blockTag: "latest" | "pending"): Promise<number> {
127
+ const block = await this.#provider.request({
128
+ method: "eth_getBlockByNumber",
129
+ params: [blockTag, false],
130
+ });
131
+
132
+ assertHardhatInvariant(
133
+ typeof block === "object" &&
134
+ block !== null &&
135
+ "gasLimit" in block &&
136
+ typeof block.gasLimit === "string",
137
+ `the ${blockTag} block should have a gasLimit`,
138
+ );
139
+
140
+ return hexStringToNumber(block.gasLimit);
141
+ }
87
142
  }
@@ -63,10 +63,34 @@ export async function createHandlersArray<
63
63
  }
64
64
 
65
65
  if (networkConfig.gas === undefined || networkConfig.gas === "auto") {
66
+ // On EDR networks, if the gas estimation fails because an internal call
67
+ // runs out of gas regardless of the gas limit, we fall back to the same
68
+ // default transaction gas limit that the network uses for requests
69
+ // without a gas field. The EdrProvider exposes the exact value it was
70
+ // configured with, so the fallback always matches the provider's actual
71
+ // default. Providers that don't expose it (e.g. HTTP connections) get no
72
+ // fallback, and the handler surfaces the estimation error instead of
73
+ // guessing a limit that may not suit the remote network.
74
+ const provider = networkConnection.provider;
75
+ const fallbackGas =
76
+ "defaultTransactionGasLimit" in provider &&
77
+ typeof provider.defaultTransactionGasLimit === "bigint"
78
+ ? provider.defaultTransactionGasLimit
79
+ : undefined;
80
+
81
+ // The fallback only gets capped on networks that enforce a block gas
82
+ // limit. Read lazily, as enforcement can turn on at runtime; providers
83
+ // that don't report it are conservatively assumed to enforce one.
84
+ const isBlockGasLimitEnforced = () =>
85
+ !("isBlockGasLimitEnforced" in provider) ||
86
+ provider.isBlockGasLimitEnforced !== false;
87
+
66
88
  requestHandlers.push(
67
89
  new AutomaticGasHandler(
68
90
  networkConnection.provider,
69
91
  networkConfig.gasMultiplier,
92
+ fallbackGas,
93
+ isBlockGasLimitEnforced,
70
94
  ),
71
95
  );
72
96
  } else {
@@ -110,6 +110,7 @@ declare module "../../../../types/config.js" {
110
110
  blockGasLimit?: number | bigint | false;
111
111
  coinbase?: string;
112
112
  forking?: EdrNetworkForkingUserConfig;
113
+ gasEstimationMode?: "topLevelSuccess" | "noInternalOutOfGas";
113
114
  hardfork?: string;
114
115
  initialBaseFeePerGas?: number | bigint;
115
116
  initialDate?: string | Date;
@@ -253,6 +254,7 @@ declare module "../../../../types/config.js" {
253
254
  blockGasLimit?: bigint | false;
254
255
  coinbase: Uint8Array;
255
256
  forking?: EdrNetworkForkingConfig;
257
+ gasEstimationMode: "topLevelSuccess" | "noInternalOutOfGas";
256
258
  hardfork: string;
257
259
  initialBaseFeePerGas?: bigint;
258
260
  initialDate: string | Date;
@@ -319,6 +319,12 @@ const edrNetworkUserConfigSchema = z.object({
319
319
  blockGasLimit: z.optional(gasLimitWithDisableUserConfigSchema),
320
320
  coinbase: z.optional(z.string()),
321
321
  forking: z.optional(edrNetworkForkingUserConfigSchema),
322
+ gasEstimationMode: z.optional(
323
+ unionType(
324
+ [z.literal("topLevelSuccess"), z.literal("noInternalOutOfGas")],
325
+ "Expected 'topLevelSuccess' or 'noInternalOutOfGas'",
326
+ ),
327
+ ),
322
328
  hardfork: z.optional(z.string()),
323
329
  initialBaseFeePerGas: z.optional(gasUnitUserConfigSchema),
324
330
  initialDate: z.optional(
@@ -256,6 +256,7 @@ const _handleError = (error: Error): JsonRpcResponse => {
256
256
  // that would be lost when wrapped in InternalError below.
257
257
  const txHash = extractTxHash(error);
258
258
  const returnData = extractReturnData(error);
259
+ const reason = extractErrorReason(error);
259
260
 
260
261
  // Check if this is a revert error (code 3) matching the geth/anvil convention.
261
262
  const isRevertError =
@@ -271,9 +272,12 @@ const _handleError = (error: Error): JsonRpcResponse => {
271
272
 
272
273
  // Revert errors (code 3): return raw hex to match the geth/anvil convention
273
274
  // that viem/ethers/web3.js rely on. Other errors keep the wrapper for diagnostics.
275
+ // `reason` is the discriminator clients use to recognize specific failures
276
+ // (e.g. "InternalCallOutOfGas") once the error class itself is lost to
277
+ // serialization, so it must survive it.
274
278
  const data: unknown = isRevertError
275
279
  ? returnData
276
- : { message: error.message, txHash, data: returnData };
280
+ : { message: error.message, txHash, data: returnData, reason };
277
281
 
278
282
  const response: FailedJsonRpcResponse = {
279
283
  jsonrpc: "2.0",
@@ -318,3 +322,13 @@ function extractReturnData(error: Error): string | undefined {
318
322
  return error.data.data;
319
323
  }
320
324
  }
325
+
326
+ function extractErrorReason(error: Error): string | undefined {
327
+ if (
328
+ "data" in error &&
329
+ isObject(error.data) &&
330
+ typeof error.data.reason === "string"
331
+ ) {
332
+ return error.data.reason;
333
+ }
334
+ }
@@ -32,11 +32,23 @@ export function formatInlineConfigErrors(
32
32
  return `- ${sourceName}: ${formatInlineConfigSourceProblem(error.problem)}`;
33
33
  }
34
34
 
35
- return `- ${sourceName}:${error.line}: ${error.contract}.${error.function}: ${formatInlineConfigDirectiveProblem(error.problem)}`;
35
+ return `- ${sourceName}:${error.line}: ${formatDirectiveOrigin(error.contract, error.function)}: ${formatInlineConfigDirectiveProblem(error.problem)}`;
36
36
  })
37
37
  .join("\n");
38
38
  }
39
39
 
40
+ /**
41
+ * Names where a directive was found: `Contract.testFn` for a function-level
42
+ * directive, and just `Contract` for a contract-level one, which EDR reports
43
+ * without a function.
44
+ */
45
+ function formatDirectiveOrigin(
46
+ contract: string,
47
+ functionName: string | undefined,
48
+ ): string {
49
+ return functionName === undefined ? contract : `${contract}.${functionName}`;
50
+ }
51
+
40
52
  function formatInlineConfigDirectiveProblem(
41
53
  problem: InlineConfigDirectiveProblem,
42
54
  ): string {
@@ -65,6 +77,6 @@ function formatInlineConfigSourceProblem(
65
77
  case "InlineConfigSourceFileNotFound":
66
78
  return `the source file could not be read at "${problem.path}": ${problem.reason}`;
67
79
  case "InlineConfigDirectiveLocation":
68
- return `a directive of ${problem.contract}.${problem.function} could not be located: ${problem.reason}`;
80
+ return `a directive of ${formatDirectiveOrigin(problem.contract, problem.function)} could not be located: ${problem.reason}`;
69
81
  }
70
82
  }
@@ -32,6 +32,13 @@ abstract class BaseResolvedConfigurationVariable implements ResolvedConfiguratio
32
32
 
33
33
  protected abstract _getRawValue(): Promise<string>;
34
34
 
35
+ /**
36
+ * A description of this variable, used to identify it in error messages.
37
+ *
38
+ * Resolved values may be secrets, so they must never be included in errors.
39
+ */
40
+ protected abstract _getDescription(): string;
41
+
35
42
  constructor(public readonly format: string) {
36
43
  assertHardhatInvariant(
37
44
  this.format.includes(CONFIGURATION_VARIABLE_MARKER),
@@ -57,9 +64,10 @@ abstract class BaseResolvedConfigurationVariable implements ResolvedConfiguratio
57
64
  new URL(value);
58
65
  return value;
59
66
  } catch (_error) {
60
- throw new HardhatError(HardhatError.ERRORS.CORE.GENERAL.INVALID_URL, {
61
- url: value,
62
- });
67
+ throw new HardhatError(
68
+ HardhatError.ERRORS.CORE.GENERAL.INVALID_CONFIG_VARIABLE_URL,
69
+ { configVariable: this._getDescription() },
70
+ );
63
71
  }
64
72
  }
65
73
 
@@ -69,9 +77,10 @@ abstract class BaseResolvedConfigurationVariable implements ResolvedConfiguratio
69
77
  try {
70
78
  return BigInt(value);
71
79
  } catch (_error) {
72
- throw new HardhatError(HardhatError.ERRORS.CORE.GENERAL.INVALID_BIGINT, {
73
- value,
74
- });
80
+ throw new HardhatError(
81
+ HardhatError.ERRORS.CORE.GENERAL.INVALID_CONFIG_VARIABLE_BIGINT,
82
+ { configVariable: this._getDescription() },
83
+ );
75
84
  }
76
85
  }
77
86
 
@@ -81,10 +90,8 @@ abstract class BaseResolvedConfigurationVariable implements ResolvedConfiguratio
81
90
  return normalizeHexString(value);
82
91
  } catch {
83
92
  throw new HardhatError(
84
- HardhatError.ERRORS.CORE.GENERAL.INVALID_HEX_STRING,
85
- {
86
- value,
87
- },
93
+ HardhatError.ERRORS.CORE.GENERAL.INVALID_CONFIG_VARIABLE_HEX_STRING,
94
+ { configVariable: this._getDescription() },
88
95
  );
89
96
  }
90
97
  }
@@ -112,6 +119,10 @@ export class LazyResolvedConfigurationVariable extends BaseResolvedConfiguration
112
119
  }
113
120
  }
114
121
 
122
+ protected _getDescription(): string {
123
+ return `the configuration variable "${this.name}"`;
124
+ }
125
+
115
126
  protected async _getRawValue(): Promise<string> {
116
127
  // Env vars take precedence over every configurationVariables plugin hook
117
128
  // (e.g. keystore). Skip the hook chain entirely when the env var is set so
@@ -157,6 +168,10 @@ export class FixedValueConfigurationVariable extends BaseResolvedConfigurationVa
157
168
  this.#value = value;
158
169
  }
159
170
 
171
+ protected _getDescription(): string {
172
+ return "an inline configuration value";
173
+ }
174
+
160
175
  protected async _getRawValue(): Promise<string> {
161
176
  return this.#value;
162
177
  }
@@ -0,0 +1 @@
1
+ export { keccak256 } from "@nomicfoundation/edr";
@@ -5,7 +5,7 @@
5
5
  "description": "A TypeScript Hardhat project using Node Test Runner and Viem",
6
6
  "type": "module",
7
7
  "devDependencies": {
8
- "hardhat": "workspace:^3.16.0",
8
+ "hardhat": "workspace:^3.17.0",
9
9
  "@nomicfoundation/hardhat-toolbox-viem": "workspace:^5.0.7",
10
10
  "@nomicfoundation/hardhat-ignition": "workspace:^3.1.8",
11
11
  "@types/node": "^22.8.5",
@@ -5,9 +5,9 @@
5
5
  "description": "A TypeScript Hardhat project using Mocha and Ethers.js",
6
6
  "type": "module",
7
7
  "devDependencies": {
8
- "hardhat": "workspace:^3.16.0",
8
+ "hardhat": "workspace:^3.17.0",
9
9
  "@nomicfoundation/hardhat-toolbox-mocha-ethers": "workspace:^3.0.7",
10
- "@nomicfoundation/hardhat-ethers": "workspace:^4.0.15",
10
+ "@nomicfoundation/hardhat-ethers": "workspace:^4.1.0",
11
11
  "@nomicfoundation/hardhat-ignition": "workspace:^3.1.8",
12
12
  "@types/chai": "^5.2.3",
13
13
  "@types/chai-as-promised": "^8.0.1",
@@ -5,7 +5,7 @@
5
5
  "description": "A minimal Hardhat project",
6
6
  "type": "module",
7
7
  "devDependencies": {
8
- "hardhat": "workspace:^3.16.0",
8
+ "hardhat": "workspace:^3.17.0",
9
9
  "@types/node": "^22.8.5",
10
10
  "typescript": "~6.0.3"
11
11
  }