hardhat 3.4.1 → 3.4.3

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 (292) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/dist/src/cli.js +5 -5
  3. package/dist/src/cli.js.map +1 -1
  4. package/dist/src/internal/builtin-plugins/artifacts/artifact-manager.d.ts.map +1 -1
  5. package/dist/src/internal/builtin-plugins/artifacts/artifact-manager.js +10 -3
  6. package/dist/src/internal/builtin-plugins/artifacts/artifact-manager.js.map +1 -1
  7. package/dist/src/internal/builtin-plugins/console/task-action.js +4 -4
  8. package/dist/src/internal/builtin-plugins/console/task-action.js.map +1 -1
  9. package/dist/src/internal/builtin-plugins/coverage/coverage-manager.js +7 -7
  10. package/dist/src/internal/builtin-plugins/coverage/coverage-manager.js.map +1 -1
  11. package/dist/src/internal/builtin-plugins/coverage/exports.d.ts +1 -1
  12. package/dist/src/internal/builtin-plugins/coverage/exports.d.ts.map +1 -1
  13. package/dist/src/internal/builtin-plugins/coverage/exports.js +1 -1
  14. package/dist/src/internal/builtin-plugins/coverage/exports.js.map +1 -1
  15. package/dist/src/internal/builtin-plugins/coverage/helpers/accessors.d.ts +7 -0
  16. package/dist/src/internal/builtin-plugins/coverage/helpers/accessors.d.ts.map +1 -0
  17. package/dist/src/internal/builtin-plugins/coverage/helpers/accessors.js +24 -0
  18. package/dist/src/internal/builtin-plugins/coverage/helpers/accessors.js.map +1 -0
  19. package/dist/src/internal/builtin-plugins/coverage/helpers/compat.d.ts +4 -0
  20. package/dist/src/internal/builtin-plugins/coverage/helpers/compat.d.ts.map +1 -0
  21. package/dist/src/internal/builtin-plugins/coverage/helpers/compat.js +27 -0
  22. package/dist/src/internal/builtin-plugins/coverage/helpers/compat.js.map +1 -0
  23. package/dist/src/internal/builtin-plugins/coverage/hook-handlers/clean.js +1 -1
  24. package/dist/src/internal/builtin-plugins/coverage/hook-handlers/clean.js.map +1 -1
  25. package/dist/src/internal/builtin-plugins/coverage/hook-handlers/hre.d.ts.map +1 -1
  26. package/dist/src/internal/builtin-plugins/coverage/hook-handlers/hre.js +18 -15
  27. package/dist/src/internal/builtin-plugins/coverage/hook-handlers/hre.js.map +1 -1
  28. package/dist/src/internal/builtin-plugins/coverage/hook-handlers/solidity.js +3 -3
  29. package/dist/src/internal/builtin-plugins/coverage/hook-handlers/solidity.js.map +1 -1
  30. package/dist/src/internal/builtin-plugins/coverage/hook-handlers/test.js +1 -1
  31. package/dist/src/internal/builtin-plugins/coverage/hook-handlers/test.js.map +1 -1
  32. package/dist/src/internal/builtin-plugins/coverage/instrumentation.d.ts.map +1 -1
  33. package/dist/src/internal/builtin-plugins/coverage/instrumentation.js +7 -2
  34. package/dist/src/internal/builtin-plugins/coverage/instrumentation.js.map +1 -1
  35. package/dist/src/internal/builtin-plugins/coverage/process-coverage.js +6 -6
  36. package/dist/src/internal/builtin-plugins/coverage/process-coverage.js.map +1 -1
  37. package/dist/src/internal/builtin-plugins/flatten/task-action.d.ts.map +1 -1
  38. package/dist/src/internal/builtin-plugins/flatten/task-action.js +4 -4
  39. package/dist/src/internal/builtin-plugins/flatten/task-action.js.map +1 -1
  40. package/dist/src/internal/builtin-plugins/gas-analytics/function-gas-snapshots.d.ts.map +1 -1
  41. package/dist/src/internal/builtin-plugins/gas-analytics/function-gas-snapshots.js +10 -10
  42. package/dist/src/internal/builtin-plugins/gas-analytics/function-gas-snapshots.js.map +1 -1
  43. package/dist/src/internal/builtin-plugins/gas-analytics/gas-analytics-manager.d.ts.map +1 -1
  44. package/dist/src/internal/builtin-plugins/gas-analytics/gas-analytics-manager.js +12 -9
  45. package/dist/src/internal/builtin-plugins/gas-analytics/gas-analytics-manager.js.map +1 -1
  46. package/dist/src/internal/builtin-plugins/gas-analytics/helpers/accessors.d.ts.map +1 -1
  47. package/dist/src/internal/builtin-plugins/gas-analytics/helpers/accessors.js +10 -4
  48. package/dist/src/internal/builtin-plugins/gas-analytics/helpers/accessors.js.map +1 -1
  49. package/dist/src/internal/builtin-plugins/gas-analytics/helpers/utils.js +2 -2
  50. package/dist/src/internal/builtin-plugins/gas-analytics/helpers/utils.js.map +1 -1
  51. package/dist/src/internal/builtin-plugins/gas-analytics/hook-handlers/hre.d.ts.map +1 -1
  52. package/dist/src/internal/builtin-plugins/gas-analytics/hook-handlers/hre.js +18 -14
  53. package/dist/src/internal/builtin-plugins/gas-analytics/hook-handlers/hre.js.map +1 -1
  54. package/dist/src/internal/builtin-plugins/gas-analytics/snapshot-cheatcodes.d.ts.map +1 -1
  55. package/dist/src/internal/builtin-plugins/gas-analytics/snapshot-cheatcodes.js +11 -16
  56. package/dist/src/internal/builtin-plugins/gas-analytics/snapshot-cheatcodes.js.map +1 -1
  57. package/dist/src/internal/builtin-plugins/gas-analytics/tasks/solidity-test/task-action.d.ts.map +1 -1
  58. package/dist/src/internal/builtin-plugins/gas-analytics/tasks/solidity-test/task-action.js +5 -5
  59. package/dist/src/internal/builtin-plugins/gas-analytics/tasks/solidity-test/task-action.js.map +1 -1
  60. package/dist/src/internal/builtin-plugins/network-manager/config-resolution.js +1 -1
  61. package/dist/src/internal/builtin-plugins/network-manager/config-resolution.js.map +1 -1
  62. package/dist/src/internal/builtin-plugins/network-manager/edr/edr-constants.d.ts +14 -0
  63. package/dist/src/internal/builtin-plugins/network-manager/edr/edr-constants.d.ts.map +1 -0
  64. package/dist/src/internal/builtin-plugins/network-manager/edr/edr-constants.js +40 -0
  65. package/dist/src/internal/builtin-plugins/network-manager/edr/edr-constants.js.map +1 -0
  66. package/dist/src/internal/builtin-plugins/network-manager/edr/edr-provider.d.ts +1 -12
  67. package/dist/src/internal/builtin-plugins/network-manager/edr/edr-provider.d.ts.map +1 -1
  68. package/dist/src/internal/builtin-plugins/network-manager/edr/edr-provider.js +2 -41
  69. package/dist/src/internal/builtin-plugins/network-manager/edr/edr-provider.js.map +1 -1
  70. package/dist/src/internal/builtin-plugins/network-manager/edr/types/hardfork.d.ts.map +1 -1
  71. package/dist/src/internal/builtin-plugins/network-manager/edr/types/hardfork.js +2 -5
  72. package/dist/src/internal/builtin-plugins/network-manager/edr/types/hardfork.js.map +1 -1
  73. package/dist/src/internal/builtin-plugins/network-manager/edr/utils/convert-to-edr.js +1 -1
  74. package/dist/src/internal/builtin-plugins/network-manager/edr/utils/convert-to-edr.js.map +1 -1
  75. package/dist/src/internal/builtin-plugins/network-manager/edr/utils/trace-formatters.d.ts +2 -2
  76. package/dist/src/internal/builtin-plugins/network-manager/edr/utils/trace-formatters.d.ts.map +1 -1
  77. package/dist/src/internal/builtin-plugins/network-manager/edr/utils/trace-formatters.js +21 -24
  78. package/dist/src/internal/builtin-plugins/network-manager/edr/utils/trace-formatters.js.map +1 -1
  79. package/dist/src/internal/builtin-plugins/network-manager/edr/utils/trace-output.d.ts.map +1 -1
  80. package/dist/src/internal/builtin-plugins/network-manager/edr/utils/trace-output.js +13 -11
  81. package/dist/src/internal/builtin-plugins/network-manager/edr/utils/trace-output.js.map +1 -1
  82. package/dist/src/internal/builtin-plugins/node/artifacts/build-info-watcher.js +2 -2
  83. package/dist/src/internal/builtin-plugins/node/artifacts/build-info-watcher.js.map +1 -1
  84. package/dist/src/internal/builtin-plugins/node/helpers.d.ts +2 -1
  85. package/dist/src/internal/builtin-plugins/node/helpers.d.ts.map +1 -1
  86. package/dist/src/internal/builtin-plugins/node/helpers.js +4 -4
  87. package/dist/src/internal/builtin-plugins/node/helpers.js.map +1 -1
  88. package/dist/src/internal/builtin-plugins/node/json-rpc/server.js +2 -2
  89. package/dist/src/internal/builtin-plugins/node/json-rpc/server.js.map +1 -1
  90. package/dist/src/internal/builtin-plugins/node/task-action.d.ts.map +1 -1
  91. package/dist/src/internal/builtin-plugins/node/task-action.js +4 -4
  92. package/dist/src/internal/builtin-plugins/node/task-action.js.map +1 -1
  93. package/dist/src/internal/builtin-plugins/solidity/build-system/build-system.d.ts.map +1 -1
  94. package/dist/src/internal/builtin-plugins/solidity/build-system/build-system.js +68 -29
  95. package/dist/src/internal/builtin-plugins/solidity/build-system/build-system.js.map +1 -1
  96. package/dist/src/internal/builtin-plugins/solidity/build-system/compilation-job-cost.d.ts +8 -0
  97. package/dist/src/internal/builtin-plugins/solidity/build-system/compilation-job-cost.d.ts.map +1 -0
  98. package/dist/src/internal/builtin-plugins/solidity/build-system/compilation-job-cost.js +46 -0
  99. package/dist/src/internal/builtin-plugins/solidity/build-system/compilation-job-cost.js.map +1 -0
  100. package/dist/src/internal/builtin-plugins/solidity/build-system/compiler/compiler.d.ts.map +1 -1
  101. package/dist/src/internal/builtin-plugins/solidity/build-system/compiler/compiler.js +9 -3
  102. package/dist/src/internal/builtin-plugins/solidity/build-system/compiler/compiler.js.map +1 -1
  103. package/dist/src/internal/builtin-plugins/solidity/build-system/compiler/downloader.d.ts.map +1 -1
  104. package/dist/src/internal/builtin-plugins/solidity/build-system/compiler/downloader.js +2 -2
  105. package/dist/src/internal/builtin-plugins/solidity/build-system/compiler/downloader.js.map +1 -1
  106. package/dist/src/internal/builtin-plugins/solidity/build-system/compiler/index.js +2 -2
  107. package/dist/src/internal/builtin-plugins/solidity/build-system/compiler/index.js.map +1 -1
  108. package/dist/src/internal/builtin-plugins/solidity/build-system/compiler/solcjs-wrapper.d.ts.map +1 -1
  109. package/dist/src/internal/builtin-plugins/solidity/build-system/compiler/solcjs-wrapper.js +7 -19
  110. package/dist/src/internal/builtin-plugins/solidity/build-system/compiler/solcjs-wrapper.js.map +1 -1
  111. package/dist/src/internal/builtin-plugins/solidity/build-system/resolver/dependency-resolver.d.ts.map +1 -1
  112. package/dist/src/internal/builtin-plugins/solidity/build-system/resolver/dependency-resolver.js +4 -3
  113. package/dist/src/internal/builtin-plugins/solidity/build-system/resolver/dependency-resolver.js.map +1 -1
  114. package/dist/src/internal/builtin-plugins/solidity/build-system/resolver/utils.d.ts +2 -1
  115. package/dist/src/internal/builtin-plugins/solidity/build-system/resolver/utils.d.ts.map +1 -1
  116. package/dist/src/internal/builtin-plugins/solidity/build-system/resolver/utils.js +12 -8
  117. package/dist/src/internal/builtin-plugins/solidity/build-system/resolver/utils.js.map +1 -1
  118. package/dist/src/internal/builtin-plugins/solidity/build-system/solc-info.d.ts +3 -2
  119. package/dist/src/internal/builtin-plugins/solidity/build-system/solc-info.d.ts.map +1 -1
  120. package/dist/src/internal/builtin-plugins/solidity/build-system/solc-info.js +15 -6
  121. package/dist/src/internal/builtin-plugins/solidity/build-system/solc-info.js.map +1 -1
  122. package/dist/src/internal/builtin-plugins/solidity/config.d.ts.map +1 -1
  123. package/dist/src/internal/builtin-plugins/solidity/config.js +2 -2
  124. package/dist/src/internal/builtin-plugins/solidity/config.js.map +1 -1
  125. package/dist/src/internal/builtin-plugins/solidity/constants.d.ts +1 -0
  126. package/dist/src/internal/builtin-plugins/solidity/constants.d.ts.map +1 -1
  127. package/dist/src/internal/builtin-plugins/solidity/constants.js +2 -0
  128. package/dist/src/internal/builtin-plugins/solidity/constants.js.map +1 -1
  129. package/dist/src/internal/builtin-plugins/solidity/hook-handlers/hre.d.ts.map +1 -1
  130. package/dist/src/internal/builtin-plugins/solidity/hook-handlers/hre.js +6 -1
  131. package/dist/src/internal/builtin-plugins/solidity/hook-handlers/hre.js.map +1 -1
  132. package/dist/src/internal/builtin-plugins/solidity-test/config.d.ts.map +1 -1
  133. package/dist/src/internal/builtin-plugins/solidity-test/config.js +1 -0
  134. package/dist/src/internal/builtin-plugins/solidity-test/config.js.map +1 -1
  135. package/dist/src/internal/builtin-plugins/solidity-test/helpers.d.ts +1 -2
  136. package/dist/src/internal/builtin-plugins/solidity-test/helpers.d.ts.map +1 -1
  137. package/dist/src/internal/builtin-plugins/solidity-test/helpers.js +3 -3
  138. package/dist/src/internal/builtin-plugins/solidity-test/helpers.js.map +1 -1
  139. package/dist/src/internal/builtin-plugins/solidity-test/reporter.d.ts +2 -2
  140. package/dist/src/internal/builtin-plugins/solidity-test/reporter.d.ts.map +1 -1
  141. package/dist/src/internal/builtin-plugins/solidity-test/reporter.js +19 -17
  142. package/dist/src/internal/builtin-plugins/solidity-test/reporter.js.map +1 -1
  143. package/dist/src/internal/builtin-plugins/solidity-test/task-action.d.ts.map +1 -1
  144. package/dist/src/internal/builtin-plugins/solidity-test/task-action.js +6 -3
  145. package/dist/src/internal/builtin-plugins/solidity-test/task-action.js.map +1 -1
  146. package/dist/src/internal/builtin-plugins/solidity-test/type-extensions.d.ts +1 -0
  147. package/dist/src/internal/builtin-plugins/solidity-test/type-extensions.d.ts.map +1 -1
  148. package/dist/src/internal/builtin-plugins/test/task-action.d.ts.map +1 -1
  149. package/dist/src/internal/builtin-plugins/test/task-action.js +9 -7
  150. package/dist/src/internal/builtin-plugins/test/task-action.js.map +1 -1
  151. package/dist/src/internal/cli/banner-manager.js +2 -2
  152. package/dist/src/internal/cli/banner-manager.js.map +1 -1
  153. package/dist/src/internal/cli/error-handler.d.ts.map +1 -1
  154. package/dist/src/internal/cli/error-handler.js +6 -6
  155. package/dist/src/internal/cli/error-handler.js.map +1 -1
  156. package/dist/src/internal/cli/help/get-help-string.js +2 -2
  157. package/dist/src/internal/cli/help/get-help-string.js.map +1 -1
  158. package/dist/src/internal/cli/init/init.d.ts.map +1 -1
  159. package/dist/src/internal/cli/init/init.js +57 -36
  160. package/dist/src/internal/cli/init/init.js.map +1 -1
  161. package/dist/src/internal/cli/init/package-manager.d.ts.map +1 -1
  162. package/dist/src/internal/cli/init/package-manager.js +5 -5
  163. package/dist/src/internal/cli/init/package-manager.js.map +1 -1
  164. package/dist/src/internal/cli/init/prompt.d.ts.map +1 -1
  165. package/dist/src/internal/cli/init/prompt.js +3 -3
  166. package/dist/src/internal/cli/init/prompt.js.map +1 -1
  167. package/dist/src/internal/cli/init/template.d.ts.map +1 -1
  168. package/dist/src/internal/cli/init/template.js +5 -14
  169. package/dist/src/internal/cli/init/template.js.map +1 -1
  170. package/dist/src/internal/cli/main.d.ts.map +1 -1
  171. package/dist/src/internal/cli/main.js +2 -2
  172. package/dist/src/internal/cli/main.js.map +1 -1
  173. package/dist/src/internal/cli/node-version.d.ts +1 -1
  174. package/dist/src/internal/cli/node-version.d.ts.map +1 -1
  175. package/dist/src/internal/cli/node-version.js +17 -10
  176. package/dist/src/internal/cli/node-version.js.map +1 -1
  177. package/dist/src/internal/cli/telemetry/analytics/analytics.js +2 -2
  178. package/dist/src/internal/cli/telemetry/analytics/analytics.js.map +1 -1
  179. package/dist/src/internal/cli/telemetry/analytics/utils.js +2 -2
  180. package/dist/src/internal/cli/telemetry/analytics/utils.js.map +1 -1
  181. package/dist/src/internal/cli/telemetry/error-reporter/global-error-handlers.js +2 -2
  182. package/dist/src/internal/cli/telemetry/error-reporter/global-error-handlers.js.map +1 -1
  183. package/dist/src/internal/cli/telemetry/sentry/reporter.js +2 -2
  184. package/dist/src/internal/cli/telemetry/sentry/reporter.js.map +1 -1
  185. package/dist/src/internal/cli/telemetry/sentry/subprocess.js +2 -2
  186. package/dist/src/internal/cli/telemetry/sentry/subprocess.js.map +1 -1
  187. package/dist/src/internal/cli/telemetry/sentry/transport.js +2 -2
  188. package/dist/src/internal/cli/telemetry/sentry/transport.js.map +1 -1
  189. package/dist/src/internal/cli/telemetry/telemetry-permissions.js +2 -2
  190. package/dist/src/internal/cli/telemetry/telemetry-permissions.js.map +1 -1
  191. package/dist/src/internal/config-loading.js +2 -2
  192. package/dist/src/internal/config-loading.js.map +1 -1
  193. package/dist/src/internal/core/hook-manager.d.ts.map +1 -1
  194. package/dist/src/internal/core/hook-manager.js +202 -58
  195. package/dist/src/internal/core/hook-manager.js.map +1 -1
  196. package/dist/src/internal/core/hre.js +2 -2
  197. package/dist/src/internal/core/hre.js.map +1 -1
  198. package/dist/src/internal/core/lazy-user-interruptions.d.ts +11 -0
  199. package/dist/src/internal/core/lazy-user-interruptions.d.ts.map +1 -0
  200. package/dist/src/internal/core/lazy-user-interruptions.js +39 -0
  201. package/dist/src/internal/core/lazy-user-interruptions.js.map +1 -0
  202. package/dist/src/internal/core/user-interruptions.js +4 -4
  203. package/dist/src/internal/core/user-interruptions.js.map +1 -1
  204. package/dist/src/internal/using-hardhat2-plugin-errors.d.ts.map +1 -1
  205. package/dist/src/internal/using-hardhat2-plugin-errors.js +2 -2
  206. package/dist/src/internal/using-hardhat2-plugin-errors.js.map +1 -1
  207. package/package.json +6 -9
  208. package/src/cli.ts +5 -5
  209. package/src/internal/builtin-plugins/artifacts/artifact-manager.ts +12 -5
  210. package/src/internal/builtin-plugins/console/task-action.ts +4 -4
  211. package/src/internal/builtin-plugins/coverage/coverage-manager.ts +7 -7
  212. package/src/internal/builtin-plugins/coverage/exports.ts +1 -1
  213. package/src/internal/builtin-plugins/coverage/helpers/accessors.ts +44 -0
  214. package/src/internal/builtin-plugins/coverage/helpers/compat.ts +37 -0
  215. package/src/internal/builtin-plugins/coverage/hook-handlers/clean.ts +1 -1
  216. package/src/internal/builtin-plugins/coverage/hook-handlers/hre.ts +26 -16
  217. package/src/internal/builtin-plugins/coverage/hook-handlers/solidity.ts +3 -3
  218. package/src/internal/builtin-plugins/coverage/hook-handlers/test.ts +1 -1
  219. package/src/internal/builtin-plugins/coverage/instrumentation.ts +21 -2
  220. package/src/internal/builtin-plugins/coverage/process-coverage.ts +6 -6
  221. package/src/internal/builtin-plugins/flatten/task-action.ts +8 -4
  222. package/src/internal/builtin-plugins/gas-analytics/function-gas-snapshots.ts +11 -10
  223. package/src/internal/builtin-plugins/gas-analytics/gas-analytics-manager.ts +13 -9
  224. package/src/internal/builtin-plugins/gas-analytics/helpers/accessors.ts +12 -5
  225. package/src/internal/builtin-plugins/gas-analytics/helpers/utils.ts +2 -2
  226. package/src/internal/builtin-plugins/gas-analytics/hook-handlers/hre.ts +29 -17
  227. package/src/internal/builtin-plugins/gas-analytics/snapshot-cheatcodes.ts +12 -15
  228. package/src/internal/builtin-plugins/gas-analytics/tasks/solidity-test/task-action.ts +11 -5
  229. package/src/internal/builtin-plugins/network-manager/config-resolution.ts +1 -1
  230. package/src/internal/builtin-plugins/network-manager/edr/edr-constants.ts +61 -0
  231. package/src/internal/builtin-plugins/network-manager/edr/edr-provider.ts +2 -61
  232. package/src/internal/builtin-plugins/network-manager/edr/types/hardfork.ts +3 -9
  233. package/src/internal/builtin-plugins/network-manager/edr/utils/convert-to-edr.ts +1 -1
  234. package/src/internal/builtin-plugins/network-manager/edr/utils/trace-formatters.ts +23 -23
  235. package/src/internal/builtin-plugins/network-manager/edr/utils/trace-output.ts +14 -11
  236. package/src/internal/builtin-plugins/node/artifacts/build-info-watcher.ts +2 -2
  237. package/src/internal/builtin-plugins/node/helpers.ts +8 -5
  238. package/src/internal/builtin-plugins/node/json-rpc/server.ts +2 -2
  239. package/src/internal/builtin-plugins/node/task-action.ts +5 -4
  240. package/src/internal/builtin-plugins/solidity/build-system/build-system.ts +92 -52
  241. package/src/internal/builtin-plugins/solidity/build-system/compilation-job-cost.ts +61 -0
  242. package/src/internal/builtin-plugins/solidity/build-system/compiler/compiler.ts +17 -3
  243. package/src/internal/builtin-plugins/solidity/build-system/compiler/downloader.ts +4 -2
  244. package/src/internal/builtin-plugins/solidity/build-system/compiler/index.ts +2 -2
  245. package/src/internal/builtin-plugins/solidity/build-system/compiler/solcjs-wrapper.ts +19 -22
  246. package/src/internal/builtin-plugins/solidity/build-system/resolver/dependency-resolver.ts +9 -1
  247. package/src/internal/builtin-plugins/solidity/build-system/resolver/utils.ts +16 -7
  248. package/src/internal/builtin-plugins/solidity/build-system/solc-info.ts +27 -6
  249. package/src/internal/builtin-plugins/solidity/config.ts +5 -2
  250. package/src/internal/builtin-plugins/solidity/constants.ts +3 -0
  251. package/src/internal/builtin-plugins/solidity/hook-handlers/hre.ts +13 -4
  252. package/src/internal/builtin-plugins/solidity-test/config.ts +1 -0
  253. package/src/internal/builtin-plugins/solidity-test/helpers.ts +3 -4
  254. package/src/internal/builtin-plugins/solidity-test/reporter.ts +19 -18
  255. package/src/internal/builtin-plugins/solidity-test/task-action.ts +6 -3
  256. package/src/internal/builtin-plugins/solidity-test/type-extensions.ts +1 -0
  257. package/src/internal/builtin-plugins/test/task-action.ts +13 -7
  258. package/src/internal/cli/banner-manager.ts +2 -2
  259. package/src/internal/cli/error-handler.ts +10 -6
  260. package/src/internal/cli/help/get-help-string.ts +2 -2
  261. package/src/internal/cli/init/init.ts +86 -43
  262. package/src/internal/cli/init/package-manager.ts +8 -6
  263. package/src/internal/cli/init/prompt.ts +4 -3
  264. package/src/internal/cli/init/template.ts +22 -27
  265. package/src/internal/cli/main.ts +4 -3
  266. package/src/internal/cli/node-version.ts +20 -12
  267. package/src/internal/cli/telemetry/analytics/analytics.ts +2 -2
  268. package/src/internal/cli/telemetry/analytics/utils.ts +2 -2
  269. package/src/internal/cli/telemetry/error-reporter/global-error-handlers.ts +2 -2
  270. package/src/internal/cli/telemetry/sentry/reporter.ts +2 -2
  271. package/src/internal/cli/telemetry/sentry/subprocess.ts +2 -2
  272. package/src/internal/cli/telemetry/sentry/transport.ts +2 -2
  273. package/src/internal/cli/telemetry/telemetry-permissions.ts +2 -2
  274. package/src/internal/config-loading.ts +2 -2
  275. package/src/internal/core/hook-manager.ts +283 -101
  276. package/src/internal/core/hre.ts +2 -2
  277. package/src/internal/core/lazy-user-interruptions.ts +75 -0
  278. package/src/internal/core/user-interruptions.ts +4 -4
  279. package/src/internal/using-hardhat2-plugin-errors.ts +2 -2
  280. package/templates/hardhat-3/01-node-test-runner-viem/package.json +7 -7
  281. package/templates/hardhat-3/02-mocha-ethers/package.json +13 -13
  282. package/templates/hardhat-3/03-minimal/package.json +1 -1
  283. package/dist/src/internal/builtin-plugins/coverage/helpers.d.ts +0 -15
  284. package/dist/src/internal/builtin-plugins/coverage/helpers.d.ts.map +0 -1
  285. package/dist/src/internal/builtin-plugins/coverage/helpers.js +0 -35
  286. package/dist/src/internal/builtin-plugins/coverage/helpers.js.map +0 -1
  287. package/dist/src/internal/utils/colorizer.d.ts +0 -10
  288. package/dist/src/internal/utils/colorizer.d.ts.map +0 -1
  289. package/dist/src/internal/utils/colorizer.js +0 -2
  290. package/dist/src/internal/utils/colorizer.js.map +0 -1
  291. package/src/internal/builtin-plugins/coverage/helpers.ts +0 -63
  292. package/src/internal/utils/colorizer.ts +0 -9
@@ -4,13 +4,13 @@ import path from "node:path";
4
4
  import { fileURLToPath, pathToFileURL } from "node:url";
5
5
 
6
6
  import { HardhatError } from "@nomicfoundation/hardhat-errors";
7
+ import { createDebug } from "@nomicfoundation/hardhat-utils/debug";
7
8
  import { ensureError } from "@nomicfoundation/hardhat-utils/error";
8
9
  import { exists, findUp, getRealPath } from "@nomicfoundation/hardhat-utils/fs";
9
10
  import { isObject } from "@nomicfoundation/hardhat-utils/lang";
10
11
  import { resolveFromRoot } from "@nomicfoundation/hardhat-utils/path";
11
- import debug from "debug";
12
12
 
13
- const log = debug("hardhat:core:config-loading");
13
+ const log = createDebug("hardhat:core:config-loading");
14
14
 
15
15
  /**
16
16
  * This cache stores any `.ts` files compiled using `tsImport`.
@@ -12,7 +12,10 @@ import type {
12
12
  import type { HardhatPlugin } from "../../types/plugins.js";
13
13
  import type { LastParameter, Return } from "../../types/utils.js";
14
14
 
15
- import { assertHardhatInvariant } from "@nomicfoundation/hardhat-errors";
15
+ import {
16
+ assertHardhatInvariant,
17
+ HardhatError,
18
+ } from "@nomicfoundation/hardhat-errors";
16
19
  import { ensureError } from "@nomicfoundation/hardhat-utils/error";
17
20
  import { AsyncMutex } from "@nomicfoundation/hardhat-utils/synchronization";
18
21
 
@@ -23,35 +26,94 @@ export class HookManagerImplementation implements HookManager {
23
26
 
24
27
  readonly #projectRoot: string;
25
28
 
26
- readonly #pluginsInReverseOrder: HardhatPlugin[];
27
-
28
29
  /**
30
+ * The context passed to hook handlers, except to the `config` ones, to break
31
+ * a circular dependency between the config and the hook handler.
32
+ *
29
33
  * Initially `undefined` to be able to run the config hooks during
30
34
  * initialization.
31
35
  */
32
36
  #context: HookContext | undefined;
33
37
 
34
38
  /**
35
- * The initialized handler categories for each plugin.
39
+ * Plugins that provide hook handlers for each category, in reverse order.
40
+ *
41
+ * Precomputed from the plugin list at construction.
42
+ */
43
+ readonly #pluginsByHookCategory: Map<keyof HardhatHooks, HardhatPlugin[]> =
44
+ new Map();
45
+
46
+ /**
47
+ * Cached resolved category objects per hook category in reverse plugin
48
+ * order.
49
+ *
50
+ * Only written by #getStaticHookHandlerCategories, which uses a mutex to
51
+ * ensure that every Hook Category Factory is run once per HookManager
52
+ * instance.
36
53
  */
37
- readonly #staticHookHandlerCategories: Map<
38
- string,
39
- Map<keyof HardhatHooks, Partial<HardhatHooks[keyof HardhatHooks]>>
54
+ readonly #resolvedStaticCategories: Map<
55
+ keyof HardhatHooks,
56
+ Array<Partial<HardhatHooks[keyof HardhatHooks]>>
40
57
  > = new Map();
41
58
 
42
59
  /**
43
60
  * A map of the dynamically registered handler categories.
44
61
  *
45
62
  * Each array is a list of categories, in reverse order of registration.
63
+ *
64
+ * Written by registerHandlers and unregisterHandlers.
46
65
  */
47
66
  readonly #dynamicHookHandlerCategories: Map<
48
67
  keyof HardhatHooks,
49
68
  Array<Partial<HardhatHooks[keyof HardhatHooks]>>
50
69
  > = new Map();
51
70
 
71
+ /**
72
+ * Cached combined (dynamic + static) handlers per (category, hook name) in
73
+ * chained running order.
74
+ *
75
+ * Only written by #getHandlersInChainedRunningOrder, and invalidated
76
+ * per-category on dynamic handlers register/unregister.
77
+ */
78
+ readonly #chainedHandlers: Map<keyof HardhatHooks, Map<string, any[]>> =
79
+ new Map();
80
+
81
+ /**
82
+ * Cached combined handlers per (category, hook name) in sequential running
83
+ * order (reverse of chained).
84
+ *
85
+ * Only written by #getHandlersInSequentialRunningOrder, and invalidated
86
+ * per-category on dynamic handlers register/unregister.
87
+ */
88
+ readonly #sequentialHandlers: Map<keyof HardhatHooks, Map<string, any[]>> =
89
+ new Map();
90
+
52
91
  constructor(projectRoot: string, plugins: HardhatPlugin[]) {
53
92
  this.#projectRoot = projectRoot;
54
- this.#pluginsInReverseOrder = plugins.toReversed();
93
+
94
+ for (const plugin of plugins.toReversed()) {
95
+ if (plugin.hookHandlers === undefined) {
96
+ continue;
97
+ }
98
+
99
+ for (const hookCategoryName of Object.keys(plugin.hookHandlers) as Array<
100
+ keyof HardhatHooks
101
+ >) {
102
+ if (plugin.hookHandlers[hookCategoryName] === undefined) {
103
+ continue;
104
+ }
105
+
106
+ let pluginsForCategory =
107
+ this.#pluginsByHookCategory.get(hookCategoryName);
108
+
109
+ if (pluginsForCategory === undefined) {
110
+ pluginsForCategory = [];
111
+ this.#pluginsByHookCategory.set(hookCategoryName, pluginsForCategory);
112
+ }
113
+
114
+ pluginsForCategory.push(plugin);
115
+ }
116
+ }
55
117
  }
56
118
 
57
119
  public setContext(context: HookContext): void {
@@ -69,6 +131,8 @@ export class HookManagerImplementation implements HookManager {
69
131
  }
70
132
 
71
133
  categories.unshift(hookHandlerCategory);
134
+
135
+ this.#invalidateResolvedHandlersCache(hookCategoryName);
72
136
  }
73
137
 
74
138
  public unregisterHandlers<HookCategoryNameT extends keyof HardhatHooks>(
@@ -84,6 +148,8 @@ export class HookManagerImplementation implements HookManager {
84
148
  hookCategoryName,
85
149
  categories.filter((c) => c !== hookHandlerCategory),
86
150
  );
151
+
152
+ this.#invalidateResolvedHandlersCache(hookCategoryName);
87
153
  }
88
154
 
89
155
  public async runHandlerChain<
@@ -96,10 +162,23 @@ export class HookManagerImplementation implements HookManager {
96
162
  params: InitialChainedHookParams<HookCategoryNameT, HookT>,
97
163
  defaultImplementation: LastParameter<HookT>,
98
164
  ): Promise<Awaited<Return<HardhatHooks[HookCategoryNameT][HookNameT]>>> {
99
- const handlers = await this.#getHandlersInChainedRunningOrder(
100
- hookCategoryName,
101
- hookName,
102
- );
165
+ // Synchronous fast path for already cached handlers. This duplicates
166
+ // the check inside #getHandlersInChainedRunningOrder on purpose:
167
+ // calling that async method introduces a microtask tick even on a
168
+ // cache hit, whereas a direct Map lookup stays on the current tick.
169
+ // That tick matters here because runHandlerChain is on every hook's
170
+ // hot path, and this path pairs with the empty-handlers shortcut
171
+ // below to dispatch straight to defaultImplementation with no awaits.
172
+ const cachedHandlers = this.#chainedHandlers
173
+ .get(hookCategoryName)
174
+ ?.get(hookName as string);
175
+
176
+ const handlers =
177
+ cachedHandlers ??
178
+ (await this.#getHandlersInChainedRunningOrder(
179
+ hookCategoryName,
180
+ hookName,
181
+ ));
103
182
 
104
183
  let handlerParams: Parameters<typeof defaultImplementation>;
105
184
  if (hookCategoryName !== "config") {
@@ -113,6 +192,13 @@ export class HookManagerImplementation implements HookManager {
113
192
  handlerParams = params as any;
114
193
  }
115
194
 
195
+ // Fast path for the common case of no registered handlers: skip building
196
+ // handlerParams and the `next` closure, and call the default implementation
197
+ // directly.
198
+ if (handlers.length === 0) {
199
+ return (await defaultImplementation(...handlerParams)) as any;
200
+ }
201
+
116
202
  const numberOfHandlers = handlers.length;
117
203
  let index = 0;
118
204
  const next = async (...nextParams: typeof handlerParams) => {
@@ -220,14 +306,48 @@ export class HookManagerImplementation implements HookManager {
220
306
  hookCategoryName: HookCategoryNameT,
221
307
  hookName: HookNameT,
222
308
  ): Promise<Array<HardhatHooks[HookCategoryNameT][HookNameT]>> {
223
- const pluginHooks = await this.#getPluginHooks(hookCategoryName, hookName);
309
+ let handlersByName = this.#chainedHandlers.get(hookCategoryName);
310
+ if (handlersByName === undefined) {
311
+ handlersByName = new Map();
312
+ this.#chainedHandlers.set(hookCategoryName, handlersByName);
313
+ }
314
+
315
+ const cached = handlersByName.get(hookName as string);
316
+ if (cached !== undefined) {
317
+ return cached;
318
+ }
319
+
320
+ const staticCategories =
321
+ await this.#getStaticHookHandlerCategories(hookCategoryName);
224
322
 
225
- const dynamicHooks = await this.#getDynamicHooks(
323
+ // IMPORTANT NOTE: Accessing the dynamic hook handlers MUST happen
324
+ // after awaiting the static ones. See
325
+ // #invalidateResolvedHandlersCache for more info.
326
+ const dynamicCategories = this.#dynamicHookHandlerCategories.get(
226
327
  hookCategoryName,
227
- hookName,
228
- );
328
+ ) as Array<Partial<HardhatHooks[HookCategoryNameT]>> | undefined;
329
+
330
+ const handlers: Array<HardhatHooks[HookCategoryNameT][HookNameT]> = [];
331
+
332
+ if (dynamicCategories !== undefined) {
333
+ for (const category of dynamicCategories) {
334
+ const handler = category[hookName];
335
+ if (handler !== undefined) {
336
+ handlers.push(handler as HardhatHooks[HookCategoryNameT][HookNameT]);
337
+ }
338
+ }
339
+ }
340
+
341
+ for (const category of staticCategories) {
342
+ const handler = category[hookName];
343
+ if (handler !== undefined) {
344
+ handlers.push(handler as HardhatHooks[HookCategoryNameT][HookNameT]);
345
+ }
346
+ }
229
347
 
230
- return [...dynamicHooks, ...pluginHooks];
348
+ handlersByName.set(hookName as string, handlers);
349
+
350
+ return handlers;
231
351
  }
232
352
 
233
353
  async #getHandlersInSequentialRunningOrder<
@@ -237,111 +357,173 @@ export class HookManagerImplementation implements HookManager {
237
357
  hookCategoryName: HookCategoryNameT,
238
358
  hookName: HookNameT,
239
359
  ): Promise<Array<HardhatHooks[HookCategoryNameT][HookNameT]>> {
240
- const handlersInChainedOrder = await this.#getHandlersInChainedRunningOrder(
360
+ let handlersByName = this.#sequentialHandlers.get(hookCategoryName);
361
+ if (handlersByName === undefined) {
362
+ handlersByName = new Map();
363
+ this.#sequentialHandlers.set(hookCategoryName, handlersByName);
364
+ }
365
+
366
+ const cached = handlersByName.get(hookName as string);
367
+ if (cached !== undefined) {
368
+ return cached;
369
+ }
370
+
371
+ const chained = await this.#getHandlersInChainedRunningOrder(
241
372
  hookCategoryName,
242
373
  hookName,
243
374
  );
244
375
 
245
- return handlersInChainedOrder.reverse();
376
+ const sequential = chained.toReversed();
377
+
378
+ handlersByName.set(hookName as string, sequential);
379
+
380
+ return sequential;
246
381
  }
247
382
 
248
- async #getDynamicHooks<
383
+ async #getStaticHookHandlerCategories<
249
384
  HookCategoryNameT extends keyof HardhatHooks,
250
- HookNameT extends keyof HardhatHooks[HookCategoryNameT],
251
385
  >(
252
386
  hookCategoryName: HookCategoryNameT,
253
- hookName: HookNameT,
254
- ): Promise<Array<HardhatHooks[HookCategoryNameT][HookNameT]>> {
255
- const categories = this.#dynamicHookHandlerCategories.get(
256
- hookCategoryName,
257
- ) as Array<Partial<HardhatHooks[HookCategoryNameT]>> | undefined;
387
+ ): Promise<Array<Partial<HardhatHooks[HookCategoryNameT]>>> {
388
+ const cached = this.#resolvedStaticCategories.get(hookCategoryName) as
389
+ | Array<Partial<HardhatHooks[HookCategoryNameT]>>
390
+ | undefined;
258
391
 
259
- if (categories === undefined) {
392
+ if (cached !== undefined) {
393
+ return cached;
394
+ }
395
+
396
+ const plugins = this.#pluginsByHookCategory.get(hookCategoryName);
397
+
398
+ // We don't need to get the mutex to resolve this case, as it will always
399
+ // be an empty array, and won't execute any factory.
400
+ if (plugins === undefined) {
401
+ this.#resolvedStaticCategories.set(hookCategoryName, []);
260
402
  return [];
261
403
  }
262
404
 
263
- return categories.flatMap((hookCategory) => {
264
- return (hookCategory[hookName] ?? []) as Array<
265
- HardhatHooks[HookCategoryNameT][HookNameT]
266
- >;
405
+ return await this.#mutex.exclusiveRun(async () => {
406
+ // Re-check under the mutex in case another caller just populated it.
407
+ const recheck = this.#resolvedStaticCategories.get(hookCategoryName) as
408
+ | Array<Partial<HardhatHooks[HookCategoryNameT]>>
409
+ | undefined;
410
+
411
+ if (recheck !== undefined) {
412
+ return recheck;
413
+ }
414
+
415
+ const resolved = await Promise.all(
416
+ plugins.map(
417
+ async (plugin) =>
418
+ await this.#getPluginStaticHookCategory(plugin, hookCategoryName),
419
+ ),
420
+ );
421
+
422
+ this.#resolvedStaticCategories.set(hookCategoryName, resolved);
423
+
424
+ return resolved;
267
425
  });
268
426
  }
269
427
 
270
- async #getPluginHooks<
428
+ /**
429
+ * Returns the hook category object for a plugin that has the hook category
430
+ * defined.
431
+ *
432
+ * @param plugin A plugin that MUST have the given hook category defined.
433
+ * @param hookCategoryName The name of the hook category.
434
+ * @returns The hook category object.
435
+ */
436
+ async #getPluginStaticHookCategory<
271
437
  HookCategoryNameT extends keyof HardhatHooks,
272
- HookNameT extends keyof HardhatHooks[HookCategoryNameT],
273
438
  >(
439
+ plugin: HardhatPlugin,
274
440
  hookCategoryName: HookCategoryNameT,
275
- hookName: HookNameT,
276
- ): Promise<Array<HardhatHooks[HookCategoryNameT][HookNameT]>> {
277
- const categories: Array<
278
- Partial<HardhatHooks[HookCategoryNameT]> | undefined
279
- > = await this.#mutex.exclusiveRun(async () => {
280
- return await Promise.all(
281
- this.#pluginsInReverseOrder.map(async (plugin) => {
282
- const existingCategory = this.#staticHookHandlerCategories
283
- .get(plugin.id)
284
- ?.get(hookCategoryName);
285
-
286
- if (existingCategory !== undefined) {
287
- return existingCategory as Partial<HardhatHooks[HookCategoryNameT]>;
288
- }
289
-
290
- const hookHandlerCategoryFactory =
291
- plugin.hookHandlers?.[hookCategoryName];
292
-
293
- if (hookHandlerCategoryFactory === undefined) {
294
- return;
295
- }
296
-
297
- let factory;
298
- try {
299
- factory = (await hookHandlerCategoryFactory()).default;
300
- } catch (error) {
301
- ensureError(error);
302
-
303
- await detectPluginNpmDependencyProblems(
304
- this.#projectRoot,
305
- plugin,
306
- error,
307
- );
308
-
309
- throw error;
310
- }
311
-
312
- assertHardhatInvariant(
313
- typeof factory === "function",
314
- `Plugin ${plugin.id} doesn't export a hook factory for category ${hookCategoryName}`,
315
- );
316
-
317
- const hookCategory = await factory();
318
-
319
- assertHardhatInvariant(
320
- hookCategory !== null && typeof hookCategory === "object",
321
- `Plugin ${plugin.id} doesn't export a valid factory for category ${hookCategoryName}, it didn't return an object`,
322
- );
323
-
324
- if (!this.#staticHookHandlerCategories.has(plugin.id)) {
325
- this.#staticHookHandlerCategories.set(plugin.id, new Map());
326
- }
327
-
328
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- Defined right above
329
- this.#staticHookHandlerCategories
330
- .get(plugin.id)!
331
- .set(hookCategoryName, hookCategory);
332
-
333
- return hookCategory;
334
- }),
441
+ ): Promise<Partial<HardhatHooks[HookCategoryNameT]>> {
442
+ const hookHandlerCategoryFactory = plugin.hookHandlers?.[hookCategoryName];
443
+
444
+ assertHardhatInvariant(
445
+ hookHandlerCategoryFactory !== undefined,
446
+ "#pluginsByHookCategory only contains plugins with this hook category",
447
+ );
448
+
449
+ let factory;
450
+ try {
451
+ factory = (await hookHandlerCategoryFactory()).default;
452
+ } catch (error) {
453
+ ensureError(error);
454
+
455
+ await detectPluginNpmDependencyProblems(this.#projectRoot, plugin, error);
456
+
457
+ throw new HardhatError(
458
+ HardhatError.ERRORS.CORE.HOOKS.FAILED_TO_LOAD_HOOK_HANDLER_FACTORY,
459
+ { pluginId: plugin.id, hookCategoryName },
460
+ error,
335
461
  );
336
- });
462
+ }
337
463
 
338
- return categories.flatMap((category) => {
339
- const handler = category?.[hookName];
340
- if (handler === undefined) {
341
- return [];
342
- }
464
+ assertHardhatInvariant(
465
+ typeof factory === "function",
466
+ `Plugin ${plugin.id} doesn't export a hook factory for category ${hookCategoryName}`,
467
+ );
343
468
 
344
- return handler as HardhatHooks[HookCategoryNameT][HookNameT];
345
- });
469
+ let hookCategory: Partial<HardhatHooks[HookCategoryNameT]>;
470
+ try {
471
+ hookCategory = await factory();
472
+ } catch (error) {
473
+ ensureError(error);
474
+
475
+ throw new HardhatError(
476
+ HardhatError.ERRORS.CORE.HOOKS.FAILED_TO_RUN_HOOK_HANDLER_FACTORY,
477
+ { pluginId: plugin.id, hookCategoryName },
478
+ error,
479
+ );
480
+ }
481
+
482
+ assertHardhatInvariant(
483
+ hookCategory !== null && typeof hookCategory === "object",
484
+ `Plugin ${plugin.id} doesn't export a valid factory for category ${hookCategoryName}, it didn't return an object`,
485
+ );
486
+
487
+ return hookCategory;
488
+ }
489
+
490
+ #invalidateResolvedHandlersCache<
491
+ HookCategoryNameT extends keyof HardhatHooks,
492
+ >(hookCategoryName: HookCategoryNameT) {
493
+ // Invalidation deletes the outer entry rather than clearing the inner
494
+ // map. This matters under concurrency.
495
+ //
496
+ // A reader of #getHandlersInChainedRunningOrder (or its sequential
497
+ // sibling) captures a reference to the inner map before awaiting the
498
+ // static categories, and writes its computed array back after the
499
+ // await. If invalidation runs during that await, deleting the outer
500
+ // entry leaves the reader's inner map orphaned: its write lands in a
501
+ // map no longer reachable from #chainedHandlers/#sequentialHandlers,
502
+ // so it cannot poison the shared cache. The next reader sees
503
+ // `undefined`, installs a fresh inner map, and rebuilds from the
504
+ // current dynamic state.
505
+ //
506
+ // Two distinct properties make this safe, guaranteed by two different
507
+ // things:
508
+ //
509
+ // 1. The in-flight reader's own return value is correct. This is
510
+ // because #getHandlersInChainedRunningOrder reads
511
+ // #dynamicHookHandlerCategories *after* awaiting the static
512
+ // categories. Any invalidation that happened during the await is
513
+ // visible to the reader when it resumes, so the array it builds
514
+ // reflects the current dynamic state.
515
+ //
516
+ // 2. The shared cache never holds a stale array. This is guaranteed
517
+ // by the orphaning-by-delete described above: a reader that
518
+ // started before the invalidation can only write into an
519
+ // unreachable inner map.
520
+ //
521
+ // Property 1 depends on the ordering of the dynamic handlers read relative
522
+ // to the await. If that read ever moved *before* the await, a reader
523
+ // could build a stale array and return it to its caller — the cache
524
+ // would still be protected by property 2, but the reader's caller
525
+ // would see the stale result.
526
+ this.#chainedHandlers.delete(hookCategoryName);
527
+ this.#sequentialHandlers.delete(hookCategoryName);
346
528
  }
347
529
  }
@@ -40,9 +40,9 @@ import {
40
40
  resolveGlobalOptions,
41
41
  } from "./global-options.js";
42
42
  import { HookManagerImplementation } from "./hook-manager.js";
43
+ import { LazyUserInterruptionManager } from "./lazy-user-interruptions.js";
43
44
  import { resolvePluginList } from "./plugins/resolve-plugin-list.js";
44
45
  import { TaskManagerImplementation } from "./tasks/task-manager.js";
45
- import { UserInterruptionManagerImplementation } from "./user-interruptions.js";
46
46
 
47
47
  export class HardhatRuntimeEnvironmentImplementation
48
48
  implements HardhatRuntimeEnvironment
@@ -134,7 +134,7 @@ export class HardhatRuntimeEnvironmentImplementation
134
134
 
135
135
  // Set the HookContext in the hook manager so that non-config hooks can
136
136
  // use it
137
- const interruptions = new UserInterruptionManagerImplementation(hooks);
137
+ const interruptions = new LazyUserInterruptionManager(hooks);
138
138
 
139
139
  const hre = new HardhatRuntimeEnvironmentImplementation(
140
140
  extendedUserConfig,
@@ -0,0 +1,75 @@
1
+ import type { UserInterruptionManagerImplementation as UserInterruptionManagerImplementationT } from "./user-interruptions.js";
2
+ import type { HookManager } from "../../types/hooks.js";
3
+ import type { UserInterruptionManager } from "../../types/user-interruptions.js";
4
+
5
+ let UserInterruptionManagerImplementation:
6
+ | typeof UserInterruptionManagerImplementationT
7
+ | undefined;
8
+
9
+ export class LazyUserInterruptionManager implements UserInterruptionManager {
10
+ readonly #hooks: HookManager;
11
+
12
+ #userInterruptionManager: UserInterruptionManagerImplementationT | undefined;
13
+
14
+ constructor(hooks: HookManager) {
15
+ this.#hooks = hooks;
16
+ }
17
+
18
+ public async displayMessage(
19
+ interruptor: string,
20
+ message: string,
21
+ ): Promise<void> {
22
+ const userInterruptionManager = await this.#getUserInterruptionManager();
23
+ return await userInterruptionManager.displayMessage(interruptor, message);
24
+ }
25
+
26
+ public async requestInput(
27
+ interruptor: string,
28
+ inputDescription: string,
29
+ ): Promise<string> {
30
+ const userInterruptionManager = await this.#getUserInterruptionManager();
31
+ return await userInterruptionManager.requestInput(
32
+ interruptor,
33
+ inputDescription,
34
+ );
35
+ }
36
+
37
+ public async requestSecretInput(
38
+ interruptor: string,
39
+ inputDescription: string,
40
+ ): Promise<string> {
41
+ const userInterruptionManager = await this.#getUserInterruptionManager();
42
+ return await userInterruptionManager.requestSecretInput(
43
+ interruptor,
44
+ inputDescription,
45
+ );
46
+ }
47
+
48
+ public async uninterrupted<ReturnT>(
49
+ f: () => ReturnT,
50
+ ): Promise<Awaited<ReturnT>> {
51
+ const userInterruptionManager = await this.#getUserInterruptionManager();
52
+ return await userInterruptionManager.uninterrupted(f);
53
+ }
54
+
55
+ async #getUserInterruptionManager(): Promise<UserInterruptionManagerImplementationT> {
56
+ // Note: `await import` must run BEFORE the instance cache check so that
57
+ // concurrent callers share a single microtask-dedupe point — otherwise
58
+ // each suspended caller re-enters the branch and constructs its own
59
+ // impl, so callers end up holding different impl instances and state,
60
+ // which can cause concurrency issues.
61
+ if (UserInterruptionManagerImplementation === undefined) {
62
+ ({ UserInterruptionManagerImplementation } = await import(
63
+ "./user-interruptions.js"
64
+ ));
65
+ }
66
+
67
+ if (this.#userInterruptionManager === undefined) {
68
+ this.#userInterruptionManager = new UserInterruptionManagerImplementation(
69
+ this.#hooks,
70
+ );
71
+ }
72
+
73
+ return this.#userInterruptionManager;
74
+ }
75
+ }
@@ -2,10 +2,10 @@ import type { HookContext, HookManager } from "../../types/hooks.js";
2
2
  import type { UserInterruptionManager } from "../../types/user-interruptions.js";
3
3
 
4
4
  import { createInterface } from "node:readline";
5
+ import { styleText } from "node:util";
5
6
 
6
7
  import { assertHardhatInvariant } from "@nomicfoundation/hardhat-errors";
7
8
  import { AsyncMutex } from "@nomicfoundation/hardhat-utils/synchronization";
8
- import chalk from "chalk";
9
9
 
10
10
  export class UserInterruptionManagerImplementation
11
11
  implements UserInterruptionManager
@@ -71,7 +71,7 @@ async function defaultDisplayMessage(
71
71
  interruptor: string,
72
72
  message: string,
73
73
  ) {
74
- console.log(chalk.blue(`[${interruptor}]`) + ` ${message}`);
74
+ console.log(styleText("blue", `[${interruptor}]`) + ` ${message}`);
75
75
  }
76
76
 
77
77
  async function defaultRequestInput(
@@ -86,7 +86,7 @@ async function defaultRequestInput(
86
86
 
87
87
  return await new Promise<string>((resolve) => {
88
88
  rl.question(
89
- chalk.blue(`[${interruptor}]`) + ` ${inputDescription}: `,
89
+ styleText("blue", `[${interruptor}]`) + ` ${inputDescription}: `,
90
90
  (answer) => {
91
91
  resolve(answer);
92
92
  rl.close();
@@ -140,7 +140,7 @@ async function defaultRequestSecretInput(
140
140
 
141
141
  return await new Promise<string>((resolve) => {
142
142
  rl.question(
143
- chalk.blue(`[${interruptor}]`) + ` ${inputDescription}: `,
143
+ styleText("blue", `[${interruptor}]`) + ` ${inputDescription}: `,
144
144
  (answer) => {
145
145
  resolve(answer);
146
146
  rl.close();
@@ -1,8 +1,8 @@
1
1
  import { fileURLToPath } from "node:url";
2
+ import { styleText } from "node:util";
2
3
 
3
4
  import { CustomError } from "@nomicfoundation/hardhat-utils/error";
4
5
  import { shortenPath } from "@nomicfoundation/hardhat-utils/path";
5
- import chalk from "chalk";
6
6
 
7
7
  export class UsingHardhat2PluginError extends CustomError {
8
8
  public readonly callerRelativePath: string | undefined;
@@ -13,7 +13,7 @@ export class UsingHardhat2PluginError extends CustomError {
13
13
  if (callerPath !== undefined) {
14
14
  message = `You are trying to use a Hardhat 2 plugin in a Hardhat 3 project.
15
15
 
16
- This file is part of a Hardhat 2 plugin calling an API that was removed in Hardhat 3: ${chalk.bold(callerPath)}
16
+ This file is part of a Hardhat 2 plugin calling an API that was removed in Hardhat 3: ${styleText("bold", callerPath)}
17
17
 
18
18
  Please read https://hardhat.org/migrate-from-hardhat2 to learn how to migrate your project to Hardhat 3.
19
19
  `;