@0xsequence/catapult 1.3.17 → 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.
- package/README.md +276 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +1 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/index.d.ts +1 -0
- package/dist/commands/index.d.ts.map +1 -1
- package/dist/commands/index.js +1 -0
- package/dist/commands/index.js.map +1 -1
- package/dist/commands/list.d.ts.map +1 -1
- package/dist/commands/list.js +12 -0
- package/dist/commands/list.js.map +1 -1
- package/dist/commands/provenance.d.ts +3 -0
- package/dist/commands/provenance.d.ts.map +1 -0
- package/dist/commands/provenance.js +138 -0
- package/dist/commands/provenance.js.map +1 -0
- package/dist/lib/__tests__/deployer.spec.js +118 -1
- package/dist/lib/__tests__/deployer.spec.js.map +1 -1
- package/dist/lib/__tests__/network-loader.spec.js.map +1 -1
- package/dist/lib/__tests__/provenance.spec.d.ts +2 -0
- package/dist/lib/__tests__/provenance.spec.d.ts.map +1 -0
- package/dist/lib/__tests__/provenance.spec.js +205 -0
- package/dist/lib/__tests__/provenance.spec.js.map +1 -0
- package/dist/lib/contracts/__tests__/repository.spec.js +243 -0
- package/dist/lib/contracts/__tests__/repository.spec.js.map +1 -1
- package/dist/lib/contracts/repository.d.ts +9 -1
- package/dist/lib/contracts/repository.d.ts.map +1 -1
- package/dist/lib/contracts/repository.js +93 -7
- package/dist/lib/contracts/repository.js.map +1 -1
- package/dist/lib/core/__tests__/assert-action.spec.d.ts +2 -0
- package/dist/lib/core/__tests__/assert-action.spec.d.ts.map +1 -0
- package/dist/lib/core/__tests__/assert-action.spec.js +377 -0
- package/dist/lib/core/__tests__/assert-action.spec.js.map +1 -0
- package/dist/lib/core/__tests__/engine.spec.js +80 -0
- package/dist/lib/core/__tests__/engine.spec.js.map +1 -1
- package/dist/lib/core/__tests__/loader.spec.js +29 -0
- package/dist/lib/core/__tests__/loader.spec.js.map +1 -1
- package/dist/lib/core/__tests__/resolver.spec.js +405 -0
- package/dist/lib/core/__tests__/resolver.spec.js.map +1 -1
- package/dist/lib/core/__tests__/sign-actions.spec.d.ts +2 -0
- package/dist/lib/core/__tests__/sign-actions.spec.d.ts.map +1 -0
- package/dist/lib/core/__tests__/sign-actions.spec.js +128 -0
- package/dist/lib/core/__tests__/sign-actions.spec.js.map +1 -0
- package/dist/lib/core/__tests__/signer.spec.d.ts +2 -0
- package/dist/lib/core/__tests__/signer.spec.d.ts.map +1 -0
- package/dist/lib/core/__tests__/signer.spec.js +40 -0
- package/dist/lib/core/__tests__/signer.spec.js.map +1 -0
- package/dist/lib/core/context.d.ts +3 -2
- package/dist/lib/core/context.d.ts.map +1 -1
- package/dist/lib/core/context.js +3 -2
- package/dist/lib/core/context.js.map +1 -1
- package/dist/lib/core/engine.d.ts +4 -0
- package/dist/lib/core/engine.d.ts.map +1 -1
- package/dist/lib/core/engine.js +206 -0
- package/dist/lib/core/engine.js.map +1 -1
- package/dist/lib/core/loader.d.ts +1 -0
- package/dist/lib/core/loader.d.ts.map +1 -1
- package/dist/lib/core/loader.js +6 -1
- package/dist/lib/core/loader.js.map +1 -1
- package/dist/lib/core/resolver.d.ts +2 -0
- package/dist/lib/core/resolver.d.ts.map +1 -1
- package/dist/lib/core/resolver.js +89 -0
- package/dist/lib/core/resolver.js.map +1 -1
- package/dist/lib/core/signer.d.ts +7 -0
- package/dist/lib/core/signer.d.ts.map +1 -0
- package/dist/lib/core/signer.js +60 -0
- package/dist/lib/core/signer.js.map +1 -0
- package/dist/lib/deployer.d.ts.map +1 -1
- package/dist/lib/deployer.js +21 -4
- package/dist/lib/deployer.js.map +1 -1
- package/dist/lib/index.d.ts +1 -0
- package/dist/lib/index.d.ts.map +1 -1
- package/dist/lib/index.js +1 -0
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/parsers/__tests__/job.spec.js +77 -0
- package/dist/lib/parsers/__tests__/job.spec.js.map +1 -1
- package/dist/lib/parsers/__tests__/source.spec.d.ts +2 -0
- package/dist/lib/parsers/__tests__/source.spec.d.ts.map +1 -0
- package/dist/lib/parsers/__tests__/source.spec.js +158 -0
- package/dist/lib/parsers/__tests__/source.spec.js.map +1 -0
- package/dist/lib/parsers/index.d.ts +1 -0
- package/dist/lib/parsers/index.d.ts.map +1 -1
- package/dist/lib/parsers/index.js +1 -0
- package/dist/lib/parsers/index.js.map +1 -1
- package/dist/lib/parsers/job.d.ts.map +1 -1
- package/dist/lib/parsers/job.js +11 -0
- package/dist/lib/parsers/job.js.map +1 -1
- package/dist/lib/parsers/source.d.ts +4 -0
- package/dist/lib/parsers/source.d.ts.map +1 -0
- package/dist/lib/parsers/source.js +107 -0
- package/dist/lib/parsers/source.js.map +1 -0
- package/dist/lib/provenance.d.ts +34 -0
- package/dist/lib/provenance.d.ts.map +1 -0
- package/dist/lib/provenance.js +694 -0
- package/dist/lib/provenance.js.map +1 -0
- package/dist/lib/types/actions.d.ts +42 -2
- package/dist/lib/types/actions.d.ts.map +1 -1
- package/dist/lib/types/actions.js +4 -0
- package/dist/lib/types/actions.js.map +1 -1
- package/dist/lib/types/contracts.d.ts +3 -0
- package/dist/lib/types/contracts.d.ts.map +1 -1
- package/dist/lib/types/definitions.d.ts +1 -0
- package/dist/lib/types/definitions.d.ts.map +1 -1
- package/dist/lib/types/index.d.ts +1 -0
- package/dist/lib/types/index.d.ts.map +1 -1
- package/dist/lib/types/index.js +1 -0
- package/dist/lib/types/index.js.map +1 -1
- package/dist/lib/types/source.d.ts +26 -0
- package/dist/lib/types/source.d.ts.map +1 -0
- package/dist/lib/types/source.js +3 -0
- package/dist/lib/types/source.js.map +1 -0
- package/dist/lib/types/values.d.ts +33 -1
- package/dist/lib/types/values.d.ts.map +1 -1
- package/package.json +4 -1
- package/.eslintrc.json +0 -29
- package/.github/workflows/ci.yml +0 -181
- package/CONCEPT.md +0 -24
- package/contracts/checked-call.huff +0 -65
- package/eslint.config.js +0 -48
- package/examples/jobs/guards-v1.yaml +0 -17
- package/examples/jobs/sequence-seq-0001-patch.yaml +0 -59
- package/examples/jobs/sequence-v1.yaml +0 -59
- package/examples/templates/sequence-factory-v1.yaml +0 -56
- package/jest.config.js +0 -25
- package/src/cli.ts +0 -17
- package/src/commands/common.ts +0 -61
- package/src/commands/dry.ts +0 -209
- package/src/commands/etherscan.ts +0 -360
- package/src/commands/index.ts +0 -5
- package/src/commands/list.ts +0 -249
- package/src/commands/run.ts +0 -146
- package/src/commands/utils.ts +0 -215
- package/src/index.ts +0 -67
- package/src/lib/__tests__/deployer-events.spec.ts +0 -338
- package/src/lib/__tests__/deployer.spec.ts +0 -2093
- package/src/lib/__tests__/network-loader.spec.ts +0 -150
- package/src/lib/__tests__/network-selection.spec.ts +0 -41
- package/src/lib/__tests__/network-utils.spec.ts +0 -230
- package/src/lib/artifacts/__tests__/fixtures/contract1.json +0 -19
- package/src/lib/artifacts/__tests__/fixtures/contract2.json +0 -19
- package/src/lib/artifacts/__tests__/fixtures/duplicate-name.json +0 -19
- package/src/lib/artifacts/__tests__/fixtures/nested/nested-contract.json +0 -18
- package/src/lib/artifacts/__tests__/fixtures/not-an-artifact.json +0 -8
- package/src/lib/artifacts/__tests__/fixtures/readme.txt +0 -2
- package/src/lib/contracts/__tests__/repository.spec.ts +0 -344
- package/src/lib/contracts/repository.ts +0 -313
- package/src/lib/core/__tests__/context.spec.ts +0 -37
- package/src/lib/core/__tests__/engine.spec.ts +0 -1889
- package/src/lib/core/__tests__/graph.spec.ts +0 -125
- package/src/lib/core/__tests__/json-integration.spec.ts +0 -425
- package/src/lib/core/__tests__/loader.spec.ts +0 -334
- package/src/lib/core/__tests__/multi-platform-verification.spec.ts +0 -406
- package/src/lib/core/__tests__/resolver.spec.ts +0 -2053
- package/src/lib/core/__tests__/static-action.spec.ts +0 -172
- package/src/lib/core/context.ts +0 -127
- package/src/lib/core/engine.ts +0 -1782
- package/src/lib/core/graph.ts +0 -252
- package/src/lib/core/loader.ts +0 -247
- package/src/lib/core/resolver.ts +0 -757
- package/src/lib/deployer.ts +0 -981
- package/src/lib/events/__tests__/event-system.spec.ts +0 -392
- package/src/lib/events/cli-adapter.ts +0 -369
- package/src/lib/events/emitter.ts +0 -62
- package/src/lib/events/index.ts +0 -3
- package/src/lib/events/types.ts +0 -520
- package/src/lib/index.ts +0 -14
- package/src/lib/network-loader.ts +0 -90
- package/src/lib/network-selection.ts +0 -73
- package/src/lib/network-utils.ts +0 -64
- package/src/lib/parsers/__tests__/buildinfo.spec.ts +0 -122
- package/src/lib/parsers/__tests__/fixtures/buildinfo/invalid-bytecode-buildinfo.json +0 -62
- package/src/lib/parsers/__tests__/fixtures/buildinfo/invalid-json.txt +0 -2
- package/src/lib/parsers/__tests__/fixtures/buildinfo/multi-contract-buildinfo.json +0 -89
- package/src/lib/parsers/__tests__/fixtures/buildinfo/no-contracts-buildinfo.json +0 -17
- package/src/lib/parsers/__tests__/fixtures/buildinfo/simple-buildinfo.json +0 -63
- package/src/lib/parsers/__tests__/fixtures/buildinfo/wrong-format.json +0 -4
- package/src/lib/parsers/__tests__/job.spec.ts +0 -358
- package/src/lib/parsers/__tests__/template.spec.ts +0 -111
- package/src/lib/parsers/artifact/__tests__/artifact.spec.ts +0 -117
- package/src/lib/parsers/artifact/__tests__/fixtures/empty-bytecode.json +0 -5
- package/src/lib/parsers/artifact/__tests__/fixtures/hardhat-artifact.json +0 -67
- package/src/lib/parsers/artifact/__tests__/fixtures/invalid-bytecode.json +0 -5
- package/src/lib/parsers/artifact/__tests__/fixtures/invalid-json.txt +0 -11
- package/src/lib/parsers/artifact/__tests__/fixtures/minimal-artifact.json +0 -5
- package/src/lib/parsers/artifact/__tests__/fixtures/missing-abi.json +0 -4
- package/src/lib/parsers/artifact/__tests__/fixtures/missing-bytecode.json +0 -11
- package/src/lib/parsers/artifact/__tests__/fixtures/missing-contract-name.json +0 -11
- package/src/lib/parsers/artifact/__tests__/fixtures/simple-artifact.json +0 -40
- package/src/lib/parsers/artifact/__tests__/fixtures/wrong-types.json +0 -7
- package/src/lib/parsers/artifact/foundry-1.2.ts +0 -72
- package/src/lib/parsers/artifact/index.ts +0 -27
- package/src/lib/parsers/artifact/types.ts +0 -9
- package/src/lib/parsers/buildinfo.ts +0 -127
- package/src/lib/parsers/constants.ts +0 -56
- package/src/lib/parsers/index.ts +0 -5
- package/src/lib/parsers/job.ts +0 -148
- package/src/lib/parsers/template.ts +0 -135
- package/src/lib/std/templates/arachnid-deterministic-deployment-proxy.yaml +0 -68
- package/src/lib/std/templates/assured-deployment.yaml +0 -46
- package/src/lib/std/templates/era-evm-predeploy.yaml +0 -35
- package/src/lib/std/templates/erc-2470.yaml +0 -70
- package/src/lib/std/templates/min-balance.yaml +0 -35
- package/src/lib/std/templates/nano-universal-deployer.yaml +0 -61
- package/src/lib/std/templates/raw-erc-2470.yaml +0 -62
- package/src/lib/std/templates/raw-nano-universal-deployer.yaml +0 -54
- package/src/lib/std/templates/raw-sequence-universal-deployer-2.yaml +0 -52
- package/src/lib/std/templates/sequence-universal-deployer-2.yaml +0 -61
- package/src/lib/types/__tests__/json-request-action.spec.ts +0 -243
- package/src/lib/types/__tests__/read-json-value.spec.ts +0 -278
- package/src/lib/types/__tests__/resolve-json-value.spec.ts +0 -769
- package/src/lib/types/actions.ts +0 -127
- package/src/lib/types/artifacts.ts +0 -21
- package/src/lib/types/buildinfo.ts +0 -116
- package/src/lib/types/conditions.ts +0 -50
- package/src/lib/types/contracts.ts +0 -23
- package/src/lib/types/definitions.ts +0 -70
- package/src/lib/types/index.ts +0 -8
- package/src/lib/types/network.ts +0 -33
- package/src/lib/types/project.ts +0 -9
- package/src/lib/types/task.ts +0 -9
- package/src/lib/types/values.ts +0 -150
- package/src/lib/utils/assertion.ts +0 -24
- package/src/lib/utils/validation.ts +0 -116
- package/src/lib/validation/contract-references.ts +0 -210
- package/src/lib/validation/index.ts +0 -1
- package/src/lib/verification/__tests__/etherscan.spec.ts +0 -710
- package/src/lib/verification/__tests__/sourcify.spec.ts +0 -288
- package/src/lib/verification/etherscan.ts +0 -547
- package/src/lib/verification/sourcify.ts +0 -248
- package/test_validation/artifacts/TestContract.json +0 -9
- package/test_validation/jobs/test-missing.yaml +0 -16
- package/test_validation/networks.yaml +0 -3
- package/tsconfig.json +0 -36
package/src/commands/run.ts
DELETED
|
@@ -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
|
-
}
|
package/src/commands/utils.ts
DELETED
|
@@ -1,215 +0,0 @@
|
|
|
1
|
-
import { Command } from 'commander'
|
|
2
|
-
import chalk from 'chalk'
|
|
3
|
-
import * as fs from 'fs'
|
|
4
|
-
import * as path from 'path'
|
|
5
|
-
import { projectOption, verbosityOption } from './common'
|
|
6
|
-
import { loadNetworks } from '../lib/network-loader'
|
|
7
|
-
import { setVerbosity } from '../index'
|
|
8
|
-
|
|
9
|
-
interface UtilsOptions {
|
|
10
|
-
project: string
|
|
11
|
-
verbose: number
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export function makeUtilsCommand(): Command {
|
|
15
|
-
const utils = new Command('utils')
|
|
16
|
-
.description('Utility commands for project management')
|
|
17
|
-
|
|
18
|
-
const chainIdToName = new Command('chain-id-to-name')
|
|
19
|
-
.description('Convert a chain ID to network name')
|
|
20
|
-
projectOption(chainIdToName)
|
|
21
|
-
verbosityOption(chainIdToName)
|
|
22
|
-
|
|
23
|
-
chainIdToName.argument('<chain-id>', 'The chain ID to convert')
|
|
24
|
-
chainIdToName.action(async (chainId: string, options: UtilsOptions) => {
|
|
25
|
-
try {
|
|
26
|
-
// Set verbosity level for logging
|
|
27
|
-
setVerbosity(options.verbose as 0 | 1 | 2 | 3)
|
|
28
|
-
|
|
29
|
-
const chainIdNumber = parseInt(chainId, 10)
|
|
30
|
-
if (isNaN(chainIdNumber)) {
|
|
31
|
-
console.error(chalk.red('Invalid chain ID. Please provide a valid number.'))
|
|
32
|
-
process.exit(1)
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
const networks = await loadNetworks(options.project)
|
|
36
|
-
|
|
37
|
-
const network = networks.find(n => n.chainId === chainIdNumber)
|
|
38
|
-
|
|
39
|
-
if (network) {
|
|
40
|
-
console.log(network.name)
|
|
41
|
-
} else {
|
|
42
|
-
console.error(chalk.red(`No network found with chain ID ${chainIdNumber}`))
|
|
43
|
-
process.exit(1)
|
|
44
|
-
}
|
|
45
|
-
} catch (error) {
|
|
46
|
-
console.error(chalk.red('Error converting chain ID to network name:'), error instanceof Error ? error.message : String(error))
|
|
47
|
-
process.exit(1)
|
|
48
|
-
}
|
|
49
|
-
})
|
|
50
|
-
|
|
51
|
-
utils.addCommand(chainIdToName)
|
|
52
|
-
|
|
53
|
-
// utils gen-table <output-dir>
|
|
54
|
-
const genTable = new Command('gen-table')
|
|
55
|
-
.description('Generate a consolidated addresses table from an output directory')
|
|
56
|
-
.argument('<output-dir>', 'Directory containing job output JSON files (searches recursively)')
|
|
57
|
-
.option('--name', 'Include Name column', true)
|
|
58
|
-
.option('--key', 'Include Key column', false)
|
|
59
|
-
.option('--file', 'Include File column', false)
|
|
60
|
-
.option('--chain-ids, --chainIds', 'Include ChainIds column', false)
|
|
61
|
-
.option('--job', 'Include Job column', true)
|
|
62
|
-
.option('--address', 'Include Address column', true)
|
|
63
|
-
.option('--format <format>', "Output format: 'markdown' or 'ascii' (default)", 'ascii')
|
|
64
|
-
.action(async (outputDir: string, options: { name?: boolean; key?: boolean; file?: boolean; chainIds?: boolean; job?: boolean; address?: boolean; format?: string }) => {
|
|
65
|
-
try {
|
|
66
|
-
const absoluteDir = path.resolve(outputDir)
|
|
67
|
-
if (!fs.existsSync(absoluteDir) || !fs.statSync(absoluteDir).isDirectory()) {
|
|
68
|
-
console.error(chalk.red(`Output directory not found or not a directory: ${absoluteDir}`))
|
|
69
|
-
process.exit(1)
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
const jsonFiles: string[] = []
|
|
73
|
-
const walk = (dir: string) => {
|
|
74
|
-
for (const entry of fs.readdirSync(dir)) {
|
|
75
|
-
const full = path.join(dir, entry)
|
|
76
|
-
const stat = fs.statSync(full)
|
|
77
|
-
if (stat.isDirectory()) walk(full)
|
|
78
|
-
else if (stat.isFile() && entry.toLowerCase().endsWith('.json')) jsonFiles.push(full)
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
walk(absoluteDir)
|
|
82
|
-
|
|
83
|
-
type Row = { job: string; chainIds: string; name: string; address: string; key: string; file: string }
|
|
84
|
-
const rows: Row[] = []
|
|
85
|
-
const addressRegex = /^0x[a-fA-F0-9]{40}$/
|
|
86
|
-
|
|
87
|
-
const toTitleCase = (slug: string): string => slug.split(/[-_\s]+/).filter(Boolean).map(s => s.charAt(0).toUpperCase() + s.slice(1)).join('')
|
|
88
|
-
const extractVersionSuffix = (jobName: string): string => {
|
|
89
|
-
const m = jobName.match(/[-_]?v(\d+)/i)
|
|
90
|
-
return m ? `V${m[1]}` : ''
|
|
91
|
-
}
|
|
92
|
-
const deriveName = (jobName: string, key: string): string => {
|
|
93
|
-
const version = extractVersionSuffix(jobName)
|
|
94
|
-
const baseJob = jobName.replace(/[-_]?v\d+$/i, '')
|
|
95
|
-
const keyCore = key.replace(/\.address$/i, '')
|
|
96
|
-
// Prefer descriptive key name; if too generic like 'factory', prefix with job base
|
|
97
|
-
const isGeneric = /^(factory|address)$/i.test(keyCore)
|
|
98
|
-
const nameCore = isGeneric ? `${toTitleCase(baseJob)} ${toTitleCase(keyCore)}` : toTitleCase(keyCore)
|
|
99
|
-
return `${nameCore.replace(/\s+/g, '')}${version}`
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
for (const file of jsonFiles) {
|
|
103
|
-
try {
|
|
104
|
-
const raw = fs.readFileSync(file, 'utf8')
|
|
105
|
-
const data = JSON.parse(raw)
|
|
106
|
-
if (!data || typeof data !== 'object' || !Array.isArray(data.networks)) continue
|
|
107
|
-
const jobName: string = data.jobName ?? path.basename(file, '.json')
|
|
108
|
-
for (const net of data.networks) {
|
|
109
|
-
if (!net || typeof net !== 'object') continue
|
|
110
|
-
const outputs = net.outputs as Record<string, unknown> | undefined
|
|
111
|
-
if (!outputs) continue
|
|
112
|
-
const chainIds: string[] = Array.isArray(net.chainIds) ? net.chainIds : []
|
|
113
|
-
for (const [key, value] of Object.entries(outputs)) {
|
|
114
|
-
let address: string | undefined
|
|
115
|
-
if (typeof value === 'string' && addressRegex.test(value)) {
|
|
116
|
-
address = value
|
|
117
|
-
} else if (value && typeof value === 'object' && 'address' in value && typeof value.address === 'string' && addressRegex.test(value.address)) {
|
|
118
|
-
address = value.address
|
|
119
|
-
}
|
|
120
|
-
if (!address) continue
|
|
121
|
-
rows.push({
|
|
122
|
-
job: jobName,
|
|
123
|
-
chainIds: chainIds.join(','),
|
|
124
|
-
name: deriveName(jobName, key),
|
|
125
|
-
address,
|
|
126
|
-
key,
|
|
127
|
-
file
|
|
128
|
-
})
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
} catch {
|
|
132
|
-
// skip invalid JSON
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
rows.sort((a, b) => a.job.localeCompare(b.job) || a.name.localeCompare(b.name))
|
|
137
|
-
|
|
138
|
-
if (rows.length === 0) {
|
|
139
|
-
console.log(chalk.yellow('No address entries found.'))
|
|
140
|
-
return
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
// Determine which columns to show
|
|
144
|
-
const showJob = !!options.job
|
|
145
|
-
const showAddress = !!options.address
|
|
146
|
-
const showName = !!options.name
|
|
147
|
-
const showKey = !!options.key
|
|
148
|
-
const showChainIds = !!options.chainIds
|
|
149
|
-
const showFile = !!options.file
|
|
150
|
-
|
|
151
|
-
const selectedHeaders: (keyof Row)[] = []
|
|
152
|
-
if (showJob) selectedHeaders.push('job')
|
|
153
|
-
if (showChainIds) selectedHeaders.push('chainIds')
|
|
154
|
-
if (showName) selectedHeaders.push('name')
|
|
155
|
-
if (showAddress) selectedHeaders.push('address')
|
|
156
|
-
if (showKey) selectedHeaders.push('key')
|
|
157
|
-
if (showFile) selectedHeaders.push('file')
|
|
158
|
-
|
|
159
|
-
// Titles for columns
|
|
160
|
-
const titles: Record<keyof Row, string> = {
|
|
161
|
-
job: 'Job',
|
|
162
|
-
chainIds: 'ChainIds',
|
|
163
|
-
name: 'Name',
|
|
164
|
-
address: 'Address',
|
|
165
|
-
key: 'Key',
|
|
166
|
-
file: 'File'
|
|
167
|
-
}
|
|
168
|
-
const format = String(options.format || 'markdown').toLowerCase()
|
|
169
|
-
if (format !== 'markdown' && format !== 'ascii') {
|
|
170
|
-
console.error(chalk.red("Invalid format. Use 'markdown' or 'ascii'."))
|
|
171
|
-
process.exit(1)
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
if (format === 'markdown') {
|
|
175
|
-
const header = '| ' + selectedHeaders.map(h => titles[h]).join(' | ') + ' |'
|
|
176
|
-
const sepMd = '| ' + selectedHeaders.map(h => '-'.repeat(Math.max(3, String(titles[h]).length))).join(' | ') + ' |'
|
|
177
|
-
console.log(header)
|
|
178
|
-
console.log(sepMd)
|
|
179
|
-
for (const r of rows) {
|
|
180
|
-
console.log('| ' + selectedHeaders.map(h => String(r[h])).join(' | ') + ' |')
|
|
181
|
-
}
|
|
182
|
-
} else {
|
|
183
|
-
// ascii rendering with box-drawing characters
|
|
184
|
-
const widths: Record<string, number> = {}
|
|
185
|
-
for (const h of selectedHeaders) {
|
|
186
|
-
widths[h] = Math.max(titles[h].length, ...rows.map(r => String(r[h]).length))
|
|
187
|
-
}
|
|
188
|
-
const makeSep = (left: string, mid: string, right: string, fill: string) => {
|
|
189
|
-
return left + selectedHeaders.map(h => fill.repeat(widths[h] + 2)).join(mid) + right
|
|
190
|
-
}
|
|
191
|
-
const pad = (s: string, w: number) => s + ' '.repeat(Math.max(0, w - s.length))
|
|
192
|
-
|
|
193
|
-
const top = makeSep('┌', '┬', '┐', '─')
|
|
194
|
-
const sep = makeSep('├', '┼', '┤', '─')
|
|
195
|
-
const bot = makeSep('└', '┴', '┘', '─')
|
|
196
|
-
const headerLine = '│' + selectedHeaders.map(h => ' ' + pad(titles[h], widths[h]) + ' ').join('│') + '│'
|
|
197
|
-
const lines = rows.map(r => '│' + selectedHeaders.map(h => ' ' + pad(String(r[h]), widths[h]) + ' ').join('│') + '│')
|
|
198
|
-
|
|
199
|
-
console.log(top)
|
|
200
|
-
console.log(headerLine)
|
|
201
|
-
console.log(sep)
|
|
202
|
-
for (const line of lines) console.log(line)
|
|
203
|
-
console.log(bot)
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
} catch (error) {
|
|
207
|
-
console.error(chalk.red('Error generating table:'), error instanceof Error ? error.message : String(error))
|
|
208
|
-
process.exit(1)
|
|
209
|
-
}
|
|
210
|
-
})
|
|
211
|
-
|
|
212
|
-
utils.addCommand(genTable)
|
|
213
|
-
|
|
214
|
-
return utils
|
|
215
|
-
}
|
package/src/index.ts
DELETED
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
import { program } from 'commander'
|
|
4
|
-
import chalk from 'chalk'
|
|
5
|
-
import { setupCommands } from './cli'
|
|
6
|
-
import packageJson from '../package.json'
|
|
7
|
-
|
|
8
|
-
import { deploymentEvents, CLIEventAdapter, VerbosityLevel } from './lib/events'
|
|
9
|
-
|
|
10
|
-
// Set up CLI event adapter to convert events to console output
|
|
11
|
-
const cliAdapter = new CLIEventAdapter(deploymentEvents)
|
|
12
|
-
|
|
13
|
-
// Export function to update CLI verbosity
|
|
14
|
-
export function setVerbosity(level: VerbosityLevel): void {
|
|
15
|
-
cliAdapter.setVerbosity(level)
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
// Setup global error handling
|
|
19
|
-
process.on('unhandledRejection', (reason, promise) => {
|
|
20
|
-
deploymentEvents.emitEvent({
|
|
21
|
-
type: 'unhandled_rejection',
|
|
22
|
-
level: 'error',
|
|
23
|
-
data: {
|
|
24
|
-
reason,
|
|
25
|
-
promise
|
|
26
|
-
}
|
|
27
|
-
})
|
|
28
|
-
process.exit(1)
|
|
29
|
-
})
|
|
30
|
-
|
|
31
|
-
process.on('uncaughtException', (error) => {
|
|
32
|
-
deploymentEvents.emitEvent({
|
|
33
|
-
type: 'uncaught_exception',
|
|
34
|
-
level: 'error',
|
|
35
|
-
data: {
|
|
36
|
-
error
|
|
37
|
-
}
|
|
38
|
-
})
|
|
39
|
-
process.exit(1)
|
|
40
|
-
})
|
|
41
|
-
|
|
42
|
-
async function main() {
|
|
43
|
-
try {
|
|
44
|
-
// Configure the main program
|
|
45
|
-
program
|
|
46
|
-
.name('catapult')
|
|
47
|
-
.description('Ethereum contract deployment CLI tool')
|
|
48
|
-
.version(packageJson.version)
|
|
49
|
-
|
|
50
|
-
// Setup all commands
|
|
51
|
-
setupCommands(program)
|
|
52
|
-
|
|
53
|
-
// Parse arguments
|
|
54
|
-
await program.parseAsync(process.argv)
|
|
55
|
-
} catch (error) {
|
|
56
|
-
deploymentEvents.emitEvent({
|
|
57
|
-
type: 'cli_error',
|
|
58
|
-
level: 'error',
|
|
59
|
-
data: {
|
|
60
|
-
message: error instanceof Error ? error.message : String(error)
|
|
61
|
-
}
|
|
62
|
-
})
|
|
63
|
-
process.exit(1)
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
main()
|