@0xsequence/catapult 1.1.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 (393) hide show
  1. package/.eslintrc.json +29 -0
  2. package/.github/workflows/ci.yml +181 -0
  3. package/CONCEPT.md +24 -0
  4. package/README.md +772 -0
  5. package/contracts/checked-call.huff +65 -0
  6. package/dist/cli.d.ts +3 -0
  7. package/dist/cli.d.ts.map +1 -0
  8. package/dist/cli.js +16 -0
  9. package/dist/cli.js.map +1 -0
  10. package/dist/commands/common.d.ts +11 -0
  11. package/dist/commands/common.d.ts.map +1 -0
  12. package/dist/commands/common.js +73 -0
  13. package/dist/commands/common.js.map +1 -0
  14. package/dist/commands/dry.d.ts +3 -0
  15. package/dist/commands/dry.d.ts.map +1 -0
  16. package/dist/commands/dry.js +171 -0
  17. package/dist/commands/dry.js.map +1 -0
  18. package/dist/commands/etherscan.d.ts +3 -0
  19. package/dist/commands/etherscan.d.ts.map +1 -0
  20. package/dist/commands/etherscan.js +323 -0
  21. package/dist/commands/etherscan.js.map +1 -0
  22. package/dist/commands/index.d.ts +6 -0
  23. package/dist/commands/index.d.ts.map +1 -0
  24. package/dist/commands/index.js +22 -0
  25. package/dist/commands/index.js.map +1 -0
  26. package/dist/commands/list.d.ts +3 -0
  27. package/dist/commands/list.d.ts.map +1 -0
  28. package/dist/commands/list.js +259 -0
  29. package/dist/commands/list.js.map +1 -0
  30. package/dist/commands/run.d.ts +3 -0
  31. package/dist/commands/run.d.ts.map +1 -0
  32. package/dist/commands/run.js +96 -0
  33. package/dist/commands/run.js.map +1 -0
  34. package/dist/commands/utils.d.ts +3 -0
  35. package/dist/commands/utils.d.ts.map +1 -0
  36. package/dist/commands/utils.js +46 -0
  37. package/dist/commands/utils.js.map +1 -0
  38. package/dist/index.d.ts +4 -0
  39. package/dist/index.d.ts.map +1 -0
  40. package/dist/index.js +58 -0
  41. package/dist/index.js.map +1 -0
  42. package/dist/lib/__tests__/deployer-events.spec.d.ts +2 -0
  43. package/dist/lib/__tests__/deployer-events.spec.d.ts.map +1 -0
  44. package/dist/lib/__tests__/deployer-events.spec.js +260 -0
  45. package/dist/lib/__tests__/deployer-events.spec.js.map +1 -0
  46. package/dist/lib/__tests__/deployer.spec.d.ts +2 -0
  47. package/dist/lib/__tests__/deployer.spec.d.ts.map +1 -0
  48. package/dist/lib/__tests__/deployer.spec.js +884 -0
  49. package/dist/lib/__tests__/deployer.spec.js.map +1 -0
  50. package/dist/lib/__tests__/network-utils.spec.d.ts +2 -0
  51. package/dist/lib/__tests__/network-utils.spec.d.ts.map +1 -0
  52. package/dist/lib/__tests__/network-utils.spec.js +140 -0
  53. package/dist/lib/__tests__/network-utils.spec.js.map +1 -0
  54. package/dist/lib/contracts/__tests__/repository.spec.d.ts +2 -0
  55. package/dist/lib/contracts/__tests__/repository.spec.d.ts.map +1 -0
  56. package/dist/lib/contracts/__tests__/repository.spec.js +321 -0
  57. package/dist/lib/contracts/__tests__/repository.spec.js.map +1 -0
  58. package/dist/lib/contracts/repository.d.ts +27 -0
  59. package/dist/lib/contracts/repository.d.ts.map +1 -0
  60. package/dist/lib/contracts/repository.js +241 -0
  61. package/dist/lib/contracts/repository.js.map +1 -0
  62. package/dist/lib/core/__tests__/engine.spec.d.ts +2 -0
  63. package/dist/lib/core/__tests__/engine.spec.d.ts.map +1 -0
  64. package/dist/lib/core/__tests__/engine.spec.js +1212 -0
  65. package/dist/lib/core/__tests__/engine.spec.js.map +1 -0
  66. package/dist/lib/core/__tests__/graph.spec.d.ts +2 -0
  67. package/dist/lib/core/__tests__/graph.spec.d.ts.map +1 -0
  68. package/dist/lib/core/__tests__/graph.spec.js +116 -0
  69. package/dist/lib/core/__tests__/graph.spec.js.map +1 -0
  70. package/dist/lib/core/__tests__/json-integration.spec.d.ts +2 -0
  71. package/dist/lib/core/__tests__/json-integration.spec.d.ts.map +1 -0
  72. package/dist/lib/core/__tests__/json-integration.spec.js +300 -0
  73. package/dist/lib/core/__tests__/json-integration.spec.js.map +1 -0
  74. package/dist/lib/core/__tests__/loader.spec.d.ts +2 -0
  75. package/dist/lib/core/__tests__/loader.spec.d.ts.map +1 -0
  76. package/dist/lib/core/__tests__/loader.spec.js +288 -0
  77. package/dist/lib/core/__tests__/loader.spec.js.map +1 -0
  78. package/dist/lib/core/__tests__/multi-platform-verification.spec.d.ts +2 -0
  79. package/dist/lib/core/__tests__/multi-platform-verification.spec.d.ts.map +1 -0
  80. package/dist/lib/core/__tests__/multi-platform-verification.spec.js +342 -0
  81. package/dist/lib/core/__tests__/multi-platform-verification.spec.js.map +1 -0
  82. package/dist/lib/core/__tests__/resolver.spec.d.ts +2 -0
  83. package/dist/lib/core/__tests__/resolver.spec.d.ts.map +1 -0
  84. package/dist/lib/core/__tests__/resolver.spec.js +1367 -0
  85. package/dist/lib/core/__tests__/resolver.spec.js.map +1 -0
  86. package/dist/lib/core/__tests__/static-action.spec.d.ts +2 -0
  87. package/dist/lib/core/__tests__/static-action.spec.d.ts.map +1 -0
  88. package/dist/lib/core/__tests__/static-action.spec.js +136 -0
  89. package/dist/lib/core/__tests__/static-action.spec.js.map +1 -0
  90. package/dist/lib/core/context.d.ts +29 -0
  91. package/dist/lib/core/context.d.ts.map +1 -0
  92. package/dist/lib/core/context.js +88 -0
  93. package/dist/lib/core/context.js.map +1 -0
  94. package/dist/lib/core/engine.d.ts +25 -0
  95. package/dist/lib/core/engine.d.ts.map +1 -0
  96. package/dist/lib/core/engine.js +1191 -0
  97. package/dist/lib/core/engine.js.map +1 -0
  98. package/dist/lib/core/graph.d.ts +18 -0
  99. package/dist/lib/core/graph.d.ts.map +1 -0
  100. package/dist/lib/core/graph.js +158 -0
  101. package/dist/lib/core/graph.js.map +1 -0
  102. package/dist/lib/core/loader.d.ts +25 -0
  103. package/dist/lib/core/loader.d.ts.map +1 -0
  104. package/dist/lib/core/loader.js +248 -0
  105. package/dist/lib/core/loader.js.map +1 -0
  106. package/dist/lib/core/resolver.d.ts +20 -0
  107. package/dist/lib/core/resolver.d.ts.map +1 -0
  108. package/dist/lib/core/resolver.js +307 -0
  109. package/dist/lib/core/resolver.js.map +1 -0
  110. package/dist/lib/deployer.d.ts +39 -0
  111. package/dist/lib/deployer.d.ts.map +1 -0
  112. package/dist/lib/deployer.js +533 -0
  113. package/dist/lib/deployer.js.map +1 -0
  114. package/dist/lib/events/__tests__/event-system.spec.d.ts +2 -0
  115. package/dist/lib/events/__tests__/event-system.spec.d.ts.map +1 -0
  116. package/dist/lib/events/__tests__/event-system.spec.js +256 -0
  117. package/dist/lib/events/__tests__/event-system.spec.js.map +1 -0
  118. package/dist/lib/events/cli-adapter.d.ts +13 -0
  119. package/dist/lib/events/cli-adapter.d.ts.map +1 -0
  120. package/dist/lib/events/cli-adapter.js +244 -0
  121. package/dist/lib/events/cli-adapter.js.map +1 -0
  122. package/dist/lib/events/emitter.d.ts +11 -0
  123. package/dist/lib/events/emitter.d.ts.map +1 -0
  124. package/dist/lib/events/emitter.js +29 -0
  125. package/dist/lib/events/emitter.js.map +1 -0
  126. package/dist/lib/events/index.d.ts +4 -0
  127. package/dist/lib/events/index.d.ts.map +1 -0
  128. package/dist/lib/events/index.js +20 -0
  129. package/dist/lib/events/index.js.map +1 -0
  130. package/dist/lib/events/types.d.ts +368 -0
  131. package/dist/lib/events/types.d.ts.map +1 -0
  132. package/dist/lib/events/types.js +3 -0
  133. package/dist/lib/events/types.js.map +1 -0
  134. package/dist/lib/index.d.ts +5 -0
  135. package/dist/lib/index.d.ts.map +1 -0
  136. package/dist/lib/index.js +44 -0
  137. package/dist/lib/index.js.map +1 -0
  138. package/dist/lib/network-loader.d.ts +3 -0
  139. package/dist/lib/network-loader.d.ts.map +1 -0
  140. package/dist/lib/network-loader.js +80 -0
  141. package/dist/lib/network-loader.js.map +1 -0
  142. package/dist/lib/network-match.d.ts +3 -0
  143. package/dist/lib/network-match.d.ts.map +1 -0
  144. package/dist/lib/network-match.js +62 -0
  145. package/dist/lib/network-match.js.map +1 -0
  146. package/dist/lib/network-utils.d.ts +4 -0
  147. package/dist/lib/network-utils.d.ts.map +1 -0
  148. package/dist/lib/network-utils.js +39 -0
  149. package/dist/lib/network-utils.js.map +1 -0
  150. package/dist/lib/parsers/__tests__/buildinfo.spec.d.ts +2 -0
  151. package/dist/lib/parsers/__tests__/buildinfo.spec.d.ts.map +1 -0
  152. package/dist/lib/parsers/__tests__/buildinfo.spec.js +132 -0
  153. package/dist/lib/parsers/__tests__/buildinfo.spec.js.map +1 -0
  154. package/dist/lib/parsers/__tests__/job.spec.d.ts +2 -0
  155. package/dist/lib/parsers/__tests__/job.spec.d.ts.map +1 -0
  156. package/dist/lib/parsers/__tests__/job.spec.js +318 -0
  157. package/dist/lib/parsers/__tests__/job.spec.js.map +1 -0
  158. package/dist/lib/parsers/__tests__/template.spec.d.ts +2 -0
  159. package/dist/lib/parsers/__tests__/template.spec.d.ts.map +1 -0
  160. package/dist/lib/parsers/__tests__/template.spec.js +126 -0
  161. package/dist/lib/parsers/__tests__/template.spec.js.map +1 -0
  162. package/dist/lib/parsers/artifact/__tests__/artifact.spec.d.ts +2 -0
  163. package/dist/lib/parsers/artifact/__tests__/artifact.spec.d.ts.map +1 -0
  164. package/dist/lib/parsers/artifact/__tests__/artifact.spec.js +128 -0
  165. package/dist/lib/parsers/artifact/__tests__/artifact.spec.js.map +1 -0
  166. package/dist/lib/parsers/artifact/foundry-1.2.d.ts +3 -0
  167. package/dist/lib/parsers/artifact/foundry-1.2.d.ts.map +1 -0
  168. package/dist/lib/parsers/artifact/foundry-1.2.js +82 -0
  169. package/dist/lib/parsers/artifact/foundry-1.2.js.map +1 -0
  170. package/dist/lib/parsers/artifact/index.d.ts +3 -0
  171. package/dist/lib/parsers/artifact/index.d.ts.map +1 -0
  172. package/dist/lib/parsers/artifact/index.js +17 -0
  173. package/dist/lib/parsers/artifact/index.js.map +1 -0
  174. package/dist/lib/parsers/artifact/types.d.ts +3 -0
  175. package/dist/lib/parsers/artifact/types.d.ts.map +1 -0
  176. package/dist/lib/parsers/artifact/types.js +3 -0
  177. package/dist/lib/parsers/artifact/types.js.map +1 -0
  178. package/dist/lib/parsers/buildinfo.d.ts +5 -0
  179. package/dist/lib/parsers/buildinfo.d.ts.map +1 -0
  180. package/dist/lib/parsers/buildinfo.js +85 -0
  181. package/dist/lib/parsers/buildinfo.js.map +1 -0
  182. package/dist/lib/parsers/constants.d.ts +4 -0
  183. package/dist/lib/parsers/constants.d.ts.map +1 -0
  184. package/dist/lib/parsers/constants.js +45 -0
  185. package/dist/lib/parsers/constants.js.map +1 -0
  186. package/dist/lib/parsers/index.d.ts +5 -0
  187. package/dist/lib/parsers/index.d.ts.map +1 -0
  188. package/dist/lib/parsers/index.js +21 -0
  189. package/dist/lib/parsers/index.js.map +1 -0
  190. package/dist/lib/parsers/job.d.ts +3 -0
  191. package/dist/lib/parsers/job.d.ts.map +1 -0
  192. package/dist/lib/parsers/job.js +74 -0
  193. package/dist/lib/parsers/job.js.map +1 -0
  194. package/dist/lib/parsers/template.d.ts +3 -0
  195. package/dist/lib/parsers/template.d.ts.map +1 -0
  196. package/dist/lib/parsers/template.js +91 -0
  197. package/dist/lib/parsers/template.js.map +1 -0
  198. package/dist/lib/std/templates/assured-deployment.yaml +45 -0
  199. package/dist/lib/std/templates/erc-2470.yaml +67 -0
  200. package/dist/lib/std/templates/min-balance.yaml +32 -0
  201. package/dist/lib/std/templates/nano-universal-deployer.yaml +59 -0
  202. package/dist/lib/std/templates/raw-erc-2470.yaml +59 -0
  203. package/dist/lib/std/templates/raw-nano-universal-deployer.yaml +51 -0
  204. package/dist/lib/std/templates/raw-sequence-universal-deployer-2.yaml +48 -0
  205. package/dist/lib/std/templates/sequence-universal-deployer-2.yaml +57 -0
  206. package/dist/lib/types/__tests__/json-request-action.spec.d.ts +2 -0
  207. package/dist/lib/types/__tests__/json-request-action.spec.d.ts.map +1 -0
  208. package/dist/lib/types/__tests__/json-request-action.spec.js +219 -0
  209. package/dist/lib/types/__tests__/json-request-action.spec.js.map +1 -0
  210. package/dist/lib/types/__tests__/read-json-value.spec.d.ts +2 -0
  211. package/dist/lib/types/__tests__/read-json-value.spec.d.ts.map +1 -0
  212. package/dist/lib/types/__tests__/read-json-value.spec.js +233 -0
  213. package/dist/lib/types/__tests__/read-json-value.spec.js.map +1 -0
  214. package/dist/lib/types/actions.d.ts +74 -0
  215. package/dist/lib/types/actions.d.ts.map +1 -0
  216. package/dist/lib/types/actions.js +18 -0
  217. package/dist/lib/types/actions.js.map +1 -0
  218. package/dist/lib/types/artifacts.d.ts +15 -0
  219. package/dist/lib/types/artifacts.d.ts.map +1 -0
  220. package/dist/lib/types/artifacts.js +3 -0
  221. package/dist/lib/types/artifacts.js.map +1 -0
  222. package/dist/lib/types/buildinfo.d.ts +112 -0
  223. package/dist/lib/types/buildinfo.d.ts.map +1 -0
  224. package/dist/lib/types/buildinfo.js +3 -0
  225. package/dist/lib/types/buildinfo.js.map +1 -0
  226. package/dist/lib/types/conditions.d.ts +17 -0
  227. package/dist/lib/types/conditions.d.ts.map +1 -0
  228. package/dist/lib/types/conditions.js +21 -0
  229. package/dist/lib/types/conditions.js.map +1 -0
  230. package/dist/lib/types/contracts.d.ts +14 -0
  231. package/dist/lib/types/contracts.d.ts.map +1 -0
  232. package/dist/lib/types/contracts.js +3 -0
  233. package/dist/lib/types/contracts.js.map +1 -0
  234. package/dist/lib/types/definitions.d.ts +51 -0
  235. package/dist/lib/types/definitions.d.ts.map +1 -0
  236. package/dist/lib/types/definitions.js +3 -0
  237. package/dist/lib/types/definitions.js.map +1 -0
  238. package/dist/lib/types/index.d.ts +9 -0
  239. package/dist/lib/types/index.d.ts.map +1 -0
  240. package/dist/lib/types/index.js +25 -0
  241. package/dist/lib/types/index.js.map +1 -0
  242. package/dist/lib/types/network.d.ts +9 -0
  243. package/dist/lib/types/network.d.ts.map +1 -0
  244. package/dist/lib/types/network.js +3 -0
  245. package/dist/lib/types/network.js.map +1 -0
  246. package/dist/lib/types/project.d.ts +5 -0
  247. package/dist/lib/types/project.d.ts.map +1 -0
  248. package/dist/lib/types/project.js +3 -0
  249. package/dist/lib/types/project.js.map +1 -0
  250. package/dist/lib/types/task.d.ts +9 -0
  251. package/dist/lib/types/task.d.ts.map +1 -0
  252. package/dist/lib/types/task.js +3 -0
  253. package/dist/lib/types/task.js.map +1 -0
  254. package/dist/lib/types/values.d.ts +78 -0
  255. package/dist/lib/types/values.d.ts.map +1 -0
  256. package/dist/lib/types/values.js +3 -0
  257. package/dist/lib/types/values.js.map +1 -0
  258. package/dist/lib/utils/validation.d.ts +5 -0
  259. package/dist/lib/utils/validation.d.ts.map +1 -0
  260. package/dist/lib/utils/validation.js +77 -0
  261. package/dist/lib/utils/validation.js.map +1 -0
  262. package/dist/lib/validation/contract-references.d.ts +12 -0
  263. package/dist/lib/validation/contract-references.d.ts.map +1 -0
  264. package/dist/lib/validation/contract-references.js +112 -0
  265. package/dist/lib/validation/contract-references.js.map +1 -0
  266. package/dist/lib/validation/index.d.ts +1 -0
  267. package/dist/lib/validation/index.d.ts.map +1 -0
  268. package/dist/lib/validation/index.js +2 -0
  269. package/dist/lib/validation/index.js.map +1 -0
  270. package/dist/lib/verification/__tests__/etherscan.spec.d.ts +2 -0
  271. package/dist/lib/verification/__tests__/etherscan.spec.d.ts.map +1 -0
  272. package/dist/lib/verification/__tests__/etherscan.spec.js +565 -0
  273. package/dist/lib/verification/__tests__/etherscan.spec.js.map +1 -0
  274. package/dist/lib/verification/__tests__/sourcify.spec.d.ts +2 -0
  275. package/dist/lib/verification/__tests__/sourcify.spec.d.ts.map +1 -0
  276. package/dist/lib/verification/__tests__/sourcify.spec.js +212 -0
  277. package/dist/lib/verification/__tests__/sourcify.spec.js.map +1 -0
  278. package/dist/lib/verification/etherscan.d.ts +56 -0
  279. package/dist/lib/verification/etherscan.d.ts.map +1 -0
  280. package/dist/lib/verification/etherscan.js +340 -0
  281. package/dist/lib/verification/etherscan.js.map +1 -0
  282. package/dist/lib/verification/sourcify.d.ts +12 -0
  283. package/dist/lib/verification/sourcify.d.ts.map +1 -0
  284. package/dist/lib/verification/sourcify.js +227 -0
  285. package/dist/lib/verification/sourcify.js.map +1 -0
  286. package/eslint.config.js +48 -0
  287. package/examples/jobs/guards-v1.yaml +17 -0
  288. package/examples/jobs/sequence-seq-0001-patch.yaml +59 -0
  289. package/examples/jobs/sequence-v1.yaml +59 -0
  290. package/examples/templates/sequence-factory-v1.yaml +56 -0
  291. package/jest.config.js +25 -0
  292. package/package.json +68 -0
  293. package/src/cli.ts +17 -0
  294. package/src/commands/common.ts +61 -0
  295. package/src/commands/dry.ts +208 -0
  296. package/src/commands/etherscan.ts +360 -0
  297. package/src/commands/index.ts +5 -0
  298. package/src/commands/list.ts +249 -0
  299. package/src/commands/run.ts +136 -0
  300. package/src/commands/utils.ts +52 -0
  301. package/src/index.ts +67 -0
  302. package/src/lib/__tests__/deployer-events.spec.ts +338 -0
  303. package/src/lib/__tests__/deployer.spec.ts +1204 -0
  304. package/src/lib/__tests__/network-utils.spec.ts +181 -0
  305. package/src/lib/artifacts/__tests__/fixtures/contract1.json +19 -0
  306. package/src/lib/artifacts/__tests__/fixtures/contract2.json +19 -0
  307. package/src/lib/artifacts/__tests__/fixtures/duplicate-name.json +19 -0
  308. package/src/lib/artifacts/__tests__/fixtures/nested/nested-contract.json +18 -0
  309. package/src/lib/artifacts/__tests__/fixtures/not-an-artifact.json +8 -0
  310. package/src/lib/artifacts/__tests__/fixtures/readme.txt +2 -0
  311. package/src/lib/contracts/__tests__/repository.spec.ts +344 -0
  312. package/src/lib/contracts/repository.ts +313 -0
  313. package/src/lib/core/__tests__/engine.spec.ts +1514 -0
  314. package/src/lib/core/__tests__/graph.spec.ts +125 -0
  315. package/src/lib/core/__tests__/json-integration.spec.ts +360 -0
  316. package/src/lib/core/__tests__/loader.spec.ts +334 -0
  317. package/src/lib/core/__tests__/multi-platform-verification.spec.ts +406 -0
  318. package/src/lib/core/__tests__/resolver.spec.ts +1693 -0
  319. package/src/lib/core/__tests__/static-action.spec.ts +172 -0
  320. package/src/lib/core/context.ts +127 -0
  321. package/src/lib/core/engine.ts +1531 -0
  322. package/src/lib/core/graph.ts +252 -0
  323. package/src/lib/core/loader.ts +263 -0
  324. package/src/lib/core/resolver.ts +498 -0
  325. package/src/lib/deployer.ts +768 -0
  326. package/src/lib/events/__tests__/event-system.spec.ts +343 -0
  327. package/src/lib/events/cli-adapter.ts +325 -0
  328. package/src/lib/events/emitter.ts +62 -0
  329. package/src/lib/events/index.ts +3 -0
  330. package/src/lib/events/types.ts +469 -0
  331. package/src/lib/index.ts +14 -0
  332. package/src/lib/network-loader.ts +59 -0
  333. package/src/lib/network-utils.ts +64 -0
  334. package/src/lib/parsers/__tests__/buildinfo.spec.ts +122 -0
  335. package/src/lib/parsers/__tests__/fixtures/buildinfo/invalid-bytecode-buildinfo.json +62 -0
  336. package/src/lib/parsers/__tests__/fixtures/buildinfo/invalid-json.txt +2 -0
  337. package/src/lib/parsers/__tests__/fixtures/buildinfo/multi-contract-buildinfo.json +89 -0
  338. package/src/lib/parsers/__tests__/fixtures/buildinfo/no-contracts-buildinfo.json +17 -0
  339. package/src/lib/parsers/__tests__/fixtures/buildinfo/simple-buildinfo.json +63 -0
  340. package/src/lib/parsers/__tests__/fixtures/buildinfo/wrong-format.json +4 -0
  341. package/src/lib/parsers/__tests__/job.spec.ts +335 -0
  342. package/src/lib/parsers/__tests__/template.spec.ts +111 -0
  343. package/src/lib/parsers/artifact/__tests__/artifact.spec.ts +117 -0
  344. package/src/lib/parsers/artifact/__tests__/fixtures/empty-bytecode.json +5 -0
  345. package/src/lib/parsers/artifact/__tests__/fixtures/hardhat-artifact.json +67 -0
  346. package/src/lib/parsers/artifact/__tests__/fixtures/invalid-bytecode.json +5 -0
  347. package/src/lib/parsers/artifact/__tests__/fixtures/invalid-json.txt +11 -0
  348. package/src/lib/parsers/artifact/__tests__/fixtures/minimal-artifact.json +5 -0
  349. package/src/lib/parsers/artifact/__tests__/fixtures/missing-abi.json +4 -0
  350. package/src/lib/parsers/artifact/__tests__/fixtures/missing-bytecode.json +11 -0
  351. package/src/lib/parsers/artifact/__tests__/fixtures/missing-contract-name.json +11 -0
  352. package/src/lib/parsers/artifact/__tests__/fixtures/simple-artifact.json +40 -0
  353. package/src/lib/parsers/artifact/__tests__/fixtures/wrong-types.json +7 -0
  354. package/src/lib/parsers/artifact/foundry-1.2.ts +72 -0
  355. package/src/lib/parsers/artifact/index.ts +27 -0
  356. package/src/lib/parsers/artifact/types.ts +9 -0
  357. package/src/lib/parsers/buildinfo.ts +127 -0
  358. package/src/lib/parsers/constants.ts +56 -0
  359. package/src/lib/parsers/index.ts +5 -0
  360. package/src/lib/parsers/job.ts +101 -0
  361. package/src/lib/parsers/template.ts +131 -0
  362. package/src/lib/std/templates/assured-deployment.yaml +45 -0
  363. package/src/lib/std/templates/erc-2470.yaml +67 -0
  364. package/src/lib/std/templates/min-balance.yaml +32 -0
  365. package/src/lib/std/templates/nano-universal-deployer.yaml +59 -0
  366. package/src/lib/std/templates/raw-erc-2470.yaml +59 -0
  367. package/src/lib/std/templates/raw-nano-universal-deployer.yaml +51 -0
  368. package/src/lib/std/templates/raw-sequence-universal-deployer-2.yaml +48 -0
  369. package/src/lib/std/templates/sequence-universal-deployer-2.yaml +57 -0
  370. package/src/lib/types/__tests__/json-request-action.spec.ts +243 -0
  371. package/src/lib/types/__tests__/read-json-value.spec.ts +264 -0
  372. package/src/lib/types/actions.ts +127 -0
  373. package/src/lib/types/artifacts.ts +21 -0
  374. package/src/lib/types/buildinfo.ts +116 -0
  375. package/src/lib/types/conditions.ts +50 -0
  376. package/src/lib/types/contracts.ts +23 -0
  377. package/src/lib/types/definitions.ts +68 -0
  378. package/src/lib/types/index.ts +8 -0
  379. package/src/lib/types/network.ts +22 -0
  380. package/src/lib/types/project.ts +9 -0
  381. package/src/lib/types/task.ts +9 -0
  382. package/src/lib/types/values.ts +116 -0
  383. package/src/lib/utils/validation.ts +116 -0
  384. package/src/lib/validation/contract-references.ts +210 -0
  385. package/src/lib/validation/index.ts +1 -0
  386. package/src/lib/verification/__tests__/etherscan.spec.ts +710 -0
  387. package/src/lib/verification/__tests__/sourcify.spec.ts +288 -0
  388. package/src/lib/verification/etherscan.ts +546 -0
  389. package/src/lib/verification/sourcify.ts +248 -0
  390. package/test_validation/artifacts/TestContract.json +9 -0
  391. package/test_validation/jobs/test-missing.yaml +16 -0
  392. package/test_validation/networks.yaml +3 -0
  393. package/tsconfig.json +36 -0
@@ -0,0 +1,1191 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.ExecutionEngine = void 0;
37
+ const types_1 = require("../types");
38
+ const resolver_1 = require("./resolver");
39
+ const validation_1 = require("../utils/validation");
40
+ const events_1 = require("../events");
41
+ const etherscan_1 = require("../verification/etherscan");
42
+ const ethers_1 = require("ethers");
43
+ class ExecutionEngine {
44
+ constructor(templates, eventEmitter, verificationRegistry, noPostCheckConditions) {
45
+ this.resolver = new resolver_1.ValueResolver();
46
+ this.templates = templates;
47
+ this.events = eventEmitter || events_1.deploymentEvents;
48
+ this.verificationRegistry = verificationRegistry || (0, etherscan_1.createDefaultVerificationRegistry)();
49
+ this.noPostCheckConditions = noPostCheckConditions ?? false;
50
+ }
51
+ getPostCheckRetryConfig(context) {
52
+ const network = context.getNetwork();
53
+ const isLocal = network.chainId === 31337 ||
54
+ network.chainId === 1337 ||
55
+ /localhost|127\.0\.0\.1/i.test(network.rpcUrl);
56
+ if (isLocal) {
57
+ return { retries: 100, delayMs: 50 };
58
+ }
59
+ return { retries: 15, delayMs: 2000 };
60
+ }
61
+ async executeJob(job, context) {
62
+ this.events.emitEvent({
63
+ type: 'job_started',
64
+ level: 'info',
65
+ data: {
66
+ jobName: job.name,
67
+ jobVersion: job.version,
68
+ networkName: context.getNetwork().name,
69
+ chainId: context.getNetwork().chainId
70
+ }
71
+ });
72
+ const previousContextPath = context.getContextPath();
73
+ context.setContextPath(job._path);
74
+ try {
75
+ const executionOrder = this.topologicalSortActions(job);
76
+ for (const actionName of executionOrder) {
77
+ const action = job.actions.find(a => a.name === actionName);
78
+ if (!action) {
79
+ throw new Error(`Internal error: Action "${actionName}" not found in job "${job.name}".`);
80
+ }
81
+ await this.executeAction(action, context, new Map());
82
+ }
83
+ if (!this.noPostCheckConditions && job.skip_condition) {
84
+ const { retries, delayMs } = this.getPostCheckRetryConfig(context);
85
+ const shouldSkip = await this.retryBooleanCheck(async () => this.evaluateSkipConditions(job.skip_condition, context, new Map()), retries, delayMs);
86
+ if (!shouldSkip) {
87
+ throw new Error(`Job "${job.name}" failed post-execution check: skip conditions did not evaluate to true`);
88
+ }
89
+ }
90
+ }
91
+ finally {
92
+ context.setContextPath(previousContextPath);
93
+ }
94
+ this.events.emitEvent({
95
+ type: 'job_completed',
96
+ level: 'info',
97
+ data: {
98
+ jobName: job.name,
99
+ networkName: context.getNetwork().name,
100
+ chainId: context.getNetwork().chainId
101
+ }
102
+ });
103
+ }
104
+ async executeAction(action, context, scope) {
105
+ const actionName = 'name' in action ? action.name : action.type;
106
+ const templateName = 'template' in action
107
+ ? (action.template || action.type)
108
+ : action.type;
109
+ if (!templateName) {
110
+ throw new Error(`Action "${actionName}": missing both template and type fields`);
111
+ }
112
+ const printableName = (typeof actionName === 'string' && actionName.trim().length > 0)
113
+ ? actionName
114
+ : ((0, types_1.isPrimitiveActionType)(templateName) ? templateName : `template:${templateName}`);
115
+ this.events.emitEvent({
116
+ type: 'action_started',
117
+ level: 'info',
118
+ data: {
119
+ actionName: printableName,
120
+ jobName: 'unknown'
121
+ }
122
+ });
123
+ const shouldSkip = await this.evaluateSkipConditions(action.skip_condition, context, scope);
124
+ if (shouldSkip) {
125
+ this.events.emitEvent({
126
+ type: 'action_skipped',
127
+ level: 'info',
128
+ data: {
129
+ actionName: actionName,
130
+ reason: 'condition met'
131
+ }
132
+ });
133
+ const hasCustomOutput = 'name' in action && action.name &&
134
+ action.output &&
135
+ typeof action.output === 'object' &&
136
+ !Array.isArray(action.output);
137
+ if (hasCustomOutput) {
138
+ const customOutput = action.output;
139
+ for (const [key, value] of Object.entries(customOutput)) {
140
+ const resolvedOutput = await this.resolver.resolve(value, context, scope);
141
+ const outputKey = `${action.name}.${key}`;
142
+ context.setOutput(outputKey, resolvedOutput);
143
+ this.events.emitEvent({
144
+ type: 'output_stored',
145
+ level: 'debug',
146
+ data: {
147
+ outputKey,
148
+ value: resolvedOutput
149
+ }
150
+ });
151
+ }
152
+ }
153
+ return;
154
+ }
155
+ if ((0, types_1.isPrimitiveActionType)(templateName)) {
156
+ const hasCustomOutput = 'name' in action && action.name &&
157
+ action.output &&
158
+ typeof action.output === 'object' &&
159
+ !Array.isArray(action.output);
160
+ const primitiveAction = 'template' in action
161
+ ? {
162
+ type: (action.type || action.template),
163
+ name: action.name,
164
+ arguments: action.arguments,
165
+ skip_condition: action.skip_condition,
166
+ depends_on: action.depends_on
167
+ }
168
+ : action;
169
+ await this.executePrimitive(primitiveAction, context, scope, hasCustomOutput);
170
+ if (hasCustomOutput) {
171
+ const customOutput = action.output;
172
+ for (const [key, value] of Object.entries(customOutput)) {
173
+ const resolvedOutput = await this.resolver.resolve(value, context, scope);
174
+ const outputKey = `${action.name}.${key}`;
175
+ context.setOutput(outputKey, resolvedOutput);
176
+ this.events.emitEvent({
177
+ type: 'output_stored',
178
+ level: 'debug',
179
+ data: {
180
+ outputKey,
181
+ value: resolvedOutput
182
+ }
183
+ });
184
+ }
185
+ }
186
+ }
187
+ else {
188
+ await this.executeTemplate(action, templateName, context, scope);
189
+ }
190
+ }
191
+ async executeTemplate(callingAction, templateName, context, parentScope = new Map()) {
192
+ const template = this.templates.get(templateName);
193
+ if (!template) {
194
+ const actionName = 'name' in callingAction ? callingAction.name : callingAction.type;
195
+ throw new Error(`Template "${templateName}" not found for action "${actionName}".`);
196
+ }
197
+ this.events.emitEvent({
198
+ type: 'template_entered',
199
+ level: 'debug',
200
+ data: {
201
+ templateName: template.name
202
+ }
203
+ });
204
+ const templateScope = new Map();
205
+ if ('arguments' in callingAction) {
206
+ for (const [key, value] of Object.entries(callingAction.arguments)) {
207
+ const resolvedValue = await this.resolver.resolve(value, context, parentScope);
208
+ templateScope.set(key, resolvedValue);
209
+ }
210
+ }
211
+ const previousContextPath = context.getContextPath();
212
+ context.setContextPath(template._path);
213
+ try {
214
+ if (template.setup) {
215
+ if (template.setup.skip_condition && await this.evaluateSkipConditions(template.setup.skip_condition, context, templateScope)) {
216
+ this.events.emitEvent({
217
+ type: 'template_setup_skipped',
218
+ level: 'info',
219
+ data: {
220
+ templateName: template.name,
221
+ reason: 'setup skip condition met'
222
+ }
223
+ });
224
+ }
225
+ else if (template.setup.actions) {
226
+ this.events.emitEvent({
227
+ type: 'template_setup_started',
228
+ level: 'debug',
229
+ data: {
230
+ templateName: template.name
231
+ }
232
+ });
233
+ for (const setupAction of template.setup.actions) {
234
+ await this.executeAction(setupAction, context, templateScope);
235
+ }
236
+ this.events.emitEvent({
237
+ type: 'template_setup_completed',
238
+ level: 'debug',
239
+ data: {
240
+ templateName: template.name
241
+ }
242
+ });
243
+ }
244
+ }
245
+ const templateSkipConditions = template.skip_condition;
246
+ const templateShouldSkip = await this.evaluateSkipConditions(templateSkipConditions, context, templateScope);
247
+ if (templateShouldSkip) {
248
+ this.events.emitEvent({
249
+ type: 'template_skipped',
250
+ level: 'info',
251
+ data: {
252
+ templateName: template.name,
253
+ reason: 'condition met'
254
+ }
255
+ });
256
+ }
257
+ else {
258
+ for (const templateAction of template.actions) {
259
+ await this.executeAction(templateAction, context, templateScope);
260
+ }
261
+ }
262
+ if (!this.noPostCheckConditions && template.skip_condition) {
263
+ const { retries, delayMs } = this.getPostCheckRetryConfig(context);
264
+ const shouldSkip = await this.retryBooleanCheck(async () => this.evaluateSkipConditions(template.skip_condition, context, templateScope), retries, delayMs);
265
+ if (!shouldSkip) {
266
+ throw new Error(`Template "${template.name}" failed post-execution check: skip conditions did not evaluate to true`);
267
+ }
268
+ }
269
+ if ('name' in callingAction) {
270
+ const actionName = callingAction.name;
271
+ const customOutput = callingAction.output;
272
+ if (customOutput && typeof customOutput === 'object' && !Array.isArray(customOutput)) {
273
+ for (const [key, value] of Object.entries(customOutput)) {
274
+ const resolvedOutput = await this.resolver.resolve(value, context, templateScope);
275
+ const outputKey = `${actionName}.${key}`;
276
+ context.setOutput(outputKey, resolvedOutput);
277
+ this.events.emitEvent({
278
+ type: 'output_stored',
279
+ level: 'debug',
280
+ data: {
281
+ outputKey,
282
+ value: resolvedOutput
283
+ }
284
+ });
285
+ }
286
+ }
287
+ else if (template.outputs) {
288
+ for (const [key, value] of Object.entries(template.outputs)) {
289
+ const resolvedOutput = await this.resolver.resolve(value, context, templateScope);
290
+ const outputKey = `${actionName}.${key}`;
291
+ context.setOutput(outputKey, resolvedOutput);
292
+ this.events.emitEvent({
293
+ type: 'output_stored',
294
+ level: 'debug',
295
+ data: {
296
+ outputKey,
297
+ value: resolvedOutput
298
+ }
299
+ });
300
+ }
301
+ }
302
+ }
303
+ this.events.emitEvent({
304
+ type: 'template_exited',
305
+ level: 'debug',
306
+ data: {
307
+ templateName: template.name
308
+ }
309
+ });
310
+ }
311
+ finally {
312
+ context.setContextPath(previousContextPath);
313
+ }
314
+ }
315
+ async executePrimitive(action, context, scope, hasCustomOutput = false) {
316
+ const actionName = action.name || action.type;
317
+ this.events.emitEvent({
318
+ type: 'primitive_action',
319
+ level: 'debug',
320
+ data: {
321
+ actionType: action.type
322
+ }
323
+ });
324
+ switch (action.type) {
325
+ case 'send-transaction': {
326
+ const resolvedTo = await this.resolver.resolve(action.arguments.to, context, scope);
327
+ const resolvedData = action.arguments.data ? await this.resolver.resolve(action.arguments.data, context, scope) : '0x';
328
+ const resolvedValue = action.arguments.value ? await this.resolver.resolve(action.arguments.value, context, scope) : 0;
329
+ const resolvedGasMultiplier = action.arguments.gasMultiplier !== undefined ? await this.resolver.resolve(action.arguments.gasMultiplier, context, scope) : undefined;
330
+ const to = (0, validation_1.validateAddress)(resolvedTo, actionName);
331
+ const data = (0, validation_1.validateHexData)(resolvedData, actionName, 'data');
332
+ const value = (0, validation_1.validateBigNumberish)(resolvedValue, actionName, 'value');
333
+ let gasMultiplier;
334
+ if (resolvedGasMultiplier !== undefined) {
335
+ if (typeof resolvedGasMultiplier !== 'number' || resolvedGasMultiplier <= 0) {
336
+ throw new Error(`Action "${actionName}": gasMultiplier must be a positive number, got: ${resolvedGasMultiplier}`);
337
+ }
338
+ gasMultiplier = resolvedGasMultiplier;
339
+ }
340
+ const txParams = { to, data, value };
341
+ const network = context.getNetwork();
342
+ if (network.gasLimit) {
343
+ const baseGasLimit = network.gasLimit;
344
+ txParams.gasLimit = gasMultiplier ? Math.floor(baseGasLimit * gasMultiplier) : baseGasLimit;
345
+ }
346
+ else if (gasMultiplier) {
347
+ const signer = await context.getResolvedSigner();
348
+ const estimatedGas = await signer.estimateGas({ to, data, value });
349
+ txParams.gasLimit = Math.floor(Number(estimatedGas) * gasMultiplier);
350
+ }
351
+ const signer = await context.getResolvedSigner();
352
+ const tx = await signer.sendTransaction(txParams);
353
+ this.events.emitEvent({
354
+ type: 'transaction_sent',
355
+ level: 'info',
356
+ data: {
357
+ to,
358
+ value: value.toString(),
359
+ dataPreview: String(data).substring(0, 42),
360
+ txHash: tx.hash
361
+ }
362
+ });
363
+ const receipt = await tx.wait();
364
+ if (!receipt || receipt.status !== 1) {
365
+ throw new Error(`Transaction for action "${actionName}" failed (reverted). Hash: ${tx.hash}`);
366
+ }
367
+ this.events.emitEvent({
368
+ type: 'transaction_confirmed',
369
+ level: 'info',
370
+ data: {
371
+ txHash: tx.hash,
372
+ blockNumber: receipt.blockNumber
373
+ }
374
+ });
375
+ if (action.name && !hasCustomOutput) {
376
+ context.setOutput(`${action.name}.hash`, tx.hash);
377
+ context.setOutput(`${action.name}.receipt`, receipt);
378
+ }
379
+ break;
380
+ }
381
+ case 'send-signed-transaction': {
382
+ const resolvedRawTx = await this.resolver.resolve(action.arguments.transaction, context, scope);
383
+ const rawTx = (0, validation_1.validateRawTransaction)(resolvedRawTx, actionName);
384
+ const tx = await context.provider.broadcastTransaction(rawTx);
385
+ this.events.emitEvent({
386
+ type: 'transaction_sent',
387
+ level: 'info',
388
+ data: {
389
+ to: '',
390
+ value: '0',
391
+ dataPreview: 'signed transaction',
392
+ txHash: tx.hash
393
+ }
394
+ });
395
+ const receipt = await tx.wait();
396
+ if (!receipt || receipt.status !== 1) {
397
+ throw new Error(`Signed transaction for action "${actionName}" failed (reverted). Hash: ${tx.hash}`);
398
+ }
399
+ this.events.emitEvent({
400
+ type: 'transaction_confirmed',
401
+ level: 'info',
402
+ data: {
403
+ txHash: tx.hash,
404
+ blockNumber: receipt.blockNumber
405
+ }
406
+ });
407
+ if (action.name && !hasCustomOutput) {
408
+ context.setOutput(`${action.name}.hash`, tx.hash);
409
+ context.setOutput(`${action.name}.receipt`, receipt);
410
+ }
411
+ break;
412
+ }
413
+ case 'verify-contract': {
414
+ const actionName = action.name || action.type;
415
+ const resolvedAddress = await this.resolver.resolve(action.arguments.address, context, scope);
416
+ const resolvedContract = await this.resolver.resolve(action.arguments.contract, context, scope);
417
+ const resolvedConstructorArgs = action.arguments.constructorArguments
418
+ ? await this.resolver.resolve(action.arguments.constructorArguments, context, scope)
419
+ : undefined;
420
+ const resolvedPlatform = action.arguments.platform
421
+ ? await this.resolver.resolve(action.arguments.platform, context, scope)
422
+ : 'all';
423
+ const address = (0, validation_1.validateAddress)(resolvedAddress, actionName);
424
+ if (!resolvedContract || typeof resolvedContract !== 'object') {
425
+ throw new Error(`Action "${actionName}": contract must be a Contract object`);
426
+ }
427
+ const contract = resolvedContract;
428
+ let platformsToTry;
429
+ if (resolvedPlatform === 'all') {
430
+ platformsToTry = ['all'];
431
+ }
432
+ else if (typeof resolvedPlatform === 'string') {
433
+ platformsToTry = [resolvedPlatform];
434
+ }
435
+ else if (Array.isArray(resolvedPlatform)) {
436
+ if (!resolvedPlatform.every(p => typeof p === 'string')) {
437
+ throw new Error(`Action "${actionName}": platform array must contain only strings`);
438
+ }
439
+ platformsToTry = resolvedPlatform;
440
+ }
441
+ else {
442
+ throw new Error(`Action "${actionName}": platform must be a string, array of strings, or 'all'`);
443
+ }
444
+ if (!contract.sourceName) {
445
+ throw new Error(`Action "${actionName}": Contract is missing sourceName required for verification`);
446
+ }
447
+ if (!contract.contractName) {
448
+ throw new Error(`Action "${actionName}": Contract is missing contractName required for verification`);
449
+ }
450
+ if (!contract.compiler) {
451
+ throw new Error(`Action "${actionName}": Contract is missing compiler information required for verification`);
452
+ }
453
+ if (!contract.buildInfoId) {
454
+ throw new Error(`Action "${actionName}": Contract is missing buildInfoId required for verification`);
455
+ }
456
+ let constructorArguments;
457
+ if (resolvedConstructorArgs !== undefined) {
458
+ constructorArguments = (0, validation_1.validateHexData)(resolvedConstructorArgs, actionName, 'constructorArguments');
459
+ }
460
+ const network = context.getNetwork();
461
+ const contractName = `${contract.sourceName}:${contract.contractName}`;
462
+ if (platformsToTry.includes('all')) {
463
+ const configuredPlatforms = this.verificationRegistry.getConfiguredPlatforms(network);
464
+ if (configuredPlatforms.length === 0) {
465
+ this.events.emitEvent({
466
+ type: 'action_skipped',
467
+ level: 'warn',
468
+ data: {
469
+ actionName: actionName,
470
+ reason: `No configured verification platforms available for network ${network.name}`
471
+ }
472
+ });
473
+ return;
474
+ }
475
+ let anySuccess = false;
476
+ for (const platform of configuredPlatforms) {
477
+ try {
478
+ await this.verifyOnSinglePlatform(platform, contract, address, constructorArguments, network, actionName, contractName, action, context, hasCustomOutput);
479
+ anySuccess = true;
480
+ }
481
+ catch (error) {
482
+ this.events.emitEvent({
483
+ type: 'verification_failed',
484
+ level: 'warn',
485
+ data: {
486
+ actionName: actionName,
487
+ address,
488
+ contractName,
489
+ platform: platform.name,
490
+ error: error instanceof Error ? error.message : String(error)
491
+ }
492
+ });
493
+ }
494
+ }
495
+ if (!anySuccess) {
496
+ throw new Error(`Verification failed on all configured platforms for network ${network.name}`);
497
+ }
498
+ }
499
+ else {
500
+ let anySuccess = false;
501
+ for (const platformName of platformsToTry) {
502
+ const platform = this.verificationRegistry.get(platformName);
503
+ if (!platform) {
504
+ throw new Error(`Action "${actionName}": Unsupported verification platform "${platformName}"`);
505
+ }
506
+ try {
507
+ await this.verifyOnSinglePlatform(platform, contract, address, constructorArguments, network, actionName, contractName, action, context, hasCustomOutput);
508
+ anySuccess = true;
509
+ }
510
+ catch (error) {
511
+ this.events.emitEvent({
512
+ type: 'verification_failed',
513
+ level: platformsToTry.length > 1 ? 'warn' : 'error',
514
+ data: {
515
+ actionName: actionName,
516
+ address,
517
+ contractName,
518
+ platform: platform.name,
519
+ error: error instanceof Error ? error.message : String(error)
520
+ }
521
+ });
522
+ if (platformsToTry.length === 1) {
523
+ throw error;
524
+ }
525
+ }
526
+ }
527
+ if (!anySuccess && platformsToTry.length > 1) {
528
+ throw new Error(`Verification failed on all specified platforms: ${platformsToTry.join(', ')}`);
529
+ }
530
+ }
531
+ break;
532
+ }
533
+ case 'static': {
534
+ const resolvedValue = await this.resolver.resolve(action.arguments.value, context, scope);
535
+ if (action.name && !hasCustomOutput) {
536
+ context.setOutput(`${action.name}.value`, resolvedValue);
537
+ }
538
+ break;
539
+ }
540
+ case 'create-contract': {
541
+ const resolvedData = await this.resolver.resolve(action.arguments.data, context, scope);
542
+ const resolvedValue = action.arguments.value ? await this.resolver.resolve(action.arguments.value, context, scope) : 0;
543
+ const resolvedGasMultiplier = action.arguments.gasMultiplier !== undefined ? await this.resolver.resolve(action.arguments.gasMultiplier, context, scope) : undefined;
544
+ const data = (0, validation_1.validateHexData)(resolvedData, actionName, 'data');
545
+ const value = (0, validation_1.validateBigNumberish)(resolvedValue, actionName, 'value');
546
+ let gasMultiplier;
547
+ if (resolvedGasMultiplier !== undefined) {
548
+ if (typeof resolvedGasMultiplier !== 'number' || resolvedGasMultiplier <= 0) {
549
+ throw new Error(`Action "${actionName}": gasMultiplier must be a positive number, got: ${resolvedGasMultiplier}`);
550
+ }
551
+ gasMultiplier = resolvedGasMultiplier;
552
+ }
553
+ const txParams = { to: null, data, value };
554
+ const network = context.getNetwork();
555
+ if (network.gasLimit) {
556
+ const baseGasLimit = network.gasLimit;
557
+ txParams.gasLimit = gasMultiplier ? Math.floor(baseGasLimit * gasMultiplier) : baseGasLimit;
558
+ }
559
+ else if (gasMultiplier) {
560
+ const signer = await context.getResolvedSigner();
561
+ const estimatedGas = await signer.estimateGas({ to: null, data, value });
562
+ txParams.gasLimit = Math.floor(Number(estimatedGas) * gasMultiplier);
563
+ }
564
+ const signer = await context.getResolvedSigner();
565
+ const tx = await signer.sendTransaction(txParams);
566
+ this.events.emitEvent({
567
+ type: 'transaction_sent',
568
+ level: 'info',
569
+ data: {
570
+ to: 'contract creation',
571
+ value: value.toString(),
572
+ dataPreview: String(data).substring(0, 42),
573
+ txHash: tx.hash
574
+ }
575
+ });
576
+ const receipt = await tx.wait();
577
+ if (!receipt || receipt.status !== 1) {
578
+ throw new Error(`Contract creation for action "${actionName}" failed (reverted). Hash: ${tx.hash}`);
579
+ }
580
+ if (!receipt.contractAddress) {
581
+ throw new Error(`Contract creation for action "${actionName}" did not return a contract address. Hash: ${tx.hash}`);
582
+ }
583
+ this.events.emitEvent({
584
+ type: 'transaction_confirmed',
585
+ level: 'info',
586
+ data: {
587
+ txHash: tx.hash,
588
+ blockNumber: receipt.blockNumber
589
+ }
590
+ });
591
+ this.events.emitEvent({
592
+ type: 'contract_created',
593
+ level: 'info',
594
+ data: {
595
+ contractAddress: receipt.contractAddress,
596
+ txHash: tx.hash,
597
+ blockNumber: receipt.blockNumber
598
+ }
599
+ });
600
+ if (action.name && !hasCustomOutput) {
601
+ context.setOutput(`${action.name}.hash`, tx.hash);
602
+ context.setOutput(`${action.name}.receipt`, receipt);
603
+ context.setOutput(`${action.name}.address`, receipt.contractAddress);
604
+ }
605
+ break;
606
+ }
607
+ case 'test-nicks-method': {
608
+ const defaultBytecode = '0x608060405234801561001057600080fd5b5061013d806100206000396000f3fe60806040526004361061001e5760003560e01c80639c4ae2d014610023575b600080fd5b6100cb6004803603604081101561003957600080fd5b81019060208101813564010000000081111561005457600080fd5b82018360208201111561006657600080fd5b8035906020019184600183028401116401000000008311171561008857600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955050913592506100cd915050565b005b60008183516020850134f56040805173ffffffffffffffffffffffffffffffffffffffff83168152905191925081900360200190a050505056fea264697066735822122033609f614f03931b92d88c309d698449bb77efcd517328d341fa4f923c5d8c7964736f6c63430007060033';
609
+ const args = action.arguments || {};
610
+ const resolvedBytecode = args.bytecode ? await this.resolver.resolve(args.bytecode, context, scope) : defaultBytecode;
611
+ const resolvedGasPrice = args.gasPrice ? await this.resolver.resolve(args.gasPrice, context, scope) : undefined;
612
+ const resolvedGasLimit = args.gasLimit ? await this.resolver.resolve(args.gasLimit, context, scope) : undefined;
613
+ const resolvedFundingAmount = args.fundingAmount ? await this.resolver.resolve(args.fundingAmount, context, scope) : undefined;
614
+ const bytecode = (0, validation_1.validateHexData)(resolvedBytecode, actionName, 'bytecode');
615
+ const gasPrice = resolvedGasPrice ? (0, validation_1.validateBigNumberish)(resolvedGasPrice, actionName, 'gasPrice') : undefined;
616
+ const gasLimit = resolvedGasLimit ? (0, validation_1.validateBigNumberish)(resolvedGasLimit, actionName, 'gasLimit') : undefined;
617
+ const fundingAmount = resolvedFundingAmount ? (0, validation_1.validateBigNumberish)(resolvedFundingAmount, actionName, 'fundingAmount') : undefined;
618
+ const success = await this.testNicksMethod(bytecode, context, gasPrice, gasLimit, fundingAmount);
619
+ if (!success) {
620
+ throw new Error(`Nick's method test failed for action "${actionName}"`);
621
+ }
622
+ this.events.emitEvent({
623
+ type: 'action_completed',
624
+ level: 'info',
625
+ data: {
626
+ actionName: actionName,
627
+ result: 'Nick\'s method test passed'
628
+ }
629
+ });
630
+ if (action.name && !hasCustomOutput) {
631
+ context.setOutput(`${action.name}.success`, true);
632
+ }
633
+ break;
634
+ }
635
+ case 'json-request': {
636
+ const resolvedUrl = await this.resolver.resolve(action.arguments.url, context, scope);
637
+ const resolvedMethod = action.arguments.method ? await this.resolver.resolve(action.arguments.method, context, scope) : 'GET';
638
+ const resolvedHeaders = action.arguments.headers ? await this.resolver.resolve(action.arguments.headers, context, scope) : {};
639
+ const resolvedBody = action.arguments.body ? await this.resolver.resolve(action.arguments.body, context, scope) : undefined;
640
+ if (typeof resolvedUrl !== 'string') {
641
+ throw new Error(`Action "${actionName}": url must be a string, got: ${typeof resolvedUrl}`);
642
+ }
643
+ if (typeof resolvedMethod !== 'string') {
644
+ throw new Error(`Action "${actionName}": method must be a string, got: ${typeof resolvedMethod}`);
645
+ }
646
+ if (resolvedHeaders && typeof resolvedHeaders !== 'object') {
647
+ throw new Error(`Action "${actionName}": headers must be an object, got: ${typeof resolvedHeaders}`);
648
+ }
649
+ try {
650
+ const fetchOptions = {
651
+ method: resolvedMethod.toUpperCase(),
652
+ headers: {
653
+ 'Content-Type': 'application/json',
654
+ ...resolvedHeaders
655
+ }
656
+ };
657
+ if (resolvedBody !== undefined && resolvedMethod.toUpperCase() !== 'GET') {
658
+ fetchOptions.body = JSON.stringify(resolvedBody);
659
+ }
660
+ this.events.emitEvent({
661
+ type: 'action_started',
662
+ level: 'info',
663
+ data: {
664
+ actionName: actionName,
665
+ message: `Making ${resolvedMethod.toUpperCase()} request to ${resolvedUrl}`
666
+ }
667
+ });
668
+ const response = await fetch(resolvedUrl, fetchOptions);
669
+ if (!response.ok) {
670
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
671
+ }
672
+ const responseData = await response.json();
673
+ this.events.emitEvent({
674
+ type: 'action_completed',
675
+ level: 'info',
676
+ data: {
677
+ actionName: actionName,
678
+ message: `Request completed successfully (${response.status})`
679
+ }
680
+ });
681
+ if (action.name && !hasCustomOutput) {
682
+ context.setOutput(`${action.name}.response`, responseData);
683
+ context.setOutput(`${action.name}.status`, response.status);
684
+ context.setOutput(`${action.name}.statusText`, response.statusText);
685
+ }
686
+ }
687
+ catch (error) {
688
+ this.events.emitEvent({
689
+ type: 'action_failed',
690
+ level: 'error',
691
+ data: {
692
+ actionName: actionName,
693
+ error: error instanceof Error ? error.message : String(error)
694
+ }
695
+ });
696
+ throw new Error(`Action "${actionName}" failed: ${error instanceof Error ? error.message : String(error)}`);
697
+ }
698
+ break;
699
+ }
700
+ default:
701
+ throw new Error(`Unknown or unimplemented primitive action type: ${action.type}`);
702
+ }
703
+ }
704
+ async verifyOnSinglePlatform(platform, contract, address, constructorArguments, network, actionName, contractName, action, context, hasCustomOutput = false) {
705
+ const supportsNetwork = platform.supportsNetwork(network);
706
+ if (!supportsNetwork) {
707
+ this.events.emitEvent({
708
+ type: 'action_skipped',
709
+ level: 'info',
710
+ data: {
711
+ actionName: actionName,
712
+ reason: `Network ${network.name} does not support ${platform.name} verification`
713
+ }
714
+ });
715
+ return;
716
+ }
717
+ const isConfigured = platform.isConfigured();
718
+ if (!isConfigured) {
719
+ this.events.emitEvent({
720
+ type: 'action_skipped',
721
+ level: 'warn',
722
+ data: {
723
+ actionName: actionName,
724
+ reason: `Verification skipped: ${platform.getConfigurationRequirements()}`
725
+ }
726
+ });
727
+ return;
728
+ }
729
+ let buildInfoPath;
730
+ for (const sourcePath of contract._sources) {
731
+ if (sourcePath.includes('/build-info/') && sourcePath.endsWith('.json')) {
732
+ buildInfoPath = sourcePath;
733
+ break;
734
+ }
735
+ }
736
+ if (!buildInfoPath) {
737
+ throw new Error(`Action "${actionName}": No build-info file found in contract sources`);
738
+ }
739
+ const fs = await Promise.resolve().then(() => __importStar(require('fs/promises')));
740
+ let buildInfoContent;
741
+ try {
742
+ buildInfoContent = await fs.readFile(buildInfoPath, 'utf-8');
743
+ }
744
+ catch (error) {
745
+ throw new Error(`Action "${actionName}": Failed to read build info file at ${buildInfoPath}: ${error instanceof Error ? error.message : String(error)}`);
746
+ }
747
+ let buildInfo;
748
+ try {
749
+ buildInfo = JSON.parse(buildInfoContent);
750
+ }
751
+ catch (error) {
752
+ throw new Error(`Action "${actionName}": Failed to parse build info JSON: ${error instanceof Error ? error.message : String(error)}`);
753
+ }
754
+ this.events.emitEvent({
755
+ type: 'verification_started',
756
+ level: 'info',
757
+ data: {
758
+ actionName: actionName,
759
+ address,
760
+ contractName,
761
+ platform: platform.name,
762
+ networkName: network.name
763
+ }
764
+ });
765
+ try {
766
+ const verificationResult = await platform.verifyContract({
767
+ contract,
768
+ buildInfo,
769
+ address,
770
+ constructorArguments,
771
+ network
772
+ });
773
+ if (!verificationResult.success) {
774
+ throw new Error(`Verification failed: ${verificationResult.message}`);
775
+ }
776
+ if (verificationResult.isAlreadyVerified) {
777
+ this.events.emitEvent({
778
+ type: 'verification_completed',
779
+ level: 'info',
780
+ data: {
781
+ actionName: actionName,
782
+ address,
783
+ contractName,
784
+ platform: platform.name,
785
+ message: verificationResult.message
786
+ }
787
+ });
788
+ }
789
+ else {
790
+ this.events.emitEvent({
791
+ type: 'verification_submitted',
792
+ level: 'info',
793
+ data: {
794
+ actionName: actionName,
795
+ platform: platform.name,
796
+ guid: verificationResult.guid || 'N/A',
797
+ message: verificationResult.message
798
+ }
799
+ });
800
+ this.events.emitEvent({
801
+ type: 'verification_completed',
802
+ level: 'info',
803
+ data: {
804
+ actionName: actionName,
805
+ address,
806
+ contractName,
807
+ platform: platform.name,
808
+ message: 'Contract verified successfully'
809
+ }
810
+ });
811
+ }
812
+ if (action.name && !hasCustomOutput) {
813
+ context.setOutput(`${action.name}.verified`, true);
814
+ if (verificationResult.guid) {
815
+ context.setOutput(`${action.name}.guid`, verificationResult.guid);
816
+ }
817
+ }
818
+ }
819
+ catch (error) {
820
+ this.events.emitEvent({
821
+ type: 'verification_failed',
822
+ level: 'error',
823
+ data: {
824
+ actionName: actionName,
825
+ address,
826
+ contractName,
827
+ platform: platform.name,
828
+ error: error instanceof Error ? error.message : String(error)
829
+ }
830
+ });
831
+ throw error;
832
+ }
833
+ }
834
+ async testNicksMethod(bytecode, context, gasPrice, gasLimit, fundingAmount) {
835
+ let testResult = false;
836
+ let eoaAddress;
837
+ let wallet;
838
+ try {
839
+ const defaultGasPrice = gasPrice || ethers_1.ethers.parseUnits('100', 'gwei');
840
+ const defaultGasLimit = gasLimit || 250000n;
841
+ const calculatedCost = BigInt(defaultGasPrice.toString()) * BigInt(defaultGasLimit.toString());
842
+ const defaultFundingAmount = fundingAmount || calculatedCost;
843
+ const signer = await context.getResolvedSigner();
844
+ const signerAddress = await signer.getAddress();
845
+ const signerBalance = await context.provider.getBalance(signerAddress);
846
+ if (signerBalance < BigInt(defaultFundingAmount.toString())) {
847
+ this.events.emitEvent({
848
+ type: 'action_failed',
849
+ level: 'error',
850
+ data: {
851
+ message: `Insufficient funds: signer has ${ethers_1.ethers.formatEther(signerBalance)} ETH but needs ${ethers_1.ethers.formatEther(defaultFundingAmount)} ETH`
852
+ }
853
+ });
854
+ return false;
855
+ }
856
+ const result = await this.generateNicksMethodTransaction(bytecode, defaultGasPrice, defaultGasLimit);
857
+ const rawTx = result.rawTx;
858
+ eoaAddress = result.eoaAddress;
859
+ wallet = result.wallet;
860
+ this.events.emitEvent({
861
+ type: 'debug_info',
862
+ level: 'debug',
863
+ data: {
864
+ message: `Testing Nick's method with EOA: ${eoaAddress}`
865
+ }
866
+ });
867
+ const currentBalance = await context.provider.getBalance(eoaAddress);
868
+ const neededFunding = BigInt(defaultFundingAmount.toString()) - currentBalance;
869
+ if (neededFunding > 0) {
870
+ this.events.emitEvent({
871
+ type: 'transaction_sent',
872
+ level: 'debug',
873
+ data: {
874
+ to: eoaAddress,
875
+ value: neededFunding.toString(),
876
+ dataPreview: 'funding EOA for Nick\'s method test',
877
+ txHash: 'pending'
878
+ }
879
+ });
880
+ this.events.emitEvent({
881
+ type: 'debug_info',
882
+ level: 'debug',
883
+ data: {
884
+ message: `[NICK'S METHOD DEBUG] Sending funding transaction: ${ethers_1.ethers.formatEther(neededFunding)} ETH to ${eoaAddress}`
885
+ }
886
+ });
887
+ const signer = await context.getResolvedSigner();
888
+ const fundingTx = await signer.sendTransaction({
889
+ to: eoaAddress,
890
+ value: neededFunding
891
+ });
892
+ this.events.emitEvent({
893
+ type: 'debug_info',
894
+ level: 'debug',
895
+ data: {
896
+ message: `[NICK'S METHOD DEBUG] Funding transaction sent: ${fundingTx.hash}, waiting for confirmation...`
897
+ }
898
+ });
899
+ const fundingReceipt = await fundingTx.wait();
900
+ this.events.emitEvent({
901
+ type: 'transaction_confirmed',
902
+ level: 'debug',
903
+ data: {
904
+ txHash: fundingTx.hash,
905
+ blockNumber: fundingReceipt?.blockNumber || 0
906
+ }
907
+ });
908
+ this.events.emitEvent({
909
+ type: 'debug_info',
910
+ level: 'debug',
911
+ data: {
912
+ message: `[NICK'S METHOD DEBUG] Funded EOA ${eoaAddress} with ${ethers_1.ethers.formatEther(neededFunding)} ETH, receipt status: ${fundingReceipt?.status}`
913
+ }
914
+ });
915
+ if (!fundingReceipt || fundingReceipt.status !== 1) {
916
+ this.events.emitEvent({
917
+ type: 'action_failed',
918
+ level: 'error',
919
+ data: {
920
+ message: `[NICK'S METHOD DEBUG] Funding transaction failed! Hash: ${fundingTx.hash}, Status: ${fundingReceipt?.status}`
921
+ }
922
+ });
923
+ return false;
924
+ }
925
+ }
926
+ else {
927
+ this.events.emitEvent({
928
+ type: 'debug_info',
929
+ level: 'debug',
930
+ data: {
931
+ message: `[NICK'S METHOD DEBUG] EOA already has sufficient balance, skipping funding`
932
+ }
933
+ });
934
+ }
935
+ this.events.emitEvent({
936
+ type: 'debug_info',
937
+ level: 'debug',
938
+ data: {
939
+ message: `[NICK'S METHOD DEBUG] Broadcasting Nick's method transaction. RawTx: ${rawTx.substring(0, 100)}...`
940
+ }
941
+ });
942
+ const deployTx = await context.provider.broadcastTransaction(rawTx);
943
+ this.events.emitEvent({
944
+ type: 'debug_info',
945
+ level: 'debug',
946
+ data: {
947
+ message: `[NICK'S METHOD DEBUG] Transaction broadcasted successfully. Hash: ${deployTx.hash}, waiting for confirmation...`
948
+ }
949
+ });
950
+ const receipt = await deployTx.wait();
951
+ this.events.emitEvent({
952
+ type: 'debug_info',
953
+ level: 'debug',
954
+ data: {
955
+ message: `[NICK'S METHOD DEBUG] Transaction receipt received. Status: ${receipt?.status}, ContractAddress: ${receipt?.contractAddress}, BlockNumber: ${receipt?.blockNumber}`
956
+ }
957
+ });
958
+ if (receipt && receipt.status === 1) {
959
+ this.events.emitEvent({
960
+ type: 'transaction_confirmed',
961
+ level: 'info',
962
+ data: {
963
+ txHash: deployTx.hash,
964
+ blockNumber: receipt.blockNumber || 0
965
+ }
966
+ });
967
+ this.events.emitEvent({
968
+ type: 'debug_info',
969
+ level: 'debug',
970
+ data: {
971
+ message: `[NICK'S METHOD DEBUG] Nick's method test successful - contract deployed at ${receipt.contractAddress}`
972
+ }
973
+ });
974
+ testResult = true;
975
+ }
976
+ else {
977
+ this.events.emitEvent({
978
+ type: 'action_failed',
979
+ level: 'error',
980
+ data: {
981
+ message: `[NICK'S METHOD DEBUG] Nick's method test failed - transaction reverted or failed. Hash: ${deployTx.hash}, Status: ${receipt?.status}`
982
+ }
983
+ });
984
+ testResult = false;
985
+ }
986
+ }
987
+ catch (error) {
988
+ this.events.emitEvent({
989
+ type: 'action_failed',
990
+ level: 'error',
991
+ data: {
992
+ message: `[NICK'S METHOD DEBUG] Nick's method test failed with error: ${error instanceof Error ? error.message : String(error)}`
993
+ }
994
+ });
995
+ if (error instanceof Error && error.stack) {
996
+ this.events.emitEvent({
997
+ type: 'action_failed',
998
+ level: 'debug',
999
+ data: {
1000
+ message: `[NICK'S METHOD DEBUG] Error stack trace: ${error.stack}`
1001
+ }
1002
+ });
1003
+ }
1004
+ testResult = false;
1005
+ }
1006
+ finally {
1007
+ if (eoaAddress && wallet) {
1008
+ try {
1009
+ await this.returnRemainingFunds(eoaAddress, wallet, context);
1010
+ }
1011
+ catch (error) {
1012
+ this.events.emitEvent({
1013
+ type: 'action_failed',
1014
+ level: 'warn',
1015
+ data: {
1016
+ message: `Failed to return remaining funds from EOA ${eoaAddress}: ${error instanceof Error ? error.message : String(error)}`
1017
+ }
1018
+ });
1019
+ }
1020
+ }
1021
+ }
1022
+ return testResult;
1023
+ }
1024
+ async generateNicksMethodTransaction(bytecode, gasPrice, gasLimit) {
1025
+ const wallet = ethers_1.ethers.Wallet.createRandom();
1026
+ const unsignedTx = {
1027
+ type: 0,
1028
+ chainId: 0,
1029
+ nonce: 0,
1030
+ gasPrice: gasPrice,
1031
+ gasLimit: gasLimit,
1032
+ to: null,
1033
+ value: 0,
1034
+ data: bytecode
1035
+ };
1036
+ const signedTx = await wallet.signTransaction(unsignedTx);
1037
+ const parsedTx = ethers_1.ethers.Transaction.from(signedTx);
1038
+ const eoaAddress = parsedTx.from;
1039
+ return {
1040
+ rawTx: signedTx,
1041
+ eoaAddress: eoaAddress,
1042
+ wallet: wallet
1043
+ };
1044
+ }
1045
+ async returnRemainingFunds(eoaAddress, wallet, context) {
1046
+ const remainingBalance = await context.provider.getBalance(eoaAddress);
1047
+ if (remainingBalance <= 0n) {
1048
+ return;
1049
+ }
1050
+ const connectedWallet = wallet.connect(context.provider);
1051
+ const gasPrice = await context.provider.getFeeData().then(data => data.gasPrice || ethers_1.ethers.parseUnits('20', 'gwei'));
1052
+ const gasLimit = 21000n;
1053
+ const gasCost = BigInt(gasPrice.toString()) * gasLimit;
1054
+ if (remainingBalance <= gasCost) {
1055
+ this.events.emitEvent({
1056
+ type: 'action_info',
1057
+ level: 'debug',
1058
+ data: {
1059
+ message: `Remaining balance ${ethers_1.ethers.formatEther(remainingBalance)} ETH is insufficient to cover gas costs for fund return`
1060
+ }
1061
+ });
1062
+ return;
1063
+ }
1064
+ const amountToSend = remainingBalance - gasCost;
1065
+ this.events.emitEvent({
1066
+ type: 'transaction_sent',
1067
+ level: 'debug',
1068
+ data: {
1069
+ to: await (await context.getResolvedSigner()).getAddress(),
1070
+ value: amountToSend.toString(),
1071
+ dataPreview: 'returning remaining funds from Nick\'s method test',
1072
+ txHash: 'pending'
1073
+ }
1074
+ });
1075
+ const returnTx = await connectedWallet.sendTransaction({
1076
+ to: await (await context.getResolvedSigner()).getAddress(),
1077
+ value: amountToSend,
1078
+ gasPrice: gasPrice,
1079
+ gasLimit: gasLimit
1080
+ });
1081
+ await returnTx.wait();
1082
+ this.events.emitEvent({
1083
+ type: 'transaction_confirmed',
1084
+ level: 'debug',
1085
+ data: {
1086
+ txHash: returnTx.hash,
1087
+ blockNumber: (await returnTx.wait())?.blockNumber || 0
1088
+ }
1089
+ });
1090
+ this.events.emitEvent({
1091
+ type: 'debug_info',
1092
+ level: 'debug',
1093
+ data: {
1094
+ message: `Returned ${ethers_1.ethers.formatEther(amountToSend)} ETH from test EOA ${eoaAddress} to original wallet`
1095
+ }
1096
+ });
1097
+ }
1098
+ async retryBooleanCheck(checkFn, retries = 3, delayMs = 2000) {
1099
+ const milestones = new Set();
1100
+ const total = retries + 1;
1101
+ milestones.add(1);
1102
+ milestones.add(Math.max(1, Math.floor(total * 0.25)));
1103
+ milestones.add(Math.max(1, Math.floor(total * 0.5)));
1104
+ milestones.add(Math.max(1, Math.floor(total * 0.75)));
1105
+ milestones.add(total);
1106
+ for (let attempt = 0; attempt < total; attempt++) {
1107
+ try {
1108
+ const result = await checkFn();
1109
+ if (result) {
1110
+ return true;
1111
+ }
1112
+ if (milestones.has(attempt + 1)) {
1113
+ this.events.emitEvent({
1114
+ type: 'debug_info',
1115
+ level: 'debug',
1116
+ data: {
1117
+ message: `Post-execution check returned false (attempt ${attempt + 1}/${total}).`
1118
+ }
1119
+ });
1120
+ }
1121
+ }
1122
+ catch (err) {
1123
+ if (milestones.has(attempt + 1)) {
1124
+ this.events.emitEvent({
1125
+ type: 'debug_info',
1126
+ level: 'debug',
1127
+ data: {
1128
+ message: `Post-execution check threw error (attempt ${attempt + 1}/${total}): ${err instanceof Error ? err.message : String(err)}`
1129
+ }
1130
+ });
1131
+ }
1132
+ }
1133
+ if (attempt < retries) {
1134
+ await new Promise(res => setTimeout(res, delayMs));
1135
+ }
1136
+ }
1137
+ return false;
1138
+ }
1139
+ async evaluateSkipConditions(conditions, context, scope) {
1140
+ if (!conditions || conditions.length === 0) {
1141
+ return false;
1142
+ }
1143
+ for (const condition of conditions) {
1144
+ const shouldSkip = await this.resolver.resolve(condition, context, scope);
1145
+ if (shouldSkip) {
1146
+ return true;
1147
+ }
1148
+ }
1149
+ return false;
1150
+ }
1151
+ topologicalSortActions(job) {
1152
+ const sorted = [];
1153
+ const graph = new Map();
1154
+ const inDegree = new Map();
1155
+ const actionMap = new Map(job.actions.map(a => [a.name, a]));
1156
+ for (const action of job.actions) {
1157
+ graph.set(action.name, new Set(action.depends_on || []));
1158
+ inDegree.set(action.name, 0);
1159
+ }
1160
+ for (const [actionName, dependencies] of graph.entries()) {
1161
+ for (const depName of dependencies) {
1162
+ if (!actionMap.has(depName)) {
1163
+ throw new Error(`Action "${actionName}" in job "${job.name}" has an invalid dependency on "${depName}", which does not exist.`);
1164
+ }
1165
+ inDegree.set(actionName, (inDegree.get(actionName) ?? 0) + 1);
1166
+ }
1167
+ }
1168
+ const queue = Array.from(inDegree.entries())
1169
+ .filter(([, degree]) => degree === 0)
1170
+ .map(([name]) => name);
1171
+ while (queue.length > 0) {
1172
+ const currentName = queue.shift();
1173
+ sorted.push(currentName);
1174
+ for (const [actionName, dependencies] of graph.entries()) {
1175
+ if (dependencies.has(currentName)) {
1176
+ const newDegree = (inDegree.get(actionName) ?? 1) - 1;
1177
+ inDegree.set(actionName, newDegree);
1178
+ if (newDegree === 0) {
1179
+ queue.push(actionName);
1180
+ }
1181
+ }
1182
+ }
1183
+ }
1184
+ if (sorted.length !== job.actions.length) {
1185
+ throw new Error(`Circular dependency detected among actions in job "${job.name}".`);
1186
+ }
1187
+ return sorted;
1188
+ }
1189
+ }
1190
+ exports.ExecutionEngine = ExecutionEngine;
1191
+ //# sourceMappingURL=engine.js.map