@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,252 @@
1
+ // src/lib/core/graph.ts
2
+ import { Job, Template, isJobCompletedCondition } from '../types'
3
+ import { isPrimitiveActionType } from '../types/actions'
4
+
5
+ /**
6
+ * Represents the complete dependency graph of all jobs in a project.
7
+ * It is responsible for parsing job and template dependencies, detecting
8
+ * cycles, and providing a valid execution order.
9
+ */
10
+ export class DependencyGraph {
11
+ private graph: Map<string, Set<string>> = new Map()
12
+ private executionOrder: string[] = []
13
+ private allJobNames: Set<string>
14
+
15
+ constructor(
16
+ private readonly jobs: Map<string, Job>,
17
+ private readonly templates: Map<string, Template>,
18
+ ) {
19
+ this.allJobNames = new Set(this.jobs.keys())
20
+ this.build()
21
+ this.checkForCycles()
22
+ this.executionOrder = this.topologicalSort()
23
+ }
24
+
25
+ /**
26
+ * Returns the list of job names in a valid execution order.
27
+ * Jobs with no dependencies come first.
28
+ */
29
+ public getExecutionOrder(): string[] {
30
+ return this.executionOrder
31
+ }
32
+
33
+ /**
34
+ * Returns the direct and transitive dependencies for a given job.
35
+ */
36
+ public getDependencies(jobName: string): Set<string> {
37
+ return this.graph.get(jobName) || new Set()
38
+ }
39
+
40
+ /**
41
+ * Populates the dependency graph by analyzing each job.
42
+ */
43
+ private build(): void {
44
+ for (const jobName of this.allJobNames) {
45
+ this.graph.set(jobName, this.findAllDependencies(jobName))
46
+ }
47
+ }
48
+
49
+ /**
50
+ * Recursively finds all dependencies for a given job, including those
51
+ * from its `depends_on` list and those hidden within its templates' setup blocks.
52
+ *
53
+ * @param jobName The name of the job to analyze.
54
+ * @param visited A set to track visited jobs in the current path to detect cycles.
55
+ * @returns A set of all job names that the given job depends on.
56
+ */
57
+ private findAllDependencies(jobName: string, visited: Set<string> = new Set()): Set<string> {
58
+ if (visited.has(jobName)) {
59
+ // This path is cyclic. The cycle will be properly reported by `checkForCycles`.
60
+ // Here, we just stop the recursion to prevent an infinite loop.
61
+ return new Set()
62
+ }
63
+ visited.add(jobName)
64
+
65
+ const job = this.jobs.get(jobName)
66
+ if (!job) {
67
+ throw new Error(`Integrity error: Job "${jobName}" not found during graph build.`)
68
+ }
69
+
70
+ const directDependencies = new Set<string>()
71
+
72
+ // 1. Add dependencies from the job's `depends_on` field.
73
+ job.depends_on?.forEach(dep => directDependencies.add(dep))
74
+
75
+ // 2. Find dependencies within the templates used by the job's actions.
76
+ for (const action of job.actions) {
77
+ // Get the template or type name
78
+ const templateName = action.template || action.type
79
+ if (!templateName) {
80
+ throw new Error(`Invalid configuration: Action in job "${jobName}" has no template or type field.`)
81
+ }
82
+
83
+ // If the action is a primitive, it cannot have job dependencies. Skip it.
84
+ if (isPrimitiveActionType(templateName)) {
85
+ continue
86
+ }
87
+
88
+ const template = this.templates.get(templateName)
89
+ if (!template) {
90
+ throw new Error(`Invalid configuration: Template "${templateName}" used by job "${jobName}" not found.`)
91
+ }
92
+
93
+ // Recursively find dependencies in the template's setup block.
94
+ this.findTemplateSetupDependencies(template).forEach(dep => directDependencies.add(dep))
95
+ }
96
+
97
+ // 3. Now, for each direct dependency, find its transitive dependencies.
98
+ const allDependencies = new Set<string>(directDependencies)
99
+ for (const dep of directDependencies) {
100
+ if (!this.allJobNames.has(dep)) {
101
+ throw new Error(`Invalid dependency: Job "${jobName}" depends on "${dep}", which does not exist.`)
102
+ }
103
+ // The `visited` set is passed down to detect cycles across calls.
104
+ const transitiveDeps = this.findAllDependencies(dep, new Set(visited))
105
+ transitiveDeps.forEach(transDep => allDependencies.add(transDep))
106
+ }
107
+
108
+ return allDependencies
109
+ }
110
+
111
+ /**
112
+ * Helper to extract job dependencies from a template's setup block.
113
+ */
114
+ private findTemplateSetupDependencies(template: Template): Set<string> {
115
+ const dependencies = new Set<string>()
116
+ const setup = template.setup
117
+ if (!setup) return dependencies
118
+
119
+ // Case 1: Dependencies from `skip_condition` (e.g., `job-completed`).
120
+ setup.skip_condition?.forEach(condition => {
121
+ if (isJobCompletedCondition(condition)) {
122
+ dependencies.add(condition.arguments.job)
123
+ }
124
+ })
125
+
126
+ // Case 2: Dependencies from setup actions that are themselves templates.
127
+ setup.actions?.forEach(action => {
128
+ // Ignore primitive actions within a setup block.
129
+ if (isPrimitiveActionType(action.type)) {
130
+ return
131
+ }
132
+
133
+ // In your YAML, setup blocks sometimes call other templates directly.
134
+ // e.g. `sequence-universal-deployer-2`'s setup calls `nano-universal-deployer`
135
+ // Here, `action.type` IS the template name.
136
+ const actionTemplate = this.templates.get(action.type)
137
+ if (actionTemplate) {
138
+ // This is a nested template call, so we must find its dependencies too.
139
+ this.findTemplateSetupDependencies(actionTemplate).forEach(dep => dependencies.add(dep))
140
+ }
141
+ })
142
+
143
+ return dependencies
144
+ }
145
+
146
+ /**
147
+ * Checks the entire graph for circular dependencies.
148
+ * @throws {Error} if a cycle is detected.
149
+ */
150
+ private checkForCycles(): void {
151
+ for (const [jobName, dependencies] of this.graph.entries()) {
152
+ if (dependencies.has(jobName)) {
153
+ // To provide a more helpful error, we need to find the actual path.
154
+ const path = this.findPath(jobName, jobName)
155
+ throw new Error(`Circular dependency detected: ${path.join(' -> ')}`)
156
+ }
157
+ }
158
+ }
159
+
160
+ /**
161
+ * Helper to find a dependency path from a start node to an end node.
162
+ * Used for creating helpful error messages for cycles.
163
+ */
164
+ private findPath(start: string, end: string, visited: Set<string> = new Set()): string[] {
165
+ visited.add(start)
166
+ const job = this.jobs.get(start)
167
+ if (!job) return []
168
+
169
+ const directDependencies = new Set(job.depends_on || [])
170
+ for (const action of job.actions) {
171
+ const templateName = action.template || action.type
172
+ if (!templateName || isPrimitiveActionType(templateName)) {
173
+ continue
174
+ }
175
+ const template = this.templates.get(templateName)!
176
+ this.findTemplateSetupDependencies(template).forEach(dep => directDependencies.add(dep))
177
+ }
178
+
179
+ if (directDependencies.has(end)) {
180
+ return [start, end]
181
+ }
182
+
183
+ for (const dep of directDependencies) {
184
+ if (!visited.has(dep)) {
185
+ const path = this.findPath(dep, end, visited)
186
+ if (path.length > 0) {
187
+ return [start, ...path]
188
+ }
189
+ }
190
+ }
191
+
192
+ return []
193
+ }
194
+
195
+ /**
196
+ * Performs a topological sort on the graph to determine execution order.
197
+ * Uses Kahn's algorithm.
198
+ */
199
+ private topologicalSort(): string[] {
200
+ const inDegree = new Map<string, number>()
201
+ const sorted: string[] = []
202
+
203
+ // This map stores which jobs depend on a given key.
204
+ // e.g., `adjacency.get('A')` -> `['B', 'C']` means B and C depend on A.
205
+ const adjacency = new Map<string, string[]>()
206
+
207
+ // Initialize in-degrees and adjacency list for all jobs.
208
+ for (const jobName of this.allJobNames) {
209
+ inDegree.set(jobName, 0)
210
+ adjacency.set(jobName, [])
211
+ }
212
+
213
+ // Build the inverted graph (adjacency list) and calculate initial in-degrees.
214
+ for (const [jobName, dependencies] of this.graph.entries()) {
215
+ inDegree.set(jobName, dependencies.size)
216
+ for (const dep of dependencies) {
217
+ // `jobName` depends on `dep`, so `dep` is a prerequisite for `jobName`.
218
+ adjacency.get(dep)?.push(jobName)
219
+ }
220
+ }
221
+
222
+ // Initialize queue with nodes having an in-degree of 0.
223
+ const queue: string[] = []
224
+ for (const [jobName, degree] of inDegree.entries()) {
225
+ if (degree === 0) {
226
+ queue.push(jobName)
227
+ }
228
+ }
229
+
230
+ // Process the queue.
231
+ while (queue.length > 0) {
232
+ const current = queue.shift()!
233
+ sorted.push(current)
234
+
235
+ const dependents = adjacency.get(current) || []
236
+ for (const dependent of dependents) {
237
+ const newDegree = (inDegree.get(dependent) || 1) - 1
238
+ inDegree.set(dependent, newDegree)
239
+ if (newDegree === 0) {
240
+ queue.push(dependent)
241
+ }
242
+ }
243
+ }
244
+
245
+ if (sorted.length !== this.allJobNames.size) {
246
+ // This should theoretically be caught by `checkForCycles`, but it's good defense.
247
+ throw new Error('Topological sort failed. The graph likely has a cycle.')
248
+ }
249
+
250
+ return sorted
251
+ }
252
+ }
@@ -0,0 +1,263 @@
1
+ import * as fs from 'fs/promises'
2
+ import * as path from 'path'
3
+ import { parseJob, parseTemplate } from '../parsers'
4
+ import { Job, Template } from '../types'
5
+ import { ContractRepository } from '../contracts/repository'
6
+ import { parseConstants } from '../parsers/constants'
7
+
8
+ export interface ProjectLoaderOptions {
9
+ loadStdTemplates?: boolean
10
+ }
11
+
12
+ export class ProjectLoader {
13
+ public jobs: Map<string, Job> = new Map()
14
+ public templates: Map<string, Template> = new Map()
15
+ public readonly contractRepository: ContractRepository
16
+
17
+ // Top-level constants registry
18
+ public constants: Map<string, any> = new Map()
19
+ // Track source files for constants for duplicate reporting
20
+ private constantSources: Map<string, string> = new Map()
21
+
22
+ constructor(
23
+ private readonly projectRoot: string,
24
+ private readonly options: ProjectLoaderOptions = {}
25
+ ) {
26
+ this.contractRepository = new ContractRepository()
27
+ }
28
+
29
+ async load() {
30
+ // Load all contracts from the project root first
31
+ await this.contractRepository.loadFrom(this.projectRoot)
32
+
33
+ // Load standard library templates (unless disabled)
34
+ if (this.options.loadStdTemplates !== false) {
35
+ const stdTemplatePath = path.resolve(__dirname, '..', 'std', 'templates')
36
+ if (await this.pathExists(stdTemplatePath)) {
37
+ await this.loadTemplatesFromDir(stdTemplatePath)
38
+ }
39
+ }
40
+
41
+ // Load user-defined templates
42
+ const userTemplatePath = path.join(this.projectRoot, 'templates')
43
+ if (await this.pathExists(userTemplatePath)) {
44
+ await this.loadTemplatesFromDir(userTemplatePath)
45
+ }
46
+
47
+ // Load jobs
48
+ const jobsPath = path.join(this.projectRoot, 'jobs')
49
+ if (await this.pathExists(jobsPath)) {
50
+ await this.loadJobsFromDir(jobsPath)
51
+ }
52
+
53
+ // Load templates from within job directories
54
+ if (await this.pathExists(jobsPath)) {
55
+ await this.loadTemplatesFromJobDirs(jobsPath)
56
+ }
57
+
58
+ // Load top-level constants from anywhere in project root
59
+ await this.loadConstantsFromDir(this.projectRoot)
60
+ }
61
+
62
+ private async loadTemplatesFromDir(dir: string) {
63
+ const templateFiles = await this.findTemplateFiles(dir)
64
+ for (const filePath of templateFiles) {
65
+ try {
66
+ const content = await fs.readFile(filePath, 'utf-8')
67
+ const template = parseTemplate(content)
68
+ template._path = filePath
69
+ this.templates.set(template.name, template)
70
+ } catch (error) {
71
+ // Surface YAML/template parsing errors so malformed templates fail the load
72
+ if (error instanceof Error && (error.message.startsWith('Failed to parse template YAML:') || error.message.startsWith('Invalid template'))) {
73
+ throw new Error(`Template load error in ${filePath}: ${error.message}`)
74
+ }
75
+ // If it's a file system error (e.g., permission), rethrow to make it visible as well
76
+ if (error instanceof Error && (error as any).code) {
77
+ throw new Error(`Failed to read template file ${filePath}: ${(error as any).code} ${error.message}`)
78
+ }
79
+ // Otherwise rethrow to avoid silently ignoring real issues
80
+ throw error
81
+ }
82
+ }
83
+ }
84
+
85
+ /**
86
+ * Recursively finds all template files (.yaml/.yml) in a directory.
87
+ */
88
+ private async findTemplateFiles(dir: string, ignoreDirs: Set<string> = new Set(['node_modules', 'dist', '.git', '.idea', '.vscode'])): Promise<string[]> {
89
+ let results: string[] = []
90
+ try {
91
+ const list = await fs.readdir(dir, { withFileTypes: true })
92
+
93
+ for (const dirent of list) {
94
+ const fullPath = path.resolve(dir, dirent.name)
95
+ if (dirent.isDirectory()) {
96
+ if (!ignoreDirs.has(dirent.name)) {
97
+ results = results.concat(await this.findTemplateFiles(fullPath, ignoreDirs))
98
+ }
99
+ } else if (dirent.isFile() && (dirent.name.endsWith('.yaml') || dirent.name.endsWith('.yml'))) {
100
+ results.push(fullPath)
101
+ }
102
+ }
103
+ } catch (err) {
104
+ // Ignore errors from trying to read directories we don't have access to, etc.
105
+ }
106
+ return results
107
+ }
108
+
109
+ private async loadJobsFromDir(dir: string) {
110
+ const jobFiles = await this.findJobFiles(dir)
111
+ for (const filePath of jobFiles) {
112
+ try {
113
+ const content = await fs.readFile(filePath, 'utf-8')
114
+ const raw: any = (() => { try { return require('yaml').parse(content) } catch { return {} } })()
115
+ if (raw && typeof raw === 'object' && raw.type === 'template') {
116
+ // This is actually a template file; load through the template path to avoid misclassification
117
+ const template = parseTemplate(content)
118
+ template._path = filePath
119
+ this.templates.set(template.name, template)
120
+ continue
121
+ }
122
+
123
+ const job = parseJob(content)
124
+ // Capture optional job-level constants by peeking the raw YAML for "constants"
125
+ try {
126
+ const raw = JSON.parse(JSON.stringify(require('yaml').parse(content)))
127
+ if (raw && typeof raw === 'object' && raw.constants !== undefined) {
128
+ if (typeof raw.constants !== 'object' || Array.isArray(raw.constants)) {
129
+ throw new Error(`Invalid job "${job.name}": "constants" field must be an object if provided.`)
130
+ }
131
+ (job as any).constants = raw.constants
132
+ }
133
+ } catch (peekErr) {
134
+ // parseJob already validated YAML; if this peek fails due to YAML parsing, surface it
135
+ if (peekErr instanceof Error && peekErr.message.includes('Failed to parse')) {
136
+ throw new Error(`Job constants peek failed for ${filePath}: ${peekErr.message}`)
137
+ }
138
+ // Otherwise ignore non-YAML related errors here
139
+ }
140
+ job._path = filePath
141
+ this.jobs.set(job.name, job)
142
+ } catch (error) {
143
+ // If job YAML is malformed or invalid, skip this job but continue loading others
144
+ if (error instanceof Error && (error.message.startsWith('Failed to parse job YAML:') || error.message.startsWith('Invalid job'))) {
145
+ console.warn(`Skipping malformed job at ${filePath}: ${error.message}`)
146
+ continue
147
+ }
148
+ // If it's a file system error (e.g., permission), rethrow to make it visible as well
149
+ if (error instanceof Error && (error as any).code) {
150
+ throw new Error(`Failed to read job file ${filePath}: ${(error as any).code} ${error.message}`)
151
+ }
152
+ // For other unexpected errors, rethrow
153
+ throw error
154
+ }
155
+ }
156
+ }
157
+
158
+ /**
159
+ * Recursively finds all job files (.yaml/.yml) in a directory.
160
+ */
161
+ private async findJobFiles(dir: string, ignoreDirs: Set<string> = new Set(['node_modules', 'dist', '.git', '.idea', '.vscode'])): Promise<string[]> {
162
+ let results: string[] = []
163
+ try {
164
+ const list = await fs.readdir(dir, { withFileTypes: true })
165
+
166
+ for (const dirent of list) {
167
+ const fullPath = path.resolve(dir, dirent.name)
168
+ if (dirent.isDirectory()) {
169
+ if (!ignoreDirs.has(dirent.name)) {
170
+ results = results.concat(await this.findJobFiles(fullPath, ignoreDirs))
171
+ }
172
+ } else if (dirent.isFile() && (dirent.name.endsWith('.yaml') || dirent.name.endsWith('.yml'))) {
173
+ results.push(fullPath)
174
+ }
175
+ }
176
+ } catch (err) {
177
+ // Ignore errors from trying to read directories we don't have access to, etc.
178
+ }
179
+ return results
180
+ }
181
+
182
+ /**
183
+ * Loads templates from within job directories by scanning for 'templates' subdirectories.
184
+ */
185
+ private async loadTemplatesFromJobDirs(jobsRootDir: string) {
186
+ await this.findAndLoadTemplatesInJobDirs(jobsRootDir)
187
+ }
188
+
189
+ /**
190
+ * Recursively searches for 'templates' directories within job directories and loads templates from them.
191
+ */
192
+ private async findAndLoadTemplatesInJobDirs(dir: string, ignoreDirs: Set<string> = new Set(['node_modules', 'dist', '.git', '.idea', '.vscode'])): Promise<void> {
193
+ try {
194
+ const list = await fs.readdir(dir, { withFileTypes: true })
195
+
196
+ for (const dirent of list) {
197
+ const fullPath = path.resolve(dir, dirent.name)
198
+ if (dirent.isDirectory()) {
199
+ if (!ignoreDirs.has(dirent.name)) {
200
+ // If this directory is named 'templates', load templates from it
201
+ if (dirent.name === 'templates') {
202
+ await this.loadTemplatesFromDir(fullPath)
203
+ }
204
+ // Continue recursively searching for more template directories
205
+ await this.findAndLoadTemplatesInJobDirs(fullPath, ignoreDirs)
206
+ }
207
+ }
208
+ }
209
+ } catch (err) {
210
+ // Ignore errors from trying to read directories we don't have access to, etc.
211
+ }
212
+ }
213
+
214
+ /**
215
+ * Load and merge all top-level constants from any YAML file with type: "constants"
216
+ * located anywhere under the given directory.
217
+ */
218
+ private async loadConstantsFromDir(dir: string, ignoreDirs: Set<string> = new Set(['node_modules', 'dist', '.git', '.idea', '.vscode'])): Promise<void> {
219
+ try {
220
+ const list = await fs.readdir(dir, { withFileTypes: true })
221
+ for (const dirent of list) {
222
+ const fullPath = path.resolve(dir, dirent.name)
223
+ if (dirent.isDirectory()) {
224
+ if (!ignoreDirs.has(dirent.name)) {
225
+ await this.loadConstantsFromDir(fullPath, ignoreDirs)
226
+ }
227
+ } else if (dirent.isFile() && (dirent.name.endsWith('.yaml') || dirent.name.endsWith('.yml'))) {
228
+ try {
229
+ const content = await fs.readFile(fullPath, 'utf-8')
230
+ const constantsDoc = parseConstants(content)
231
+ if (constantsDoc) {
232
+ for (const [key, value] of Object.entries(constantsDoc.constants)) {
233
+ if (this.constants.has(key)) {
234
+ const prevSource = this.constantSources.get(key)
235
+ throw new Error(`Duplicate constant "${key}" found in ${fullPath}${prevSource ? ` (previously defined in ${prevSource})` : ''}`)
236
+ }
237
+ this.constants.set(key, value)
238
+ this.constantSources.set(key, fullPath)
239
+ }
240
+ }
241
+ } catch (err) {
242
+ // For constants files, surface parsing errors to fail fast
243
+ if (err instanceof Error && (err.message.startsWith('Failed to parse constants YAML:') || err.message.startsWith('Invalid constants'))) {
244
+ throw new Error(`Constants load error in ${fullPath}: ${err.message}`)
245
+ }
246
+ // Otherwise, ignore if not a constants file
247
+ }
248
+ }
249
+ }
250
+ } catch (err) {
251
+ // Ignore directory read errors (like permission or non-existent)
252
+ }
253
+ }
254
+
255
+ private async pathExists(p: string): Promise<boolean> {
256
+ try {
257
+ await fs.access(p)
258
+ return true
259
+ } catch {
260
+ return false
261
+ }
262
+ }
263
+ }