hardhat 3.8.0 → 3.9.1

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 (215) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/dist/src/config.d.ts.map +1 -1
  3. package/dist/src/config.js +6 -5
  4. package/dist/src/config.js.map +1 -1
  5. package/dist/src/hhu.d.ts +3 -0
  6. package/dist/src/hhu.d.ts.map +1 -0
  7. package/dist/src/hhu.js +14 -0
  8. package/dist/src/hhu.js.map +1 -0
  9. package/dist/src/internal/builtin-plugins/artifacts/hook-handlers/hre.d.ts.map +1 -1
  10. package/dist/src/internal/builtin-plugins/artifacts/hook-handlers/hre.js +4 -1
  11. package/dist/src/internal/builtin-plugins/artifacts/hook-handlers/hre.js.map +1 -1
  12. package/dist/src/internal/builtin-plugins/coverage/config.d.ts +6 -0
  13. package/dist/src/internal/builtin-plugins/coverage/config.d.ts.map +1 -0
  14. package/dist/src/internal/builtin-plugins/coverage/config.js +18 -0
  15. package/dist/src/internal/builtin-plugins/coverage/config.js.map +1 -0
  16. package/dist/src/internal/builtin-plugins/coverage/hook-handlers/config.d.ts +4 -0
  17. package/dist/src/internal/builtin-plugins/coverage/hook-handlers/config.d.ts.map +1 -0
  18. package/dist/src/internal/builtin-plugins/coverage/hook-handlers/config.js +15 -0
  19. package/dist/src/internal/builtin-plugins/coverage/hook-handlers/config.js.map +1 -0
  20. package/dist/src/internal/builtin-plugins/coverage/hook-handlers/solidity.d.ts.map +1 -1
  21. package/dist/src/internal/builtin-plugins/coverage/hook-handlers/solidity.js +10 -1
  22. package/dist/src/internal/builtin-plugins/coverage/hook-handlers/solidity.js.map +1 -1
  23. package/dist/src/internal/builtin-plugins/coverage/index.d.ts.map +1 -1
  24. package/dist/src/internal/builtin-plugins/coverage/index.js +1 -0
  25. package/dist/src/internal/builtin-plugins/coverage/index.js.map +1 -1
  26. package/dist/src/internal/builtin-plugins/coverage/type-extensions.d.ts +20 -0
  27. package/dist/src/internal/builtin-plugins/coverage/type-extensions.d.ts.map +1 -1
  28. package/dist/src/internal/builtin-plugins/gas-analytics/function-gas-snapshots.d.ts +2 -2
  29. package/dist/src/internal/builtin-plugins/gas-analytics/function-gas-snapshots.d.ts.map +1 -1
  30. package/dist/src/internal/builtin-plugins/gas-analytics/function-gas-snapshots.js +21 -23
  31. package/dist/src/internal/builtin-plugins/gas-analytics/function-gas-snapshots.js.map +1 -1
  32. package/dist/src/internal/builtin-plugins/gas-analytics/snapshot-cheatcodes.d.ts +2 -2
  33. package/dist/src/internal/builtin-plugins/gas-analytics/snapshot-cheatcodes.d.ts.map +1 -1
  34. package/dist/src/internal/builtin-plugins/gas-analytics/snapshot-cheatcodes.js +21 -27
  35. package/dist/src/internal/builtin-plugins/gas-analytics/snapshot-cheatcodes.js.map +1 -1
  36. package/dist/src/internal/builtin-plugins/gas-analytics/tasks/solidity-test/task-action.d.ts +3 -1
  37. package/dist/src/internal/builtin-plugins/gas-analytics/tasks/solidity-test/task-action.d.ts.map +1 -1
  38. package/dist/src/internal/builtin-plugins/gas-analytics/tasks/solidity-test/task-action.js +18 -10
  39. package/dist/src/internal/builtin-plugins/gas-analytics/tasks/solidity-test/task-action.js.map +1 -1
  40. package/dist/src/internal/builtin-plugins/hhu/index.d.ts +4 -0
  41. package/dist/src/internal/builtin-plugins/hhu/index.d.ts.map +1 -0
  42. package/dist/src/internal/builtin-plugins/hhu/index.js +9 -0
  43. package/dist/src/internal/builtin-plugins/hhu/index.js.map +1 -0
  44. package/dist/src/internal/builtin-plugins/hhu/tasks/constants/index.d.ts +3 -0
  45. package/dist/src/internal/builtin-plugins/hhu/tasks/constants/index.d.ts.map +1 -0
  46. package/dist/src/internal/builtin-plugins/hhu/tasks/constants/index.js +8 -0
  47. package/dist/src/internal/builtin-plugins/hhu/tasks/constants/index.js.map +1 -0
  48. package/dist/src/internal/builtin-plugins/hhu/tasks/constants/zero-address.d.ts +4 -0
  49. package/dist/src/internal/builtin-plugins/hhu/tasks/constants/zero-address.d.ts.map +1 -0
  50. package/dist/src/internal/builtin-plugins/hhu/tasks/constants/zero-address.js +6 -0
  51. package/dist/src/internal/builtin-plugins/hhu/tasks/constants/zero-address.js.map +1 -0
  52. package/dist/src/internal/builtin-plugins/hhu/tasks/convert/index.d.ts +3 -0
  53. package/dist/src/internal/builtin-plugins/hhu/tasks/convert/index.d.ts.map +1 -0
  54. package/dist/src/internal/builtin-plugins/hhu/tasks/convert/index.js +27 -0
  55. package/dist/src/internal/builtin-plugins/hhu/tasks/convert/index.js.map +1 -0
  56. package/dist/src/internal/builtin-plugins/hhu/tasks/convert/pad.d.ts +10 -0
  57. package/dist/src/internal/builtin-plugins/hhu/tasks/convert/pad.d.ts.map +1 -0
  58. package/dist/src/internal/builtin-plugins/hhu/tasks/convert/pad.js +31 -0
  59. package/dist/src/internal/builtin-plugins/hhu/tasks/convert/pad.js.map +1 -0
  60. package/dist/src/internal/builtin-plugins/hhu/tasks/fetch/block-number.d.ts +4 -0
  61. package/dist/src/internal/builtin-plugins/hhu/tasks/fetch/block-number.d.ts.map +1 -0
  62. package/dist/src/internal/builtin-plugins/hhu/tasks/fetch/block-number.js +17 -0
  63. package/dist/src/internal/builtin-plugins/hhu/tasks/fetch/block-number.js.map +1 -0
  64. package/dist/src/internal/builtin-plugins/hhu/tasks/fetch/index.d.ts +3 -0
  65. package/dist/src/internal/builtin-plugins/hhu/tasks/fetch/index.d.ts.map +1 -0
  66. package/dist/src/internal/builtin-plugins/hhu/tasks/fetch/index.js +8 -0
  67. package/dist/src/internal/builtin-plugins/hhu/tasks/fetch/index.js.map +1 -0
  68. package/dist/src/internal/builtin-plugins/hhu/tasks/index.d.ts +11 -0
  69. package/dist/src/internal/builtin-plugins/hhu/tasks/index.d.ts.map +1 -0
  70. package/dist/src/internal/builtin-plugins/hhu/tasks/index.js +20 -0
  71. package/dist/src/internal/builtin-plugins/hhu/tasks/index.js.map +1 -0
  72. package/dist/src/internal/builtin-plugins/hhu/tasks/utils-task.d.ts +13 -0
  73. package/dist/src/internal/builtin-plugins/hhu/tasks/utils-task.d.ts.map +1 -0
  74. package/dist/src/internal/builtin-plugins/hhu/tasks/utils-task.js +17 -0
  75. package/dist/src/internal/builtin-plugins/hhu/tasks/utils-task.js.map +1 -0
  76. package/dist/src/internal/builtin-plugins/hhu/types.d.ts +45 -0
  77. package/dist/src/internal/builtin-plugins/hhu/types.d.ts.map +1 -0
  78. package/dist/src/internal/builtin-plugins/hhu/types.js +2 -0
  79. package/dist/src/internal/builtin-plugins/hhu/types.js.map +1 -0
  80. package/dist/src/internal/builtin-plugins/index.d.ts.map +1 -1
  81. package/dist/src/internal/builtin-plugins/index.js +5 -0
  82. package/dist/src/internal/builtin-plugins/index.js.map +1 -1
  83. package/dist/src/internal/builtin-plugins/network-manager/edr/genesis-state.d.ts +2 -1
  84. package/dist/src/internal/builtin-plugins/network-manager/edr/genesis-state.d.ts.map +1 -1
  85. package/dist/src/internal/builtin-plugins/network-manager/edr/genesis-state.js +13 -10
  86. package/dist/src/internal/builtin-plugins/network-manager/edr/genesis-state.js.map +1 -1
  87. package/dist/src/internal/builtin-plugins/network-manager/edr/stack-traces/stack-trace-solidity-errors.d.ts +1 -0
  88. package/dist/src/internal/builtin-plugins/network-manager/edr/stack-traces/stack-trace-solidity-errors.d.ts.map +1 -1
  89. package/dist/src/internal/builtin-plugins/network-manager/edr/stack-traces/stack-trace-solidity-errors.js +17 -0
  90. package/dist/src/internal/builtin-plugins/network-manager/edr/stack-traces/stack-trace-solidity-errors.js.map +1 -1
  91. package/dist/src/internal/builtin-plugins/network-manager/index.d.ts.map +1 -1
  92. package/dist/src/internal/builtin-plugins/network-manager/index.js +2 -10
  93. package/dist/src/internal/builtin-plugins/network-manager/index.js.map +1 -1
  94. package/dist/src/internal/builtin-plugins/network-manager/network-option.d.ts +9 -0
  95. package/dist/src/internal/builtin-plugins/network-manager/network-option.d.ts.map +1 -0
  96. package/dist/src/internal/builtin-plugins/network-manager/network-option.js +15 -0
  97. package/dist/src/internal/builtin-plugins/network-manager/network-option.js.map +1 -0
  98. package/dist/src/internal/builtin-plugins/network-manager/request-handlers/handlers/accounts/automatic-sender-handler.d.ts +4 -2
  99. package/dist/src/internal/builtin-plugins/network-manager/request-handlers/handlers/accounts/automatic-sender-handler.d.ts.map +1 -1
  100. package/dist/src/internal/builtin-plugins/network-manager/request-handlers/handlers/accounts/automatic-sender-handler.js +28 -6
  101. package/dist/src/internal/builtin-plugins/network-manager/request-handlers/handlers/accounts/automatic-sender-handler.js.map +1 -1
  102. package/dist/src/internal/builtin-plugins/network-manager/type-validation.d.ts.map +1 -1
  103. package/dist/src/internal/builtin-plugins/network-manager/type-validation.js +10 -1
  104. package/dist/src/internal/builtin-plugins/network-manager/type-validation.js.map +1 -1
  105. package/dist/src/internal/builtin-plugins/solidity/build-system/warning-suppression.d.ts.map +1 -1
  106. package/dist/src/internal/builtin-plugins/solidity/build-system/warning-suppression.js +3 -0
  107. package/dist/src/internal/builtin-plugins/solidity/build-system/warning-suppression.js.map +1 -1
  108. package/dist/src/internal/builtin-plugins/solidity/source-names.d.ts +12 -0
  109. package/dist/src/internal/builtin-plugins/solidity/source-names.d.ts.map +1 -0
  110. package/dist/src/internal/builtin-plugins/solidity/source-names.js +18 -0
  111. package/dist/src/internal/builtin-plugins/solidity/source-names.js.map +1 -0
  112. package/dist/src/internal/builtin-plugins/solidity-test/config.d.ts.map +1 -1
  113. package/dist/src/internal/builtin-plugins/solidity-test/config.js +1 -4
  114. package/dist/src/internal/builtin-plugins/solidity-test/config.js.map +1 -1
  115. package/dist/src/internal/builtin-plugins/solidity-test/eip712/index.d.ts.map +1 -1
  116. package/dist/src/internal/builtin-plugins/solidity-test/eip712/index.js +7 -12
  117. package/dist/src/internal/builtin-plugins/solidity-test/eip712/index.js.map +1 -1
  118. package/dist/src/internal/builtin-plugins/solidity-test/stack-trace-solidity-errors.d.ts.map +1 -1
  119. package/dist/src/internal/builtin-plugins/solidity-test/stack-trace-solidity-errors.js +3 -1
  120. package/dist/src/internal/builtin-plugins/solidity-test/stack-trace-solidity-errors.js.map +1 -1
  121. package/dist/src/internal/cli/help/get-global-help-string.d.ts +3 -1
  122. package/dist/src/internal/cli/help/get-global-help-string.d.ts.map +1 -1
  123. package/dist/src/internal/cli/help/get-global-help-string.js +3 -3
  124. package/dist/src/internal/cli/help/get-global-help-string.js.map +1 -1
  125. package/dist/src/internal/cli/help/get-help-string.d.ts +3 -1
  126. package/dist/src/internal/cli/help/get-help-string.d.ts.map +1 -1
  127. package/dist/src/internal/cli/help/get-help-string.js +4 -4
  128. package/dist/src/internal/cli/help/get-help-string.js.map +1 -1
  129. package/dist/src/internal/cli/help/utils.d.ts +3 -1
  130. package/dist/src/internal/cli/help/utils.d.ts.map +1 -1
  131. package/dist/src/internal/cli/help/utils.js +2 -2
  132. package/dist/src/internal/cli/help/utils.js.map +1 -1
  133. package/dist/src/internal/cli/hhu.d.ts +14 -0
  134. package/dist/src/internal/cli/hhu.d.ts.map +1 -0
  135. package/dist/src/internal/cli/hhu.js +184 -0
  136. package/dist/src/internal/cli/hhu.js.map +1 -0
  137. package/dist/src/internal/cli/main.d.ts +0 -25
  138. package/dist/src/internal/cli/main.d.ts.map +1 -1
  139. package/dist/src/internal/cli/main.js +23 -303
  140. package/dist/src/internal/cli/main.js.map +1 -1
  141. package/dist/src/internal/cli/parser.d.ts +25 -0
  142. package/dist/src/internal/cli/parser.d.ts.map +1 -0
  143. package/dist/src/internal/cli/parser.js +282 -0
  144. package/dist/src/internal/cli/parser.js.map +1 -0
  145. package/dist/src/internal/cli/telemetry/analytics/analytics.d.ts +1 -1
  146. package/dist/src/internal/cli/telemetry/analytics/analytics.d.ts.map +1 -1
  147. package/dist/src/internal/cli/telemetry/analytics/analytics.js +2 -1
  148. package/dist/src/internal/cli/telemetry/analytics/analytics.js.map +1 -1
  149. package/dist/src/internal/cli/telemetry/analytics/types.d.ts +1 -0
  150. package/dist/src/internal/cli/telemetry/analytics/types.d.ts.map +1 -1
  151. package/dist/src/internal/edr/context.d.ts.map +1 -1
  152. package/dist/src/internal/edr/context.js +25 -7
  153. package/dist/src/internal/edr/context.js.map +1 -1
  154. package/dist/src/internal/using-hardhat2-plugin-errors.d.ts +2 -2
  155. package/dist/src/internal/using-hardhat2-plugin-errors.d.ts.map +1 -1
  156. package/dist/src/internal/using-hardhat2-plugin-errors.js +7 -3
  157. package/dist/src/internal/using-hardhat2-plugin-errors.js.map +1 -1
  158. package/dist/src/internal/{builtin-plugins/solidity-test/eip712 → utils}/glob.d.ts +4 -0
  159. package/dist/src/internal/utils/glob.d.ts.map +1 -0
  160. package/dist/src/internal/{builtin-plugins/solidity-test/eip712 → utils}/glob.js +3 -3
  161. package/dist/src/internal/utils/glob.js.map +1 -0
  162. package/dist/src/plugins.d.ts.map +1 -1
  163. package/dist/src/plugins.js +3 -2
  164. package/dist/src/plugins.js.map +1 -1
  165. package/package.json +4 -4
  166. package/src/config.ts +17 -5
  167. package/src/hhu.ts +18 -0
  168. package/src/internal/builtin-plugins/artifacts/hook-handlers/hre.ts +11 -3
  169. package/src/internal/builtin-plugins/coverage/config.ts +28 -0
  170. package/src/internal/builtin-plugins/coverage/hook-handlers/config.ts +30 -0
  171. package/src/internal/builtin-plugins/coverage/hook-handlers/solidity.ts +15 -2
  172. package/src/internal/builtin-plugins/coverage/index.ts +1 -0
  173. package/src/internal/builtin-plugins/coverage/type-extensions.ts +24 -0
  174. package/src/internal/builtin-plugins/gas-analytics/function-gas-snapshots.ts +32 -32
  175. package/src/internal/builtin-plugins/gas-analytics/snapshot-cheatcodes.ts +32 -36
  176. package/src/internal/builtin-plugins/gas-analytics/tasks/solidity-test/task-action.ts +22 -9
  177. package/src/internal/builtin-plugins/hhu/index.ts +13 -0
  178. package/src/internal/builtin-plugins/hhu/tasks/constants/index.ts +18 -0
  179. package/src/internal/builtin-plugins/hhu/tasks/constants/zero-address.ts +9 -0
  180. package/src/internal/builtin-plugins/hhu/tasks/convert/index.ts +40 -0
  181. package/src/internal/builtin-plugins/hhu/tasks/convert/pad.ts +61 -0
  182. package/src/internal/builtin-plugins/hhu/tasks/fetch/block-number.ts +28 -0
  183. package/src/internal/builtin-plugins/hhu/tasks/fetch/index.ts +18 -0
  184. package/src/internal/builtin-plugins/hhu/tasks/index.ts +36 -0
  185. package/src/internal/builtin-plugins/hhu/tasks/utils-task.ts +29 -0
  186. package/src/internal/builtin-plugins/hhu/types.ts +57 -0
  187. package/src/internal/builtin-plugins/index.ts +6 -0
  188. package/src/internal/builtin-plugins/network-manager/edr/genesis-state.ts +22 -14
  189. package/src/internal/builtin-plugins/network-manager/edr/stack-traces/stack-trace-solidity-errors.ts +33 -0
  190. package/src/internal/builtin-plugins/network-manager/index.ts +3 -10
  191. package/src/internal/builtin-plugins/network-manager/network-option.ts +17 -0
  192. package/src/internal/builtin-plugins/network-manager/request-handlers/handlers/accounts/automatic-sender-handler.ts +39 -9
  193. package/src/internal/builtin-plugins/network-manager/type-validation.ts +14 -1
  194. package/src/internal/builtin-plugins/solidity/build-system/warning-suppression.ts +3 -0
  195. package/src/internal/builtin-plugins/solidity/source-names.ts +19 -0
  196. package/src/internal/builtin-plugins/solidity-test/config.ts +1 -4
  197. package/src/internal/builtin-plugins/solidity-test/eip712/index.ts +8 -16
  198. package/src/internal/builtin-plugins/solidity-test/stack-trace-solidity-errors.ts +6 -1
  199. package/src/internal/cli/help/get-global-help-string.ts +3 -2
  200. package/src/internal/cli/help/get-help-string.ts +4 -3
  201. package/src/internal/cli/help/utils.ts +2 -1
  202. package/src/internal/cli/hhu.ts +298 -0
  203. package/src/internal/cli/main.ts +41 -495
  204. package/src/internal/cli/parser.ts +472 -0
  205. package/src/internal/cli/telemetry/analytics/analytics.ts +5 -1
  206. package/src/internal/cli/telemetry/analytics/types.ts +3 -0
  207. package/src/internal/edr/context.ts +39 -23
  208. package/src/internal/using-hardhat2-plugin-errors.ts +12 -3
  209. package/src/internal/{builtin-plugins/solidity-test/eip712 → utils}/glob.ts +3 -3
  210. package/src/plugins.ts +5 -2
  211. package/templates/hardhat-3/01-node-test-runner-viem/package.json +6 -6
  212. package/templates/hardhat-3/02-mocha-ethers/package.json +9 -9
  213. package/templates/hardhat-3/03-minimal/package.json +1 -1
  214. package/dist/src/internal/builtin-plugins/solidity-test/eip712/glob.d.ts.map +0 -1
  215. package/dist/src/internal/builtin-plugins/solidity-test/eip712/glob.js.map +0 -1
@@ -0,0 +1,61 @@
1
+ import type { NewUtilsTaskActionFunction } from "../../types.js";
2
+
3
+ import { HardhatError } from "@nomicfoundation/hardhat-errors";
4
+ import {
5
+ getUnprefixedHexString,
6
+ isHexString,
7
+ } from "@nomicfoundation/hardhat-utils/hex";
8
+
9
+ interface PadActionArguments {
10
+ value: string;
11
+ length: number;
12
+ left: boolean;
13
+ right: boolean;
14
+ }
15
+
16
+ const padAction: NewUtilsTaskActionFunction<PadActionArguments> = async ({
17
+ value,
18
+ length,
19
+ left,
20
+ right,
21
+ }) => {
22
+ if (left && right) {
23
+ throw new HardhatError(
24
+ HardhatError.ERRORS.CORE.ARGUMENTS.MUTUALLY_EXCLUSIVE_OPTIONS,
25
+ { optionA: "left", optionB: "right" },
26
+ );
27
+ }
28
+
29
+ if (length < 0) {
30
+ throw new HardhatError(HardhatError.ERRORS.CORE.ARGUMENTS.INVALID_VALUE, {
31
+ value: length,
32
+ name: "length",
33
+ reason: "it must be a non-negative integer",
34
+ });
35
+ }
36
+
37
+ if (!isHexString(value)) {
38
+ throw new HardhatError(
39
+ HardhatError.ERRORS.CORE.GENERAL.INVALID_HEX_STRING,
40
+ { value },
41
+ );
42
+ }
43
+
44
+ const unprefixedHexString = getUnprefixedHexString(value);
45
+
46
+ if (unprefixedHexString.length > length * 2) {
47
+ throw new HardhatError(HardhatError.ERRORS.CORE.ARGUMENTS.INVALID_VALUE, {
48
+ value,
49
+ name: "value",
50
+ reason: `it's longer than the target length of ${length} bytes`,
51
+ });
52
+ }
53
+
54
+ const paddedHexString = right
55
+ ? unprefixedHexString.padEnd(length * 2, "0")
56
+ : unprefixedHexString.padStart(length * 2, "0");
57
+
58
+ console.log(`0x${paddedHexString}`);
59
+ };
60
+
61
+ export default padAction;
@@ -0,0 +1,28 @@
1
+ import type { NewUtilsTaskActionFunction } from "../../types.js";
2
+
3
+ import { assertHardhatInvariant } from "@nomicfoundation/hardhat-errors";
4
+ import { hexStringToBigInt } from "@nomicfoundation/hardhat-utils/hex";
5
+
6
+ const fetchBlockNumberAction: NewUtilsTaskActionFunction = async (
7
+ _taskArguments,
8
+ hre,
9
+ ) => {
10
+ const connection = await hre.network.create();
11
+
12
+ try {
13
+ const blockNumber = await connection.provider.request({
14
+ method: "eth_blockNumber",
15
+ });
16
+
17
+ assertHardhatInvariant(
18
+ typeof blockNumber === "string",
19
+ "eth_blockNumber should return a string",
20
+ );
21
+
22
+ console.log(hexStringToBigInt(blockNumber).toString());
23
+ } finally {
24
+ await connection.close();
25
+ }
26
+ };
27
+
28
+ export default fetchBlockNumberAction;
@@ -0,0 +1,18 @@
1
+ import type { UtilsTaskDefinition } from "../../types.js";
2
+
3
+ import { emptyTask, task } from "../../../../core/config.js";
4
+ import { buildUtilsTask } from "../utils-task.js";
5
+
6
+ export function fetch(prefix: string[]): UtilsTaskDefinition[] {
7
+ const fetchTask = emptyTask(
8
+ [...prefix, "fetch"],
9
+ "Fetch on-chain data",
10
+ ).build();
11
+
12
+ const blockNumberTask = buildUtilsTask(
13
+ task([...prefix, "fetch", "block-number"], "Print the latest block number"),
14
+ async () => await import("./block-number.js"),
15
+ );
16
+
17
+ return [fetchTask, blockNumberTask];
18
+ }
@@ -0,0 +1,36 @@
1
+ import type { UtilsTaskDefinition } from "../types.js";
2
+
3
+ import { emptyTask } from "../../../core/config.js";
4
+
5
+ import { constants } from "./constants/index.js";
6
+ import { convert } from "./convert/index.js";
7
+ import { fetch } from "./fetch/index.js";
8
+
9
+ export interface GenerateTasksOptions {
10
+ /**
11
+ * Whether to nest every task under a top-level `utils` task. Used by the
12
+ * Hardhat CLI (`hardhat utils constants ...`) but not by the standalone hhu
13
+ * binary (`hhu constants ...`).
14
+ */
15
+ prefixWithUtils: boolean;
16
+ }
17
+
18
+ /**
19
+ * The category builders that contribute the utils tasks. Each one receives the
20
+ * id prefix to nest its tasks under and returns its task definitions. Adding a
21
+ * new category is a single entry here.
22
+ */
23
+ const CATEGORIES = [constants, convert, fetch];
24
+
25
+ export function generateTasks(
26
+ options: GenerateTasksOptions,
27
+ ): UtilsTaskDefinition[] {
28
+ const prefix = options.prefixWithUtils ? ["utils"] : [];
29
+
30
+ return [
31
+ ...(prefix.length > 0
32
+ ? [emptyTask(prefix, "Utilities for common Ethereum tasks").build()]
33
+ : []),
34
+ ...CATEGORIES.flatMap((category) => category(prefix)),
35
+ ];
36
+ }
@@ -0,0 +1,29 @@
1
+ import type {
2
+ LazyActionObject,
3
+ NewTaskDefinitionBuilder,
4
+ TaskArguments,
5
+ } from "../../../../types/tasks.js";
6
+ import type {
7
+ NewUtilsTaskActionFunction,
8
+ NewUtilsTaskDefinition,
9
+ } from "../types.js";
10
+
11
+ /**
12
+ * Builds a utils task from a configured task builder and a lazily-loaded action.
13
+ *
14
+ * The standard builder's `setAction`/`build` are hardcoded to
15
+ * `NewTaskActionFunction`, so it can't produce a `NewUtilsTaskDefinition` on its
16
+ * own. This helper requires the action to be a `NewUtilsTaskActionFunction`
17
+ * (rejecting wider actions at the call site), which is what makes re-narrowing
18
+ * the built definition sound.
19
+ */
20
+ export function buildUtilsTask<TaskArgumentsT extends TaskArguments>(
21
+ builder: NewTaskDefinitionBuilder<TaskArgumentsT>,
22
+ action: LazyActionObject<NewUtilsTaskActionFunction<TaskArgumentsT>>,
23
+ ): NewUtilsTaskDefinition {
24
+ // The narrower action is assignable to the builder's `NewTaskActionFunction`,
25
+ // and since `action` is statically a `NewUtilsTaskActionFunction`, re-narrowing
26
+ // the result is safe.
27
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- see above
28
+ return builder.setAction(action).build() as NewUtilsTaskDefinition;
29
+ }
@@ -0,0 +1,57 @@
1
+ import type { HardhatRuntimeEnvironment } from "../../../types/hre.js";
2
+ import type { NetworkManager } from "../../../types/network.js";
3
+ import type {
4
+ BaseTaskDefinition,
5
+ EmptyTaskDefinition,
6
+ LazyActionObject,
7
+ TaskArguments,
8
+ } from "../../../types/tasks.js";
9
+
10
+ /**
11
+ * The subset of the HRE that utils tasks are allowed to use.
12
+ *
13
+ * It is narrowed to what the hhu binary can provide without always creating
14
+ * a real HRE.
15
+ */
16
+ export interface UtilsHardhatRuntimeEnvironment {
17
+ network: Pick<NetworkManager, "create">;
18
+ }
19
+
20
+ /**
21
+ * The fake HRE that the hhu binary builds so it can parse and run utils without
22
+ * creating a real one. It's the surface utils actions use
23
+ * ({@link UtilsHardhatRuntimeEnvironment}) plus the `config` that
24
+ * `TaskManagerImplementation` needs to build the task map.
25
+ */
26
+ export interface FakeHhuHardhatRuntimeEnvironment
27
+ extends UtilsHardhatRuntimeEnvironment {
28
+ config: Pick<HardhatRuntimeEnvironment["config"], "tasks" | "plugins">;
29
+ }
30
+
31
+ /**
32
+ * The type of a utils task's action function.
33
+ *
34
+ * It mirrors `NewTaskActionFunction`, but the HRE passed as the second argument
35
+ * is narrowed to `UtilsHardhatRuntimeEnvironment` so that utils tasks only
36
+ * depend on the small surface that both the Hardhat CLI and the hhu binary can
37
+ * provide.
38
+ */
39
+ export type NewUtilsTaskActionFunction<
40
+ TaskArgumentsT extends TaskArguments = TaskArguments,
41
+ > = (taskArguments: TaskArgumentsT, hre: UtilsHardhatRuntimeEnvironment) => any;
42
+
43
+ /**
44
+ * The definition of a utils task.
45
+ *
46
+ * It mirrors `NewTaskDefinition`, but narrows that action to a
47
+ * `NewUtilsTaskActionFunction`.
48
+ */
49
+ export type NewUtilsTaskDefinition = BaseTaskDefinition & {
50
+ action: LazyActionObject<NewUtilsTaskActionFunction>;
51
+ };
52
+
53
+ /**
54
+ * The subset of `TaskDefinition` that utils tasks produce: either an empty task
55
+ * (a namespace placeholder) or a utils task. Override tasks are not supported.
56
+ */
57
+ export type UtilsTaskDefinition = EmptyTaskDefinition | NewUtilsTaskDefinition;
@@ -6,6 +6,10 @@ import console from "./console/index.js";
6
6
  import coverage from "./coverage/index.js";
7
7
  import flatten from "./flatten/index.js";
8
8
  import gasAnalytics from "./gas-analytics/index.js";
9
+ // The hhu / `utils` feature is unreleased and intentionally not wired up yet.
10
+ // To enable it, uncomment the three `hhu` lines (this import, the type re-export
11
+ // below, and the `builtinPlugins` entry) and re-add `bin.hhu` in package.json.
12
+ // import hhu from "./hhu/index.js";
9
13
  import networkManager from "./network-manager/index.js";
10
14
  import node from "./node/index.js";
11
15
  import run from "./run/index.js";
@@ -22,6 +26,7 @@ export type * from "./console/index.js";
22
26
  export type * from "./coverage/index.js";
23
27
  export type * from "./flatten/index.js";
24
28
  export type * from "./gas-analytics/index.js";
29
+ // export type * from "./hhu/index.js";
25
30
  export type * from "./network-manager/index.js";
26
31
  export type * from "./node/index.js";
27
32
  export type * from "./run/index.js";
@@ -46,4 +51,5 @@ export const builtinPlugins: HardhatPlugin[] = [
46
51
  node,
47
52
  flatten,
48
53
  telemetry,
54
+ // hhu,
49
55
  ];
@@ -12,6 +12,7 @@ import {
12
12
  opHardforkFromString,
13
13
  type AccountOverride,
14
14
  } from "@nomicfoundation/edr";
15
+ import { bytesToHexString } from "@nomicfoundation/hardhat-utils/hex";
15
16
  import { AsyncMutex } from "@nomicfoundation/hardhat-utils/synchronization";
16
17
  import { hexToBytes } from "ethereum-cryptography/utils";
17
18
 
@@ -50,7 +51,7 @@ const genesisStateAndAccountsCache: WeakMap<
50
51
  Map<
51
52
  string,
52
53
  {
53
- genesisState: Map<Uint8Array, AccountOverride>;
54
+ genesisState: Map<string, AccountOverride>;
54
55
  ownedAccounts: Array<{ secretKey: string; balance: bigint }>;
55
56
  }
56
57
  >
@@ -66,7 +67,7 @@ export async function getGenesisStateAndOwnedAccounts(
66
67
  chainType: ChainType,
67
68
  specId: string,
68
69
  ): Promise<{
69
- genesisState: Map<Uint8Array, AccountOverride>;
70
+ genesisState: Map<string, AccountOverride>;
70
71
  ownedAccounts: Array<{ secretKey: string; balance: bigint }>;
71
72
  }> {
72
73
  const cached = genesisStateAndAccountsCache
@@ -131,7 +132,7 @@ async function createGenesisStateAndOwnedAccounts(
131
132
  chainType: ChainType,
132
133
  specId: string,
133
134
  ): Promise<{
134
- genesisState: Map<Uint8Array, AccountOverride>;
135
+ genesisState: Map<string, AccountOverride>;
135
136
  ownedAccounts: Array<{ secretKey: string; balance: bigint }>;
136
137
  }> {
137
138
  if (microEthSignerAddress === undefined) {
@@ -142,7 +143,7 @@ async function createGenesisStateAndOwnedAccounts(
142
143
 
143
144
  const ownedAccounts = await hardhatAccountsToEdrOwnedAccounts(accountsConfig);
144
145
 
145
- const genesisState: Map<Uint8Array, AccountOverride> = new Map(
146
+ const genesisState: Map<string, AccountOverride> = new Map(
146
147
  ownedAccounts.map(({ secretKey, balance }) => {
147
148
  const address = hexToBytes(addr.fromPrivateKey(secretKey));
148
149
  const accountOverride: AccountOverride = {
@@ -151,7 +152,7 @@ async function createGenesisStateAndOwnedAccounts(
151
152
  code: new Uint8Array(), // Empty account code, removing potential delegation code when forking
152
153
  };
153
154
 
154
- return [address, accountOverride];
155
+ return [bytesToHexString(address), accountOverride];
155
156
  }),
156
157
  );
157
158
 
@@ -162,18 +163,25 @@ async function createGenesisStateAndOwnedAccounts(
162
163
  ? opGenesisState(opHardforkFromString(specId))
163
164
  : l1GenesisState(l1HardforkFromString(specId));
164
165
 
166
+ mergeGenesisState(genesisState, chainGenesisState);
167
+
168
+ return { genesisState, ownedAccounts };
169
+ }
170
+
171
+ export function mergeGenesisState(
172
+ genesisState: Map<string, AccountOverride>,
173
+ chainGenesisState: readonly AccountOverride[],
174
+ ): void {
165
175
  for (const account of chainGenesisState) {
166
- const existingOverride = genesisState.get(account.address);
176
+ const addressKey = bytesToHexString(account.address);
177
+ const existingOverride = genesisState.get(addressKey);
167
178
  if (existingOverride !== undefined) {
168
179
  // Favor the genesis state specified by the user
169
- account.balance = account.balance ?? existingOverride.balance;
170
- account.nonce = account.nonce ?? existingOverride.nonce;
171
- account.code = account.code ?? existingOverride.code;
172
- account.storage = account.storage ?? existingOverride.storage;
173
- } else {
174
- genesisState.set(account.address, account);
180
+ account.balance = existingOverride.balance ?? account.balance;
181
+ account.nonce = existingOverride.nonce ?? account.nonce;
182
+ account.code = existingOverride.code ?? account.code;
183
+ account.storage = existingOverride.storage ?? account.storage;
175
184
  }
185
+ genesisState.set(addressKey, account);
176
186
  }
177
-
178
- return { genesisState, ownedAccounts };
179
187
  }
@@ -21,6 +21,32 @@ import {
21
21
  UNRECOGNIZED_FUNCTION_NAME,
22
22
  } from "./solidity-stack-trace.js";
23
23
 
24
+ interface CheatcodeSuggestion {
25
+ message: string;
26
+ docsUrl?: string;
27
+ }
28
+
29
+ const CHEATCODE_SUGGESTIONS: Record<string, CheatcodeSuggestion> = {
30
+ "eip712HashType(string,string)": {
31
+ message:
32
+ "Providing a path to a bindings file is not supported, please use the eip712HashType(string calldata typeNameOrDefinition) cheatcode instead.",
33
+ docsUrl:
34
+ "https://hardhat.org/docs/reference/cheatcodes/utilities/eip712-hash-type",
35
+ },
36
+ };
37
+
38
+ export function getCheatcodeSuggestion(cheatcode: string): string {
39
+ const suggestion = CHEATCODE_SUGGESTIONS[cheatcode];
40
+
41
+ if (suggestion === undefined) {
42
+ return "";
43
+ }
44
+
45
+ return suggestion.docsUrl !== undefined
46
+ ? `${suggestion.message} See ${suggestion.docsUrl} for more information.`
47
+ : suggestion.message;
48
+ }
49
+
24
50
  export function createSolidityErrorWithStackTrace(
25
51
  fallbackMessage: string,
26
52
  stackTrace: SolidityStackTrace,
@@ -277,6 +303,13 @@ function getMessageFromLastStackTraceEntry(
277
303
  switch (stackTraceEntry.details.code) {
278
304
  case CheatcodeErrorCode.UnsupportedCheatcode:
279
305
  message = `Cheatcode '${stackTraceEntry.details.cheatcode}' is not supported by Hardhat.`;
306
+
307
+ const suggestion = getCheatcodeSuggestion(
308
+ stackTraceEntry.details.cheatcode,
309
+ );
310
+
311
+ message += suggestion.length > 0 ? " " + suggestion : "";
312
+
280
313
  break;
281
314
  case CheatcodeErrorCode.MissingCheatcode:
282
315
  message = `Cheatcode '${stackTraceEntry.details.cheatcode}' is not yet available in this version of Hardhat.`;
@@ -1,8 +1,8 @@
1
1
  import type { HardhatPlugin } from "../../../types/plugins.js";
2
2
 
3
3
  import { definePlugin } from "../../../plugins.js";
4
- import { ArgumentType } from "../../../types/arguments.js";
5
- import { globalOption } from "../../core/config.js";
4
+
5
+ import { NETWORK_GLOBAL_OPTION } from "./network-option.js";
6
6
 
7
7
  export type * from "./type-extensions/config.js";
8
8
  export type * from "./type-extensions/global-options.js";
@@ -16,14 +16,7 @@ const hardhatPlugin: HardhatPlugin = definePlugin({
16
16
  hre: () => import("./hook-handlers/hre.js"),
17
17
  network: () => import("./hook-handlers/network.js"),
18
18
  },
19
- globalOptions: [
20
- globalOption({
21
- name: "network",
22
- description: "The network to connect to",
23
- type: ArgumentType.STRING_WITHOUT_DEFAULT,
24
- defaultValue: undefined,
25
- }),
26
- ],
19
+ globalOptions: [NETWORK_GLOBAL_OPTION],
27
20
  npmPackage: "hardhat",
28
21
  dependencies: () => [import("../artifacts/index.js")],
29
22
  });
@@ -0,0 +1,17 @@
1
+ import type { GlobalOptionDefinition } from "../../../types/arguments.js";
2
+
3
+ import { ArgumentType } from "../../../types/arguments.js";
4
+ import { globalOption } from "../../core/config.js";
5
+
6
+ /**
7
+ * The `--network` global option, contributed by the network-manager plugin.
8
+ *
9
+ * Exported so the standalone hhu binary, which doesn't load the plugin, can
10
+ * reuse the exact same definition instead of duplicating it.
11
+ */
12
+ export const NETWORK_GLOBAL_OPTION: GlobalOptionDefinition = globalOption({
13
+ name: "network",
14
+ description: "The network to connect to",
15
+ type: ArgumentType.STRING_WITHOUT_DEFAULT,
16
+ defaultValue: undefined,
17
+ });
@@ -1,32 +1,62 @@
1
- import { assertHardhatInvariant } from "@nomicfoundation/hardhat-errors";
1
+ import type {
2
+ JsonRpcRequest,
3
+ JsonRpcResponse,
4
+ } from "../../../../../../types/providers.js";
5
+
6
+ import { isObject } from "@nomicfoundation/hardhat-utils/lang";
7
+
8
+ import { getRequestParams } from "../../../json-rpc.js";
9
+ import { InternalError } from "../../../provider-errors.js";
2
10
 
3
11
  import { SenderHandler } from "./sender.js";
4
12
 
5
13
  /**
6
14
  * This class automatically retrieves and caches the first available account from the connected provider.
7
- * It overrides the getSender method of the base class to request the list of accounts if the first account has not been fetched yet,
8
- * ensuring dynamic selection of the sender for all JSON-RPC requests without requiring manual input.
15
+ * On the first supported request, fetches and caches `eth_accounts` so callers don't need to set `from` manually.
16
+ * If `eth_accounts` responds with a non-array, it returns a JSON-RPC error.
9
17
  */
10
18
  export class AutomaticSenderHandler extends SenderHandler {
11
19
  #alreadyFetchedAccounts = false;
12
20
  #firstAccount: string | undefined;
13
21
 
14
- protected async getSender(): Promise<string | undefined> {
22
+ public override async handle(
23
+ jsonRpcRequest: JsonRpcRequest,
24
+ ): Promise<JsonRpcRequest | JsonRpcResponse> {
25
+ if (!this.isSupportedMethod(jsonRpcRequest)) {
26
+ return jsonRpcRequest;
27
+ }
28
+
29
+ const [tx] = getRequestParams(jsonRpcRequest);
30
+ if (!isObject(tx) || tx.from !== undefined) {
31
+ // Skip the eth_accounts fetch when we won't need a sender anyway:
32
+ // the tx isn't an object, or it already carries a `from`.
33
+ return await super.handle(jsonRpcRequest);
34
+ }
35
+
15
36
  if (this.#alreadyFetchedAccounts === false) {
16
37
  const accounts = await this.provider.request({
17
38
  method: "eth_accounts",
18
39
  });
19
40
 
20
- // TODO: This shouldn't be an exception but a failed JSON response!
21
- assertHardhatInvariant(
22
- Array.isArray(accounts),
23
- "eth_accounts response should be an array",
24
- );
41
+ if (!Array.isArray(accounts)) {
42
+ return {
43
+ jsonrpc: "2.0",
44
+ id: jsonRpcRequest.id,
45
+ error: {
46
+ code: InternalError.CODE,
47
+ message: "eth_accounts did not return an array of accounts",
48
+ },
49
+ };
50
+ }
25
51
 
26
52
  this.#firstAccount = accounts[0];
27
53
  this.#alreadyFetchedAccounts = true;
28
54
  }
29
55
 
56
+ return await super.handle(jsonRpcRequest);
57
+ }
58
+
59
+ protected async getSender(): Promise<string | undefined> {
30
60
  return this.#firstAccount;
31
61
  }
32
62
  }
@@ -322,7 +322,20 @@ const edrNetworkUserConfigSchema = z.object({
322
322
  hardfork: z.optional(z.string()),
323
323
  initialBaseFeePerGas: z.optional(gasUnitUserConfigSchema),
324
324
  initialDate: z.optional(
325
- unionType([z.string(), z.instanceof(Date)], "Expected a string or a Date"),
325
+ unionType(
326
+ [z.string(), z.instanceof(Date)],
327
+ "Expected a string or a Date",
328
+ ).refine(
329
+ (val) => {
330
+ if (typeof val === "string") return !Number.isNaN(Date.parse(val));
331
+ if (val instanceof Date) return !Number.isNaN(val.getTime());
332
+ // already union of string/Date, all types are exhausted
333
+ return true;
334
+ },
335
+ {
336
+ message: "initialDate must be a parseable date string or a valid Date",
337
+ },
338
+ ),
326
339
  ),
327
340
  loggingEnabled: z.optional(z.boolean()),
328
341
  minGasPrice: z.optional(gasUnitUserConfigSchema),
@@ -8,6 +8,7 @@ export const SPDX_WARNING = "SPDX license identifier not provided";
8
8
  export const PRAGMA_WARNING =
9
9
  "Source file does not specify required compiler version";
10
10
  const CONTRACT_SIZE_WARNING = "Contract code size is";
11
+ const INIT_CODE_SIZE_WARNING = "Contract initcode size is";
11
12
 
12
13
  // Suppression rules are grouped by scope. Each array has its own match logic
13
14
  // in `shouldSuppressWarning` function; add new entries to the array that fits, or add
@@ -32,6 +33,7 @@ const TEST_FILE_WARNING_MESSAGES: readonly string[] = [
32
33
  SPDX_WARNING,
33
34
  PRAGMA_WARNING,
34
35
  CONTRACT_SIZE_WARNING,
36
+ INIT_CODE_SIZE_WARNING,
35
37
  ];
36
38
 
37
39
  // Warnings suppressed only when running with `--coverage`. An entry with no
@@ -44,6 +46,7 @@ const COVERAGE_MODE_RULES: ReadonlyArray<{
44
46
  filePath?: string;
45
47
  }> = [
46
48
  { message: CONTRACT_SIZE_WARNING },
49
+ { message: INIT_CODE_SIZE_WARNING },
47
50
  {
48
51
  message: NATSPEC_MEMORY_SAFE_ASSEMBLY_WARNING,
49
52
  filePath: COVERAGE_LIBRARY_FILE_NAME,
@@ -0,0 +1,19 @@
1
+ import { HARDHAT_PROJECT_INPUT_SOURCE_NAME_ROOT } from "./constants.js";
2
+
3
+ const PROJECT_INPUT_SOURCE_NAME_PREFIX = `${HARDHAT_PROJECT_INPUT_SOURCE_NAME_ROOT}/`;
4
+
5
+ /**
6
+ * Recovers the user-facing source name from a solc input source name by
7
+ * stripping the Hardhat project prefix.
8
+ *
9
+ * Project files have an input source name like `project/contracts/Foo.sol`,
10
+ * whereas the user writes paths — and config globs — against the
11
+ * project-relative `contracts/Foo.sol`. npm package input source names
12
+ * (`npm/<pkg>@<version>/...`) don't carry the project prefix and are returned
13
+ * unchanged.
14
+ */
15
+ export function toUserSourceName(inputSourceName: string): string {
16
+ return inputSourceName.startsWith(PROJECT_INPUT_SOURCE_NAME_PREFIX)
17
+ ? inputSourceName.slice(PROJECT_INPUT_SOURCE_NAME_PREFIX.length)
18
+ : inputSourceName;
19
+ }
@@ -55,10 +55,7 @@ const solidityTestProfileUserConfigType = z.object({
55
55
  prevRandao: z.bigint().optional(),
56
56
  gasLimit: z.bigint().optional(),
57
57
  blockGasLimit: z.number().or(z.bigint()).or(z.literal(false)).optional(),
58
- // TODO: widen back to .number().or(z.bigint()).or(z.literal(false))
59
- // once Solidity test runner no longer breaks setUp() when
60
- // disableTransactionGasCap is false. See PR #8301.
61
- transactionGasCap: z.literal(false).optional(),
58
+ transactionGasCap: z.number().or(z.bigint()).or(z.literal(false)).optional(),
62
59
  fuzz: z
63
60
  .object({
64
61
  failurePersistDir: z.string().optional(),
@@ -7,25 +7,20 @@ import {
7
7
  bytesToUtf8String,
8
8
  } from "@nomicfoundation/hardhat-utils/bytes";
9
9
 
10
- import { HARDHAT_PROJECT_INPUT_SOURCE_NAME_ROOT } from "../../solidity/constants.js";
10
+ import { isPathSelected } from "../../../utils/glob.js";
11
+ import { toUserSourceName } from "../../solidity/source-names.js";
11
12
 
12
13
  import {
13
14
  buildUserDefinedValueTypeIndex,
14
15
  extractStructsFromAst,
15
16
  } from "./ast-walker.js";
16
17
  import { canonicalizeStructs } from "./canonicalize.js";
17
- import { isPathSelected } from "./glob.js";
18
18
 
19
19
  export interface Eip712TypesConfig {
20
20
  include: string[];
21
21
  exclude: string[];
22
22
  }
23
23
 
24
- // When a transitive project file doesn't produce an artifact — and so is
25
- // missing from `inputToUserSource` — stripping this prefix recovers the
26
- // user-facing path that the user's include/exclude globs are written against.
27
- const PROJECT_INPUT_SOURCE_NAME_PREFIX = `${HARDHAT_PROJECT_INPUT_SOURCE_NAME_ROOT}/`;
28
-
29
24
  /**
30
25
  * Walks every compiled source's AST, extracts every struct definition, and
31
26
  * returns the flat list of canonical EIP-712 type strings expected by EDR's
@@ -89,15 +84,12 @@ export function collectEip712CanonicalTypes(
89
84
  );
90
85
 
91
86
  for (const [inputSourceName, source] of Object.entries(sources)) {
92
- let userSourceName = inputToUserSource.get(inputSourceName);
93
-
94
- if (userSourceName === undefined) {
95
- userSourceName = inputSourceName.startsWith(
96
- PROJECT_INPUT_SOURCE_NAME_PREFIX,
97
- )
98
- ? inputSourceName.slice(PROJECT_INPUT_SOURCE_NAME_PREFIX.length)
99
- : inputSourceName;
100
- }
87
+ // A transitive project file that doesn't produce an artifact is missing
88
+ // from `inputToUserSource`; recovering the user source name from the
89
+ // input source name covers that case.
90
+ const userSourceName =
91
+ inputToUserSource.get(inputSourceName) ??
92
+ toUserSourceName(inputSourceName);
101
93
 
102
94
  // Collect every source so non-selected files can serve as dep targets;
103
95
  // selection is enforced at emit time via `selectedNames`.
@@ -6,6 +6,7 @@ import {
6
6
  StackTraceEntryType,
7
7
  CheatcodeErrorCode,
8
8
  } from "../network-manager/edr/stack-traces/solidity-stack-trace.js";
9
+ import { getCheatcodeSuggestion } from "../network-manager/edr/stack-traces/stack-trace-solidity-errors.js";
9
10
 
10
11
  export function getMessageFromLastStackTraceEntry(
11
12
  stackTraceEntry: SolidityStackTraceEntry,
@@ -71,7 +72,11 @@ export function getMessageFromLastStackTraceEntry(
71
72
  if (stackTraceEntry.details !== undefined) {
72
73
  switch (stackTraceEntry.details.code) {
73
74
  case CheatcodeErrorCode.UnsupportedCheatcode:
74
- return `Cheatcode '${stackTraceEntry.details.cheatcode}' is not supported by Hardhat.`;
75
+ const suggestion = getCheatcodeSuggestion(
76
+ stackTraceEntry.details.cheatcode,
77
+ );
78
+
79
+ return `Cheatcode '${stackTraceEntry.details.cheatcode}' is not supported by Hardhat.${suggestion.length > 0 ? " " + suggestion : ""}`;
75
80
  case CheatcodeErrorCode.MissingCheatcode:
76
81
  return `Cheatcode '${stackTraceEntry.details.cheatcode}' is not yet available in this version of Hardhat.`;
77
82
  }