hardhat 3.4.5 → 3.5.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 (248) hide show
  1. package/CHANGELOG.md +54 -0
  2. package/dist/src/config.d.ts +0 -1
  3. package/dist/src/config.d.ts.map +1 -1
  4. package/dist/src/config.js.map +1 -1
  5. package/dist/src/hre.d.ts +0 -1
  6. package/dist/src/hre.d.ts.map +1 -1
  7. package/dist/src/hre.js.map +1 -1
  8. package/dist/src/index.d.ts +0 -1
  9. package/dist/src/index.d.ts.map +1 -1
  10. package/dist/src/index.js.map +1 -1
  11. package/dist/src/internal/builtin-global-options.d.ts.map +1 -1
  12. package/dist/src/internal/builtin-global-options.js +1 -1
  13. package/dist/src/internal/builtin-global-options.js.map +1 -1
  14. package/dist/src/internal/builtin-plugins/gas-analytics/snapshot-cheatcodes.d.ts +21 -0
  15. package/dist/src/internal/builtin-plugins/gas-analytics/snapshot-cheatcodes.d.ts.map +1 -1
  16. package/dist/src/internal/builtin-plugins/gas-analytics/snapshot-cheatcodes.js +49 -1
  17. package/dist/src/internal/builtin-plugins/gas-analytics/snapshot-cheatcodes.js.map +1 -1
  18. package/dist/src/internal/builtin-plugins/gas-analytics/tasks/solidity-test/task-action.d.ts +2 -1
  19. package/dist/src/internal/builtin-plugins/gas-analytics/tasks/solidity-test/task-action.d.ts.map +1 -1
  20. package/dist/src/internal/builtin-plugins/gas-analytics/tasks/solidity-test/task-action.js +12 -2
  21. package/dist/src/internal/builtin-plugins/gas-analytics/tasks/solidity-test/task-action.js.map +1 -1
  22. package/dist/src/internal/builtin-plugins/network-manager/config-resolution.d.ts.map +1 -1
  23. package/dist/src/internal/builtin-plugins/network-manager/config-resolution.js +9 -2
  24. package/dist/src/internal/builtin-plugins/network-manager/config-resolution.js.map +1 -1
  25. package/dist/src/internal/builtin-plugins/network-manager/edr/edr-constants.d.ts +1 -0
  26. package/dist/src/internal/builtin-plugins/network-manager/edr/edr-constants.d.ts.map +1 -1
  27. package/dist/src/internal/builtin-plugins/network-manager/edr/edr-constants.js +1 -0
  28. package/dist/src/internal/builtin-plugins/network-manager/edr/edr-constants.js.map +1 -1
  29. package/dist/src/internal/builtin-plugins/network-manager/edr/edr-provider.d.ts.map +1 -1
  30. package/dist/src/internal/builtin-plugins/network-manager/edr/edr-provider.js +25 -5
  31. package/dist/src/internal/builtin-plugins/network-manager/edr/edr-provider.js.map +1 -1
  32. package/dist/src/internal/builtin-plugins/network-manager/edr/utils/convert-to-edr.d.ts +16 -0
  33. package/dist/src/internal/builtin-plugins/network-manager/edr/utils/convert-to-edr.d.ts.map +1 -1
  34. package/dist/src/internal/builtin-plugins/network-manager/edr/utils/convert-to-edr.js +28 -1
  35. package/dist/src/internal/builtin-plugins/network-manager/edr/utils/convert-to-edr.js.map +1 -1
  36. package/dist/src/internal/builtin-plugins/network-manager/network-manager.d.ts.map +1 -1
  37. package/dist/src/internal/builtin-plugins/network-manager/network-manager.js +2 -6
  38. package/dist/src/internal/builtin-plugins/network-manager/network-manager.js.map +1 -1
  39. package/dist/src/internal/builtin-plugins/network-manager/type-extensions/config.d.ts +5 -3
  40. package/dist/src/internal/builtin-plugins/network-manager/type-extensions/config.d.ts.map +1 -1
  41. package/dist/src/internal/builtin-plugins/network-manager/type-validation.d.ts.map +1 -1
  42. package/dist/src/internal/builtin-plugins/network-manager/type-validation.js +3 -1
  43. package/dist/src/internal/builtin-plugins/network-manager/type-validation.js.map +1 -1
  44. package/dist/src/internal/builtin-plugins/network-manager/utils/apply-coverage-network-overrides.d.ts +18 -0
  45. package/dist/src/internal/builtin-plugins/network-manager/utils/apply-coverage-network-overrides.d.ts.map +1 -0
  46. package/dist/src/internal/builtin-plugins/network-manager/utils/apply-coverage-network-overrides.js +27 -0
  47. package/dist/src/internal/builtin-plugins/network-manager/utils/apply-coverage-network-overrides.js.map +1 -0
  48. package/dist/src/internal/builtin-plugins/node/json-rpc/handler.js +6 -5
  49. package/dist/src/internal/builtin-plugins/node/json-rpc/handler.js.map +1 -1
  50. package/dist/src/internal/builtin-plugins/solidity/build-system/build-system.d.ts +1 -4
  51. package/dist/src/internal/builtin-plugins/solidity/build-system/build-system.d.ts.map +1 -1
  52. package/dist/src/internal/builtin-plugins/solidity/build-system/build-system.js +1 -11
  53. package/dist/src/internal/builtin-plugins/solidity/build-system/build-system.js.map +1 -1
  54. package/dist/src/internal/builtin-plugins/solidity/build-system/resolver/remapped-npm-packages-graph.d.ts.map +1 -1
  55. package/dist/src/internal/builtin-plugins/solidity/build-system/resolver/remapped-npm-packages-graph.js +1 -1
  56. package/dist/src/internal/builtin-plugins/solidity/build-system/resolver/remapped-npm-packages-graph.js.map +1 -1
  57. package/dist/src/internal/builtin-plugins/solidity/build-system/warning-suppression.d.ts +6 -10
  58. package/dist/src/internal/builtin-plugins/solidity/build-system/warning-suppression.d.ts.map +1 -1
  59. package/dist/src/internal/builtin-plugins/solidity/build-system/warning-suppression.js +54 -43
  60. package/dist/src/internal/builtin-plugins/solidity/build-system/warning-suppression.js.map +1 -1
  61. package/dist/src/internal/builtin-plugins/solidity/constants.d.ts +10 -0
  62. package/dist/src/internal/builtin-plugins/solidity/constants.d.ts.map +1 -1
  63. package/dist/src/internal/builtin-plugins/solidity/constants.js +10 -0
  64. package/dist/src/internal/builtin-plugins/solidity/constants.js.map +1 -1
  65. package/dist/src/internal/builtin-plugins/solidity/hook-handlers/hre.d.ts.map +1 -1
  66. package/dist/src/internal/builtin-plugins/solidity/hook-handlers/hre.js +2 -1
  67. package/dist/src/internal/builtin-plugins/solidity/hook-handlers/hre.js.map +1 -1
  68. package/dist/src/internal/builtin-plugins/solidity/index.d.ts.map +1 -1
  69. package/dist/src/internal/builtin-plugins/solidity/index.js +1 -0
  70. package/dist/src/internal/builtin-plugins/solidity/index.js.map +1 -1
  71. package/dist/src/internal/builtin-plugins/solidity/tasks/compile.d.ts +9 -0
  72. package/dist/src/internal/builtin-plugins/solidity/tasks/compile.d.ts.map +1 -0
  73. package/dist/src/internal/builtin-plugins/solidity/tasks/compile.js +10 -0
  74. package/dist/src/internal/builtin-plugins/solidity/tasks/compile.js.map +1 -0
  75. package/dist/src/internal/builtin-plugins/solidity-test/config.d.ts +4 -3
  76. package/dist/src/internal/builtin-plugins/solidity-test/config.d.ts.map +1 -1
  77. package/dist/src/internal/builtin-plugins/solidity-test/config.js +55 -8
  78. package/dist/src/internal/builtin-plugins/solidity-test/config.js.map +1 -1
  79. package/dist/src/internal/builtin-plugins/solidity-test/eip712/ast-walker.d.ts +58 -0
  80. package/dist/src/internal/builtin-plugins/solidity-test/eip712/ast-walker.d.ts.map +1 -0
  81. package/dist/src/internal/builtin-plugins/solidity-test/eip712/ast-walker.js +226 -0
  82. package/dist/src/internal/builtin-plugins/solidity-test/eip712/ast-walker.js.map +1 -0
  83. package/dist/src/internal/builtin-plugins/solidity-test/eip712/canonicalize.d.ts +29 -0
  84. package/dist/src/internal/builtin-plugins/solidity-test/eip712/canonicalize.d.ts.map +1 -0
  85. package/dist/src/internal/builtin-plugins/solidity-test/eip712/canonicalize.js +244 -0
  86. package/dist/src/internal/builtin-plugins/solidity-test/eip712/canonicalize.js.map +1 -0
  87. package/dist/src/internal/builtin-plugins/solidity-test/eip712/glob.d.ts +7 -0
  88. package/dist/src/internal/builtin-plugins/solidity-test/eip712/glob.d.ts.map +1 -0
  89. package/dist/src/internal/builtin-plugins/solidity-test/eip712/glob.js +204 -0
  90. package/dist/src/internal/builtin-plugins/solidity-test/eip712/glob.js.map +1 -0
  91. package/dist/src/internal/builtin-plugins/solidity-test/eip712/index.d.ts +21 -0
  92. package/dist/src/internal/builtin-plugins/solidity-test/eip712/index.d.ts.map +1 -0
  93. package/dist/src/internal/builtin-plugins/solidity-test/eip712/index.js +77 -0
  94. package/dist/src/internal/builtin-plugins/solidity-test/eip712/index.js.map +1 -0
  95. package/dist/src/internal/builtin-plugins/solidity-test/helpers.d.ts +4 -3
  96. package/dist/src/internal/builtin-plugins/solidity-test/helpers.d.ts.map +1 -1
  97. package/dist/src/internal/builtin-plugins/solidity-test/helpers.js +20 -3
  98. package/dist/src/internal/builtin-plugins/solidity-test/helpers.js.map +1 -1
  99. package/dist/src/internal/builtin-plugins/solidity-test/task-action.d.ts.map +1 -1
  100. package/dist/src/internal/builtin-plugins/solidity-test/task-action.js +5 -1
  101. package/dist/src/internal/builtin-plugins/solidity-test/task-action.js.map +1 -1
  102. package/dist/src/internal/builtin-plugins/solidity-test/test-profiles.d.ts +2 -0
  103. package/dist/src/internal/builtin-plugins/solidity-test/test-profiles.d.ts.map +1 -0
  104. package/dist/src/internal/builtin-plugins/solidity-test/test-profiles.js +2 -0
  105. package/dist/src/internal/builtin-plugins/solidity-test/test-profiles.js.map +1 -0
  106. package/dist/src/internal/builtin-plugins/solidity-test/type-extensions.d.ts +91 -32
  107. package/dist/src/internal/builtin-plugins/solidity-test/type-extensions.d.ts.map +1 -1
  108. package/dist/src/internal/cli/error-handler.d.ts +11 -2
  109. package/dist/src/internal/cli/error-handler.d.ts.map +1 -1
  110. package/dist/src/internal/cli/error-handler.js +72 -46
  111. package/dist/src/internal/cli/error-handler.js.map +1 -1
  112. package/dist/src/internal/cli/init/init.d.ts +31 -6
  113. package/dist/src/internal/cli/init/init.d.ts.map +1 -1
  114. package/dist/src/internal/cli/init/init.js +126 -13
  115. package/dist/src/internal/cli/init/init.js.map +1 -1
  116. package/dist/src/internal/cli/init/package-manager.d.ts +7 -1
  117. package/dist/src/internal/cli/init/package-manager.d.ts.map +1 -1
  118. package/dist/src/internal/cli/init/package-manager.js +14 -2
  119. package/dist/src/internal/cli/init/package-manager.js.map +1 -1
  120. package/dist/src/internal/cli/main.d.ts.map +1 -1
  121. package/dist/src/internal/cli/main.js +42 -2
  122. package/dist/src/internal/cli/main.js.map +1 -1
  123. package/dist/src/internal/cli/telemetry/error-classification/classifier.d.ts +2 -1
  124. package/dist/src/internal/cli/telemetry/error-classification/classifier.d.ts.map +1 -1
  125. package/dist/src/internal/cli/telemetry/error-classification/classifier.js +2 -1
  126. package/dist/src/internal/cli/telemetry/error-classification/classifier.js.map +1 -1
  127. package/dist/src/internal/using-hardhat2-plugin-errors.d.ts.map +1 -1
  128. package/dist/src/internal/using-hardhat2-plugin-errors.js +8 -11
  129. package/dist/src/internal/using-hardhat2-plugin-errors.js.map +1 -1
  130. package/dist/src/types/arguments.d.ts +1 -0
  131. package/dist/src/types/arguments.d.ts.map +1 -1
  132. package/dist/src/types/arguments.js +1 -0
  133. package/dist/src/types/arguments.js.map +1 -1
  134. package/dist/src/types/artifacts.d.ts +1 -0
  135. package/dist/src/types/artifacts.d.ts.map +1 -1
  136. package/dist/src/types/artifacts.js +1 -1
  137. package/dist/src/types/artifacts.js.map +1 -1
  138. package/dist/src/types/builtin-plugin-type-extensions.d.ts +2 -0
  139. package/dist/src/types/builtin-plugin-type-extensions.d.ts.map +1 -0
  140. package/dist/src/types/builtin-plugin-type-extensions.js +2 -0
  141. package/dist/src/types/builtin-plugin-type-extensions.js.map +1 -0
  142. package/dist/src/types/config.d.ts +1 -0
  143. package/dist/src/types/config.d.ts.map +1 -1
  144. package/dist/src/types/config.js +1 -1
  145. package/dist/src/types/config.js.map +1 -1
  146. package/dist/src/types/global-options.d.ts +1 -0
  147. package/dist/src/types/global-options.d.ts.map +1 -1
  148. package/dist/src/types/global-options.js +1 -1
  149. package/dist/src/types/global-options.js.map +1 -1
  150. package/dist/src/types/hooks.d.ts +1 -0
  151. package/dist/src/types/hooks.d.ts.map +1 -1
  152. package/dist/src/types/hooks.js +1 -1
  153. package/dist/src/types/hooks.js.map +1 -1
  154. package/dist/src/types/hre.d.ts +1 -0
  155. package/dist/src/types/hre.d.ts.map +1 -1
  156. package/dist/src/types/hre.js +1 -1
  157. package/dist/src/types/hre.js.map +1 -1
  158. package/dist/src/types/index.d.ts +1 -0
  159. package/dist/src/types/index.d.ts.map +1 -1
  160. package/dist/src/types/index.js +1 -0
  161. package/dist/src/types/index.js.map +1 -1
  162. package/dist/src/types/network.d.ts +1 -0
  163. package/dist/src/types/network.d.ts.map +1 -1
  164. package/dist/src/types/network.js +1 -1
  165. package/dist/src/types/network.js.map +1 -1
  166. package/dist/src/types/plugins.d.ts +1 -1
  167. package/dist/src/types/plugins.d.ts.map +1 -1
  168. package/dist/src/types/plugins.js +1 -1
  169. package/dist/src/types/plugins.js.map +1 -1
  170. package/dist/src/types/providers.d.ts +1 -0
  171. package/dist/src/types/providers.d.ts.map +1 -1
  172. package/dist/src/types/providers.js +1 -1
  173. package/dist/src/types/providers.js.map +1 -1
  174. package/dist/src/types/solidity.d.ts +1 -0
  175. package/dist/src/types/solidity.d.ts.map +1 -1
  176. package/dist/src/types/solidity.js +1 -0
  177. package/dist/src/types/solidity.js.map +1 -1
  178. package/dist/src/types/tasks.d.ts +1 -0
  179. package/dist/src/types/tasks.d.ts.map +1 -1
  180. package/dist/src/types/tasks.js +1 -0
  181. package/dist/src/types/tasks.js.map +1 -1
  182. package/dist/src/types/test.d.ts +1 -0
  183. package/dist/src/types/test.d.ts.map +1 -1
  184. package/dist/src/types/test.js +1 -1
  185. package/dist/src/types/test.js.map +1 -1
  186. package/dist/src/types/user-interruptions.d.ts +1 -0
  187. package/dist/src/types/user-interruptions.d.ts.map +1 -1
  188. package/dist/src/types/user-interruptions.js +1 -1
  189. package/dist/src/types/user-interruptions.js.map +1 -1
  190. package/package.json +12 -11
  191. package/src/config.ts +0 -2
  192. package/src/hre.ts +0 -3
  193. package/src/index.ts +0 -3
  194. package/src/internal/builtin-global-options.ts +2 -1
  195. package/src/internal/builtin-plugins/gas-analytics/snapshot-cheatcodes.ts +90 -1
  196. package/src/internal/builtin-plugins/gas-analytics/tasks/solidity-test/task-action.ts +24 -2
  197. package/src/internal/builtin-plugins/network-manager/config-resolution.ts +11 -3
  198. package/src/internal/builtin-plugins/network-manager/edr/edr-constants.ts +2 -0
  199. package/src/internal/builtin-plugins/network-manager/edr/edr-provider.ts +38 -8
  200. package/src/internal/builtin-plugins/network-manager/edr/utils/convert-to-edr.ts +43 -1
  201. package/src/internal/builtin-plugins/network-manager/network-manager.ts +5 -6
  202. package/src/internal/builtin-plugins/network-manager/type-extensions/config.ts +5 -3
  203. package/src/internal/builtin-plugins/network-manager/type-validation.ts +7 -1
  204. package/src/internal/builtin-plugins/network-manager/utils/apply-coverage-network-overrides.ts +32 -0
  205. package/src/internal/builtin-plugins/node/json-rpc/handler.ts +7 -5
  206. package/src/internal/builtin-plugins/solidity/build-system/build-system.ts +2 -15
  207. package/src/internal/builtin-plugins/solidity/build-system/resolver/remapped-npm-packages-graph.ts +1 -2
  208. package/src/internal/builtin-plugins/solidity/build-system/warning-suppression.ts +81 -59
  209. package/src/internal/builtin-plugins/solidity/constants.ts +11 -0
  210. package/src/internal/builtin-plugins/solidity/hook-handlers/hre.ts +2 -1
  211. package/src/internal/builtin-plugins/solidity/index.ts +1 -0
  212. package/src/internal/builtin-plugins/solidity/tasks/compile.ts +12 -0
  213. package/src/internal/builtin-plugins/solidity-test/config.ts +85 -12
  214. package/src/internal/builtin-plugins/solidity-test/eip712/ast-walker.ts +324 -0
  215. package/src/internal/builtin-plugins/solidity-test/eip712/canonicalize.ts +317 -0
  216. package/src/internal/builtin-plugins/solidity-test/eip712/glob.ts +225 -0
  217. package/src/internal/builtin-plugins/solidity-test/eip712/index.ts +120 -0
  218. package/src/internal/builtin-plugins/solidity-test/helpers.ts +28 -4
  219. package/src/internal/builtin-plugins/solidity-test/task-action.ts +12 -1
  220. package/src/internal/builtin-plugins/solidity-test/test-profiles.ts +1 -0
  221. package/src/internal/builtin-plugins/solidity-test/type-extensions.ts +100 -33
  222. package/src/internal/cli/error-handler.ts +103 -72
  223. package/src/internal/cli/init/init.ts +203 -16
  224. package/src/internal/cli/init/package-manager.ts +18 -1
  225. package/src/internal/cli/main.ts +65 -2
  226. package/src/internal/cli/telemetry/error-classification/classifier.ts +2 -1
  227. package/src/internal/using-hardhat2-plugin-errors.ts +8 -11
  228. package/src/types/arguments.ts +2 -0
  229. package/src/types/artifacts.ts +2 -0
  230. package/src/types/builtin-plugin-type-extensions.ts +15 -0
  231. package/src/types/config.ts +2 -0
  232. package/src/types/global-options.ts +2 -0
  233. package/src/types/hooks.ts +2 -0
  234. package/src/types/hre.ts +2 -0
  235. package/src/types/index.ts +2 -0
  236. package/src/types/network.ts +2 -0
  237. package/src/types/plugins.ts +1 -2
  238. package/src/types/providers.ts +2 -0
  239. package/src/types/solidity.ts +2 -0
  240. package/src/types/tasks.ts +2 -0
  241. package/src/types/test.ts +2 -0
  242. package/src/types/user-interruptions.ts +2 -0
  243. package/templates/hardhat-3/01-node-test-runner-viem/package.json +11 -11
  244. package/templates/hardhat-3/01-node-test-runner-viem/tsconfig.json +4 -7
  245. package/templates/hardhat-3/02-mocha-ethers/package.json +13 -13
  246. package/templates/hardhat-3/02-mocha-ethers/tsconfig.json +4 -7
  247. package/templates/hardhat-3/03-minimal/package.json +2 -2
  248. package/templates/hardhat-3/03-minimal/tsconfig.json +4 -7
@@ -0,0 +1,225 @@
1
+ // The same patterns are reused for every source file, so compile each one once.
2
+ const compiledGlobCache = new Map<string, RegExp>();
3
+
4
+ /**
5
+ * Returns true when `path` should be included given user-supplied include and
6
+ * exclude glob lists. `include` is the gate: an empty `include` matches
7
+ * nothing. `exclude` then narrows the included set.
8
+ */
9
+ export function isPathSelected(
10
+ path: string,
11
+ include: string[],
12
+ exclude: string[],
13
+ ): boolean {
14
+ if (include.length === 0) {
15
+ return false;
16
+ }
17
+
18
+ if (!matchesAny(path, include)) {
19
+ return false;
20
+ }
21
+
22
+ if (exclude.length > 0 && matchesAny(path, exclude)) {
23
+ return false;
24
+ }
25
+
26
+ return true;
27
+ }
28
+
29
+ /**
30
+ * Returns true if `value` matches at least one of the given glob patterns.
31
+ */
32
+ function matchesAny(value: string, patterns: string[]): boolean {
33
+ for (const pattern of patterns) {
34
+ if (getCompiledGlob(pattern).test(value)) {
35
+ return true;
36
+ }
37
+ }
38
+
39
+ return false;
40
+ }
41
+
42
+ /**
43
+ * Compiles a glob pattern into a regular expression. Supports `*`, `**`,
44
+ * `?`, `[abc]` (including `[a-z]` ranges and `[!abc]` / `[^abc]` negation),
45
+ * and `{a,b,c}` alternation.
46
+ */
47
+ function globToRegExp(pattern: string): RegExp {
48
+ return new RegExp(`^${translateGlob(pattern)}$`);
49
+ }
50
+
51
+ function translateGlob(pattern: string): string {
52
+ let regex = "";
53
+ let i = 0;
54
+ while (i < pattern.length) {
55
+ const c = pattern[i];
56
+
57
+ if (c === "*") {
58
+ if (pattern[i + 1] === "*") {
59
+ // `**` as a full path segment matches zero or more directories,
60
+ // e.g. `**/x.sol` matches both `x.sol` and `a/b/x.sol`.
61
+ const afterSlash = i === 0 || pattern[i - 1] === "/";
62
+ const beforeSlash = pattern[i + 2] === "/";
63
+ if (afterSlash && beforeSlash) {
64
+ regex += "(?:.*/)?";
65
+ i += 3;
66
+ } else {
67
+ regex += ".*";
68
+ i += 2;
69
+ }
70
+ } else {
71
+ regex += "[^/]*";
72
+ i += 1;
73
+ }
74
+ } else if (c === "?") {
75
+ regex += "[^/]";
76
+ i += 1;
77
+ } else if (c === "[") {
78
+ const end = findCharClassEnd(pattern, i);
79
+ if (end !== -1) {
80
+ regex += translateCharClass(pattern.slice(i + 1, end));
81
+ i = end + 1;
82
+ continue;
83
+ }
84
+
85
+ regex += "\\[";
86
+ i += 1;
87
+ } else if (c === "{") {
88
+ const end = findBraceEnd(pattern, i);
89
+ if (end !== -1) {
90
+ const alternatives = splitBraceAlternatives(
91
+ pattern.slice(i + 1, end),
92
+ ).map(translateGlob);
93
+
94
+ regex += `(?:${alternatives.join("|")})`;
95
+ i = end + 1;
96
+
97
+ continue;
98
+ }
99
+
100
+ regex += "\\{";
101
+ i += 1;
102
+ } else if (/[.+^$()|\\\]}]/.test(c)) {
103
+ regex += `\\${c}`;
104
+ i += 1;
105
+ } else {
106
+ regex += c;
107
+ i += 1;
108
+ }
109
+ }
110
+
111
+ return regex;
112
+ }
113
+
114
+ /**
115
+ * Returns the index of the `]` that closes the character class opened at
116
+ * `start`, or -1 if none is found. E.g. for `a[bc]d` starting at 1, returns 4.
117
+ */
118
+ function findCharClassEnd(pattern: string, start: number): number {
119
+ for (let i = start + 1; i < pattern.length; i++) {
120
+ if (pattern[i] === "]") {
121
+ return i;
122
+ }
123
+ }
124
+
125
+ return -1;
126
+ }
127
+
128
+ /**
129
+ * Returns the index of the `}` that closes the brace group opened at `start`,
130
+ * handling nested groups and skipping character classes, or -1 if unterminated.
131
+ * E.g. `{a,{b,c}}` returns the outer `}`; `{a[}]b}` skips the bracketed `}`.
132
+ */
133
+ function findBraceEnd(pattern: string, start: number): number {
134
+ let depth = 1;
135
+ let i = start + 1;
136
+ while (i < pattern.length) {
137
+ const c = pattern[i];
138
+ if (c === "{") {
139
+ depth += 1;
140
+ } else if (c === "}") {
141
+ depth -= 1;
142
+ if (depth === 0) {
143
+ return i;
144
+ }
145
+ } else if (c === "[") {
146
+ const end = findCharClassEnd(pattern, i);
147
+ if (end !== -1) {
148
+ i = end;
149
+ }
150
+ }
151
+
152
+ i += 1;
153
+ }
154
+
155
+ return -1;
156
+ }
157
+
158
+ /**
159
+ * Splits a brace group's body on top-level commas, leaving commas inside
160
+ * nested braces or character classes untouched. E.g. `a,{b,c},[d,e]` →
161
+ * `["a", "{b,c}", "[d,e]"]`.
162
+ */
163
+ function splitBraceAlternatives(inside: string): string[] {
164
+ const result: string[] = [];
165
+ let depth = 0;
166
+ let start = 0;
167
+ let i = 0;
168
+ while (i < inside.length) {
169
+ const c = inside[i];
170
+
171
+ if (c === "{") {
172
+ depth += 1;
173
+ } else if (c === "}") {
174
+ depth -= 1;
175
+ } else if (c === "[") {
176
+ const end = findCharClassEnd(inside, i);
177
+ if (end !== -1) {
178
+ i = end;
179
+ }
180
+ } else if (c === "," && depth === 0) {
181
+ result.push(inside.slice(start, i));
182
+ start = i + 1;
183
+ }
184
+
185
+ i += 1;
186
+ }
187
+
188
+ result.push(inside.slice(start));
189
+ return result;
190
+ }
191
+
192
+ /**
193
+ * Translates a glob character class body into a regex character class.
194
+ * E.g. `Mm` → `[Mm]`, `!ab` → `[^ab]`, `a-z` → `[a-z]`.
195
+ */
196
+ function translateCharClass(content: string): string {
197
+ let negated = false;
198
+ let body = content;
199
+ if (body.startsWith("!") || body.startsWith("^")) {
200
+ negated = true;
201
+ body = body.slice(1);
202
+ }
203
+
204
+ let escaped = "";
205
+ for (const ch of body) {
206
+ if (ch === "\\" || ch === "]") {
207
+ escaped += `\\${ch}`;
208
+ } else {
209
+ escaped += ch;
210
+ }
211
+ }
212
+
213
+ return `(?!/)[${negated ? "^" : ""}${escaped}]`;
214
+ }
215
+
216
+ function getCompiledGlob(pattern: string): RegExp {
217
+ let compiled = compiledGlobCache.get(pattern);
218
+
219
+ if (compiled === undefined) {
220
+ compiled = globToRegExp(pattern);
221
+ compiledGlobCache.set(pattern, compiled);
222
+ }
223
+
224
+ return compiled;
225
+ }
@@ -0,0 +1,120 @@
1
+ import type { CollectedStruct } from "./ast-walker.js";
2
+ import type { SolidityBuildInfoOutput } from "../../../../types/solidity/solidity-artifacts.js";
3
+ import type { BuildInfoAndOutput } from "../edr-artifacts.js";
4
+
5
+ import {
6
+ bytesIncludesUtf8String,
7
+ bytesToUtf8String,
8
+ } from "@nomicfoundation/hardhat-utils/bytes";
9
+
10
+ import { HARDHAT_PROJECT_INPUT_SOURCE_NAME_ROOT } from "../../solidity/constants.js";
11
+
12
+ import {
13
+ buildUserDefinedValueTypeIndex,
14
+ extractStructsFromAst,
15
+ } from "./ast-walker.js";
16
+ import { canonicalizeStructs } from "./canonicalize.js";
17
+ import { isPathSelected } from "./glob.js";
18
+
19
+ export interface Eip712TypesConfig {
20
+ include: string[];
21
+ exclude: string[];
22
+ }
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
+ /**
30
+ * Walks every compiled source's AST, extracts every struct definition, and
31
+ * returns the flat list of canonical EIP-712 type strings expected by EDR's
32
+ * `eip712CanonicalTypes` config field. Only structs from sources matching
33
+ * `include`/`exclude` are emitted; non-selected sources still feed the dep
34
+ * graph so cross-file deps inline correctly.
35
+ *
36
+ * `inputToUserSource` maps solc input source names to user source names; it's
37
+ * built by the caller from the artifact set so we don't pay to parse every
38
+ * build info just to recover that mapping.
39
+ *
40
+ * When `include` is empty/unset the feature is off: collection short-circuits
41
+ * and returns an empty list without parsing any build info.
42
+ */
43
+ export function collectEip712CanonicalTypes(
44
+ buildInfosAndOutputs: BuildInfoAndOutput[],
45
+ inputToUserSource: ReadonlyMap<string, string>,
46
+ config: Eip712TypesConfig,
47
+ ): string[] {
48
+ const { include, exclude } = config;
49
+
50
+ if (include.length === 0) {
51
+ return [];
52
+ }
53
+
54
+ const collected: CollectedStruct[] = [];
55
+ const selectedNames = new Set<string>();
56
+
57
+ for (const { buildInfo, output } of buildInfosAndOutputs) {
58
+ // Byte-level fast path: a build info whose source bytes don't contain
59
+ // `struct ` can't define any EIP-712 type, so skip JSON-parsing its output.
60
+ if (!bytesIncludesUtf8String(buildInfo, "struct ")) {
61
+ continue;
62
+ }
63
+
64
+ const parsedOutput: SolidityBuildInfoOutput = JSON.parse(
65
+ bytesToUtf8String(output),
66
+ );
67
+
68
+ const sources = parsedOutput.output.sources;
69
+ if (sources === undefined) {
70
+ continue;
71
+ }
72
+
73
+ // Two constraints determine the index's scope:
74
+ //
75
+ // 1. Per build info, not pooled across them. solc assigns node ids
76
+ // fresh in each compilation, so the same numeric id can mean
77
+ // different user-defined value types in different builds. Pooling
78
+ // would let one compilation's definition silently overwrite
79
+ // another's at the same key, mis-resolving `referencedDeclaration`.
80
+ // See the test "scopes user-defined value type resolution per build
81
+ // info when node ids collide" for a repro.
82
+ //
83
+ // 2. Whole build info, not narrowed to a subset of sources. A struct
84
+ // member's `referencedDeclaration` can point at a user-defined
85
+ // value type defined in any source within the same compilation, so
86
+ // the index must cover every source in the build.
87
+ const userDefinedValueTypeI = buildUserDefinedValueTypeIndex(
88
+ Object.values(sources).map((s) => s.ast),
89
+ );
90
+
91
+ 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
+ }
101
+
102
+ // Collect every source so non-selected files can serve as dep targets;
103
+ // selection is enforced at emit time via `selectedNames`.
104
+ const structs = extractStructsFromAst(
105
+ source.ast,
106
+ userSourceName,
107
+ userDefinedValueTypeI,
108
+ );
109
+ collected.push(...structs);
110
+
111
+ if (isPathSelected(userSourceName, include, exclude)) {
112
+ for (const s of structs) {
113
+ selectedNames.add(s.name);
114
+ }
115
+ }
116
+ }
117
+ }
118
+
119
+ return canonicalizeStructs(collected, selectedNames);
120
+ }
@@ -1,6 +1,6 @@
1
1
  import type { Abi } from "../../../types/artifacts.js";
2
2
  import type { ChainType } from "../../../types/network.js";
3
- import type { SolidityTestConfig } from "../../../types/test.js";
3
+ import type { SolidityTestProfileConfig } from "../../../types/test.js";
4
4
  import type {
5
5
  SolidityTestRunnerConfigArgs,
6
6
  PathPermission,
@@ -19,6 +19,7 @@ import {
19
19
  opHardforkFromString,
20
20
  l1HardforkFromString,
21
21
  } from "@nomicfoundation/edr";
22
+ import { toBigInt } from "@nomicfoundation/hardhat-utils/bigint";
22
23
  import { hexStringToBytes } from "@nomicfoundation/hardhat-utils/hex";
23
24
 
24
25
  import { DEFAULT_VERBOSITY, OPTIMISM_CHAIN_TYPE } from "../../constants.js";
@@ -32,12 +33,13 @@ interface SolidityTestConfigParams {
32
33
  chainType: ChainType;
33
34
  projectRoot: string;
34
35
  hardfork?: string;
35
- config: SolidityTestConfig;
36
+ config: Omit<SolidityTestProfileConfig, "eip712Types">;
36
37
  verbosity: number;
37
38
  observability?: ObservabilityConfig;
38
39
  testPattern?: string;
39
40
  generateGasReport: boolean;
40
41
  testFunctionOverrides?: TestFunctionOverride[];
42
+ eip712CanonicalTypes?: string[];
41
43
  }
42
44
 
43
45
  export async function solidityTestConfigToSolidityTestRunnerConfigArgs({
@@ -50,6 +52,7 @@ export async function solidityTestConfigToSolidityTestRunnerConfigArgs({
50
52
  testPattern,
51
53
  generateGasReport,
52
54
  testFunctionOverrides,
55
+ eip712CanonicalTypes,
53
56
  }: SolidityTestConfigParams): Promise<SolidityTestRunnerConfigArgs> {
54
57
  const fsPermissions: PathPermission[] | undefined = [
55
58
  config.fsPermissions?.readWriteFile?.map((p) => ({
@@ -98,8 +101,18 @@ export async function solidityTestConfigToSolidityTestRunnerConfigArgs({
98
101
  const includeTraces = verbosityToIncludeTraces(verbosity);
99
102
 
100
103
  const blockGasLimit =
101
- config.blockGasLimit === false ? undefined : config.blockGasLimit;
102
- const disableBlockGasLimit = config.blockGasLimit === false;
104
+ typeof config.blockGasLimit === "number" ||
105
+ typeof config.blockGasLimit === "bigint"
106
+ ? toBigInt(config.blockGasLimit)
107
+ : undefined;
108
+ const disableBlockGasLimit = blockGasLimit === undefined;
109
+
110
+ const transactionGasCap =
111
+ typeof config.transactionGasCap === "number" ||
112
+ typeof config.transactionGasCap === "bigint"
113
+ ? toBigInt(config.transactionGasCap)
114
+ : undefined;
115
+ const disableTransactionGasCap = transactionGasCap === undefined;
103
116
 
104
117
  const blockDifficulty = config.prevRandao;
105
118
 
@@ -136,6 +149,8 @@ export async function solidityTestConfigToSolidityTestRunnerConfigArgs({
136
149
  includeTraces,
137
150
  blockGasLimit,
138
151
  disableBlockGasLimit,
152
+ transactionGasCap,
153
+ disableTransactionGasCap,
139
154
  blockDifficulty,
140
155
  ethRpcUrl,
141
156
  forkBlockNumber,
@@ -145,15 +160,24 @@ export async function solidityTestConfigToSolidityTestRunnerConfigArgs({
145
160
  ? CollectStackTraces.Always
146
161
  : CollectStackTraces.OnFailure,
147
162
  testFunctionOverrides,
163
+ eip712CanonicalTypes,
148
164
  };
149
165
  }
150
166
 
151
167
  export function isTestSuiteArtifact(artifact: Artifact): boolean {
168
+ const bytecode = artifact.contract.bytecode;
169
+
170
+ // Skip abstract contracts and interfaces i.e. those with no bytecode
171
+ if (bytecode === "" || bytecode === "0x" || bytecode === undefined) {
172
+ return false;
173
+ }
174
+
152
175
  const abi: Abi = JSON.parse(artifact.contract.abi);
153
176
  return abi.some(({ type, name }) => {
154
177
  if (type === "function" && typeof name === "string") {
155
178
  return name.startsWith("test") || name.startsWith("invariant");
156
179
  }
180
+
157
181
  return false;
158
182
  });
159
183
  }
@@ -35,6 +35,7 @@ import {
35
35
  buildEdrArtifactsWithMetadata,
36
36
  getBuildInfosAndOutputs,
37
37
  } from "./edr-artifacts.js";
38
+ import { collectEip712CanonicalTypes } from "./eip712/index.js";
38
39
  import {
39
40
  isTestSuiteArtifact,
40
41
  warnDeprecatedTestFail,
@@ -43,6 +44,7 @@ import {
43
44
  import { getTestFunctionOverrides } from "./inline-config/index.js";
44
45
  import { testReporter } from "./reporter.js";
45
46
  import { run } from "./runner.js";
47
+ import { DEFAULT_TEST_PROFILE } from "./test-profiles.js";
46
48
 
47
49
  interface TestActionArguments {
48
50
  testFiles: string[];
@@ -200,7 +202,9 @@ const runSolidityTests: NewTaskActionFunction<TestActionArguments> = async (
200
202
  let includesFailures = false;
201
203
  let includesErrors = false;
202
204
 
203
- const solidityTestConfig = hre.config.test.solidity;
205
+ const { eip712Types, ...solidityTestConfig } =
206
+ hre.config.test.solidity.profiles[DEFAULT_TEST_PROFILE];
207
+
204
208
  let observabilityConfig: ObservabilityConfig | undefined;
205
209
  if (hre.globalOptions.coverage) {
206
210
  const coverage = getCoverageManager(hre);
@@ -232,6 +236,12 @@ const runSolidityTests: NewTaskActionFunction<TestActionArguments> = async (
232
236
  allBuildInfosAndOutputs,
233
237
  );
234
238
 
239
+ const eip712CanonicalTypes = collectEip712CanonicalTypes(
240
+ allBuildInfosAndOutputs,
241
+ sourceNameToUserSourceName,
242
+ eip712Types,
243
+ );
244
+
235
245
  const testRunnerConfig =
236
246
  await solidityTestConfigToSolidityTestRunnerConfigArgs({
237
247
  chainType,
@@ -245,6 +255,7 @@ const runSolidityTests: NewTaskActionFunction<TestActionArguments> = async (
245
255
  hre.globalOptions.gasStats ||
246
256
  hre.globalOptions.gasStatsJson !== undefined,
247
257
  testFunctionOverrides,
258
+ eip712CanonicalTypes,
248
259
  });
249
260
  const tracingConfig: TracingConfigWithBuffers = {
250
261
  buildInfos: allBuildInfosAndOutputs.map(({ buildInfo, output }) => ({
@@ -0,0 +1 @@
1
+ export const DEFAULT_TEST_PROFILE = "default";
@@ -14,7 +14,28 @@ declare module "../../../types/config.js" {
14
14
  }
15
15
 
16
16
  declare module "../../../types/test.js" {
17
- export interface SolidityTestFuzzConfigBase {
17
+ export interface SolidityTestFsPermissionsUserConfig {
18
+ readWriteFile?: string[];
19
+ readFile?: string[];
20
+ writeFile?: string[];
21
+ dangerouslyReadWriteDirectory?: string[];
22
+ readDirectory?: string[];
23
+ dangerouslyWriteDirectory?: string[];
24
+ }
25
+
26
+ export interface SolidityTestInvariantUserConfig {
27
+ failurePersistDir?: string;
28
+ runs?: number;
29
+ depth?: number;
30
+ failOnRevert?: boolean;
31
+ callOverride?: boolean;
32
+ dictionaryWeight?: number;
33
+ includeStorage?: boolean;
34
+ includePushBytes?: boolean;
35
+ shrinkRunLimit?: number;
36
+ }
37
+
38
+ export interface SolidityTestFuzzUserConfig {
18
39
  failurePersistDir?: string;
19
40
  failurePersistFile?: string;
20
41
  runs?: number;
@@ -26,19 +47,14 @@ declare module "../../../types/test.js" {
26
47
  showLogs?: boolean;
27
48
  }
28
49
 
29
- export interface SolidityTestFuzzConfig extends SolidityTestFuzzConfigBase {
30
- seed: string;
50
+ export interface SolidityTestForkingUserConfig {
51
+ url?: SensitiveString;
52
+ blockNumber?: number | bigint;
53
+ rpcEndpoints?: Record<string, SensitiveString>;
31
54
  }
32
55
 
33
- export interface SolidityTestConfigBase {
34
- fsPermissions?: {
35
- readWriteFile?: string[];
36
- readFile?: string[];
37
- writeFile?: string[];
38
- dangerouslyReadWriteDirectory?: string[];
39
- readDirectory?: string[];
40
- dangerouslyWriteDirectory?: string[];
41
- };
56
+ export interface SolidityTestProfileUserConfig {
57
+ fsPermissions?: SolidityTestFsPermissionsUserConfig;
42
58
  isolate?: boolean;
43
59
  ffi?: boolean;
44
60
  allowInternalExpectRevert?: boolean;
@@ -50,46 +66,97 @@ declare module "../../../types/test.js" {
50
66
  blockTimestamp?: bigint;
51
67
  prevRandao?: bigint;
52
68
  gasLimit?: bigint;
53
- blockGasLimit?: bigint | false;
54
-
55
- fuzz?: SolidityTestFuzzConfigBase;
56
- invariant?: {
57
- failurePersistDir?: string;
58
- runs?: number;
59
- depth?: number;
60
- failOnRevert?: boolean;
61
- callOverride?: boolean;
62
- dictionaryWeight?: number;
63
- includeStorage?: boolean;
64
- includePushBytes?: boolean;
65
- shrinkRunLimit?: number;
69
+ blockGasLimit?: number | bigint | false;
70
+ transactionGasCap?: number | bigint | false;
71
+ fuzz?: SolidityTestFuzzUserConfig;
72
+ invariant?: SolidityTestInvariantUserConfig;
73
+ forking?: SolidityTestForkingUserConfig;
74
+ eip712Types?: {
75
+ include?: string[];
76
+ exclude?: string[];
66
77
  };
67
78
  }
68
79
 
69
- export interface SolidityTestForkingUserConfig {
70
- url?: SensitiveString;
71
- blockNumber?: number | bigint;
72
- rpcEndpoints?: Record<string, SensitiveString>;
80
+ export interface SolidityTestProfilesUserConfig {
81
+ profiles: Record<string, SolidityTestProfileUserConfig>;
73
82
  }
74
83
 
75
- export interface SolidityTestUserConfig extends SolidityTestConfigBase {
76
- forking?: SolidityTestForkingUserConfig;
77
- }
84
+ export type SolidityTestUserConfig =
85
+ | SolidityTestProfileUserConfig
86
+ | SolidityTestProfilesUserConfig;
78
87
 
79
88
  export interface HardhatTestUserConfig {
80
89
  solidity?: SolidityTestUserConfig;
81
90
  }
82
91
 
92
+ export interface SolidityTestFsPermissionsConfig {
93
+ readWriteFile?: string[];
94
+ readFile?: string[];
95
+ writeFile?: string[];
96
+ dangerouslyReadWriteDirectory?: string[];
97
+ readDirectory?: string[];
98
+ dangerouslyWriteDirectory?: string[];
99
+ }
100
+
101
+ export interface SolidityTestInvariantConfig {
102
+ failurePersistDir?: string;
103
+ runs?: number;
104
+ depth?: number;
105
+ failOnRevert?: boolean;
106
+ callOverride?: boolean;
107
+ dictionaryWeight?: number;
108
+ includeStorage?: boolean;
109
+ includePushBytes?: boolean;
110
+ shrinkRunLimit?: number;
111
+ }
112
+
113
+ export interface SolidityTestFuzzConfig {
114
+ failurePersistDir?: string;
115
+ failurePersistFile?: string;
116
+ runs?: number;
117
+ maxTestRejects?: number;
118
+ seed: string;
119
+ dictionaryWeight?: number;
120
+ includeStorage?: boolean;
121
+ includePushBytes?: boolean;
122
+ showLogs?: boolean;
123
+ }
124
+
83
125
  export interface SolidityTestForkingConfig {
84
126
  url?: ResolvedConfigurationVariable;
85
127
  blockNumber?: bigint;
86
128
  rpcEndpoints?: Record<string, ResolvedConfigurationVariable>;
87
129
  }
88
130
 
89
- export interface SolidityTestConfig extends SolidityTestConfigBase {
131
+ export interface SolidityTestProfileConfig {
132
+ rpcCachePath: string;
133
+ fsPermissions?: SolidityTestFsPermissionsConfig;
134
+ isolate?: boolean;
135
+ ffi?: boolean;
136
+ allowInternalExpectRevert?: boolean;
137
+ from?: string; // 0x-prefixed hex string
138
+ txOrigin?: string; // 0x-prefixed hex string
139
+ initialBalance?: bigint;
140
+ blockBaseFeePerGas?: bigint;
141
+ coinbase?: string; // 0x-prefixed hex string
142
+ blockTimestamp?: bigint;
143
+ prevRandao?: bigint;
144
+ gasLimit?: bigint;
145
+ blockGasLimit?: number | bigint | false;
146
+ transactionGasCap?: number | bigint | false;
90
147
  fuzz: SolidityTestFuzzConfig;
148
+ invariant?: SolidityTestInvariantConfig;
91
149
  forking?: SolidityTestForkingConfig;
150
+ eip712Types: {
151
+ include: string[];
152
+ exclude: string[];
153
+ };
92
154
  }
155
+
156
+ export interface SolidityTestConfig {
157
+ profiles: Record<string, SolidityTestProfileConfig>;
158
+ }
159
+
93
160
  export interface HardhatTestConfig {
94
161
  solidity: SolidityTestConfig;
95
162
  }