@0xsequence/catapult 1.4.0 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (163) hide show
  1. package/README.md +27 -0
  2. package/dist/lib/__tests__/network-loader.spec.js.map +1 -1
  3. package/dist/lib/core/__tests__/resolver.spec.js +22 -0
  4. package/dist/lib/core/__tests__/resolver.spec.js.map +1 -1
  5. package/dist/lib/core/__tests__/sign-actions.spec.d.ts +2 -0
  6. package/dist/lib/core/__tests__/sign-actions.spec.d.ts.map +1 -0
  7. package/dist/lib/core/__tests__/sign-actions.spec.js +128 -0
  8. package/dist/lib/core/__tests__/sign-actions.spec.js.map +1 -0
  9. package/dist/lib/core/__tests__/signer.spec.d.ts +2 -0
  10. package/dist/lib/core/__tests__/signer.spec.d.ts.map +1 -0
  11. package/dist/lib/core/__tests__/signer.spec.js +40 -0
  12. package/dist/lib/core/__tests__/signer.spec.js.map +1 -0
  13. package/dist/lib/core/context.d.ts +3 -2
  14. package/dist/lib/core/context.d.ts.map +1 -1
  15. package/dist/lib/core/context.js +3 -2
  16. package/dist/lib/core/context.js.map +1 -1
  17. package/dist/lib/core/engine.d.ts +4 -0
  18. package/dist/lib/core/engine.d.ts.map +1 -1
  19. package/dist/lib/core/engine.js +173 -0
  20. package/dist/lib/core/engine.js.map +1 -1
  21. package/dist/lib/core/signer.d.ts +7 -0
  22. package/dist/lib/core/signer.d.ts.map +1 -0
  23. package/dist/lib/core/signer.js +60 -0
  24. package/dist/lib/core/signer.js.map +1 -0
  25. package/dist/lib/parsers/__tests__/source.spec.js +37 -0
  26. package/dist/lib/parsers/__tests__/source.spec.js.map +1 -1
  27. package/dist/lib/parsers/source.js +1 -1
  28. package/dist/lib/parsers/source.js.map +1 -1
  29. package/dist/lib/provenance.js +51 -2
  30. package/dist/lib/provenance.js.map +1 -1
  31. package/dist/lib/types/actions.d.ts +26 -2
  32. package/dist/lib/types/actions.d.ts.map +1 -1
  33. package/dist/lib/types/actions.js +3 -0
  34. package/dist/lib/types/actions.js.map +1 -1
  35. package/dist/lib/types/source.d.ts +2 -0
  36. package/dist/lib/types/source.d.ts.map +1 -1
  37. package/package.json +4 -1
  38. package/.eslintrc.json +0 -29
  39. package/.github/workflows/ci.yml +0 -181
  40. package/CONCEPT.md +0 -24
  41. package/contracts/checked-call.huff +0 -65
  42. package/eslint.config.js +0 -48
  43. package/examples/jobs/guards-v1.yaml +0 -17
  44. package/examples/jobs/sequence-seq-0001-patch.yaml +0 -59
  45. package/examples/jobs/sequence-v1.yaml +0 -59
  46. package/examples/templates/sequence-factory-v1.yaml +0 -56
  47. package/jest.config.js +0 -25
  48. package/src/cli.ts +0 -18
  49. package/src/commands/common.ts +0 -61
  50. package/src/commands/dry.ts +0 -209
  51. package/src/commands/etherscan.ts +0 -360
  52. package/src/commands/index.ts +0 -6
  53. package/src/commands/list.ts +0 -262
  54. package/src/commands/provenance.ts +0 -120
  55. package/src/commands/run.ts +0 -146
  56. package/src/commands/utils.ts +0 -215
  57. package/src/index.ts +0 -67
  58. package/src/lib/__tests__/deployer-events.spec.ts +0 -338
  59. package/src/lib/__tests__/deployer.spec.ts +0 -2269
  60. package/src/lib/__tests__/network-loader.spec.ts +0 -150
  61. package/src/lib/__tests__/network-selection.spec.ts +0 -41
  62. package/src/lib/__tests__/network-utils.spec.ts +0 -230
  63. package/src/lib/__tests__/provenance.spec.ts +0 -208
  64. package/src/lib/artifacts/__tests__/fixtures/contract1.json +0 -19
  65. package/src/lib/artifacts/__tests__/fixtures/contract2.json +0 -19
  66. package/src/lib/artifacts/__tests__/fixtures/duplicate-name.json +0 -19
  67. package/src/lib/artifacts/__tests__/fixtures/nested/nested-contract.json +0 -18
  68. package/src/lib/artifacts/__tests__/fixtures/not-an-artifact.json +0 -8
  69. package/src/lib/artifacts/__tests__/fixtures/readme.txt +0 -2
  70. package/src/lib/contracts/__tests__/repository.spec.ts +0 -612
  71. package/src/lib/contracts/repository.ts +0 -411
  72. package/src/lib/core/__tests__/assert-action.spec.ts +0 -474
  73. package/src/lib/core/__tests__/context.spec.ts +0 -37
  74. package/src/lib/core/__tests__/engine.spec.ts +0 -2005
  75. package/src/lib/core/__tests__/graph.spec.ts +0 -125
  76. package/src/lib/core/__tests__/json-integration.spec.ts +0 -425
  77. package/src/lib/core/__tests__/loader.spec.ts +0 -367
  78. package/src/lib/core/__tests__/multi-platform-verification.spec.ts +0 -406
  79. package/src/lib/core/__tests__/resolver.spec.ts +0 -2496
  80. package/src/lib/core/__tests__/static-action.spec.ts +0 -172
  81. package/src/lib/core/context.ts +0 -127
  82. package/src/lib/core/engine.ts +0 -1834
  83. package/src/lib/core/graph.ts +0 -252
  84. package/src/lib/core/loader.ts +0 -253
  85. package/src/lib/core/resolver.ts +0 -873
  86. package/src/lib/deployer.ts +0 -1005
  87. package/src/lib/events/__tests__/event-system.spec.ts +0 -392
  88. package/src/lib/events/cli-adapter.ts +0 -369
  89. package/src/lib/events/emitter.ts +0 -62
  90. package/src/lib/events/index.ts +0 -3
  91. package/src/lib/events/types.ts +0 -520
  92. package/src/lib/index.ts +0 -17
  93. package/src/lib/network-loader.ts +0 -90
  94. package/src/lib/network-selection.ts +0 -73
  95. package/src/lib/network-utils.ts +0 -64
  96. package/src/lib/parsers/__tests__/buildinfo.spec.ts +0 -122
  97. package/src/lib/parsers/__tests__/fixtures/buildinfo/invalid-bytecode-buildinfo.json +0 -62
  98. package/src/lib/parsers/__tests__/fixtures/buildinfo/invalid-json.txt +0 -2
  99. package/src/lib/parsers/__tests__/fixtures/buildinfo/multi-contract-buildinfo.json +0 -89
  100. package/src/lib/parsers/__tests__/fixtures/buildinfo/no-contracts-buildinfo.json +0 -17
  101. package/src/lib/parsers/__tests__/fixtures/buildinfo/simple-buildinfo.json +0 -63
  102. package/src/lib/parsers/__tests__/fixtures/buildinfo/wrong-format.json +0 -4
  103. package/src/lib/parsers/__tests__/job.spec.ts +0 -439
  104. package/src/lib/parsers/__tests__/source.spec.ts +0 -134
  105. package/src/lib/parsers/__tests__/template.spec.ts +0 -111
  106. package/src/lib/parsers/artifact/__tests__/artifact.spec.ts +0 -117
  107. package/src/lib/parsers/artifact/__tests__/fixtures/empty-bytecode.json +0 -5
  108. package/src/lib/parsers/artifact/__tests__/fixtures/hardhat-artifact.json +0 -67
  109. package/src/lib/parsers/artifact/__tests__/fixtures/invalid-bytecode.json +0 -5
  110. package/src/lib/parsers/artifact/__tests__/fixtures/invalid-json.txt +0 -11
  111. package/src/lib/parsers/artifact/__tests__/fixtures/minimal-artifact.json +0 -5
  112. package/src/lib/parsers/artifact/__tests__/fixtures/missing-abi.json +0 -4
  113. package/src/lib/parsers/artifact/__tests__/fixtures/missing-bytecode.json +0 -11
  114. package/src/lib/parsers/artifact/__tests__/fixtures/missing-contract-name.json +0 -11
  115. package/src/lib/parsers/artifact/__tests__/fixtures/simple-artifact.json +0 -40
  116. package/src/lib/parsers/artifact/__tests__/fixtures/wrong-types.json +0 -7
  117. package/src/lib/parsers/artifact/foundry-1.2.ts +0 -72
  118. package/src/lib/parsers/artifact/index.ts +0 -27
  119. package/src/lib/parsers/artifact/types.ts +0 -9
  120. package/src/lib/parsers/buildinfo.ts +0 -127
  121. package/src/lib/parsers/constants.ts +0 -56
  122. package/src/lib/parsers/index.ts +0 -6
  123. package/src/lib/parsers/job.ts +0 -160
  124. package/src/lib/parsers/source.ts +0 -129
  125. package/src/lib/parsers/template.ts +0 -135
  126. package/src/lib/provenance.ts +0 -785
  127. package/src/lib/std/templates/arachnid-deterministic-deployment-proxy.yaml +0 -68
  128. package/src/lib/std/templates/assured-deployment.yaml +0 -46
  129. package/src/lib/std/templates/era-evm-predeploy.yaml +0 -35
  130. package/src/lib/std/templates/erc-2470.yaml +0 -70
  131. package/src/lib/std/templates/min-balance.yaml +0 -35
  132. package/src/lib/std/templates/nano-universal-deployer.yaml +0 -61
  133. package/src/lib/std/templates/raw-erc-2470.yaml +0 -62
  134. package/src/lib/std/templates/raw-nano-universal-deployer.yaml +0 -54
  135. package/src/lib/std/templates/raw-sequence-universal-deployer-2.yaml +0 -52
  136. package/src/lib/std/templates/sequence-universal-deployer-2.yaml +0 -61
  137. package/src/lib/types/__tests__/json-request-action.spec.ts +0 -243
  138. package/src/lib/types/__tests__/read-json-value.spec.ts +0 -278
  139. package/src/lib/types/__tests__/resolve-json-value.spec.ts +0 -769
  140. package/src/lib/types/actions.ts +0 -148
  141. package/src/lib/types/artifacts.ts +0 -21
  142. package/src/lib/types/buildinfo.ts +0 -116
  143. package/src/lib/types/conditions.ts +0 -50
  144. package/src/lib/types/contracts.ts +0 -26
  145. package/src/lib/types/definitions.ts +0 -77
  146. package/src/lib/types/index.ts +0 -9
  147. package/src/lib/types/network.ts +0 -33
  148. package/src/lib/types/project.ts +0 -9
  149. package/src/lib/types/source.ts +0 -26
  150. package/src/lib/types/task.ts +0 -9
  151. package/src/lib/types/values.ts +0 -221
  152. package/src/lib/utils/assertion.ts +0 -24
  153. package/src/lib/utils/validation.ts +0 -116
  154. package/src/lib/validation/contract-references.ts +0 -210
  155. package/src/lib/validation/index.ts +0 -1
  156. package/src/lib/verification/__tests__/etherscan.spec.ts +0 -710
  157. package/src/lib/verification/__tests__/sourcify.spec.ts +0 -288
  158. package/src/lib/verification/etherscan.ts +0 -547
  159. package/src/lib/verification/sourcify.ts +0 -248
  160. package/test_validation/artifacts/TestContract.json +0 -9
  161. package/test_validation/jobs/test-missing.yaml +0 -16
  162. package/test_validation/networks.yaml +0 -3
  163. package/tsconfig.json +0 -36
@@ -1,262 +0,0 @@
1
- import { Command } from 'commander'
2
- import chalk from 'chalk'
3
- import * as path from 'path'
4
- import { loadProject, projectOption, noStdOption, verbosityOption } from './common'
5
- import { loadNetworks } from '../lib/network-loader'
6
- import { setVerbosity } from '../index'
7
-
8
- interface ListOptions {
9
- project: string
10
- std: boolean
11
- verbose: number
12
- }
13
-
14
- interface NetworksListOptions {
15
- project: string
16
- verbose: number
17
- onlyTestnets?: boolean
18
- onlyNonTestnets?: boolean
19
- }
20
-
21
- function formatSourceProvenance(provenance: { repo: string; commit?: string; ref?: string; build?: string }): string {
22
- const ref = provenance.commit || provenance.ref
23
- const suffix = ref ? ` @ ${ref}` : ''
24
- const build = provenance.build ? ` (${provenance.build})` : ''
25
- return `${provenance.repo}${suffix}${build}`
26
- }
27
-
28
- export function makeListCommand(): Command {
29
- const list = new Command('list')
30
- .description('List project resources like jobs, contracts, and networks')
31
-
32
- const listJobs = new Command('jobs')
33
- .description('List all available jobs in the project')
34
- projectOption(listJobs)
35
- noStdOption(listJobs)
36
- verbosityOption(listJobs)
37
- listJobs.action(async (options: ListOptions) => {
38
- try {
39
- // Set verbosity level for logging
40
- setVerbosity(options.verbose as 0 | 1 | 2 | 3)
41
- const loader = await loadProject(options.project, {
42
- loadStdTemplates: options.std !== false
43
- })
44
- console.log(chalk.bold.underline('Available Jobs:'))
45
- if (loader.jobs.size === 0) {
46
- console.log(chalk.yellow('No jobs found in this project.'))
47
- return
48
- }
49
- for (const job of loader.jobs.values()) {
50
- const deprecatedMark = (job as { deprecated?: boolean }).deprecated ? ` ${chalk.yellow('(deprecated)')}` : ''
51
- console.log(`- ${chalk.cyan(job.name)} (v${job.version})${deprecatedMark}`)
52
- if (job.description) {
53
- console.log(` ${chalk.gray(job.description)}`)
54
- }
55
- }
56
- } catch (error) {
57
- console.error(chalk.red('Error listing jobs:'), error instanceof Error ? error.message : String(error))
58
- process.exit(1)
59
- }
60
- })
61
-
62
- const listContracts = new Command('contracts')
63
- .description('List all contracts found in the project')
64
- projectOption(listContracts)
65
- noStdOption(listContracts)
66
- verbosityOption(listContracts)
67
- listContracts.action(async (options: ListOptions) => {
68
- try {
69
- // Set verbosity level for logging
70
- setVerbosity(options.verbose as 0 | 1 | 2 | 3)
71
- const loader = await loadProject(options.project, {
72
- loadStdTemplates: options.std !== false
73
- })
74
- const contracts = loader.contractRepository.getAll()
75
- const ambiguousRefs = loader.contractRepository.getAmbiguousReferences()
76
-
77
- // Display contracts
78
- console.log(chalk.bold.underline('Available Contracts:'))
79
- if (contracts.length === 0) {
80
- console.log(chalk.yellow('No contracts found in this project.'))
81
- } else {
82
- for (const contract of contracts) {
83
- const name = contract.contractName || 'Unknown'
84
- const source = contract.sourceName || 'Unknown'
85
- console.log(`- ${chalk.cyan(name)} (${source})`)
86
- console.log(` ${chalk.gray('Unique Hash:')} ${contract.uniqueHash}`)
87
- if (contract.buildInfoId) {
88
- console.log(` ${chalk.gray('Build Info ID:')} ${contract.buildInfoId}`)
89
- }
90
- if (contract._sourceProvenance && contract._sourceProvenance.size > 0) {
91
- for (const [buildInfoPath, provenance] of contract._sourceProvenance.entries()) {
92
- const relativeBuildInfoPath = path.relative(options.project, buildInfoPath)
93
- console.log(` ${chalk.gray('Provenance:')} ${formatSourceProvenance(provenance)} ${chalk.gray(`[${relativeBuildInfoPath}]`)}`)
94
- }
95
- }
96
- console.log(` ${chalk.gray('Sources:')} ${Array.from(contract._sources).map(p => path.relative(options.project, p)).join(', ')}`)
97
- }
98
- }
99
-
100
- // Display ambiguous references if any
101
- if (ambiguousRefs.length > 0) {
102
- console.log('\n' + chalk.bold.underline(chalk.yellow('Ambiguous References:')))
103
- console.log(chalk.yellow('The following references point to multiple contracts:'))
104
- for (const ref of ambiguousRefs) {
105
- console.log(`- ${chalk.red(ref)}`)
106
- }
107
- console.log(chalk.yellow('Use the unique hash or a more specific path to reference these contracts.'))
108
- }
109
-
110
- if (contracts.length === 0) {
111
- console.log('\n' + chalk.yellow('No contracts found in this project. Make sure you have artifact files or build-info files in your project.'))
112
- }
113
- } catch (error) {
114
- console.error(chalk.red('Error listing contracts:'), error instanceof Error ? error.message : String(error))
115
- process.exit(1)
116
- }
117
- })
118
-
119
- const listTemplates = new Command('templates')
120
- .description('List all available templates')
121
- projectOption(listTemplates)
122
- noStdOption(listTemplates)
123
- verbosityOption(listTemplates)
124
- listTemplates.action(async (options: ListOptions) => {
125
- try {
126
- // Set verbosity level for logging
127
- setVerbosity(options.verbose as 0 | 1 | 2 | 3)
128
- const loader = await loadProject(options.project, {
129
- loadStdTemplates: options.std !== false
130
- })
131
- console.log(chalk.bold.underline('Available Templates:'))
132
- if (loader.templates.size === 0) {
133
- console.log(chalk.yellow('No templates found.'))
134
- return
135
- }
136
- for (const template of loader.templates.values()) {
137
- console.log(`- ${chalk.cyan(template.name)}`)
138
- if (template.description) {
139
- console.log(` ${chalk.gray(template.description)}`)
140
- }
141
- }
142
- } catch (error) {
143
- console.error(chalk.red('Error listing templates:'), error instanceof Error ? error.message : String(error))
144
- process.exit(1)
145
- }
146
- })
147
-
148
- const listNetworks = new Command('networks')
149
- .description('List all configured networks')
150
- projectOption(listNetworks)
151
- verbosityOption(listNetworks)
152
- listNetworks.option('--only-testnets', 'Show only test networks')
153
- listNetworks.option('--only-non-testnets', 'Show only non-test networks')
154
- listNetworks.option('--simple', 'Output only network names, one per line')
155
- listNetworks.option('--simple-chain-ids', 'Output only chain IDs, one per line')
156
- listNetworks.action(async (options: NetworksListOptions & { simple?: boolean; simpleChainIds?: boolean }) => {
157
- try {
158
- // Set verbosity level for logging
159
- setVerbosity(options.verbose as 0 | 1 | 2 | 3)
160
- const networks = await loadNetworks(options.project)
161
-
162
- // Apply filtering if specified
163
- let filteredNetworks = networks
164
- if (options.onlyTestnets) {
165
- filteredNetworks = networks.filter(network => network.testnet === true)
166
- } else if (options.onlyNonTestnets) {
167
- filteredNetworks = networks.filter(network => network.testnet !== true)
168
- }
169
-
170
- // Handle simple output formats
171
- if (options.simple) {
172
- if (filteredNetworks.length === 0) {
173
- console.log('')
174
- return
175
- }
176
- console.log(filteredNetworks.map(network => network.name).join('\n'))
177
- return
178
- }
179
-
180
- if (options.simpleChainIds) {
181
- if (filteredNetworks.length === 0) {
182
- console.log('')
183
- return
184
- }
185
- console.log(filteredNetworks.map(network => network.chainId.toString()).join('\n'))
186
- return
187
- }
188
-
189
- // Default formatted output
190
- console.log(chalk.bold.underline('Available Networks:'))
191
- if (filteredNetworks.length === 0) {
192
- if (options.onlyTestnets) {
193
- console.log(chalk.yellow('No test networks configured.'))
194
- } else if (options.onlyNonTestnets) {
195
- console.log(chalk.yellow('No non-test networks configured.'))
196
- } else {
197
- console.log(chalk.yellow('No networks configured. Create a networks.yaml file in your project root.'))
198
- }
199
- return
200
- }
201
-
202
- for (const network of filteredNetworks) {
203
- const testnetIndicator = network.testnet ? chalk.green('(testnet)') : ''
204
- console.log(`- ${chalk.cyan(network.name)} (Chain ID: ${network.chainId}) ${testnetIndicator}`)
205
- console.log(` ${chalk.gray(`RPC: ${network.rpcUrl}`)}`)
206
- }
207
- } catch (error) {
208
- console.error(chalk.red('Error listing networks:'), error instanceof Error ? error.message : String(error))
209
- process.exit(1)
210
- }
211
- })
212
-
213
- // New: list constants
214
- const listConstants = new Command('constants')
215
- .description('List constants defined at top-level and per job')
216
- projectOption(listConstants)
217
- noStdOption(listConstants)
218
- verbosityOption(listConstants)
219
- listConstants.action(async (options: ListOptions) => {
220
- try {
221
- setVerbosity(options.verbose as 0 | 1 | 2 | 3)
222
- const loader = await loadProject(options.project, {
223
- loadStdTemplates: options.std !== false
224
- })
225
- console.log(chalk.bold.underline('Top-level Constants:'))
226
- if (loader.constants.size === 0) {
227
- console.log(chalk.yellow('No top-level constants found.'))
228
- } else {
229
- for (const [key, value] of loader.constants.entries()) {
230
- // Only display keys to avoid dumping large values
231
- console.log(`- ${chalk.cyan(key)}${options.verbose ? ` = ${JSON.stringify(value)}` : ''}`)
232
- }
233
- }
234
- console.log(chalk.bold.underline('\nJob-level Constants:'))
235
- let anyJobConstants = false
236
- for (const job of loader.jobs.values()) {
237
- const constants = job.constants
238
- if (constants && Object.keys(constants).length > 0) {
239
- anyJobConstants = true
240
- console.log(`- ${chalk.cyan(job.name)}:`)
241
- for (const key of Object.keys(constants)) {
242
- console.log(` • ${key}${options.verbose ? ` = ${JSON.stringify(constants[key])}` : ''}`)
243
- }
244
- }
245
- }
246
- if (!anyJobConstants) {
247
- console.log(chalk.yellow('No job-level constants found.'))
248
- }
249
- } catch (error) {
250
- console.error(chalk.red('Error listing constants:'), error instanceof Error ? error.message : String(error))
251
- process.exit(1)
252
- }
253
- })
254
-
255
- list.addCommand(listJobs)
256
- list.addCommand(listContracts)
257
- list.addCommand(listTemplates)
258
- list.addCommand(listNetworks)
259
- list.addCommand(listConstants)
260
-
261
- return list
262
- }
@@ -1,120 +0,0 @@
1
- import { Command } from 'commander'
2
- import chalk from 'chalk'
3
- import * as path from 'path'
4
- import { projectOption, noStdOption, verbosityOption } from './common'
5
- import { setVerbosity } from '../index'
6
- import {
7
- generateBuildInfoFromSourceProvenance,
8
- ProvenanceOperationResult,
9
- ProvenanceRunResult,
10
- verifySourceProvenance
11
- } from '../lib/provenance'
12
-
13
- interface ProvenanceOptions {
14
- project: string
15
- std: boolean
16
- verbose: number
17
- includeDependencies?: boolean
18
- force?: boolean
19
- }
20
-
21
- export function makeProvenanceCommand(): Command {
22
- const provenance = new Command('provenance')
23
- .description('Work with build-info source provenance')
24
-
25
- const verify = new Command('verify')
26
- .description('Verify committed build-info files against source provenance')
27
- .argument('[jobs...]', 'Optional job names or patterns to verify. Without jobs, verifies all provenance in the project.')
28
- .option('--include-dependencies', 'When jobs are provided, include their dependency jobs too.', false)
29
- projectOption(verify)
30
- noStdOption(verify)
31
- verbosityOption(verify)
32
- verify.action(async (jobs: string[], options: ProvenanceOptions) => {
33
- try {
34
- setVerbosity(options.verbose as 0 | 1 | 2 | 3)
35
- const result = await verifySourceProvenance(options.project, {
36
- jobs,
37
- includeDependencies: options.includeDependencies === true,
38
- loadStdTemplates: options.std !== false
39
- })
40
- printRunResult('verify', options.project, result)
41
- exitIfFailed(result)
42
- } catch (error) {
43
- console.error(chalk.red('Error verifying provenance:'), error instanceof Error ? error.message : String(error))
44
- process.exit(1)
45
- }
46
- })
47
-
48
- const generate = new Command('generate')
49
- .description('Generate missing build-info files from source provenance')
50
- .argument('[jobs...]', 'Optional job names or patterns to generate. Without jobs, generates for all provenance in the project.')
51
- .option('--include-dependencies', 'When jobs are provided, include their dependency jobs too.', false)
52
- .option('--force', 'Overwrite existing build-info files.', false)
53
- projectOption(generate)
54
- noStdOption(generate)
55
- verbosityOption(generate)
56
- generate.action(async (jobs: string[], options: ProvenanceOptions) => {
57
- try {
58
- setVerbosity(options.verbose as 0 | 1 | 2 | 3)
59
- const result = await generateBuildInfoFromSourceProvenance(options.project, {
60
- jobs,
61
- includeDependencies: options.includeDependencies === true,
62
- loadStdTemplates: options.std !== false,
63
- force: options.force === true
64
- })
65
- printRunResult('generate', options.project, result)
66
- exitIfFailed(result)
67
- } catch (error) {
68
- console.error(chalk.red('Error generating build-info from provenance:'), error instanceof Error ? error.message : String(error))
69
- process.exit(1)
70
- }
71
- })
72
-
73
- provenance.addCommand(verify)
74
- provenance.addCommand(generate)
75
- return provenance
76
- }
77
-
78
- function printRunResult(command: 'verify' | 'generate', projectRoot: string, result: ProvenanceRunResult): void {
79
- for (const warning of result.warnings) {
80
- console.warn(chalk.yellow(warning))
81
- }
82
-
83
- if (result.entries.length === 0) {
84
- console.log(chalk.yellow('No source provenance entries found.'))
85
- return
86
- }
87
-
88
- for (const item of result.results) {
89
- printOperationResult(projectRoot, item)
90
- }
91
-
92
- const failed = result.results.filter(item => item.status === 'failed').length
93
- const skipped = result.results.filter(item => item.status === 'skipped').length
94
- const completed = result.results.length - failed - skipped
95
- const verb = command === 'verify' ? 'verified' : 'generated'
96
-
97
- if (failed > 0) {
98
- console.log(chalk.red(`Provenance ${command} completed with ${failed} failure(s), ${completed} ${verb}, ${skipped} skipped.`))
99
- } else {
100
- console.log(chalk.green(`Provenance ${command} completed: ${completed} ${verb}, ${skipped} skipped.`))
101
- }
102
- }
103
-
104
- function printOperationResult(projectRoot: string, result: ProvenanceOperationResult): void {
105
- const target = path.relative(projectRoot, result.entry.buildInfoPath)
106
- const source = path.relative(projectRoot, result.entry.sourceDocumentPath)
107
- const prefix = result.status === 'failed'
108
- ? chalk.red('failed')
109
- : result.status === 'skipped'
110
- ? chalk.yellow('skipped')
111
- : chalk.green(result.status)
112
-
113
- console.log(`${prefix} ${target} ${chalk.gray(`[${source}]`)} - ${result.message}`)
114
- }
115
-
116
- function exitIfFailed(result: ProvenanceRunResult): void {
117
- if (result.results.some(item => item.status === 'failed')) {
118
- process.exit(1)
119
- }
120
- }
@@ -1,146 +0,0 @@
1
- import { Command } from 'commander'
2
- import { Deployer, DeployerOptions } from '../lib/deployer'
3
- import { loadNetworks } from '../lib/network-loader'
4
- import { detectNetworkFromRpc, isValidRpcUrl } from '../lib/network-utils'
5
- import { Network } from '../lib/types'
6
- import { deploymentEvents } from '../lib/events'
7
- import { projectOption, dotenvOption, noStdOption, verbosityOption, loadDotenv } from './common'
8
- import { resolveSelectedChainIds } from '../lib/network-selection'
9
- import { setVerbosity } from '../index'
10
-
11
- interface RunOptions {
12
- project: string
13
- privateKey?: string
14
- network?: string
15
- rpcUrl?: string
16
- dotenv?: string
17
- std: boolean
18
- etherscanApiKey?: string
19
- verbose: number
20
- failEarly: boolean
21
- noPostCheckConditions: boolean
22
- flatOutput: boolean
23
- summary: boolean
24
- ignoreVerifyErrors: boolean
25
- }
26
-
27
- export function makeRunCommand(): Command {
28
- const run = new Command('run')
29
- .description('Run deployment jobs on specified networks')
30
- .argument('[jobs...]', 'Specific job names or patterns to run (and their dependencies). Supports wildcards like "sequence/*" or "job?". If not provided, all jobs are run.')
31
- .option('-k, --private-key <key>', 'Signer private key. Can also be set via PRIVATE_KEY env var.')
32
- .option('-n, --network <selectors>', 'Comma-separated network selectors (by chain ID or name). If not provided, runs on all configured networks.')
33
- .option('--rpc-url <url>', 'Custom RPC URL to run on. The system will automatically detect chainId and network information. This overrides networks.yaml configuration.')
34
- .option('--etherscan-api-key <key>', 'Etherscan API key for contract verification. Can also be set via ETHERSCAN_API_KEY env var.')
35
- .option('--fail-early', 'Stop execution as soon as any job fails. Default: false', false)
36
- .option('--no-post-check-conditions', 'Skip post-execution check of skip conditions. Default: false (post-check enabled)', false)
37
- .option('--flat-output', 'Write output files in a single flat directory instead of mirroring the jobs directory structure. Default: false', false)
38
- .option('--no-summary', 'Hide final summary at the end of the run. Default: show', false)
39
- .option('--run-deprecated', 'Allow running jobs marked as deprecated. By default deprecated jobs are skipped unless explicitly targeted.', false)
40
- .option('--ignore-verify-errors', 'Convert verification errors to warnings instead of exiting with error code. Shows complete warning report at the end.', false)
41
-
42
- projectOption(run)
43
- dotenvOption(run)
44
- noStdOption(run)
45
- verbosityOption(run)
46
-
47
- run.action(async (jobs: string[], options: RunOptions) => {
48
- try {
49
- loadDotenv(options)
50
-
51
- // Set verbosity level for logging
52
- setVerbosity(options.verbose as 0 | 1 | 2 | 3)
53
-
54
- const privateKey: string | undefined = options.privateKey || process.env.PRIVATE_KEY
55
- if (!privateKey && !options.rpcUrl) {
56
- throw new Error('A private key must be provided via the --private-key option or the PRIVATE_KEY environment variable, or an --rpc-url must be specified to attempt an implicit sender.')
57
- }
58
-
59
- const etherscanApiKey = options.etherscanApiKey || process.env.ETHERSCAN_API_KEY
60
-
61
- const projectRoot = options.project
62
-
63
- // Load networks from YAML file
64
- let networks = await loadNetworks(projectRoot)
65
-
66
- // Handle custom RPC URL if provided
67
- if (options.rpcUrl) {
68
- // Custom RPC URL provided
69
-
70
- // Validate RPC URL format
71
- if (!isValidRpcUrl(options.rpcUrl)) {
72
- throw new Error(`Invalid RPC URL format: ${options.rpcUrl}`)
73
- }
74
-
75
- try {
76
- // Detect network information from RPC URL
77
- const detectedNetwork = await detectNetworkFromRpc(options.rpcUrl)
78
-
79
- // Try to find a matching network in networks.yaml by chainId to merge verification platform support
80
- const knownNetwork = networks.find(n => n.chainId === detectedNetwork.chainId)
81
-
82
- // Create a complete network object, merging with known network config if found
83
- const customNetwork: Network = {
84
- name: detectedNetwork.name || knownNetwork?.name || `custom-${detectedNetwork.chainId}`,
85
- chainId: detectedNetwork.chainId!,
86
- rpcUrl: options.rpcUrl,
87
- // Optional fields with defaults
88
- supports: detectedNetwork.supports || knownNetwork?.supports || [],
89
- gasLimit: detectedNetwork.gasLimit || knownNetwork?.gasLimit,
90
- testnet: detectedNetwork.testnet !== undefined ? detectedNetwork.testnet : knownNetwork?.testnet,
91
- evmVersion: detectedNetwork.evmVersion || knownNetwork?.evmVersion,
92
- params: detectedNetwork.params || knownNetwork?.params,
93
- }
94
-
95
- // Custom network created from RPC detection
96
-
97
- // Replace networks array with just the custom network
98
- networks = [customNetwork]
99
- } catch (error) {
100
- throw new Error(`Failed to detect network from RPC URL "${options.rpcUrl}": ${error instanceof Error ? error.message : String(error)}`)
101
- }
102
- }
103
-
104
- if (networks.length === 0 && !options.rpcUrl) {
105
- throw new Error('No networks configured. Please create a networks.yaml file in your project root or use --rpc-url to specify a custom network.')
106
- }
107
-
108
- const selectedChainIds = resolveSelectedChainIds(options.network, networks)
109
- const deployerOptions: DeployerOptions = {
110
- projectRoot,
111
- privateKey,
112
- networks,
113
- runJobs: jobs.length > 0 ? jobs : undefined,
114
- runOnNetworks: selectedChainIds,
115
- etherscanApiKey,
116
- failEarly: options.failEarly,
117
- noPostCheckConditions: options.noPostCheckConditions,
118
- showSummary: options.summary !== false,
119
- loaderOptions: {
120
- loadStdTemplates: options.std !== false
121
- },
122
- flatOutput: options.flatOutput === true,
123
- runDeprecated: (options as { runDeprecated?: boolean }).runDeprecated === true,
124
- ignoreVerifyErrors: options.ignoreVerifyErrors === true
125
- } as DeployerOptions
126
-
127
- const deployer = new Deployer(deployerOptions)
128
- await deployer.run()
129
-
130
- } catch (error) {
131
- // The deployer emits its own rich error event, so we just log a generic one if something fails before that.
132
- if (!(error instanceof Error && error.message.includes('deployment_failed'))) {
133
- deploymentEvents.emitEvent({
134
- type: 'cli_error',
135
- level: 'error',
136
- data: {
137
- message: error instanceof Error ? error.message : String(error)
138
- }
139
- })
140
- }
141
- process.exit(1)
142
- }
143
- })
144
-
145
- return run
146
- }