@0xsequence/catapult 1.3.3 → 1.3.4
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 +16 -0
- package/dist/commands/run.d.ts.map +1 -1
- package/dist/commands/run.js +4 -2
- package/dist/commands/run.js.map +1 -1
- package/dist/lib/__tests__/deployer.spec.js +71 -1
- package/dist/lib/__tests__/deployer.spec.js.map +1 -1
- package/dist/lib/core/__tests__/engine.spec.js +270 -0
- package/dist/lib/core/__tests__/engine.spec.js.map +1 -1
- package/dist/lib/core/__tests__/resolver.spec.js +132 -0
- package/dist/lib/core/__tests__/resolver.spec.js.map +1 -1
- package/dist/lib/core/engine.d.ts +13 -0
- package/dist/lib/core/engine.d.ts.map +1 -1
- package/dist/lib/core/engine.js +59 -5
- package/dist/lib/core/engine.js.map +1 -1
- package/dist/lib/core/resolver.d.ts +1 -0
- package/dist/lib/core/resolver.d.ts.map +1 -1
- package/dist/lib/core/resolver.js +24 -7
- package/dist/lib/core/resolver.js.map +1 -1
- package/dist/lib/deployer.d.ts +2 -0
- package/dist/lib/deployer.d.ts.map +1 -1
- package/dist/lib/deployer.js +18 -1
- package/dist/lib/deployer.js.map +1 -1
- package/dist/lib/events/cli-adapter.d.ts.map +1 -1
- package/dist/lib/events/cli-adapter.js +20 -0
- package/dist/lib/events/cli-adapter.js.map +1 -1
- package/dist/lib/events/types.d.ts +25 -1
- package/dist/lib/events/types.d.ts.map +1 -1
- package/dist/lib/types/values.d.ts +8 -1
- package/dist/lib/types/values.d.ts.map +1 -1
- package/dist/lib/utils/assertion.d.ts +4 -0
- package/dist/lib/utils/assertion.d.ts.map +1 -0
- package/dist/lib/utils/assertion.js +27 -0
- package/dist/lib/utils/assertion.js.map +1 -0
- package/package.json +12 -13
- package/src/commands/run.ts +4 -1
- package/src/lib/__tests__/deployer.spec.ts +108 -1
- package/src/lib/core/__tests__/engine.spec.ts +321 -0
- package/src/lib/core/__tests__/resolver.spec.ts +150 -1
- package/src/lib/core/engine.ts +92 -6
- package/src/lib/core/resolver.ts +29 -8
- package/src/lib/deployer.ts +28 -1
- package/src/lib/events/cli-adapter.ts +24 -0
- package/src/lib/events/types.ts +29 -1
- package/src/lib/types/values.ts +10 -1
- package/src/lib/utils/assertion.ts +24 -0
package/src/lib/core/resolver.ts
CHANGED
|
@@ -5,16 +5,17 @@ import {
|
|
|
5
5
|
AbiEncodeValue,
|
|
6
6
|
AbiPackValue,
|
|
7
7
|
ConstructorEncodeValue,
|
|
8
|
+
ComputeCreateValue,
|
|
8
9
|
ComputeCreate2Value,
|
|
9
10
|
ReadBalanceValue,
|
|
10
11
|
BasicArithmeticValue,
|
|
11
12
|
CallValue,
|
|
12
|
-
ContractExistsCondition,
|
|
13
13
|
ContractExistsValue,
|
|
14
14
|
JobCompletedValue,
|
|
15
15
|
ReadJsonValue,
|
|
16
16
|
} from '../types'
|
|
17
17
|
import { ExecutionContext } from './context'
|
|
18
|
+
import { isAddress, isBigNumberish, isBytesLike } from '../utils/assertion'
|
|
18
19
|
|
|
19
20
|
/**
|
|
20
21
|
* A scope for resolving local variables, such as template arguments.
|
|
@@ -154,6 +155,8 @@ export class ValueResolver {
|
|
|
154
155
|
return this.resolveAbiPack(resolvedArgs as AbiPackValue['arguments'])
|
|
155
156
|
case 'constructor-encode':
|
|
156
157
|
return this.resolveConstructorEncode(resolvedArgs as ConstructorEncodeValue['arguments'])
|
|
158
|
+
case 'compute-create':
|
|
159
|
+
return this.resolveComputeCreate(resolvedArgs as ComputeCreateValue['arguments'])
|
|
157
160
|
case 'compute-create2':
|
|
158
161
|
return this.resolveComputeCreate2(resolvedArgs as ComputeCreate2Value['arguments'])
|
|
159
162
|
case 'read-balance':
|
|
@@ -260,7 +263,7 @@ export class ValueResolver {
|
|
|
260
263
|
}
|
|
261
264
|
|
|
262
265
|
// Validate that creation code is valid bytecode
|
|
263
|
-
if (!
|
|
266
|
+
if (!isBytesLike(creationCode)) {
|
|
264
267
|
throw new Error(`Invalid creation code: ${creationCode}`)
|
|
265
268
|
}
|
|
266
269
|
|
|
@@ -280,18 +283,36 @@ export class ValueResolver {
|
|
|
280
283
|
return '0x' + cleanCreationCode + cleanEncodedArgs
|
|
281
284
|
}
|
|
282
285
|
|
|
286
|
+
private resolveComputeCreate(args: ComputeCreateValue['arguments']): string {
|
|
287
|
+
const { deployerAddress, nonce } = args
|
|
288
|
+
// Check if the deployer address is a valid address
|
|
289
|
+
if (!isAddress(deployerAddress)) {
|
|
290
|
+
throw new Error(`Invalid deployer address: ${deployerAddress}`)
|
|
291
|
+
}
|
|
292
|
+
// Check if the nonce is a valid value
|
|
293
|
+
if (!isBigNumberish(nonce)) {
|
|
294
|
+
throw new Error(`Invalid nonce: ${nonce}`)
|
|
295
|
+
}
|
|
296
|
+
const bnNonce = ethers.toBigInt(nonce)
|
|
297
|
+
// Create the create address
|
|
298
|
+
return ethers.getCreateAddress({
|
|
299
|
+
from: deployerAddress,
|
|
300
|
+
nonce: bnNonce,
|
|
301
|
+
})
|
|
302
|
+
}
|
|
303
|
+
|
|
283
304
|
private resolveComputeCreate2(args: ComputeCreate2Value['arguments']): string {
|
|
284
305
|
const { deployerAddress, salt, initCode } = args
|
|
285
306
|
// Check if the deployer address is a valid address
|
|
286
|
-
if (!
|
|
307
|
+
if (!isAddress(deployerAddress)) {
|
|
287
308
|
throw new Error(`Invalid deployer address: ${deployerAddress}`)
|
|
288
309
|
}
|
|
289
310
|
// Check if the salt is a valid bytes value
|
|
290
|
-
if (!
|
|
311
|
+
if (!isBytesLike(salt)) {
|
|
291
312
|
throw new Error(`Invalid salt: ${salt}`)
|
|
292
313
|
}
|
|
293
314
|
// Check if the init code is a valid bytes value
|
|
294
|
-
if (!
|
|
315
|
+
if (!isBytesLike(initCode)) {
|
|
295
316
|
throw new Error(`Invalid init code: ${initCode}`)
|
|
296
317
|
}
|
|
297
318
|
// Hash the init code using Keccak256
|
|
@@ -304,7 +325,7 @@ export class ValueResolver {
|
|
|
304
325
|
// Check if the address is a valid address
|
|
305
326
|
const addressValue = args.address as any
|
|
306
327
|
|
|
307
|
-
if (!
|
|
328
|
+
if (!isAddress(addressValue)) {
|
|
308
329
|
throw new Error(`Invalid address: ${addressValue}`)
|
|
309
330
|
}
|
|
310
331
|
|
|
@@ -349,7 +370,7 @@ export class ValueResolver {
|
|
|
349
370
|
}
|
|
350
371
|
|
|
351
372
|
// Validate that the target address is a valid Ethereum address
|
|
352
|
-
if (!
|
|
373
|
+
if (!isAddress(to)) {
|
|
353
374
|
throw new Error(`call: invalid target address: ${to}`)
|
|
354
375
|
}
|
|
355
376
|
|
|
@@ -407,7 +428,7 @@ export class ValueResolver {
|
|
|
407
428
|
private async resolveContractExists(args: ContractExistsValue['arguments'], context: ExecutionContext): Promise<boolean> {
|
|
408
429
|
const { address } = args
|
|
409
430
|
|
|
410
|
-
if (!
|
|
431
|
+
if (!isAddress(address)) {
|
|
411
432
|
throw new Error(`contract-exists: invalid address: ${address}`)
|
|
412
433
|
}
|
|
413
434
|
|
package/src/lib/deployer.ts
CHANGED
|
@@ -52,6 +52,9 @@ export interface DeployerOptions {
|
|
|
52
52
|
|
|
53
53
|
/** Optional: Show end-of-run summary (default: true). */
|
|
54
54
|
showSummary?: boolean
|
|
55
|
+
|
|
56
|
+
/** Optional: Convert verification errors to warnings instead of failing (default: false). */
|
|
57
|
+
ignoreVerifyErrors?: boolean
|
|
55
58
|
}
|
|
56
59
|
|
|
57
60
|
/**
|
|
@@ -157,7 +160,8 @@ export class Deployer {
|
|
|
157
160
|
const engine = new ExecutionEngine(this.loader.templates, {
|
|
158
161
|
eventEmitter: this.events,
|
|
159
162
|
verificationRegistry,
|
|
160
|
-
noPostCheckConditions: this.noPostCheckConditions
|
|
163
|
+
noPostCheckConditions: this.noPostCheckConditions,
|
|
164
|
+
ignoreVerifyErrors: this.options.ignoreVerifyErrors ?? false
|
|
161
165
|
})
|
|
162
166
|
|
|
163
167
|
// Track if any jobs have failed
|
|
@@ -312,6 +316,11 @@ export class Deployer {
|
|
|
312
316
|
// 5. Write results to output files.
|
|
313
317
|
await this.writeOutputFiles()
|
|
314
318
|
|
|
319
|
+
// Show verification warnings report if ignoreVerifyErrors is enabled
|
|
320
|
+
if (this.options.ignoreVerifyErrors) {
|
|
321
|
+
this.emitVerificationWarningsReport(engine)
|
|
322
|
+
}
|
|
323
|
+
|
|
315
324
|
// Emit end-of-run summary before final status
|
|
316
325
|
if (this.showSummary) {
|
|
317
326
|
this.emitRunSummary(hasFailures)
|
|
@@ -423,6 +432,24 @@ export class Deployer {
|
|
|
423
432
|
this.events.emitEvent(summaryEvent)
|
|
424
433
|
}
|
|
425
434
|
|
|
435
|
+
/**
|
|
436
|
+
* Emit verification warnings report when ignoreVerifyErrors is enabled
|
|
437
|
+
*/
|
|
438
|
+
private emitVerificationWarningsReport(engine: ExecutionEngine): void {
|
|
439
|
+
const warnings = engine.getVerificationWarnings()
|
|
440
|
+
|
|
441
|
+
if (warnings.length > 0) {
|
|
442
|
+
this.events.emitEvent({
|
|
443
|
+
type: 'verification_warnings_report',
|
|
444
|
+
level: 'warn',
|
|
445
|
+
data: {
|
|
446
|
+
totalWarnings: warnings.length,
|
|
447
|
+
warnings: warnings
|
|
448
|
+
}
|
|
449
|
+
})
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
|
|
426
453
|
/**
|
|
427
454
|
* Determines the final, ordered list of jobs to execute based on user input.
|
|
428
455
|
* If a user requests specific jobs, this ensures all their dependencies are also included.
|
|
@@ -266,6 +266,30 @@ export class CLIEventAdapter {
|
|
|
266
266
|
// Keep short to reduce noise
|
|
267
267
|
console.log(chalk.gray(` Verification retry ${event.data.attempt}/${event.data.maxRetries}: ${event.data.error}`))
|
|
268
268
|
break
|
|
269
|
+
|
|
270
|
+
case 'verification_skipped':
|
|
271
|
+
console.log(chalk.yellow(` ⚠️ ${event.data.reason}`))
|
|
272
|
+
break
|
|
273
|
+
|
|
274
|
+
case 'verification_warnings_report':
|
|
275
|
+
// Display detailed verification warnings report
|
|
276
|
+
console.log(chalk.yellow('\n📋 Verification Warnings Report'))
|
|
277
|
+
console.log(chalk.yellow(` Total warnings: ${event.data.totalWarnings}`))
|
|
278
|
+
console.log('')
|
|
279
|
+
|
|
280
|
+
if (event.data.warnings && event.data.warnings.length > 0) {
|
|
281
|
+
for (const warning of event.data.warnings) {
|
|
282
|
+
console.log(chalk.red(` ❌ ${warning.actionName} (${warning.contractName})`))
|
|
283
|
+
console.log(chalk.gray(` Address: ${warning.address}`))
|
|
284
|
+
console.log(chalk.gray(` Platform: ${warning.platform}`))
|
|
285
|
+
if (warning.networkName) {
|
|
286
|
+
console.log(chalk.gray(` Network: ${warning.networkName}`))
|
|
287
|
+
}
|
|
288
|
+
console.log(chalk.gray(` Error: ${warning.error}`))
|
|
289
|
+
console.log('')
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
break
|
|
269
293
|
case 'contract_created':
|
|
270
294
|
console.log(chalk.gray(` contract: ${event.data.contractAddress}`))
|
|
271
295
|
break
|
package/src/lib/events/types.ts
CHANGED
|
@@ -429,6 +429,32 @@ export interface VerificationRetryEvent extends BaseEvent {
|
|
|
429
429
|
}
|
|
430
430
|
}
|
|
431
431
|
|
|
432
|
+
export interface VerificationSkippedEvent extends BaseEvent {
|
|
433
|
+
type: 'verification_skipped'
|
|
434
|
+
level: 'warn'
|
|
435
|
+
data: {
|
|
436
|
+
actionName: string
|
|
437
|
+
reason: string
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
export interface VerificationWarningsReportEvent extends BaseEvent {
|
|
442
|
+
type: 'verification_warnings_report'
|
|
443
|
+
level: 'warn'
|
|
444
|
+
data: {
|
|
445
|
+
totalWarnings: number
|
|
446
|
+
warnings: Array<{
|
|
447
|
+
actionName: string
|
|
448
|
+
address: string
|
|
449
|
+
contractName: string
|
|
450
|
+
platform: string
|
|
451
|
+
error: string
|
|
452
|
+
jobName?: string
|
|
453
|
+
networkName?: string
|
|
454
|
+
}>
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
|
|
432
458
|
// End-of-run summary
|
|
433
459
|
export interface RunSummaryEvent extends BaseEvent {
|
|
434
460
|
type: 'run_summary'
|
|
@@ -488,5 +514,7 @@ export type DeploymentEvent =
|
|
|
488
514
|
| VerificationSubmittedEvent
|
|
489
515
|
| VerificationCompletedEvent
|
|
490
516
|
| VerificationFailedEvent
|
|
491
|
-
| VerificationRetryEvent
|
|
517
|
+
| VerificationRetryEvent
|
|
518
|
+
| VerificationSkippedEvent
|
|
519
|
+
| VerificationWarningsReportEvent
|
|
492
520
|
| RunSummaryEvent
|
package/src/lib/types/values.ts
CHANGED
|
@@ -32,6 +32,14 @@ export interface ConstructorEncodeValue {
|
|
|
32
32
|
};
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
+
export interface ComputeCreateValue {
|
|
36
|
+
type: 'compute-create';
|
|
37
|
+
arguments: {
|
|
38
|
+
deployerAddress: AddressValue;
|
|
39
|
+
nonce: Uint256Value;
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
|
|
35
43
|
export interface ComputeCreate2Value {
|
|
36
44
|
type: 'compute-create2';
|
|
37
45
|
arguments: {
|
|
@@ -94,6 +102,7 @@ export type ValueResolver =
|
|
|
94
102
|
| AbiEncodeValue
|
|
95
103
|
| AbiPackValue
|
|
96
104
|
| ConstructorEncodeValue
|
|
105
|
+
| ComputeCreateValue
|
|
97
106
|
| ComputeCreate2Value
|
|
98
107
|
| ReadBalanceValue
|
|
99
108
|
| BasicArithmeticValue
|
|
@@ -113,4 +122,4 @@ export type Value<T = string | number | boolean> = T | Reference | ValueResolver
|
|
|
113
122
|
export type BytesValue = Value<string>;
|
|
114
123
|
export type AddressValue = Value<string>;
|
|
115
124
|
export type Uint256Value = Value<string | number>;
|
|
116
|
-
export type BooleanValue = Value<boolean>;
|
|
125
|
+
export type BooleanValue = Value<boolean>;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { ethers } from "ethers";
|
|
2
|
+
|
|
3
|
+
export function isAddress(value: unknown): value is string {
|
|
4
|
+
return ethers.isAddress(value)
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export function isBytesLike(value: unknown): value is string {
|
|
8
|
+
return ethers.isBytesLike(value)
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function isBigNumberish(value: unknown): value is string | number | bigint {
|
|
12
|
+
try {
|
|
13
|
+
switch (typeof(value)) {
|
|
14
|
+
case "bigint":
|
|
15
|
+
case "number":
|
|
16
|
+
case "string":
|
|
17
|
+
ethers.toBigInt(value)
|
|
18
|
+
return true
|
|
19
|
+
}
|
|
20
|
+
} catch (error) {
|
|
21
|
+
// Fail out
|
|
22
|
+
}
|
|
23
|
+
return false
|
|
24
|
+
}
|