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,472 @@
1
+ import type {
2
+ GlobalOptionDefinitions,
3
+ GlobalOptions,
4
+ } from "../../types/global-options.js";
5
+ import type { Task, TaskArguments } from "../../types/tasks.js";
6
+
7
+ import {
8
+ HardhatError,
9
+ assertHardhatInvariant,
10
+ } from "@nomicfoundation/hardhat-errors";
11
+ import { isCi } from "@nomicfoundation/hardhat-utils/ci";
12
+ import { kebabToCamelCase } from "@nomicfoundation/hardhat-utils/string";
13
+
14
+ import {
15
+ ArgumentType,
16
+ type OptionDefinition,
17
+ type PositionalArgumentDefinition,
18
+ } from "../../types/arguments.js";
19
+ import { parseArgumentValue } from "../core/arguments.js";
20
+ import { isArgumentRequired } from "../core/tasks/utils.js";
21
+
22
+ export async function parseBuiltinGlobalOptions(
23
+ cliArguments: string[],
24
+ usedCliArguments: boolean[],
25
+ ): Promise<{
26
+ init: boolean;
27
+ configPath: string | undefined;
28
+ showStackTraces: boolean;
29
+ help: boolean;
30
+ version: boolean;
31
+ }> {
32
+ let configPath: string | undefined;
33
+ let showStackTraces: boolean = isCi();
34
+ let help: boolean = false;
35
+ let version: boolean = false;
36
+ let init: boolean = false;
37
+
38
+ // TODO: Use parseGlobalOptions(BUILTIN_GLOBAL_OPTIONS_DEFINITIONS, ...) instead
39
+ for (let i = 0; i < cliArguments.length; i++) {
40
+ const arg = cliArguments[i];
41
+
42
+ if (arg === "--init") {
43
+ usedCliArguments[i] = true;
44
+ init = true;
45
+ continue;
46
+ }
47
+
48
+ if (arg === "--config") {
49
+ usedCliArguments[i] = true;
50
+
51
+ if (configPath !== undefined) {
52
+ throw new HardhatError(
53
+ HardhatError.ERRORS.CORE.ARGUMENTS.DUPLICATED_NAME,
54
+ {
55
+ name: "--config",
56
+ },
57
+ );
58
+ }
59
+
60
+ if (
61
+ usedCliArguments[i + 1] === undefined ||
62
+ usedCliArguments[i + 1] === true
63
+ ) {
64
+ throw new HardhatError(
65
+ HardhatError.ERRORS.CORE.ARGUMENTS.MISSING_CONFIG_FILE,
66
+ );
67
+ }
68
+
69
+ configPath = cliArguments[i + 1];
70
+ i++;
71
+
72
+ usedCliArguments[i] = true;
73
+ continue;
74
+ }
75
+
76
+ if (arg === "--show-stack-traces") {
77
+ usedCliArguments[i] = true;
78
+ showStackTraces = true;
79
+ continue;
80
+ }
81
+
82
+ if (arg === "--help" || arg === "-h") {
83
+ usedCliArguments[i] = true;
84
+ help = true;
85
+ continue;
86
+ }
87
+
88
+ if (arg === "--version") {
89
+ usedCliArguments[i] = true;
90
+ version = true;
91
+ continue;
92
+ }
93
+ }
94
+
95
+ if (init && configPath !== undefined) {
96
+ throw new HardhatError(
97
+ HardhatError.ERRORS.CORE.ARGUMENTS.CANNOT_COMBINE_INIT_AND_CONFIG_PATH,
98
+ );
99
+ }
100
+
101
+ return { init, configPath, showStackTraces, help, version };
102
+ }
103
+
104
+ export async function parseGlobalOptions(
105
+ globalOptionDefinitions: GlobalOptionDefinitions,
106
+ cliArguments: string[],
107
+ usedCliArguments: boolean[],
108
+ ): Promise<Partial<GlobalOptions>> {
109
+ const globalOptions: Partial<GlobalOptions> = {};
110
+
111
+ const optionDefinitions = new Map(
112
+ [...globalOptionDefinitions].map(([key, value]) => [key, value.option]),
113
+ );
114
+
115
+ parseOptions(
116
+ cliArguments,
117
+ usedCliArguments,
118
+ optionDefinitions,
119
+ globalOptions,
120
+ true,
121
+ );
122
+
123
+ return globalOptions;
124
+ }
125
+
126
+ /**
127
+ * Parses the task from the cli args.
128
+ *
129
+ * @returns The task, or an array with the unrecognized task id.
130
+ * If no task id is provided, an empty array is returned.
131
+ */
132
+ export function parseTask(
133
+ cliArguments: string[],
134
+ usedCliArguments: boolean[],
135
+ tasksMap: Map<string, Task>,
136
+ ): Task | string[] {
137
+ const taskOrId = getTaskFromCliArguments(
138
+ cliArguments,
139
+ usedCliArguments,
140
+ tasksMap,
141
+ );
142
+
143
+ return taskOrId;
144
+ }
145
+
146
+ function getTaskFromCliArguments(
147
+ cliArguments: string[],
148
+ usedCliArguments: boolean[],
149
+ tasksMap: Map<string, Task>,
150
+ ): string[] | Task {
151
+ const taskId: string[] = [];
152
+ let task: Task | undefined;
153
+
154
+ for (let i = 0; i < cliArguments.length; i++) {
155
+ if (usedCliArguments[i]) {
156
+ continue;
157
+ }
158
+
159
+ const arg = cliArguments[i];
160
+
161
+ if (arg.startsWith("-")) {
162
+ /* A standalone '--' is ok because it is used to separate CLI tool arguments
163
+ * from task arguments, ensuring the tool passes subsequent options directly
164
+ * to the task. Everything after "--" should be considered as a positional
165
+ * argument. */
166
+ if (arg === "--" || task !== undefined) {
167
+ break;
168
+ }
169
+
170
+ /* At this point in the code, the global options have already been parsed, so
171
+ * the remaining options starting with '--' are task options. Hence, if no task
172
+ * is defined, it means that the option is not assigned to any task, and it's
173
+ * an error. */
174
+ throw new HardhatError(
175
+ HardhatError.ERRORS.CORE.ARGUMENTS.UNRECOGNIZED_OPTION,
176
+ {
177
+ option: arg,
178
+ },
179
+ );
180
+ }
181
+
182
+ if (task === undefined) {
183
+ task = tasksMap.get(arg);
184
+
185
+ if (task === undefined) {
186
+ return [arg]; // No task found
187
+ }
188
+ } else {
189
+ const subtask = task.subtasks.get(arg);
190
+
191
+ if (subtask === undefined) {
192
+ break;
193
+ }
194
+
195
+ task = subtask;
196
+ }
197
+
198
+ usedCliArguments[i] = true;
199
+ taskId.push(arg);
200
+ }
201
+
202
+ if (task === undefined) {
203
+ return taskId;
204
+ }
205
+
206
+ return task;
207
+ }
208
+
209
+ export function parseTaskArguments(
210
+ cliArguments: string[],
211
+ usedCliArguments: boolean[],
212
+ task: Task,
213
+ ): TaskArguments {
214
+ const taskArguments: TaskArguments = {};
215
+
216
+ // Parse options
217
+ parseOptions(cliArguments, usedCliArguments, task.options, taskArguments);
218
+
219
+ parsePositionalAndVariadicArguments(
220
+ cliArguments,
221
+ usedCliArguments,
222
+ task,
223
+ taskArguments,
224
+ );
225
+
226
+ const unusedIndex = usedCliArguments.indexOf(false);
227
+
228
+ if (unusedIndex !== -1) {
229
+ throw new HardhatError(HardhatError.ERRORS.CORE.ARGUMENTS.UNUSED_ARGUMENT, {
230
+ value: cliArguments[unusedIndex],
231
+ });
232
+ }
233
+
234
+ return taskArguments;
235
+ }
236
+
237
+ /**
238
+ * Parses the raw arguments from the command line, returning an array of
239
+ * arguments. If an argument starts with "--" and contains "=" (i.e. "--option=123")
240
+ * it is split into two separate arguments: the option name and the option value.
241
+ */
242
+ export function parseRawArguments(rawArguments: string[]): string[] {
243
+ return rawArguments.flatMap((arg) => {
244
+ if (arg.startsWith("--") && arg.includes("=")) {
245
+ const index = arg.indexOf("=");
246
+ const optionName = arg.substring(0, index);
247
+ const optionValue = arg.substring(index + 1);
248
+
249
+ return [optionName, optionValue];
250
+ }
251
+
252
+ return arg;
253
+ });
254
+ }
255
+
256
+ function parseOptions(
257
+ cliArguments: string[],
258
+ usedCliArguments: boolean[],
259
+ optionDefinitions: Map<string, OptionDefinition>,
260
+ providedArguments: TaskArguments,
261
+ ignoreUnknownOption = false,
262
+ ) {
263
+ const optionDefinitionsByShortName = new Map<string, OptionDefinition>();
264
+ for (const optionDefinition of optionDefinitions.values()) {
265
+ if (optionDefinition.shortName !== undefined) {
266
+ optionDefinitionsByShortName.set(
267
+ optionDefinition.shortName,
268
+ optionDefinition,
269
+ );
270
+ }
271
+ }
272
+
273
+ for (let i = 0; i < cliArguments.length; i++) {
274
+ if (usedCliArguments[i]) {
275
+ continue;
276
+ }
277
+
278
+ if (cliArguments[i] === "--") {
279
+ /* A standalone '--' is ok because it is used to separate CLI tool arguments
280
+ * from task arguments, ensuring the tool passes subsequent options directly
281
+ * to the task. Everything after "--" should be considered as a positional
282
+ * argument. */
283
+ break;
284
+ }
285
+
286
+ const arg = cliArguments[i];
287
+
288
+ let optionDefinition: OptionDefinition | undefined;
289
+
290
+ const providedByName = arg.startsWith("--");
291
+ const providedByShortName = !providedByName && arg.startsWith("-");
292
+
293
+ if (providedByName) {
294
+ const name = kebabToCamelCase(arg.substring(2));
295
+ optionDefinition = optionDefinitions.get(name);
296
+ } else if (providedByShortName) {
297
+ const shortName = arg[1];
298
+
299
+ // Check if the short name is valid
300
+ if (Array.from(arg.substring(1)).some((c) => c !== shortName)) {
301
+ throw new HardhatError(
302
+ HardhatError.ERRORS.CORE.ARGUMENTS.CANNOT_GROUP_OPTIONS,
303
+ {
304
+ option: arg,
305
+ },
306
+ );
307
+ }
308
+
309
+ optionDefinition = optionDefinitionsByShortName.get(shortName);
310
+ } else {
311
+ continue;
312
+ }
313
+
314
+ if (optionDefinition === undefined) {
315
+ if (ignoreUnknownOption === true) {
316
+ continue;
317
+ }
318
+
319
+ // Only throw an error when the argument is not a global option, because
320
+ // it might be a option related to a task
321
+ throw new HardhatError(
322
+ HardhatError.ERRORS.CORE.ARGUMENTS.UNRECOGNIZED_OPTION,
323
+ {
324
+ option: arg,
325
+ },
326
+ );
327
+ }
328
+
329
+ if (optionDefinition.hidden === true) {
330
+ throw new HardhatError(
331
+ HardhatError.ERRORS.CORE.ARGUMENTS.NO_HIDDEN_OPTION_CLI,
332
+ {
333
+ option: arg,
334
+ },
335
+ );
336
+ }
337
+
338
+ const optionName = optionDefinition.name;
339
+
340
+ // Check if the short name is valid again now that we know its type
341
+ // E.g. --flag --flag
342
+ const optionAlreadyProvided = providedArguments[optionName] !== undefined;
343
+ // E.g. -ff
344
+ const shortOptionGroupedAndRepeated = providedByShortName && arg.length > 2;
345
+ const isLevelOption = optionDefinition.type === ArgumentType.LEVEL;
346
+ if (
347
+ optionAlreadyProvided ||
348
+ (shortOptionGroupedAndRepeated && !isLevelOption)
349
+ ) {
350
+ throw new HardhatError(
351
+ HardhatError.ERRORS.CORE.ARGUMENTS.CANNOT_REPEAT_OPTIONS,
352
+ {
353
+ option: arg,
354
+ type: optionDefinition.type,
355
+ },
356
+ );
357
+ }
358
+
359
+ usedCliArguments[i] = true;
360
+
361
+ if (optionDefinition.type === ArgumentType.FLAG) {
362
+ providedArguments[optionName] = true;
363
+ continue;
364
+ } else if (
365
+ optionDefinition.type === ArgumentType.LEVEL &&
366
+ providedByShortName
367
+ ) {
368
+ providedArguments[optionName] = arg.length - 1;
369
+ continue;
370
+ } else if (
371
+ usedCliArguments[i + 1] !== undefined &&
372
+ usedCliArguments[i + 1] === false
373
+ ) {
374
+ i++;
375
+
376
+ providedArguments[optionName] = parseArgumentValue(
377
+ cliArguments[i],
378
+ optionDefinition.type,
379
+ optionName,
380
+ );
381
+
382
+ usedCliArguments[i] = true;
383
+
384
+ continue;
385
+ }
386
+
387
+ throw new HardhatError(
388
+ HardhatError.ERRORS.CORE.ARGUMENTS.MISSING_VALUE_FOR_ARGUMENT,
389
+ {
390
+ argument: arg,
391
+ },
392
+ );
393
+ }
394
+ }
395
+
396
+ function parsePositionalAndVariadicArguments(
397
+ cliArguments: string[],
398
+ usedCliArguments: boolean[],
399
+ task: Task,
400
+ providedArguments: TaskArguments,
401
+ ) {
402
+ let argIndex = 0;
403
+
404
+ for (let i = 0; i < cliArguments.length; i++) {
405
+ if (usedCliArguments[i] === true) {
406
+ continue;
407
+ }
408
+
409
+ if (cliArguments[i] === "--") {
410
+ /* A standalone '--' is ok because it is used to separate CLI tool arguments
411
+ * from task arguments, ensuring the tool passes subsequent options directly
412
+ * to the task. Everything after "--" should be considered as a positional
413
+ * argument. */
414
+ usedCliArguments[i] = true;
415
+ continue;
416
+ }
417
+
418
+ const argumentDefinition = task.positionalArguments[argIndex];
419
+
420
+ if (argumentDefinition === undefined) {
421
+ break;
422
+ }
423
+
424
+ usedCliArguments[i] = true;
425
+
426
+ const formattedValue = parseArgumentValue(
427
+ cliArguments[i],
428
+ argumentDefinition.type,
429
+ argumentDefinition.name,
430
+ );
431
+
432
+ if (argumentDefinition.isVariadic === false) {
433
+ providedArguments[argumentDefinition.name] = formattedValue;
434
+ argIndex++;
435
+ continue;
436
+ }
437
+
438
+ // Handle variadic arguments. No longer increment "argIndex" because there can
439
+ // only be one variadic argument, and it will consume all remaining arguments.
440
+ providedArguments[argumentDefinition.name] =
441
+ providedArguments[argumentDefinition.name] ?? [];
442
+ const variadicTaskArg = providedArguments[argumentDefinition.name];
443
+ assertHardhatInvariant(
444
+ Array.isArray(variadicTaskArg),
445
+ "Variadic argument values should be an array",
446
+ );
447
+ variadicTaskArg.push(formattedValue);
448
+ }
449
+
450
+ // Check if all the required arguments have been used
451
+ validateRequiredArguments(task.positionalArguments, providedArguments);
452
+ }
453
+
454
+ function validateRequiredArguments(
455
+ argumentDefinitions: PositionalArgumentDefinition[],
456
+ taskArguments: TaskArguments,
457
+ ) {
458
+ const missingRequiredArgument = argumentDefinitions.find(
459
+ ({ defaultValue, name, type }) =>
460
+ isArgumentRequired(type, defaultValue) &&
461
+ taskArguments[name] === undefined,
462
+ );
463
+
464
+ if (missingRequiredArgument === undefined) {
465
+ return;
466
+ }
467
+
468
+ throw new HardhatError(
469
+ HardhatError.ERRORS.CORE.ARGUMENTS.MISSING_VALUE_FOR_ARGUMENT,
470
+ { argument: missingRequiredArgument.name },
471
+ );
472
+ }
@@ -52,11 +52,15 @@ export async function sendTelemetryConfigAnalytics(
52
52
  return true;
53
53
  }
54
54
 
55
- export async function sendTaskAnalytics(taskId: string[]): Promise<boolean> {
55
+ export async function sendTaskAnalytics(
56
+ taskId: string[],
57
+ command: "hardhat" | "hhu",
58
+ ): Promise<boolean> {
56
59
  const taskAnalyticsEvent: AnalyticsEvent = {
57
60
  name: "task",
58
61
  params: {
59
62
  task: taskId.join(", "),
63
+ command,
60
64
  },
61
65
  };
62
66
 
@@ -37,6 +37,9 @@ export type AnalyticsEvent =
37
37
  name: "task";
38
38
  params: {
39
39
  task: string;
40
+ // The CLI surface that ran the task, so `hhu` usage can be measured
41
+ // separately from the `hardhat` CLI.
42
+ command: "hardhat" | "hhu";
40
43
  };
41
44
  }
42
45
  | {
@@ -10,32 +10,48 @@ import {
10
10
  opSolidityTestRunnerFactory,
11
11
  } from "@nomicfoundation/edr";
12
12
 
13
- let _globalEdrContext: EdrContext | undefined;
13
+ // We cache the initialization *promise* (assigned synchronously, before any
14
+ // await) rather than the resolved context. This way concurrent callers share a
15
+ // single in-flight initialization and always receive a fully-registered
16
+ // context, instead of racing on a half-initialized one.
17
+ let _globalEdrContext: Promise<EdrContext> | undefined;
14
18
 
15
19
  export async function getGlobalEdrContext(): Promise<EdrContext> {
16
20
  if (_globalEdrContext === undefined) {
17
- _globalEdrContext = new EdrContext();
18
- await _globalEdrContext.registerProviderFactory(
19
- GENERIC_CHAIN_TYPE,
20
- genericChainProviderFactory(),
21
- );
22
- await _globalEdrContext.registerProviderFactory(
23
- L1_CHAIN_TYPE,
24
- l1ProviderFactory(),
25
- );
26
- await _globalEdrContext.registerProviderFactory(
27
- OP_CHAIN_TYPE,
28
- opProviderFactory(),
29
- );
30
- await _globalEdrContext.registerSolidityTestRunnerFactory(
31
- L1_CHAIN_TYPE,
32
- l1SolidityTestRunnerFactory(),
33
- );
34
- await _globalEdrContext.registerSolidityTestRunnerFactory(
35
- OP_CHAIN_TYPE,
36
- opSolidityTestRunnerFactory(),
37
- );
21
+ const context = createGlobalEdrContext();
22
+ _globalEdrContext = context;
23
+
24
+ // If initialization fails, clear the cached promise so a later call can
25
+ // retry instead of permanently returning a rejected promise. The identity
26
+ // guard prevents a stale rejection from wiping a newer promise created by
27
+ // a retry.
28
+ context.catch(() => {
29
+ if (_globalEdrContext === context) {
30
+ _globalEdrContext = undefined;
31
+ }
32
+ });
38
33
  }
39
34
 
40
- return _globalEdrContext;
35
+ return await _globalEdrContext;
36
+ }
37
+
38
+ async function createGlobalEdrContext(): Promise<EdrContext> {
39
+ const context = new EdrContext();
40
+
41
+ await context.registerProviderFactory(
42
+ GENERIC_CHAIN_TYPE,
43
+ genericChainProviderFactory(),
44
+ );
45
+ await context.registerProviderFactory(L1_CHAIN_TYPE, l1ProviderFactory());
46
+ await context.registerProviderFactory(OP_CHAIN_TYPE, opProviderFactory());
47
+ await context.registerSolidityTestRunnerFactory(
48
+ L1_CHAIN_TYPE,
49
+ l1SolidityTestRunnerFactory(),
50
+ );
51
+ await context.registerSolidityTestRunnerFactory(
52
+ OP_CHAIN_TYPE,
53
+ opSolidityTestRunnerFactory(),
54
+ );
55
+
56
+ return context;
41
57
  }
@@ -6,7 +6,7 @@ import { shortenPath } from "@nomicfoundation/hardhat-utils/path";
6
6
 
7
7
  export class UsingHardhat2PluginError extends CustomError {
8
8
  public readonly callerRelativePath: string | undefined;
9
- constructor() {
9
+ constructor(apiName: string, migrationHint?: string) {
10
10
  const callerPath = getCallerRelativePath();
11
11
 
12
12
  let message: string;
@@ -18,6 +18,12 @@ This file is part of a Hardhat 2 plugin calling an API that was removed in Hardh
18
18
  message = `You are trying to use a Hardhat 2 plugin in a Hardhat 3 project.`;
19
19
  }
20
20
 
21
+ message += `\n\nThe removed API is: ${styleText("bold", apiName)}.`;
22
+
23
+ if (migrationHint !== undefined) {
24
+ message += `\n\n${migrationHint}`;
25
+ }
26
+
21
27
  super(message);
22
28
  // Use a non-enumerable property so that `console.error(error)` does not
23
29
  // print `{ callerRelativePath: '…' }` after the stack trace.
@@ -98,8 +104,11 @@ export function getCallerRelativePath(depth: number = 5): string | undefined {
98
104
  }
99
105
  }
100
106
 
101
- export function throwUsingHardhat2PluginError(): never {
107
+ export function throwUsingHardhat2PluginError(
108
+ apiName: string,
109
+ migrationHint?: string,
110
+ ): never {
102
111
  /* eslint-disable-next-line no-restricted-syntax -- Intentionally throwing a
103
112
  custom error here so that we always print the stack trace */
104
- throw new UsingHardhat2PluginError();
113
+ throw new UsingHardhat2PluginError(apiName, migrationHint);
105
114
  }
@@ -15,11 +15,11 @@ export function isPathSelected(
15
15
  return false;
16
16
  }
17
17
 
18
- if (!matchesAny(path, include)) {
18
+ if (!matchesAnyGlob(path, include)) {
19
19
  return false;
20
20
  }
21
21
 
22
- if (exclude.length > 0 && matchesAny(path, exclude)) {
22
+ if (exclude.length > 0 && matchesAnyGlob(path, exclude)) {
23
23
  return false;
24
24
  }
25
25
 
@@ -29,7 +29,7 @@ export function isPathSelected(
29
29
  /**
30
30
  * Returns true if `value` matches at least one of the given glob patterns.
31
31
  */
32
- function matchesAny(value: string, patterns: string[]): boolean {
32
+ export function matchesAnyGlob(value: string, patterns: string[]): boolean {
33
33
  for (const pattern of patterns) {
34
34
  if (getCompiledGlob(pattern).test(value)) {
35
35
  return true;
package/src/plugins.ts CHANGED
@@ -5,6 +5,9 @@ import type { HardhatPlugin } from "./types/plugins.js";
5
5
  import { registerLoadedPlugin } from "./internal/core/plugins/loaded-plugins-registry.js";
6
6
  import { throwUsingHardhat2PluginError } from "./internal/using-hardhat2-plugin-errors.js";
7
7
 
8
+ const LAZY_LOADING_MIGRATION_HINT =
9
+ "To migrate a plugin to Hardhat 3, export a plugin object with definePlugin from hardhat/plugins and register lazy-loaded logic through dependencies, hook handlers, and task actions.";
10
+
8
11
  /**
9
12
  * Defines a Hardhat plugin.
10
13
  *
@@ -25,12 +28,12 @@ export function definePlugin(plugin: HardhatPlugin): HardhatPlugin {
25
28
  * @deprecated This function is part of the Hardhat 2 plugin API.
26
29
  */
27
30
  export function lazyFunction(..._args: any): any {
28
- throwUsingHardhat2PluginError();
31
+ throwUsingHardhat2PluginError("lazyFunction", LAZY_LOADING_MIGRATION_HINT);
29
32
  }
30
33
 
31
34
  /**
32
35
  * @deprecated This function is part of the Hardhat 2 plugin API.
33
36
  */
34
37
  export function lazyObject(..._args: any): any {
35
- throwUsingHardhat2PluginError();
38
+ throwUsingHardhat2PluginError("lazyObject", LAZY_LOADING_MIGRATION_HINT);
36
39
  }
@@ -5,9 +5,9 @@
5
5
  "description": "A TypeScript Hardhat project using Node Test Runner and Viem",
6
6
  "type": "module",
7
7
  "devDependencies": {
8
- "hardhat": "workspace:^3.8.0",
8
+ "hardhat": "workspace:^3.9.1",
9
9
  "@nomicfoundation/hardhat-toolbox-viem": "workspace:^5.0.7",
10
- "@nomicfoundation/hardhat-ignition": "workspace:^3.1.7",
10
+ "@nomicfoundation/hardhat-ignition": "workspace:^3.1.8",
11
11
  "@types/node": "^22.8.5",
12
12
  "forge-std": "foundry-rs/forge-std#v1.9.4",
13
13
  "typescript": "~6.0.3",
@@ -16,11 +16,11 @@
16
16
  "peerDependencies": {
17
17
  "@nomicfoundation/hardhat-ignition-viem": "workspace:^3.1.6",
18
18
  "@nomicfoundation/hardhat-keystore": "workspace:^3.0.12",
19
- "@nomicfoundation/hardhat-network-helpers": "workspace:^3.0.10",
19
+ "@nomicfoundation/hardhat-network-helpers": "workspace:^3.0.11",
20
20
  "@nomicfoundation/hardhat-node-test-runner": "workspace:^3.0.17",
21
21
  "@nomicfoundation/hardhat-viem": "workspace:^3.0.9",
22
- "@nomicfoundation/hardhat-viem-assertions": "workspace:^3.1.1",
23
- "@nomicfoundation/hardhat-verify": "workspace:^3.0.19",
24
- "@nomicfoundation/ignition-core": "workspace:^3.1.7"
22
+ "@nomicfoundation/hardhat-viem-assertions": "workspace:^3.1.2",
23
+ "@nomicfoundation/hardhat-verify": "workspace:^3.0.21",
24
+ "@nomicfoundation/ignition-core": "workspace:^3.1.8"
25
25
  }
26
26
  }