hardhat 3.4.4 → 3.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (333) hide show
  1. package/CHANGELOG.md +61 -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 +0 -3
  5. package/dist/src/config.js.map +1 -1
  6. package/dist/src/hre.d.ts +0 -1
  7. package/dist/src/hre.d.ts.map +1 -1
  8. package/dist/src/hre.js +0 -3
  9. package/dist/src/hre.js.map +1 -1
  10. package/dist/src/index.d.ts +0 -1
  11. package/dist/src/index.d.ts.map +1 -1
  12. package/dist/src/index.js +0 -3
  13. package/dist/src/index.js.map +1 -1
  14. package/dist/src/internal/builtin-global-options.d.ts.map +1 -1
  15. package/dist/src/internal/builtin-global-options.js +1 -1
  16. package/dist/src/internal/builtin-global-options.js.map +1 -1
  17. package/dist/src/internal/builtin-plugins/artifacts/index.d.ts +1 -1
  18. package/dist/src/internal/builtin-plugins/artifacts/index.d.ts.map +1 -1
  19. package/dist/src/internal/builtin-plugins/artifacts/index.js +0 -1
  20. package/dist/src/internal/builtin-plugins/artifacts/index.js.map +1 -1
  21. package/dist/src/internal/builtin-plugins/clean/index.d.ts +1 -1
  22. package/dist/src/internal/builtin-plugins/clean/index.d.ts.map +1 -1
  23. package/dist/src/internal/builtin-plugins/clean/index.js +0 -1
  24. package/dist/src/internal/builtin-plugins/clean/index.js.map +1 -1
  25. package/dist/src/internal/builtin-plugins/clean/type-extensions.d.ts +1 -1
  26. package/dist/src/internal/builtin-plugins/clean/type-extensions.d.ts.map +1 -1
  27. package/dist/src/internal/builtin-plugins/clean/type-extensions.js +1 -1
  28. package/dist/src/internal/builtin-plugins/clean/type-extensions.js.map +1 -1
  29. package/dist/src/internal/builtin-plugins/coverage/hook-handlers/solidity.d.ts.map +1 -1
  30. package/dist/src/internal/builtin-plugins/coverage/hook-handlers/solidity.js +7 -10
  31. package/dist/src/internal/builtin-plugins/coverage/hook-handlers/solidity.js.map +1 -1
  32. package/dist/src/internal/builtin-plugins/coverage/index.d.ts +1 -1
  33. package/dist/src/internal/builtin-plugins/coverage/index.d.ts.map +1 -1
  34. package/dist/src/internal/builtin-plugins/coverage/index.js +0 -1
  35. package/dist/src/internal/builtin-plugins/coverage/index.js.map +1 -1
  36. package/dist/src/internal/builtin-plugins/coverage/instrumentation.d.ts +1 -4
  37. package/dist/src/internal/builtin-plugins/coverage/instrumentation.d.ts.map +1 -1
  38. package/dist/src/internal/builtin-plugins/coverage/instrumentation.js +2 -4
  39. package/dist/src/internal/builtin-plugins/coverage/instrumentation.js.map +1 -1
  40. package/dist/src/internal/builtin-plugins/coverage/type-extensions.d.ts +1 -1
  41. package/dist/src/internal/builtin-plugins/coverage/type-extensions.d.ts.map +1 -1
  42. package/dist/src/internal/builtin-plugins/coverage/type-extensions.js +1 -1
  43. package/dist/src/internal/builtin-plugins/coverage/type-extensions.js.map +1 -1
  44. package/dist/src/internal/builtin-plugins/gas-analytics/index.d.ts +1 -1
  45. package/dist/src/internal/builtin-plugins/gas-analytics/index.d.ts.map +1 -1
  46. package/dist/src/internal/builtin-plugins/gas-analytics/index.js +0 -1
  47. package/dist/src/internal/builtin-plugins/gas-analytics/index.js.map +1 -1
  48. package/dist/src/internal/builtin-plugins/gas-analytics/snapshot-cheatcodes.d.ts +21 -0
  49. package/dist/src/internal/builtin-plugins/gas-analytics/snapshot-cheatcodes.d.ts.map +1 -1
  50. package/dist/src/internal/builtin-plugins/gas-analytics/snapshot-cheatcodes.js +49 -1
  51. package/dist/src/internal/builtin-plugins/gas-analytics/snapshot-cheatcodes.js.map +1 -1
  52. package/dist/src/internal/builtin-plugins/gas-analytics/tasks/solidity-test/task-action.d.ts +2 -1
  53. package/dist/src/internal/builtin-plugins/gas-analytics/tasks/solidity-test/task-action.d.ts.map +1 -1
  54. package/dist/src/internal/builtin-plugins/gas-analytics/tasks/solidity-test/task-action.js +12 -2
  55. package/dist/src/internal/builtin-plugins/gas-analytics/tasks/solidity-test/task-action.js.map +1 -1
  56. package/dist/src/internal/builtin-plugins/gas-analytics/type-extensions.d.ts +1 -1
  57. package/dist/src/internal/builtin-plugins/gas-analytics/type-extensions.d.ts.map +1 -1
  58. package/dist/src/internal/builtin-plugins/gas-analytics/type-extensions.js +1 -1
  59. package/dist/src/internal/builtin-plugins/gas-analytics/type-extensions.js.map +1 -1
  60. package/dist/src/internal/builtin-plugins/index.d.ts +8 -8
  61. package/dist/src/internal/builtin-plugins/index.d.ts.map +1 -1
  62. package/dist/src/internal/builtin-plugins/network-manager/config-resolution.d.ts.map +1 -1
  63. package/dist/src/internal/builtin-plugins/network-manager/config-resolution.js +9 -2
  64. package/dist/src/internal/builtin-plugins/network-manager/config-resolution.js.map +1 -1
  65. package/dist/src/internal/builtin-plugins/network-manager/edr/edr-constants.d.ts +1 -0
  66. package/dist/src/internal/builtin-plugins/network-manager/edr/edr-constants.d.ts.map +1 -1
  67. package/dist/src/internal/builtin-plugins/network-manager/edr/edr-constants.js +1 -0
  68. package/dist/src/internal/builtin-plugins/network-manager/edr/edr-constants.js.map +1 -1
  69. package/dist/src/internal/builtin-plugins/network-manager/edr/edr-provider.d.ts.map +1 -1
  70. package/dist/src/internal/builtin-plugins/network-manager/edr/edr-provider.js +25 -5
  71. package/dist/src/internal/builtin-plugins/network-manager/edr/edr-provider.js.map +1 -1
  72. package/dist/src/internal/builtin-plugins/network-manager/edr/stack-traces/stack-trace-solidity-errors.d.ts.map +1 -1
  73. package/dist/src/internal/builtin-plugins/network-manager/edr/stack-traces/stack-trace-solidity-errors.js +7 -6
  74. package/dist/src/internal/builtin-plugins/network-manager/edr/stack-traces/stack-trace-solidity-errors.js.map +1 -1
  75. package/dist/src/internal/builtin-plugins/network-manager/edr/utils/convert-to-edr.d.ts +16 -0
  76. package/dist/src/internal/builtin-plugins/network-manager/edr/utils/convert-to-edr.d.ts.map +1 -1
  77. package/dist/src/internal/builtin-plugins/network-manager/edr/utils/convert-to-edr.js +28 -1
  78. package/dist/src/internal/builtin-plugins/network-manager/edr/utils/convert-to-edr.js.map +1 -1
  79. package/dist/src/internal/builtin-plugins/network-manager/index.d.ts +4 -4
  80. package/dist/src/internal/builtin-plugins/network-manager/index.d.ts.map +1 -1
  81. package/dist/src/internal/builtin-plugins/network-manager/index.js +0 -4
  82. package/dist/src/internal/builtin-plugins/network-manager/index.js.map +1 -1
  83. package/dist/src/internal/builtin-plugins/network-manager/network-manager.d.ts.map +1 -1
  84. package/dist/src/internal/builtin-plugins/network-manager/network-manager.js +2 -6
  85. package/dist/src/internal/builtin-plugins/network-manager/network-manager.js.map +1 -1
  86. package/dist/src/internal/builtin-plugins/network-manager/type-extensions/config.d.ts +5 -4
  87. package/dist/src/internal/builtin-plugins/network-manager/type-extensions/config.d.ts.map +1 -1
  88. package/dist/src/internal/builtin-plugins/network-manager/type-extensions/config.js +1 -1
  89. package/dist/src/internal/builtin-plugins/network-manager/type-extensions/config.js.map +1 -1
  90. package/dist/src/internal/builtin-plugins/network-manager/type-extensions/global-options.d.ts +1 -1
  91. package/dist/src/internal/builtin-plugins/network-manager/type-extensions/global-options.d.ts.map +1 -1
  92. package/dist/src/internal/builtin-plugins/network-manager/type-extensions/global-options.js +1 -1
  93. package/dist/src/internal/builtin-plugins/network-manager/type-extensions/global-options.js.map +1 -1
  94. package/dist/src/internal/builtin-plugins/network-manager/type-extensions/hooks.d.ts +0 -1
  95. package/dist/src/internal/builtin-plugins/network-manager/type-extensions/hooks.d.ts.map +1 -1
  96. package/dist/src/internal/builtin-plugins/network-manager/type-extensions/hooks.js +1 -1
  97. package/dist/src/internal/builtin-plugins/network-manager/type-extensions/hooks.js.map +1 -1
  98. package/dist/src/internal/builtin-plugins/network-manager/type-extensions/hre.d.ts +0 -1
  99. package/dist/src/internal/builtin-plugins/network-manager/type-extensions/hre.d.ts.map +1 -1
  100. package/dist/src/internal/builtin-plugins/network-manager/type-extensions/hre.js +1 -1
  101. package/dist/src/internal/builtin-plugins/network-manager/type-extensions/hre.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 +3 -1
  104. package/dist/src/internal/builtin-plugins/network-manager/type-validation.js.map +1 -1
  105. package/dist/src/internal/builtin-plugins/network-manager/utils/apply-coverage-network-overrides.d.ts +18 -0
  106. package/dist/src/internal/builtin-plugins/network-manager/utils/apply-coverage-network-overrides.d.ts.map +1 -0
  107. package/dist/src/internal/builtin-plugins/network-manager/utils/apply-coverage-network-overrides.js +27 -0
  108. package/dist/src/internal/builtin-plugins/network-manager/utils/apply-coverage-network-overrides.js.map +1 -0
  109. package/dist/src/internal/builtin-plugins/node/json-rpc/handler.js +6 -5
  110. package/dist/src/internal/builtin-plugins/node/json-rpc/handler.js.map +1 -1
  111. package/dist/src/internal/builtin-plugins/solidity/build-system/build-system.d.ts.map +1 -1
  112. package/dist/src/internal/builtin-plugins/solidity/build-system/build-system.js +22 -9
  113. package/dist/src/internal/builtin-plugins/solidity/build-system/build-system.js.map +1 -1
  114. package/dist/src/internal/builtin-plugins/solidity/build-system/resolver/remapped-npm-packages-graph.d.ts.map +1 -1
  115. package/dist/src/internal/builtin-plugins/solidity/build-system/resolver/remapped-npm-packages-graph.js +7 -1
  116. package/dist/src/internal/builtin-plugins/solidity/build-system/resolver/remapped-npm-packages-graph.js.map +1 -1
  117. package/dist/src/internal/builtin-plugins/solidity/constants.d.ts +10 -0
  118. package/dist/src/internal/builtin-plugins/solidity/constants.d.ts.map +1 -1
  119. package/dist/src/internal/builtin-plugins/solidity/constants.js +10 -0
  120. package/dist/src/internal/builtin-plugins/solidity/constants.js.map +1 -1
  121. package/dist/src/internal/builtin-plugins/solidity/index.d.ts +1 -1
  122. package/dist/src/internal/builtin-plugins/solidity/index.d.ts.map +1 -1
  123. package/dist/src/internal/builtin-plugins/solidity/index.js +1 -1
  124. package/dist/src/internal/builtin-plugins/solidity/index.js.map +1 -1
  125. package/dist/src/internal/builtin-plugins/solidity/tasks/compile.d.ts +9 -0
  126. package/dist/src/internal/builtin-plugins/solidity/tasks/compile.d.ts.map +1 -0
  127. package/dist/src/internal/builtin-plugins/solidity/tasks/compile.js +10 -0
  128. package/dist/src/internal/builtin-plugins/solidity/tasks/compile.js.map +1 -0
  129. package/dist/src/internal/builtin-plugins/solidity/type-extensions.d.ts +0 -4
  130. package/dist/src/internal/builtin-plugins/solidity/type-extensions.d.ts.map +1 -1
  131. package/dist/src/internal/builtin-plugins/solidity/type-extensions.js +1 -4
  132. package/dist/src/internal/builtin-plugins/solidity/type-extensions.js.map +1 -1
  133. package/dist/src/internal/builtin-plugins/solidity-test/config.d.ts +4 -3
  134. package/dist/src/internal/builtin-plugins/solidity-test/config.d.ts.map +1 -1
  135. package/dist/src/internal/builtin-plugins/solidity-test/config.js +55 -8
  136. package/dist/src/internal/builtin-plugins/solidity-test/config.js.map +1 -1
  137. package/dist/src/internal/builtin-plugins/solidity-test/eip712/ast-walker.d.ts +58 -0
  138. package/dist/src/internal/builtin-plugins/solidity-test/eip712/ast-walker.d.ts.map +1 -0
  139. package/dist/src/internal/builtin-plugins/solidity-test/eip712/ast-walker.js +226 -0
  140. package/dist/src/internal/builtin-plugins/solidity-test/eip712/ast-walker.js.map +1 -0
  141. package/dist/src/internal/builtin-plugins/solidity-test/eip712/canonicalize.d.ts +29 -0
  142. package/dist/src/internal/builtin-plugins/solidity-test/eip712/canonicalize.d.ts.map +1 -0
  143. package/dist/src/internal/builtin-plugins/solidity-test/eip712/canonicalize.js +244 -0
  144. package/dist/src/internal/builtin-plugins/solidity-test/eip712/canonicalize.js.map +1 -0
  145. package/dist/src/internal/builtin-plugins/solidity-test/eip712/glob.d.ts +7 -0
  146. package/dist/src/internal/builtin-plugins/solidity-test/eip712/glob.d.ts.map +1 -0
  147. package/dist/src/internal/builtin-plugins/solidity-test/eip712/glob.js +204 -0
  148. package/dist/src/internal/builtin-plugins/solidity-test/eip712/glob.js.map +1 -0
  149. package/dist/src/internal/builtin-plugins/solidity-test/eip712/index.d.ts +21 -0
  150. package/dist/src/internal/builtin-plugins/solidity-test/eip712/index.d.ts.map +1 -0
  151. package/dist/src/internal/builtin-plugins/solidity-test/eip712/index.js +77 -0
  152. package/dist/src/internal/builtin-plugins/solidity-test/eip712/index.js.map +1 -0
  153. package/dist/src/internal/builtin-plugins/solidity-test/helpers.d.ts +4 -3
  154. package/dist/src/internal/builtin-plugins/solidity-test/helpers.d.ts.map +1 -1
  155. package/dist/src/internal/builtin-plugins/solidity-test/helpers.js +20 -3
  156. package/dist/src/internal/builtin-plugins/solidity-test/helpers.js.map +1 -1
  157. package/dist/src/internal/builtin-plugins/solidity-test/index.d.ts +1 -1
  158. package/dist/src/internal/builtin-plugins/solidity-test/index.d.ts.map +1 -1
  159. package/dist/src/internal/builtin-plugins/solidity-test/index.js +0 -1
  160. package/dist/src/internal/builtin-plugins/solidity-test/index.js.map +1 -1
  161. package/dist/src/internal/builtin-plugins/solidity-test/inline-config/constants.d.ts +4 -2
  162. package/dist/src/internal/builtin-plugins/solidity-test/inline-config/constants.d.ts.map +1 -1
  163. package/dist/src/internal/builtin-plugins/solidity-test/inline-config/constants.js +5 -1
  164. package/dist/src/internal/builtin-plugins/solidity-test/inline-config/constants.js.map +1 -1
  165. package/dist/src/internal/builtin-plugins/solidity-test/inline-config/helpers.d.ts.map +1 -1
  166. package/dist/src/internal/builtin-plugins/solidity-test/inline-config/helpers.js +15 -3
  167. package/dist/src/internal/builtin-plugins/solidity-test/inline-config/helpers.js.map +1 -1
  168. package/dist/src/internal/builtin-plugins/solidity-test/inline-config/validation.d.ts +3 -2
  169. package/dist/src/internal/builtin-plugins/solidity-test/inline-config/validation.d.ts.map +1 -1
  170. package/dist/src/internal/builtin-plugins/solidity-test/inline-config/validation.js +18 -4
  171. package/dist/src/internal/builtin-plugins/solidity-test/inline-config/validation.js.map +1 -1
  172. package/dist/src/internal/builtin-plugins/solidity-test/task-action.d.ts.map +1 -1
  173. package/dist/src/internal/builtin-plugins/solidity-test/task-action.js +5 -1
  174. package/dist/src/internal/builtin-plugins/solidity-test/task-action.js.map +1 -1
  175. package/dist/src/internal/builtin-plugins/solidity-test/test-profiles.d.ts +2 -0
  176. package/dist/src/internal/builtin-plugins/solidity-test/test-profiles.d.ts.map +1 -0
  177. package/dist/src/internal/builtin-plugins/solidity-test/test-profiles.js +2 -0
  178. package/dist/src/internal/builtin-plugins/solidity-test/test-profiles.js.map +1 -0
  179. package/dist/src/internal/builtin-plugins/solidity-test/type-extensions.d.ts +91 -33
  180. package/dist/src/internal/builtin-plugins/solidity-test/type-extensions.d.ts.map +1 -1
  181. package/dist/src/internal/builtin-plugins/solidity-test/type-extensions.js +1 -1
  182. package/dist/src/internal/builtin-plugins/solidity-test/type-extensions.js.map +1 -1
  183. package/dist/src/internal/builtin-plugins/test/index.d.ts +1 -1
  184. package/dist/src/internal/builtin-plugins/test/index.d.ts.map +1 -1
  185. package/dist/src/internal/builtin-plugins/test/index.js +0 -1
  186. package/dist/src/internal/builtin-plugins/test/index.js.map +1 -1
  187. package/dist/src/internal/builtin-plugins/test/type-extensions.d.ts +0 -1
  188. package/dist/src/internal/builtin-plugins/test/type-extensions.d.ts.map +1 -1
  189. package/dist/src/internal/builtin-plugins/test/type-extensions.js +1 -1
  190. package/dist/src/internal/builtin-plugins/test/type-extensions.js.map +1 -1
  191. package/dist/src/internal/cli/init/init.d.ts +31 -6
  192. package/dist/src/internal/cli/init/init.d.ts.map +1 -1
  193. package/dist/src/internal/cli/init/init.js +121 -10
  194. package/dist/src/internal/cli/init/init.js.map +1 -1
  195. package/dist/src/internal/cli/main.d.ts.map +1 -1
  196. package/dist/src/internal/cli/main.js +41 -1
  197. package/dist/src/internal/cli/main.js.map +1 -1
  198. package/dist/src/types/arguments.d.ts +1 -0
  199. package/dist/src/types/arguments.d.ts.map +1 -1
  200. package/dist/src/types/arguments.js +1 -0
  201. package/dist/src/types/arguments.js.map +1 -1
  202. package/dist/src/types/artifacts.d.ts +1 -0
  203. package/dist/src/types/artifacts.d.ts.map +1 -1
  204. package/dist/src/types/artifacts.js +1 -1
  205. package/dist/src/types/artifacts.js.map +1 -1
  206. package/dist/src/types/builtin-plugin-type-extensions.d.ts +2 -0
  207. package/dist/src/types/builtin-plugin-type-extensions.d.ts.map +1 -0
  208. package/dist/src/types/builtin-plugin-type-extensions.js +2 -0
  209. package/dist/src/types/builtin-plugin-type-extensions.js.map +1 -0
  210. package/dist/src/types/config.d.ts +1 -1
  211. package/dist/src/types/config.d.ts.map +1 -1
  212. package/dist/src/types/config.js +1 -3
  213. package/dist/src/types/config.js.map +1 -1
  214. package/dist/src/types/global-options.d.ts +1 -0
  215. package/dist/src/types/global-options.d.ts.map +1 -1
  216. package/dist/src/types/global-options.js +1 -1
  217. package/dist/src/types/global-options.js.map +1 -1
  218. package/dist/src/types/hooks.d.ts +1 -0
  219. package/dist/src/types/hooks.d.ts.map +1 -1
  220. package/dist/src/types/hooks.js +1 -1
  221. package/dist/src/types/hooks.js.map +1 -1
  222. package/dist/src/types/hre.d.ts +1 -0
  223. package/dist/src/types/hre.d.ts.map +1 -1
  224. package/dist/src/types/hre.js +1 -1
  225. package/dist/src/types/hre.js.map +1 -1
  226. package/dist/src/types/index.d.ts +1 -0
  227. package/dist/src/types/index.d.ts.map +1 -1
  228. package/dist/src/types/index.js +1 -0
  229. package/dist/src/types/index.js.map +1 -1
  230. package/dist/src/types/network.d.ts +1 -0
  231. package/dist/src/types/network.d.ts.map +1 -1
  232. package/dist/src/types/network.js +1 -1
  233. package/dist/src/types/network.js.map +1 -1
  234. package/dist/src/types/plugins.d.ts +1 -1
  235. package/dist/src/types/plugins.d.ts.map +1 -1
  236. package/dist/src/types/plugins.js +1 -3
  237. package/dist/src/types/plugins.js.map +1 -1
  238. package/dist/src/types/providers.d.ts +1 -0
  239. package/dist/src/types/providers.d.ts.map +1 -1
  240. package/dist/src/types/providers.js +1 -1
  241. package/dist/src/types/providers.js.map +1 -1
  242. package/dist/src/types/solidity.d.ts +1 -0
  243. package/dist/src/types/solidity.d.ts.map +1 -1
  244. package/dist/src/types/solidity.js +1 -0
  245. package/dist/src/types/solidity.js.map +1 -1
  246. package/dist/src/types/tasks.d.ts +1 -0
  247. package/dist/src/types/tasks.d.ts.map +1 -1
  248. package/dist/src/types/tasks.js +1 -0
  249. package/dist/src/types/tasks.js.map +1 -1
  250. package/dist/src/types/test.d.ts +1 -0
  251. package/dist/src/types/test.d.ts.map +1 -1
  252. package/dist/src/types/test.js +1 -1
  253. package/dist/src/types/test.js.map +1 -1
  254. package/dist/src/types/user-interruptions.d.ts +1 -0
  255. package/dist/src/types/user-interruptions.d.ts.map +1 -1
  256. package/dist/src/types/user-interruptions.js +1 -1
  257. package/dist/src/types/user-interruptions.js.map +1 -1
  258. package/package.json +12 -12
  259. package/src/config.ts +0 -3
  260. package/src/hre.ts +0 -4
  261. package/src/index.ts +0 -4
  262. package/src/internal/builtin-global-options.ts +2 -1
  263. package/src/internal/builtin-plugins/artifacts/index.ts +1 -1
  264. package/src/internal/builtin-plugins/clean/index.ts +1 -1
  265. package/src/internal/builtin-plugins/clean/type-extensions.ts +0 -1
  266. package/src/internal/builtin-plugins/coverage/hook-handlers/solidity.ts +8 -13
  267. package/src/internal/builtin-plugins/coverage/index.ts +1 -1
  268. package/src/internal/builtin-plugins/coverage/instrumentation.ts +0 -5
  269. package/src/internal/builtin-plugins/coverage/type-extensions.ts +0 -1
  270. package/src/internal/builtin-plugins/gas-analytics/index.ts +1 -1
  271. package/src/internal/builtin-plugins/gas-analytics/snapshot-cheatcodes.ts +90 -1
  272. package/src/internal/builtin-plugins/gas-analytics/tasks/solidity-test/task-action.ts +24 -2
  273. package/src/internal/builtin-plugins/gas-analytics/type-extensions.ts +0 -1
  274. package/src/internal/builtin-plugins/index.ts +10 -10
  275. package/src/internal/builtin-plugins/network-manager/config-resolution.ts +11 -3
  276. package/src/internal/builtin-plugins/network-manager/edr/edr-constants.ts +2 -0
  277. package/src/internal/builtin-plugins/network-manager/edr/edr-provider.ts +38 -8
  278. package/src/internal/builtin-plugins/network-manager/edr/stack-traces/stack-trace-solidity-errors.ts +10 -11
  279. package/src/internal/builtin-plugins/network-manager/edr/utils/convert-to-edr.ts +43 -1
  280. package/src/internal/builtin-plugins/network-manager/index.ts +4 -4
  281. package/src/internal/builtin-plugins/network-manager/network-manager.ts +5 -6
  282. package/src/internal/builtin-plugins/network-manager/type-extensions/config.ts +5 -4
  283. package/src/internal/builtin-plugins/network-manager/type-extensions/global-options.ts +0 -1
  284. package/src/internal/builtin-plugins/network-manager/type-extensions/hooks.ts +0 -1
  285. package/src/internal/builtin-plugins/network-manager/type-extensions/hre.ts +0 -1
  286. package/src/internal/builtin-plugins/network-manager/type-validation.ts +7 -1
  287. package/src/internal/builtin-plugins/network-manager/utils/apply-coverage-network-overrides.ts +32 -0
  288. package/src/internal/builtin-plugins/node/json-rpc/handler.ts +7 -5
  289. package/src/internal/builtin-plugins/solidity/build-system/build-system.ts +32 -16
  290. package/src/internal/builtin-plugins/solidity/build-system/resolver/remapped-npm-packages-graph.ts +8 -2
  291. package/src/internal/builtin-plugins/solidity/constants.ts +11 -0
  292. package/src/internal/builtin-plugins/solidity/index.ts +2 -1
  293. package/src/internal/builtin-plugins/solidity/tasks/compile.ts +12 -0
  294. package/src/internal/builtin-plugins/solidity/type-extensions.ts +0 -4
  295. package/src/internal/builtin-plugins/solidity-test/config.ts +85 -12
  296. package/src/internal/builtin-plugins/solidity-test/eip712/ast-walker.ts +324 -0
  297. package/src/internal/builtin-plugins/solidity-test/eip712/canonicalize.ts +317 -0
  298. package/src/internal/builtin-plugins/solidity-test/eip712/glob.ts +225 -0
  299. package/src/internal/builtin-plugins/solidity-test/eip712/index.ts +120 -0
  300. package/src/internal/builtin-plugins/solidity-test/helpers.ts +28 -4
  301. package/src/internal/builtin-plugins/solidity-test/index.ts +1 -1
  302. package/src/internal/builtin-plugins/solidity-test/inline-config/constants.ts +6 -2
  303. package/src/internal/builtin-plugins/solidity-test/inline-config/helpers.ts +15 -4
  304. package/src/internal/builtin-plugins/solidity-test/inline-config/validation.ts +25 -4
  305. package/src/internal/builtin-plugins/solidity-test/task-action.ts +12 -1
  306. package/src/internal/builtin-plugins/solidity-test/test-profiles.ts +1 -0
  307. package/src/internal/builtin-plugins/solidity-test/type-extensions.ts +100 -34
  308. package/src/internal/builtin-plugins/test/index.ts +1 -1
  309. package/src/internal/builtin-plugins/test/type-extensions.ts +0 -1
  310. package/src/internal/cli/init/init.ts +198 -16
  311. package/src/internal/cli/main.ts +64 -1
  312. package/src/types/arguments.ts +2 -0
  313. package/src/types/artifacts.ts +2 -0
  314. package/src/types/builtin-plugin-type-extensions.ts +15 -0
  315. package/src/types/config.ts +1 -3
  316. package/src/types/global-options.ts +2 -0
  317. package/src/types/hooks.ts +2 -0
  318. package/src/types/hre.ts +2 -0
  319. package/src/types/index.ts +2 -0
  320. package/src/types/network.ts +2 -0
  321. package/src/types/plugins.ts +1 -3
  322. package/src/types/providers.ts +2 -0
  323. package/src/types/solidity.ts +2 -0
  324. package/src/types/tasks.ts +2 -0
  325. package/src/types/test.ts +2 -0
  326. package/src/types/user-interruptions.ts +2 -0
  327. package/templates/hardhat-3/01-node-test-runner-viem/package.json +12 -12
  328. package/templates/hardhat-3/01-node-test-runner-viem/tsconfig.json +4 -7
  329. package/templates/hardhat-3/02-mocha-ethers/package.json +15 -15
  330. package/templates/hardhat-3/02-mocha-ethers/tsconfig.json +4 -7
  331. package/templates/hardhat-3/03-minimal/package.json +2 -2
  332. package/templates/hardhat-3/03-minimal/tsconfig.json +4 -7
  333. package/coverage.sol +0 -38
@@ -0,0 +1,324 @@
1
+ import { isObject } from "@nomicfoundation/hardhat-utils/lang";
2
+
3
+ /**
4
+ * A single field of a Solidity struct
5
+ */
6
+ export interface StructMember {
7
+ name: string;
8
+ /**
9
+ * EIP-712 type string, or `undefined` if the type can't be encoded (e.g. mappings).
10
+ */
11
+ type: string | undefined;
12
+ }
13
+
14
+ /**
15
+ * A Solidity struct extracted from a source AST (Abstract Syntax Tree).
16
+ */
17
+ export interface CollectedStruct {
18
+ name: string;
19
+ members: StructMember[];
20
+ /**
21
+ * Project-relative source path. Used for diagnostics only.
22
+ */
23
+ sourcePath: string;
24
+ }
25
+
26
+ /**
27
+ * A user-defined value type (`type Foo is bytes32;`) resolves to its
28
+ * underlying elementary type for EIP-712 encoding.
29
+ * The map is keyed by the user-defined value type definition's solc node id,
30
+ * which is what `referencedDeclaration` on a `UserDefinedTypeName` reference
31
+ * points to.
32
+ */
33
+ export type UserDefinedValueTypeIndex = Map<number, Record<string, unknown>>;
34
+
35
+ /**
36
+ * Walks every AST in the build and indexes every `UserDefinedValueTypeDefinition`
37
+ * by its node `id`, mapping to its `underlyingType` (an `ElementaryTypeName`).
38
+ *
39
+ * User-defined value types can sit at file scope or inside a contract, and a
40
+ * struct in one source may reference a user-defined value type defined in
41
+ * another, so this must run across every AST in the build — not just the ones
42
+ * matched by the user's include globs.
43
+ */
44
+ export function buildUserDefinedValueTypeIndex(
45
+ asts: unknown[],
46
+ ): UserDefinedValueTypeIndex {
47
+ const index: UserDefinedValueTypeIndex = new Map();
48
+
49
+ for (const ast of asts) {
50
+ if (!isObject(ast) || ast.nodeType !== "SourceUnit") {
51
+ continue;
52
+ }
53
+
54
+ const topLevelNodes: unknown[] = Array.isArray(ast.nodes) ? ast.nodes : [];
55
+ for (const node of topLevelNodes) {
56
+ if (!isObject(node)) {
57
+ continue;
58
+ }
59
+
60
+ if (node.nodeType === "UserDefinedValueTypeDefinition") {
61
+ recordUserDefinedValueType(node, index);
62
+ } else if (node.nodeType === "ContractDefinition") {
63
+ const members: unknown[] = Array.isArray(node.nodes) ? node.nodes : [];
64
+ for (const member of members) {
65
+ if (
66
+ isObject(member) &&
67
+ member.nodeType === "UserDefinedValueTypeDefinition"
68
+ ) {
69
+ recordUserDefinedValueType(member, index);
70
+ }
71
+ }
72
+ }
73
+ }
74
+ }
75
+
76
+ return index;
77
+ }
78
+
79
+ function recordUserDefinedValueType(
80
+ node: Record<string, unknown>,
81
+ index: UserDefinedValueTypeIndex,
82
+ ): void {
83
+ if (
84
+ typeof node.id === "number" &&
85
+ isObject(node.underlyingType) &&
86
+ node.underlyingType.nodeType === "ElementaryTypeName"
87
+ ) {
88
+ index.set(node.id, node.underlyingType);
89
+ }
90
+ }
91
+
92
+ /**
93
+ * Returns every struct definition reachable from a solc source AST (Abstract Syntax Tree),
94
+ * including structs nested inside contracts.
95
+ */
96
+ export function extractStructsFromAst(
97
+ ast: unknown,
98
+ sourcePath: string,
99
+ userDefinedValueTypeI: UserDefinedValueTypeIndex = new Map(),
100
+ ): CollectedStruct[] {
101
+ if (!isObject(ast) || ast.nodeType !== "SourceUnit") {
102
+ return [];
103
+ }
104
+
105
+ const results: CollectedStruct[] = [];
106
+ const topLevelNodes: unknown[] = Array.isArray(ast.nodes) ? ast.nodes : [];
107
+
108
+ for (const node of topLevelNodes) {
109
+ if (!isObject(node)) {
110
+ continue;
111
+ }
112
+
113
+ if (node.nodeType === "StructDefinition") {
114
+ const collected = collectStruct(node, sourcePath, userDefinedValueTypeI);
115
+ if (collected !== undefined) {
116
+ results.push(collected);
117
+ }
118
+ } else if (node.nodeType === "ContractDefinition") {
119
+ const members: unknown[] = Array.isArray(node.nodes) ? node.nodes : [];
120
+ for (const member of members) {
121
+ if (isObject(member) && member.nodeType === "StructDefinition") {
122
+ const collected = collectStruct(
123
+ member,
124
+ sourcePath,
125
+ userDefinedValueTypeI,
126
+ );
127
+ if (collected !== undefined) {
128
+ results.push(collected);
129
+ }
130
+ }
131
+ }
132
+ }
133
+ }
134
+
135
+ return results;
136
+ }
137
+
138
+ function collectStruct(
139
+ node: Record<string, unknown>,
140
+ sourcePath: string,
141
+ userDefinedValueTypeI: UserDefinedValueTypeIndex,
142
+ ): CollectedStruct | undefined {
143
+ if (typeof node.name !== "string") {
144
+ return undefined;
145
+ }
146
+
147
+ const memberNodes: unknown[] = Array.isArray(node.members)
148
+ ? node.members
149
+ : [];
150
+ const members: StructMember[] = [];
151
+
152
+ for (const memberNode of memberNodes) {
153
+ if (
154
+ !isObject(memberNode) ||
155
+ memberNode.nodeType !== "VariableDeclaration"
156
+ ) {
157
+ continue;
158
+ }
159
+
160
+ if (typeof memberNode.name !== "string") {
161
+ continue;
162
+ }
163
+
164
+ members.push({
165
+ name: memberNode.name,
166
+ type: encodeMemberType(memberNode.typeName, userDefinedValueTypeI),
167
+ });
168
+ }
169
+
170
+ return {
171
+ name: node.name,
172
+ members,
173
+ sourcePath,
174
+ };
175
+ }
176
+
177
+ /**
178
+ * Converts a solc `typeName` AST node into its EIP-712 type string, following
179
+ * the same conventions as `forge bind-json`:
180
+ *
181
+ * - elementary types pass through (`address`, `uint256`, `string`, ...)
182
+ * - enums → `uint8`
183
+ * - contracts / interfaces → `address`
184
+ * - structs → bare name (`Wallet.Person` → `Person`)
185
+ * - user-defined value types → underlying elementary type (`type Foo is bytes32` → `bytes32`)
186
+ * - arrays → `T[]` (dynamic) or `T[N]` (fixed)
187
+ * - mappings / functions → `undefined` (not EIP-712 encodable)
188
+ */
189
+ export function encodeMemberType(
190
+ typeName: unknown,
191
+ userDefinedValueTypeI: UserDefinedValueTypeIndex = new Map(),
192
+ ): string | undefined {
193
+ if (!isObject(typeName)) {
194
+ return undefined;
195
+ }
196
+
197
+ switch (typeName.nodeType) {
198
+ case "ElementaryTypeName": {
199
+ // Prefer `typeDescriptions.typeString` over `name`: solc emits the
200
+ // unresolved alias in `name` (`uint`, `int`, `byte`), but the canonical
201
+ // EIP-712 type is in `typeString` (`uint256`, `int256`, `bytes1`).
202
+ // `address payable` is the exception — `typeString` is `"address payable"`
203
+ // while the canonical EIP-712 type is just `address`.
204
+ const desc = isObject(typeName.typeDescriptions)
205
+ ? typeName.typeDescriptions
206
+ : undefined;
207
+ const typeString =
208
+ typeof desc?.typeString === "string" ? desc.typeString : undefined;
209
+ if (typeString !== undefined) {
210
+ return typeString.endsWith(" payable")
211
+ ? typeString.slice(0, -" payable".length)
212
+ : typeString;
213
+ }
214
+
215
+ return typeof typeName.name === "string" ? typeName.name : undefined;
216
+ }
217
+
218
+ case "UserDefinedTypeName": {
219
+ // `typeDescriptions.typeString` is the only reliable way to tell what
220
+ // kind of user-defined type this is — e.g. "struct Foo", "enum Bar",
221
+ // "contract Token". The AST node itself doesn't say. Note that solc
222
+ // emits the "contract " prefix for interface references as well.
223
+ const desc = isObject(typeName.typeDescriptions)
224
+ ? typeName.typeDescriptions
225
+ : undefined;
226
+ const typeString =
227
+ typeof desc?.typeString === "string" ? desc.typeString : "";
228
+
229
+ if (typeString.startsWith("enum ")) {
230
+ return "uint8";
231
+ }
232
+
233
+ if (typeString.startsWith("contract ")) {
234
+ return "address";
235
+ }
236
+
237
+ if (typeString.startsWith("struct ")) {
238
+ // EIP-712 references structs by their bare name, so strip both the
239
+ // "struct " prefix, any storage-location suffix solc may append
240
+ // ("memory", "storage", ...), and any qualifier ("Wallet.Person").
241
+ const remainder = typeString.slice("struct ".length).trim();
242
+ const namePart = remainder.split(/\s+/)[0];
243
+ const segments = namePart.split(".");
244
+ return segments[segments.length - 1];
245
+ }
246
+
247
+ // User-defined value types (`type Foo is bytes32;`, solc 0.8.8+).
248
+ // Resolve via `referencedDeclaration` against the build-wide
249
+ // user-defined value type index
250
+ // and recurse on the underlying elementary type — matching forge's
251
+ // `Resolver::resolve_type` so `Foo h` encodes as `bytes32 h`, not `Foo h`.
252
+ const refId =
253
+ typeof typeName.referencedDeclaration === "number"
254
+ ? typeName.referencedDeclaration
255
+ : isObject(typeName.pathNode) &&
256
+ typeof typeName.pathNode.referencedDeclaration === "number"
257
+ ? typeName.pathNode.referencedDeclaration
258
+ : undefined;
259
+
260
+ if (refId !== undefined) {
261
+ const underlying = userDefinedValueTypeI.get(refId);
262
+ if (underlying !== undefined) {
263
+ return encodeMemberType(underlying, userDefinedValueTypeI);
264
+ }
265
+ }
266
+
267
+ // Fallback when the reference can't be resolved (missing
268
+ // `referencedDeclaration`, or its definition wasn't in the build).
269
+ // Emitting the name lets the downstream encoder produce a clear error
270
+ // rather than failing silently here.
271
+ if (typeof typeName.name === "string") {
272
+ return typeName.name;
273
+ }
274
+
275
+ if (
276
+ isObject(typeName.pathNode) &&
277
+ typeof typeName.pathNode.name === "string"
278
+ ) {
279
+ const segments = typeName.pathNode.name.split(".");
280
+ return segments[segments.length - 1];
281
+ }
282
+
283
+ return undefined;
284
+ }
285
+
286
+ case "ArrayTypeName": {
287
+ const base = encodeMemberType(typeName.baseType, userDefinedValueTypeI);
288
+ if (base === undefined) {
289
+ return undefined;
290
+ }
291
+
292
+ // solc omits `length` entirely for dynamic arrays; it isn't emitted as `null`.
293
+ const length = typeName.length;
294
+ if (length === null || length === undefined) {
295
+ return `${base}[]`;
296
+ }
297
+
298
+ // Always read from typeString: `Literal.value` preserves source text
299
+ // (`0x100`, `1_000`) but typeString canonicalizes to decimal.
300
+ const desc = isObject(typeName.typeDescriptions)
301
+ ? typeName.typeDescriptions
302
+ : undefined;
303
+ const typeString =
304
+ typeof desc?.typeString === "string" ? desc.typeString : "";
305
+ const match = /\[(\d+)\]$/.exec(typeString);
306
+
307
+ if (match !== null) {
308
+ return `${base}[${match[1]}]`;
309
+ }
310
+
311
+ return undefined;
312
+ }
313
+
314
+ case "Mapping":
315
+ return undefined;
316
+
317
+ case "FunctionTypeName":
318
+ // EIP-712 can't encode function types.
319
+ return undefined;
320
+
321
+ default:
322
+ return undefined;
323
+ }
324
+ }
@@ -0,0 +1,317 @@
1
+ import type { CollectedStruct } from "./ast-walker.js";
2
+
3
+ import { HardhatError } from "@nomicfoundation/hardhat-errors";
4
+
5
+ /**
6
+ * Produces the flat list of canonical EIP-712 type strings expected by EDR.
7
+ *
8
+ * Each encodable struct contributes one entry, built like this:
9
+ * 1. Start with the struct's own head: `Name(type1 name1,type2 name2,...)`.
10
+ * 2. If the struct has fields that reference other structs, append those
11
+ * structs' heads after it, sorted alphabetically.
12
+ *
13
+ * Examples:
14
+ * - `Person` has only primitive fields (address, string), so its entry is
15
+ * just its own head:
16
+ * `Person(address wallet,string name)`
17
+ * - `Mail` has a `Person` field, so its entry is its head plus `Person`'s
18
+ * head appended:
19
+ * `Mail(Person from,Person to,string contents)Person(address wallet,string name)`
20
+ *
21
+ * Structs that contain members whose type cannot be EIP-712 encoded (mappings,
22
+ * function types, etc.) are dropped entirely, along with any structs that
23
+ * depend on them transitively. This matches `forge bind-json`'s behavior:
24
+ * `resolve_struct_eip712` returns `None` for any struct containing unsupported
25
+ * constructs and propagates `None` through the dep graph so dependents are
26
+ * also dropped.
27
+ *
28
+ * Only names in `selectedNames` are emitted; non-selected structs still
29
+ * participate in dep resolution so cross-file deps inline correctly.
30
+ */
31
+ export function canonicalizeStructs(
32
+ structs: CollectedStruct[],
33
+ selectedNames: Set<string>,
34
+ ): string[] {
35
+ const byName = indexByName(structs, selectedNames);
36
+ const knownNames = new Set(byName.keys());
37
+ const encodable = computeEncodable(byName, knownNames);
38
+ const result: string[] = [];
39
+
40
+ for (const struct of byName.values()) {
41
+ if (!selectedNames.has(struct.name)) {
42
+ continue;
43
+ }
44
+
45
+ if (!encodable.has(struct.name)) {
46
+ continue;
47
+ }
48
+
49
+ const head = encodeStructHead(struct);
50
+ const deps = transitiveDeps(struct, byName)
51
+ .map((depName) => {
52
+ const def = byName.get(depName);
53
+ return def === undefined ? undefined : encodeStructHead(def);
54
+ })
55
+ .filter((s): s is string => s !== undefined);
56
+
57
+ deps.sort();
58
+
59
+ result.push(head + deps.join(""));
60
+ }
61
+
62
+ return result;
63
+ }
64
+
65
+ /**
66
+ * Returns the set of struct names that are EIP-712 encodable. A struct is
67
+ * encodable if none of its members has a non-decodable type (`type === undefined`,
68
+ * e.g. mappings or function types) AND every one of its struct deps — direct or
69
+ * transitive — is itself encodable.
70
+ */
71
+ function computeEncodable(
72
+ byName: Map<string, CollectedStruct>,
73
+ knownNames: Set<string>,
74
+ ): Set<string> {
75
+ const encodable = new Set<string>(byName.keys());
76
+
77
+ for (const [name, struct] of byName) {
78
+ if (struct.members.some((m) => m.type === undefined)) {
79
+ encodable.delete(name);
80
+ }
81
+ }
82
+
83
+ const depsByName = new Map<string, string[]>();
84
+ for (const [name, struct] of byName) {
85
+ depsByName.set(name, directStructDeps(struct, knownNames));
86
+ }
87
+
88
+ let changed = true;
89
+ while (changed) {
90
+ changed = false;
91
+ for (const name of [...encodable]) {
92
+ const deps = depsByName.get(name) ?? [];
93
+ if (deps.some((dep) => !encodable.has(dep))) {
94
+ encodable.delete(name);
95
+ changed = true;
96
+ }
97
+ }
98
+ }
99
+
100
+ return encodable;
101
+ }
102
+
103
+ /**
104
+ * Computes the EIP-712 `encodeType` string for one struct in isolation:
105
+ * `Name(type1 name1,type2 name2,...)`.
106
+ * Members whose type is `undefined` (e.g. mappings) are dropped.
107
+ */
108
+ function encodeStructHead(struct: CollectedStruct): string {
109
+ const memberSegments: string[] = [];
110
+ for (const member of struct.members) {
111
+ if (member.type === undefined) {
112
+ continue;
113
+ }
114
+
115
+ memberSegments.push(`${member.type} ${member.name}`);
116
+ }
117
+
118
+ return `${struct.name}(${memberSegments.join(",")})`;
119
+ }
120
+
121
+ /**
122
+ * Returns the names of all struct dependencies referenced by `struct`'s
123
+ * members. Considers the base type of arrays. Members whose base type does not
124
+ * resolve to a known struct (elementary types, address, etc.) are ignored.
125
+ */
126
+ function directStructDeps(
127
+ struct: CollectedStruct,
128
+ knownStructNames: Set<string>,
129
+ ): string[] {
130
+ const deps = new Set<string>();
131
+ for (const member of struct.members) {
132
+ if (member.type === undefined) {
133
+ continue;
134
+ }
135
+
136
+ // Strip array suffixes: `Foo[]`, `Foo[3]`, `Foo[3][2]` → `Foo`.
137
+ const base = member.type.split("[")[0];
138
+
139
+ if (knownStructNames.has(base) && base !== struct.name) {
140
+ deps.add(base);
141
+ }
142
+ }
143
+
144
+ return [...deps];
145
+ }
146
+
147
+ /**
148
+ * Walks the dep graph from `root` and returns the set of all transitively
149
+ * referenced struct names (excluding the root itself).
150
+ */
151
+ function transitiveDeps(
152
+ root: CollectedStruct,
153
+ byName: Map<string, CollectedStruct>,
154
+ ): string[] {
155
+ const visited = new Set<string>();
156
+ const knownNames = new Set(byName.keys());
157
+ const stack = directStructDeps(root, knownNames);
158
+
159
+ while (stack.length > 0) {
160
+ const next = stack.pop();
161
+
162
+ if (next === undefined || visited.has(next) || next === root.name) {
163
+ continue;
164
+ }
165
+
166
+ visited.add(next);
167
+
168
+ const def = byName.get(next);
169
+
170
+ if (def !== undefined) {
171
+ stack.push(...directStructDeps(def, knownNames));
172
+ }
173
+ }
174
+
175
+ return [...visited];
176
+ }
177
+
178
+ /**
179
+ * Builds a name → definition map from collected structs, throwing
180
+ * `EIP712_DUPLICATE_STRUCT_NAME` when two structs share a name but have
181
+ * different member lists. Definitions with identical members are silently
182
+ * deduplicated (same struct seen across multiple build infos / partial
183
+ * recompiles).
184
+ *
185
+ * The comparison uses the full member list — including members whose type
186
+ * isn't EIP-712 encodable (mappings, function types) — so that two structs
187
+ * differing only in unsupported members are detected as conflicting rather
188
+ * than collapsed into one. Comparing only the encoded head would let a
189
+ * non decodable definition silently win over an encodable one, dropping the
190
+ * struct from the canonical output.
191
+ *
192
+ * Conflicts on a name reachable from any selected struct (selected roots plus
193
+ * their transitive deps) throw, since the selected struct's inlined dep head
194
+ * would otherwise depend on which conflicting copy happened to be seen first.
195
+ * Conflicts on names truly unreachable from the selected set are silently
196
+ * deduped (first wins). Selected structs are processed first so they win over
197
+ * non-selected copies.
198
+ */
199
+ function indexByName(
200
+ structs: CollectedStruct[],
201
+ selectedNames: Set<string>,
202
+ ): Map<string, CollectedStruct> {
203
+ const byName = new Map<string, CollectedStruct>();
204
+ const fingerprintByName = new Map<string, string>();
205
+ const sourceByName = new Map<string, string>();
206
+ const deferredConflicts = new Map<
207
+ string,
208
+ { firstSource: string; secondSource: string }
209
+ >();
210
+
211
+ const ordered = [
212
+ ...structs.filter((s) => selectedNames.has(s.name)),
213
+ ...structs.filter((s) => !selectedNames.has(s.name)),
214
+ ];
215
+
216
+ for (const struct of ordered) {
217
+ const fingerprint = fingerprintStruct(struct);
218
+ const existingFingerprint = fingerprintByName.get(struct.name);
219
+
220
+ if (existingFingerprint === undefined) {
221
+ byName.set(struct.name, struct);
222
+ fingerprintByName.set(struct.name, fingerprint);
223
+ sourceByName.set(struct.name, struct.sourcePath);
224
+ continue;
225
+ }
226
+
227
+ if (existingFingerprint === fingerprint) {
228
+ continue;
229
+ }
230
+
231
+ if (!selectedNames.has(struct.name)) {
232
+ if (!deferredConflicts.has(struct.name)) {
233
+ deferredConflicts.set(struct.name, {
234
+ firstSource: sourceByName.get(struct.name) ?? "<unknown>",
235
+ secondSource: struct.sourcePath,
236
+ });
237
+ }
238
+ continue;
239
+ }
240
+
241
+ throw new HardhatError(
242
+ HardhatError.ERRORS.CORE.SOLIDITY_TESTS.EIP712_DUPLICATE_STRUCT_NAME,
243
+ {
244
+ name: struct.name,
245
+ firstSource: sourceByName.get(struct.name) ?? "<unknown>",
246
+ secondSource: struct.sourcePath,
247
+ },
248
+ );
249
+ }
250
+
251
+ if (deferredConflicts.size > 0) {
252
+ const reachable = reachableFromSelected(byName, selectedNames);
253
+ for (const [name, sources] of deferredConflicts) {
254
+ if (reachable.has(name)) {
255
+ throw new HardhatError(
256
+ HardhatError.ERRORS.CORE.SOLIDITY_TESTS.EIP712_DUPLICATE_STRUCT_NAME,
257
+ { name, ...sources },
258
+ );
259
+ }
260
+ }
261
+ }
262
+
263
+ return byName;
264
+ }
265
+
266
+ /**
267
+ * Set of struct names transitively referenced by any struct in `selectedNames`.
268
+ * The walk uses whatever first-wins definition is in `byName`; that's enough
269
+ * for conflict detection since we only need to know whether a name is
270
+ * reachable, not which conflicting copy is the "right" one.
271
+ */
272
+ function reachableFromSelected(
273
+ byName: Map<string, CollectedStruct>,
274
+ selectedNames: Set<string>,
275
+ ): Set<string> {
276
+ const knownNames = new Set(byName.keys());
277
+ const reachable = new Set<string>();
278
+ const stack: string[] = [];
279
+
280
+ for (const name of selectedNames) {
281
+ const root = byName.get(name);
282
+ if (root !== undefined) {
283
+ stack.push(...directStructDeps(root, knownNames));
284
+ }
285
+ }
286
+
287
+ while (stack.length > 0) {
288
+ const next = stack.pop();
289
+ if (next === undefined || reachable.has(next)) {
290
+ continue;
291
+ }
292
+
293
+ reachable.add(next);
294
+
295
+ const def = byName.get(next);
296
+ if (def !== undefined) {
297
+ stack.push(...directStructDeps(def, knownNames));
298
+ }
299
+ }
300
+
301
+ return reachable;
302
+ }
303
+
304
+ /**
305
+ * A stable string capturing every member of `struct`, used to detect
306
+ * conflicting definitions of the same name. Unlike `encodeStructHead`, this
307
+ * preserves members whose type can't be EIP-712 encoded — they're emitted with
308
+ * an `<unsupported>` sentinel — so structs that differ only in mapping or
309
+ * function-type members aren't collapsed together.
310
+ */
311
+ function fingerprintStruct(struct: CollectedStruct): string {
312
+ const segments = struct.members.map(
313
+ (m) => `${m.type ?? "<unsupported>"} ${m.name}`,
314
+ );
315
+
316
+ return `${struct.name}(${segments.join(",")})`;
317
+ }