@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,208 @@
1
+ import { Command } from 'commander'
2
+ import chalk from 'chalk'
3
+ import { loadProject } from './common'
4
+ import { loadNetworks } from '../lib/network-loader'
5
+ import { DependencyGraph } from '../lib/core/graph'
6
+ import { projectOption, noStdOption, verbosityOption } from './common'
7
+ import { validateContractReferences, extractUsedContractReferences } from '../lib/validation/contract-references'
8
+ import { setVerbosity } from '../index'
9
+ import { Template } from '../lib/types'
10
+
11
+ interface DryRunOptions {
12
+ project: string
13
+ std: boolean
14
+ network?: string[]
15
+ verbose: number
16
+ }
17
+
18
+ /**
19
+ * Extract only constant-like placeholders from a value, using template metadata when available.
20
+ * A placeholder is treated as a constant candidate if:
21
+ * - It is a bare identifier (no dot, no parentheses), AND
22
+ * - It is NOT declared as a template argument in the current template (when template context provided)
23
+ */
24
+ function extractConstantRefs(value: unknown, refs: string[], templateCtx?: Template) {
25
+ if (typeof value === 'string') {
26
+ const m = value.match(/^{{(.*)}}$/)
27
+ if (m) {
28
+ const expr = m[1].trim()
29
+
30
+ // Skip outputs or function-like references
31
+ if (expr.includes('.') || expr.includes('(') || expr.includes(')')) return
32
+
33
+ // If we have a template context, and the expr matches a declared argument, it's NOT a constant
34
+ if (templateCtx?.arguments && Object.prototype.hasOwnProperty.call(templateCtx.arguments, expr)) {
35
+ return
36
+ }
37
+
38
+ // Otherwise, treat as a constant candidate
39
+ refs.push(expr)
40
+ }
41
+ } else if (Array.isArray(value)) {
42
+ for (const v of value) extractConstantRefs(v, refs, templateCtx)
43
+ } else if (value && typeof value === 'object') {
44
+ for (const v of Object.values(value)) extractConstantRefs(v, refs, templateCtx)
45
+ }
46
+ }
47
+
48
+ export function makeDryRunCommand(): Command {
49
+ const dryRun = new Command('dry-run')
50
+ .description('Validate project configuration and show execution plan without running transactions')
51
+ .argument('[jobs...]', 'Specific job names to validate (and their dependencies).')
52
+ .option('-n, --network <chainIds...>', 'One or more network chain IDs to simulate running on.')
53
+
54
+ projectOption(dryRun)
55
+ noStdOption(dryRun)
56
+ verbosityOption(dryRun)
57
+
58
+ dryRun.action(async (jobs: string[], options: DryRunOptions) => {
59
+ try {
60
+ // Set verbosity level for logging
61
+ setVerbosity(options.verbose as 0 | 1 | 2 | 3)
62
+
63
+ console.log(chalk.bold.inverse(' DRY-RUN MODE '))
64
+ const projectRoot = options.project
65
+ const loader = await loadProject(projectRoot, {
66
+ loadStdTemplates: options.std !== false
67
+ })
68
+ const allNetworks = await loadNetworks(projectRoot)
69
+
70
+ console.log(chalk.blue('\nBuilding dependency graph...'))
71
+ const graph = new DependencyGraph(loader.jobs, loader.templates)
72
+ const fullOrder = graph.getExecutionOrder()
73
+ console.log(chalk.green(' - Dependency graph built successfully.'))
74
+
75
+ console.log(chalk.blue('\nContract Repository:'))
76
+ console.log(chalk.green(` - Found ${loader.contractRepository.getAll().length} unique contracts.`))
77
+
78
+ // Check for ambiguous references that are actually being used
79
+ const usedRefs = await extractUsedContractReferences(loader)
80
+ const allAmbiguousRefs = loader.contractRepository.getAmbiguousReferences()
81
+ const usedRefNames = usedRefs.map(ref => ref.reference)
82
+ const usedAmbiguousRefs = allAmbiguousRefs.filter(ref => usedRefNames.includes(ref))
83
+
84
+ if (usedAmbiguousRefs.length > 0) {
85
+ console.log(chalk.red('\n - Found ambiguous contract references being used:'))
86
+ for (const ref of usedAmbiguousRefs) {
87
+ console.log(chalk.red(` ✗ "${ref}" could refer to multiple contracts`))
88
+ }
89
+ throw new Error(`Found ${usedAmbiguousRefs.length} ambiguous contract reference(s) being used. Please use more specific references to resolve ambiguity.`)
90
+ }
91
+ console.log(chalk.green(' - All used contract references are unambiguous.'))
92
+
93
+ // Validate that all Contract() references point to existing contracts
94
+ console.log(chalk.blue('\nValidating contract references...'))
95
+ const missingRefs = await validateContractReferences(loader)
96
+ if (missingRefs.length > 0) {
97
+ console.log(chalk.red('\n - Found missing contract references:'))
98
+ for (const ref of missingRefs) {
99
+ console.log(chalk.red(` ✗ ${ref.reference} in ${ref.location}`))
100
+ }
101
+ throw new Error(`Found ${missingRefs.length} missing contract reference(s). Please ensure all referenced contracts exist.`)
102
+ }
103
+ console.log(chalk.green(' - All contract references are valid.'))
104
+
105
+ // Validate constant references exist
106
+ console.log(chalk.blue('\nValidating constant references...'))
107
+ const topLevelConstants = loader.constants
108
+ const missingConstantRefs: Array<{ ref: string; location: string }> = []
109
+
110
+ // Check jobs (arguments and outputs within templates are resolved at runtime; here we just check expressions)
111
+ for (const [jobName, job] of loader.jobs.entries()) {
112
+ // Collect refs in job actions
113
+ for (let i = 0; i < job.actions.length; i++) {
114
+ const action = job.actions[i]
115
+ const refs: string[] = []
116
+ extractConstantRefs(action.arguments, refs)
117
+ const jobConstants = job.constants || {}
118
+ for (const r of refs) {
119
+ if (!(r in jobConstants) && !topLevelConstants.has(r)) {
120
+ missingConstantRefs.push({ ref: r, location: `job '${jobName}', action ${i + 1}${action.name ? ` '${action.name}'` : ''}` })
121
+ }
122
+ }
123
+ }
124
+ }
125
+
126
+ // Check templates (setup/actions/outputs)
127
+ for (const [templateName, template] of loader.templates.entries()) {
128
+ // actions
129
+ for (let i = 0; i < template.actions.length; i++) {
130
+ const action = template.actions[i]
131
+ const refs: string[] = []
132
+ extractConstantRefs(action.arguments, refs, template)
133
+ for (const r of refs) {
134
+ if (!topLevelConstants.has(r)) {
135
+ missingConstantRefs.push({ ref: r, location: `template '${templateName}', action ${i + 1}${action.name ? ` '${action.name}'` : ''}` })
136
+ }
137
+ }
138
+ }
139
+ // setup actions
140
+ if (template.setup?.actions) {
141
+ for (let i = 0; i < (template.setup.actions?.length || 0); i++) {
142
+ const action = template.setup.actions![i]
143
+ const refs: string[] = []
144
+ extractConstantRefs(action.arguments, refs, template)
145
+ for (const r of refs) {
146
+ if (!topLevelConstants.has(r)) {
147
+ missingConstantRefs.push({ ref: r, location: `template '${templateName}' setup, action ${i + 1}${action.name ? ` '${action.name}'` : ''}` })
148
+ }
149
+ }
150
+ }
151
+ }
152
+ // outputs
153
+ if (template.outputs) {
154
+ const refs: string[] = []
155
+ extractConstantRefs(template.outputs, refs, template)
156
+ for (const r of refs) {
157
+ if (!topLevelConstants.has(r)) {
158
+ missingConstantRefs.push({ ref: r, location: `template '${templateName}' outputs` })
159
+ }
160
+ }
161
+ }
162
+ }
163
+
164
+ if (missingConstantRefs.length > 0) {
165
+ console.log(chalk.red('\n - Found missing constant references:'))
166
+ for (const m of missingConstantRefs) {
167
+ console.log(chalk.red(` ✗ ${m.ref} in ${m.location}`))
168
+ }
169
+ throw new Error(`Found ${missingConstantRefs.length} missing constant reference(s). Ensure they are defined at top-level or in the job's constants.`)
170
+ }
171
+ console.log(chalk.green(' - All constant references are valid.'))
172
+
173
+ const runJobs = jobs.length > 0 ? jobs : undefined
174
+ const runOnNetworks = options.network?.map(Number)
175
+
176
+ const jobsToRun = new Set<string>()
177
+ if (runJobs) {
178
+ for (const jobName of runJobs) {
179
+ if (!loader.jobs.has(jobName)) {
180
+ throw new Error(`Specified job "${jobName}" not found in project.`)
181
+ }
182
+ jobsToRun.add(jobName)
183
+ graph.getDependencies(jobName).forEach(dep => jobsToRun.add(dep))
184
+ }
185
+ } else {
186
+ fullOrder.forEach(j => jobsToRun.add(j))
187
+ }
188
+
189
+ const jobExecutionPlan = fullOrder.filter(jobName => jobsToRun.has(jobName))
190
+ const targetNetworks = runOnNetworks
191
+ ? allNetworks.filter(n => runOnNetworks.includes(n.chainId))
192
+ : allNetworks
193
+
194
+ console.log(chalk.blue('\nExecution Plan:'))
195
+ console.log(chalk.gray(` - Target Networks: ${targetNetworks.map(n => `${n.name} (ChainID: ${n.chainId})`).join(', ')}`))
196
+ console.log(chalk.gray(` - Job Execution Order: ${jobExecutionPlan.join(' -> ')}`))
197
+
198
+ console.log(chalk.green.bold('\n✅ Dry run successful. All job and template definitions appear to be valid.'))
199
+
200
+ } catch (error) {
201
+ console.error(chalk.red.bold('\n💥 DRY RUN FAILED!'))
202
+ console.error(chalk.red(error instanceof Error ? error.message : String(error)))
203
+ process.exit(1)
204
+ }
205
+ })
206
+
207
+ return dryRun
208
+ }
@@ -0,0 +1,360 @@
1
+ import { Command } from 'commander'
2
+ import chalk from 'chalk'
3
+ import { loadNetworks } from '../lib/network-loader'
4
+ import { projectOption, verbosityOption } from './common'
5
+ import { setVerbosity } from '../index'
6
+ import * as solc from 'solc'
7
+ import { createHash } from 'crypto'
8
+
9
+ type ApiAction = 'getsourcecode' | 'getabi'
10
+
11
+ interface EtherscanCmdBase {
12
+ project: string
13
+ verbose: number
14
+ etherscanApiKey?: string
15
+ network?: string
16
+ address: string
17
+ raw?: boolean
18
+ }
19
+
20
+ function getEtherscanApiUrl(chainId: number): string {
21
+ return `https://api.etherscan.io/v2/api?chainid=${chainId}`
22
+ }
23
+
24
+ type EtherscanSourceEnvelope = {
25
+ rawResult: Record<string, any>
26
+ parsedSource: unknown // standard-json object or flattened string
27
+ }
28
+
29
+ async function fetchFromEtherscan(
30
+ chainId: number,
31
+ apiKey: string,
32
+ address: string,
33
+ action: ApiAction
34
+ ): Promise<unknown | EtherscanSourceEnvelope> {
35
+ const apiUrl = getEtherscanApiUrl(chainId)
36
+ const params = new URLSearchParams({
37
+ module: 'contract',
38
+ action,
39
+ apikey: apiKey,
40
+ address
41
+ })
42
+ const resp = await fetch(`${apiUrl}&${params.toString()}`, {
43
+ method: 'GET',
44
+ signal: AbortSignal.timeout(20000)
45
+ })
46
+ if (!resp.ok) {
47
+ throw new Error(`HTTP ${resp.status}: ${resp.statusText}`)
48
+ }
49
+ const data = await resp.json() as {
50
+ status: string
51
+ message?: string
52
+ result:
53
+ | string
54
+ | Array<{
55
+ SourceCode?: string
56
+ ABI?: string
57
+ [key: string]: unknown
58
+ }>
59
+ }
60
+
61
+ if (data.status !== '1') {
62
+ // Etherscan v2 returns status "0" with message in result
63
+ const msg = typeof data.result === 'string' ? data.result : JSON.stringify(data.result)
64
+ throw new Error(msg || 'Unknown Etherscan error')
65
+ }
66
+
67
+ if (action === 'getabi') {
68
+ // data.result is a JSON-encoded string for ABI, parse and return as object
69
+ if (typeof data.result !== 'string') {
70
+ throw new Error('Unexpected ABI result format from Etherscan')
71
+ }
72
+ try {
73
+ return JSON.parse(data.result as string)
74
+ } catch (_e) {
75
+ throw new Error('Failed to parse ABI JSON returned by Etherscan')
76
+ }
77
+ }
78
+
79
+ if (action === 'getsourcecode') {
80
+ // data.result[0].SourceCode is a string; when standard-json it is wrapped with a leading and trailing character
81
+ if (!Array.isArray(data.result) || data.result.length === 0) {
82
+ throw new Error('Empty result from Etherscan')
83
+ }
84
+ const first = (data.result as Array<{ SourceCode?: string }>)[0] as Record<string, any>
85
+ const sourceCodeRaw = first?.SourceCode as string
86
+ if (typeof sourceCodeRaw !== 'string' || sourceCodeRaw.length === 0) {
87
+ throw new Error('No SourceCode found on Etherscan')
88
+ }
89
+
90
+ // The SourceCode may be:
91
+ // 1) a raw source (flattened) string
92
+ // 2) a JSON string that may be double-wrapped like: "{...}" or "{{...}}"
93
+ // Try to normalize to a parsed JSON object when possible, otherwise return the raw string.
94
+ const trimmed = sourceCodeRaw.trim()
95
+ // Heuristic: if it starts with '{{' and ends with '}}', strip one layer
96
+ const cleaned = trimmed.startsWith('{{') && trimmed.endsWith('}}')
97
+ ? trimmed.slice(1, -1)
98
+ : trimmed
99
+
100
+ // Try to parse JSON; if it fails, return string
101
+ try {
102
+ const parsed = JSON.parse(cleaned)
103
+ return { rawResult: first, parsedSource: parsed }
104
+ } catch {
105
+ // Not JSON, return as-is string
106
+ return { rawResult: first, parsedSource: sourceCodeRaw }
107
+ }
108
+ }
109
+
110
+ return data.result
111
+ }
112
+
113
+ export function makeEtherscanCommand(): Command {
114
+ const etherscan = new Command('etherscan')
115
+ .description('Etherscan helper commands (ABI/source fetch)')
116
+
117
+ // Common options builder
118
+ const withCommon = (cmd: Command) => {
119
+ projectOption(cmd)
120
+ verbosityOption(cmd)
121
+ cmd
122
+ .option('--etherscan-api-key <key>', 'Etherscan API key. Can also be set via ETHERSCAN_API_KEY env var.')
123
+ .option('-n, --network <chainId>', 'Target network chain ID (required to select proper Etherscan endpoint)')
124
+ .option('-a, --address <address>', 'Contract address to query', '')
125
+ .option('--raw', 'Print raw response (no pretty JSON). Useful for piping.', false)
126
+ return cmd
127
+ }
128
+
129
+ // etherscan abi
130
+ const abi = new Command('abi')
131
+ .description('Fetch contract ABI from Etherscan and print to stdout')
132
+ withCommon(abi)
133
+ abi.action(async (options: EtherscanCmdBase) => {
134
+ try {
135
+ setVerbosity(options.verbose as 0 | 1 | 2 | 3)
136
+
137
+ const apiKey = options.etherscanApiKey || process.env.ETHERSCAN_API_KEY
138
+ if (!apiKey) {
139
+ console.error(chalk.red('Etherscan API key is required. Use --etherscan-api-key or set ETHERSCAN_API_KEY.'))
140
+ process.exit(1)
141
+ }
142
+
143
+ if (!options.address) {
144
+ console.error(chalk.red('Missing required --address option'))
145
+ process.exit(1)
146
+ }
147
+
148
+ // Determine chainId
149
+ let chainId: number | undefined
150
+ if (options.network) {
151
+ const parsed = Number(options.network)
152
+ if (Number.isNaN(parsed)) {
153
+ console.error(chalk.red('Invalid --network value. Must be a chain ID number.'))
154
+ process.exit(1)
155
+ }
156
+ chainId = parsed
157
+ } else {
158
+ // If network not provided, try to infer: if only one network configured, use it
159
+ const networks = await loadNetworks(options.project)
160
+ if (networks.length === 1) {
161
+ chainId = networks[0].chainId
162
+ } else {
163
+ console.error(chalk.red('Please provide --network <chainId> (multiple or zero networks configured).'))
164
+ process.exit(1)
165
+ }
166
+ }
167
+
168
+ const result = await fetchFromEtherscan(chainId!, apiKey, options.address, 'getabi')
169
+
170
+ if (options.raw) {
171
+ // raw: output minified JSON
172
+ process.stdout.write(JSON.stringify(result))
173
+ } else {
174
+ // pretty
175
+ console.log(JSON.stringify(result, null, 2))
176
+ }
177
+ } catch (error) {
178
+ console.error(chalk.red('Error fetching ABI from Etherscan:'), error instanceof Error ? error.message : String(error))
179
+ process.exit(1)
180
+ }
181
+ })
182
+
183
+ // etherscan source
184
+ const source = new Command('source')
185
+ .description('Fetch contract source and emit a self-contained build-info JSON suitable for verification')
186
+ withCommon(source)
187
+ source.action(async (options: EtherscanCmdBase) => {
188
+ try {
189
+ setVerbosity(options.verbose as 0 | 1 | 2 | 3)
190
+
191
+ const apiKey = options.etherscanApiKey || process.env.ETHERSCAN_API_KEY
192
+ if (!apiKey) {
193
+ console.error(chalk.red('Etherscan API key is required. Use --etherscan-api-key or set ETHERSCAN_API_KEY.'))
194
+ process.exit(1)
195
+ }
196
+
197
+ if (!options.address) {
198
+ console.error(chalk.red('Missing required --address option'))
199
+ process.exit(1)
200
+ }
201
+
202
+ // Determine chainId
203
+ let chainId: number | undefined
204
+ if (options.network) {
205
+ const parsed = Number(options.network)
206
+ if (Number.isNaN(parsed)) {
207
+ console.error(chalk.red('Invalid --network value. Must be a chain ID number.'))
208
+ process.exit(1)
209
+ }
210
+ chainId = parsed
211
+ } else {
212
+ const networks = await loadNetworks(options.project)
213
+ if (networks.length === 1) {
214
+ chainId = networks[0].chainId
215
+ } else {
216
+ console.error(chalk.red('Please provide --network <chainId> (multiple or zero networks configured).'))
217
+ process.exit(1)
218
+ }
219
+ }
220
+
221
+ const result = await fetchFromEtherscan(chainId!, apiKey, options.address, 'getsourcecode') as EtherscanSourceEnvelope
222
+
223
+ const raw = result.rawResult
224
+ const parsed = result.parsedSource
225
+
226
+ // Extract compiler version with commit from metadata when available
227
+ const compilerVersion = (raw?.CompilerVersion as string | undefined) || ''
228
+ const optimizationUsed = (raw?.OptimizationUsed as string | undefined) || ''
229
+ const runsStr = (raw?.Runs as string | undefined) || ''
230
+ const evmVersionRaw = (raw?.EVMVersion as string | undefined) || ''
231
+ const isStandardJson = parsed && typeof parsed === 'object' && (parsed as any).language && (parsed as any).sources
232
+
233
+ // If we have a standard JSON input, use it; otherwise build one from flattened source
234
+ let input: any
235
+ if (isStandardJson) {
236
+ input = { ...(parsed as any) }
237
+ // Ensure outputSelection includes required entries to get creation bytecode and metadata
238
+ const currentSel = input.settings?.outputSelection || {}
239
+ const mergedSel = {
240
+ '*': {
241
+ '*': Array.from(new Set([
242
+ ...(currentSel?.['*']?.['*'] || []),
243
+ 'abi',
244
+ 'evm.bytecode',
245
+ 'evm.deployedBytecode',
246
+ 'metadata',
247
+ 'userdoc',
248
+ 'devdoc',
249
+ 'evm.methodIdentifiers'
250
+ ]))
251
+ }
252
+ }
253
+ input.settings = {
254
+ ...(input.settings || {}),
255
+ outputSelection: mergedSel
256
+ }
257
+ } else {
258
+ // Build a minimal standard JSON input from flattened source
259
+ const flattened = String(parsed || '')
260
+ input = {
261
+ language: 'Solidity',
262
+ sources: {
263
+ 'Flattened.sol': { content: flattened }
264
+ },
265
+ settings: {
266
+ optimizer: {
267
+ enabled: optimizationUsed === '1',
268
+ runs: Number.isFinite(Number(runsStr)) ? Number(runsStr) : 200
269
+ },
270
+ evmVersion: evmVersionRaw && evmVersionRaw !== 'default' ? evmVersionRaw : undefined,
271
+ outputSelection: {
272
+ '*': {
273
+ '*': [
274
+ 'abi',
275
+ 'evm.bytecode.object',
276
+ 'evm.bytecode.sourceMap',
277
+ 'evm.bytecode.linkReferences',
278
+ 'evm.deployedBytecode.object',
279
+ 'evm.deployedBytecode.sourceMap',
280
+ 'evm.deployedBytecode.linkReferences',
281
+ 'evm.deployedBytecode.immutableReferences',
282
+ 'evm.methodIdentifiers',
283
+ 'metadata'
284
+ ]
285
+ }
286
+ }
287
+ }
288
+ }
289
+ }
290
+
291
+ // Compile with exact solc version when possible
292
+ const solcInput = JSON.stringify(input)
293
+ const versionTag = compilerVersion && compilerVersion.startsWith('v') ? compilerVersion : (compilerVersion ? `v${compilerVersion}` : '')
294
+ let outputRaw: string
295
+ if (versionTag) {
296
+ outputRaw = await new Promise<string>((resolve, reject) => {
297
+ // @ts-ignore - loadRemoteVersion exists in solc js
298
+ solc.loadRemoteVersion(versionTag, (err: any, specificSolc: any) => {
299
+ if (err || !specificSolc) return reject(err || new Error('Failed to load solc version'))
300
+ try {
301
+ resolve(specificSolc.compile(solcInput))
302
+ } catch (e) {
303
+ reject(e)
304
+ }
305
+ })
306
+ })
307
+ } else {
308
+ outputRaw = solc.compile(solcInput)
309
+ }
310
+ const output = JSON.parse(outputRaw)
311
+
312
+ // Build build-info id as hex of sha1 of input
313
+ const id = createHash('sha1').update(solcInput).digest('hex')
314
+
315
+ // Determine solc versions
316
+ const solcLongVersion = (output?.compiler?.version as string | undefined) || (compilerVersion ? compilerVersion.replace(/^v/, '') : undefined)
317
+ const solcVersion = (solcLongVersion || '').split('+')[0] || (typeof (solc as any).version === 'function' ? (solc as any).version() : 'unknown')
318
+
319
+ // Augment settings with defaults similar to reference format
320
+ const basePath = process.cwd()
321
+ const includePaths = [basePath]
322
+ const allowPaths = includePaths
323
+
324
+ const buildInfo = {
325
+ id,
326
+ source_id_to_path: Object.fromEntries(Object.keys(input.sources).map((p, i) => [String(i), p])),
327
+ language: input.language,
328
+ _format: 'ethers-rs-sol-build-info-1',
329
+ input: {
330
+ version: solcVersion,
331
+ language: input.language,
332
+ sources: input.sources,
333
+ settings: input.settings,
334
+ evmVersion: input.settings?.evmVersion || 'cancun',
335
+ viaIR: input.settings?.viaIR || false,
336
+ libraries: input.settings?.libraries || {}
337
+ },
338
+ allowPaths,
339
+ basePath,
340
+ includePaths,
341
+ output: {
342
+ contracts: output.contracts || {},
343
+ sources: output.sources || {}
344
+ },
345
+ solcLongVersion: solcLongVersion || solcVersion,
346
+ solcVersion: solcVersion
347
+ }
348
+
349
+ // Print build-info JSON
350
+ console.log(options.raw ? JSON.stringify(buildInfo) : JSON.stringify(buildInfo, null, 2))
351
+ } catch (error) {
352
+ console.error(chalk.red('Error fetching source from Etherscan:'), error instanceof Error ? error.message : String(error))
353
+ process.exit(1)
354
+ }
355
+ })
356
+
357
+ etherscan.addCommand(abi)
358
+ etherscan.addCommand(source)
359
+ return etherscan
360
+ }
@@ -0,0 +1,5 @@
1
+ export * from './run'
2
+ export * from './dry'
3
+ export * from './list'
4
+ export * from './utils'
5
+ export * from './etherscan'