@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.
- package/README.md +27 -0
- package/dist/lib/__tests__/network-loader.spec.js.map +1 -1
- package/dist/lib/core/__tests__/resolver.spec.js +22 -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 +173 -0
- package/dist/lib/core/engine.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/parsers/__tests__/source.spec.js +37 -0
- package/dist/lib/parsers/__tests__/source.spec.js.map +1 -1
- package/dist/lib/parsers/source.js +1 -1
- package/dist/lib/parsers/source.js.map +1 -1
- package/dist/lib/provenance.js +51 -2
- package/dist/lib/provenance.js.map +1 -1
- package/dist/lib/types/actions.d.ts +26 -2
- package/dist/lib/types/actions.d.ts.map +1 -1
- package/dist/lib/types/actions.js +3 -0
- package/dist/lib/types/actions.js.map +1 -1
- package/dist/lib/types/source.d.ts +2 -0
- package/dist/lib/types/source.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 -18
- 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 -6
- package/src/commands/list.ts +0 -262
- package/src/commands/provenance.ts +0 -120
- 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 -2269
- 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/__tests__/provenance.spec.ts +0 -208
- 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 -612
- package/src/lib/contracts/repository.ts +0 -411
- package/src/lib/core/__tests__/assert-action.spec.ts +0 -474
- package/src/lib/core/__tests__/context.spec.ts +0 -37
- package/src/lib/core/__tests__/engine.spec.ts +0 -2005
- 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 -367
- package/src/lib/core/__tests__/multi-platform-verification.spec.ts +0 -406
- package/src/lib/core/__tests__/resolver.spec.ts +0 -2496
- 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 -1834
- package/src/lib/core/graph.ts +0 -252
- package/src/lib/core/loader.ts +0 -253
- package/src/lib/core/resolver.ts +0 -873
- package/src/lib/deployer.ts +0 -1005
- 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 -17
- 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 -439
- package/src/lib/parsers/__tests__/source.spec.ts +0 -134
- 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 -6
- package/src/lib/parsers/job.ts +0 -160
- package/src/lib/parsers/source.ts +0 -129
- package/src/lib/parsers/template.ts +0 -135
- package/src/lib/provenance.ts +0 -785
- 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 -148
- 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 -26
- package/src/lib/types/definitions.ts +0 -77
- package/src/lib/types/index.ts +0 -9
- package/src/lib/types/network.ts +0 -33
- package/src/lib/types/project.ts +0 -9
- package/src/lib/types/source.ts +0 -26
- package/src/lib/types/task.ts +0 -9
- package/src/lib/types/values.ts +0 -221
- 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/lib/types/values.ts
DELETED
|
@@ -1,221 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Represents a reference to another value in the scope, e.g., "{{var.name}}".
|
|
3
|
-
* The parser will be responsible for resolving this string into a concrete value.
|
|
4
|
-
*/
|
|
5
|
-
export type Reference = string;
|
|
6
|
-
|
|
7
|
-
// --- Value Resolver Types ---
|
|
8
|
-
// These are declarative objects that describe how to compute a value at runtime.
|
|
9
|
-
|
|
10
|
-
export interface AbiEncodeValue {
|
|
11
|
-
type: 'abi-encode';
|
|
12
|
-
arguments: {
|
|
13
|
-
signature: Value<string>;
|
|
14
|
-
values: Value<any>[];
|
|
15
|
-
};
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export interface AbiPackValue {
|
|
19
|
-
type: 'abi-pack';
|
|
20
|
-
arguments: {
|
|
21
|
-
types: Value<string>[];
|
|
22
|
-
values: Value<any>[];
|
|
23
|
-
};
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export interface ConstructorEncodeValue {
|
|
27
|
-
type: 'constructor-encode';
|
|
28
|
-
arguments: {
|
|
29
|
-
creationCode?: Value<string>;
|
|
30
|
-
types: Value<string>[];
|
|
31
|
-
values: Value<any>[];
|
|
32
|
-
};
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export interface ComputeCreateValue {
|
|
36
|
-
type: 'compute-create';
|
|
37
|
-
arguments: {
|
|
38
|
-
deployerAddress: AddressValue;
|
|
39
|
-
nonce: Uint256Value;
|
|
40
|
-
};
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
export interface ComputeCreate2Value {
|
|
44
|
-
type: 'compute-create2';
|
|
45
|
-
arguments: {
|
|
46
|
-
deployerAddress: AddressValue;
|
|
47
|
-
salt: BytesValue;
|
|
48
|
-
initCode: BytesValue;
|
|
49
|
-
};
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
export interface ReadBalanceValue {
|
|
53
|
-
type: 'read-balance';
|
|
54
|
-
arguments: {
|
|
55
|
-
address: AddressValue;
|
|
56
|
-
};
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
export interface GetStorageAtValue {
|
|
60
|
-
type: 'get-storage-at';
|
|
61
|
-
arguments: {
|
|
62
|
-
address: AddressValue;
|
|
63
|
-
slot: Value<string | number>;
|
|
64
|
-
};
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* Computes EVM storage slots for common Solidity storage layouts.
|
|
69
|
-
*
|
|
70
|
-
* The result is always returned as a 32-byte, 0x-prefixed lowercase hex string,
|
|
71
|
-
* so it can be fed directly into `get-storage-at` or nested as the `slot` of
|
|
72
|
-
* another `compute-slot` (e.g. for nested mappings).
|
|
73
|
-
*/
|
|
74
|
-
export type ComputeSlotArguments =
|
|
75
|
-
| {
|
|
76
|
-
/** Value at `mapping[key]`: keccak256(h(key) . slot). */
|
|
77
|
-
kind: 'mapping';
|
|
78
|
-
/** Declaration slot of the mapping. */
|
|
79
|
-
slot: Value<string | number>;
|
|
80
|
-
/** The mapping key. */
|
|
81
|
-
key: Value<string | number | boolean>;
|
|
82
|
-
/**
|
|
83
|
-
* Solidity type of the key, used to encode it (default: "uint256").
|
|
84
|
-
* Value types (address, uint*, int*, bytes32, bool, ...) are ABI-encoded
|
|
85
|
-
* and left-padded; dynamic types ("string", "bytes") are packed.
|
|
86
|
-
*/
|
|
87
|
-
keyType?: Value<string>;
|
|
88
|
-
}
|
|
89
|
-
| {
|
|
90
|
-
/** Element of a dynamic array: keccak256(slot) + index * elementSize. */
|
|
91
|
-
kind: 'dynamic-array';
|
|
92
|
-
/** Declaration slot of the array (also where its length lives). */
|
|
93
|
-
slot: Value<string | number>;
|
|
94
|
-
/** Element index (default: 0). */
|
|
95
|
-
index?: Value<string | number>;
|
|
96
|
-
/** Number of slots each element occupies (default: 1). */
|
|
97
|
-
elementSize?: Value<string | number>;
|
|
98
|
-
}
|
|
99
|
-
| {
|
|
100
|
-
/** Field of a struct or fixed-size array element: slot + offset. */
|
|
101
|
-
kind: 'struct-field';
|
|
102
|
-
/** Base slot of the struct / array element. */
|
|
103
|
-
slot: Value<string | number>;
|
|
104
|
-
/** Field offset in slots from the base. */
|
|
105
|
-
offset: Value<string | number>;
|
|
106
|
-
}
|
|
107
|
-
| {
|
|
108
|
-
/**
|
|
109
|
-
* ERC-7201 namespaced storage root:
|
|
110
|
-
* keccak256(abi.encode(uint256(keccak256(id)) - 1)) & ~bytes32(uint256(0xff)).
|
|
111
|
-
*/
|
|
112
|
-
kind: 'erc7201';
|
|
113
|
-
/** The namespace id, e.g. "openzeppelin.storage.Ownable". */
|
|
114
|
-
id: Value<string>;
|
|
115
|
-
}
|
|
116
|
-
| {
|
|
117
|
-
/** Well-known EIP-1967 proxy slot: keccak256("eip1967.proxy.<name>") - 1. */
|
|
118
|
-
kind: 'eip1967';
|
|
119
|
-
/** Which proxy slot to compute. */
|
|
120
|
-
name: Value<'implementation' | 'admin' | 'beacon'>;
|
|
121
|
-
};
|
|
122
|
-
|
|
123
|
-
export interface ComputeSlotValue {
|
|
124
|
-
type: 'compute-slot';
|
|
125
|
-
arguments: ComputeSlotArguments;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
export interface BasicArithmeticValue {
|
|
129
|
-
type: 'basic-arithmetic';
|
|
130
|
-
arguments: {
|
|
131
|
-
operation: 'add' | 'sub' | 'mul' | 'div' | 'eq' | 'neq' | 'gt' | 'lt' | 'gte' | 'lte';
|
|
132
|
-
values: Value<any>[];
|
|
133
|
-
};
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
export interface CallValue {
|
|
137
|
-
type: 'call';
|
|
138
|
-
arguments: {
|
|
139
|
-
to?: AddressValue; // Optional, can be inferred from context by the parser
|
|
140
|
-
signature: Value<string>;
|
|
141
|
-
values: Value<any>[];
|
|
142
|
-
};
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
export interface ContractExistsValue {
|
|
146
|
-
type: 'contract-exists';
|
|
147
|
-
arguments: {
|
|
148
|
-
address: AddressValue;
|
|
149
|
-
};
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
export interface JobCompletedValue {
|
|
153
|
-
type: 'job-completed';
|
|
154
|
-
arguments: {
|
|
155
|
-
job: Value<string>;
|
|
156
|
-
};
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
export interface ReadJsonValue {
|
|
160
|
-
type: 'read-json';
|
|
161
|
-
arguments: {
|
|
162
|
-
json: Value<any>; // The JSON object to read from
|
|
163
|
-
path: Value<string | number>; // The path to the value (e.g., "txs.data", 1, or "user.profile.name")
|
|
164
|
-
};
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
export interface ResolveJsonValue {
|
|
168
|
-
type: 'resolve-json';
|
|
169
|
-
arguments: Value<any>;
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
export interface ValueEmptyValue {
|
|
173
|
-
type: 'value-empty';
|
|
174
|
-
arguments: {
|
|
175
|
-
value: Value<any>;
|
|
176
|
-
};
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
export interface SliceBytesValue {
|
|
180
|
-
type: 'slice-bytes';
|
|
181
|
-
arguments: {
|
|
182
|
-
value: BytesValue;
|
|
183
|
-
start?: Value<number | string>;
|
|
184
|
-
end?: Value<number | string>;
|
|
185
|
-
range?: Value<string>;
|
|
186
|
-
};
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
/**
|
|
190
|
-
* A union of all possible value-resolver objects.
|
|
191
|
-
*/
|
|
192
|
-
export type ValueResolver =
|
|
193
|
-
| AbiEncodeValue
|
|
194
|
-
| AbiPackValue
|
|
195
|
-
| ConstructorEncodeValue
|
|
196
|
-
| ComputeCreateValue
|
|
197
|
-
| ComputeCreate2Value
|
|
198
|
-
| ReadBalanceValue
|
|
199
|
-
| GetStorageAtValue
|
|
200
|
-
| ComputeSlotValue
|
|
201
|
-
| BasicArithmeticValue
|
|
202
|
-
| CallValue
|
|
203
|
-
| ContractExistsValue
|
|
204
|
-
| JobCompletedValue
|
|
205
|
-
| ReadJsonValue
|
|
206
|
-
| ResolveJsonValue
|
|
207
|
-
| ValueEmptyValue
|
|
208
|
-
| SliceBytesValue;
|
|
209
|
-
|
|
210
|
-
/**
|
|
211
|
-
* A generic value type that can be a primitive literal (string, number, boolean),
|
|
212
|
-
* a reference to another value, or a value-resolver object.
|
|
213
|
-
* This accurately models the flexibility of your YAML arguments.
|
|
214
|
-
*/
|
|
215
|
-
export type Value<T = string | number | boolean> = T | Reference | ValueResolver;
|
|
216
|
-
|
|
217
|
-
// --- Specific Value Types for clarity and type-safety ---
|
|
218
|
-
export type BytesValue = Value<string>;
|
|
219
|
-
export type AddressValue = Value<string>;
|
|
220
|
-
export type Uint256Value = Value<string | number>;
|
|
221
|
-
export type BooleanValue = Value<boolean>;
|
|
@@ -1,24 +0,0 @@
|
|
|
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
|
-
}
|
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Validation utilities for type checking and conversion of resolved values.
|
|
3
|
-
* These functions provide runtime type safety for values resolved from YAML configurations.
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Validates and converts a value to a valid Ethereum address.
|
|
8
|
-
*/
|
|
9
|
-
export function validateAddress(value: unknown, actionName: string): string {
|
|
10
|
-
if (typeof value !== 'string') {
|
|
11
|
-
throw new Error(`Invalid 'to' address for action "${actionName}": expected string, got ${typeof value}`)
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
// Basic Ethereum address validation (0x followed by 40 hex characters)
|
|
15
|
-
if (!/^0x[a-fA-F0-9]{40}$/.test(value)) {
|
|
16
|
-
throw new Error(`Invalid 'to' address format for action "${actionName}": ${value}`)
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
return value
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Validates and converts a value to hex data string.
|
|
24
|
-
*/
|
|
25
|
-
export function validateHexData(value: unknown, actionName: string, fieldName: string): string {
|
|
26
|
-
if (value === null || value === undefined) {
|
|
27
|
-
return '0x'
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
if (typeof value !== 'string') {
|
|
31
|
-
throw new Error(`Invalid '${fieldName}' for action "${actionName}": expected string, got ${typeof value}`)
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
// Ensure it starts with 0x
|
|
35
|
-
if (!value.startsWith('0x')) {
|
|
36
|
-
throw new Error(`Invalid '${fieldName}' format for action "${actionName}": must start with '0x', got ${value}`)
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
// Validate hex characters (allow empty data as '0x')
|
|
40
|
-
if (value.length > 2 && !/^0x[a-fA-F0-9]*$/.test(value)) {
|
|
41
|
-
throw new Error(`Invalid '${fieldName}' format for action "${actionName}": contains non-hex characters: ${value}`)
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
return value
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* Validates and converts a value to a BigNumberish (number, string, or BigInt).
|
|
49
|
-
*/
|
|
50
|
-
export function validateBigNumberish(value: unknown, actionName: string, fieldName: string): string | number | bigint {
|
|
51
|
-
if (value === null || value === undefined) {
|
|
52
|
-
return 0
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
// Handle different input types
|
|
56
|
-
if (typeof value === 'number') {
|
|
57
|
-
if (!Number.isInteger(value) || value < 0) {
|
|
58
|
-
throw new Error(`Invalid '${fieldName}' for action "${actionName}": must be a non-negative integer, got ${value}`)
|
|
59
|
-
}
|
|
60
|
-
return value
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
if (typeof value === 'string') {
|
|
64
|
-
// Handle hex strings
|
|
65
|
-
if (value.startsWith('0x')) {
|
|
66
|
-
if (!/^0x[a-fA-F0-9]+$/.test(value)) {
|
|
67
|
-
throw new Error(`Invalid '${fieldName}' hex format for action "${actionName}": ${value}`)
|
|
68
|
-
}
|
|
69
|
-
return value
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
// Handle decimal strings
|
|
73
|
-
if (!/^\d+$/.test(value)) {
|
|
74
|
-
throw new Error(`Invalid '${fieldName}' format for action "${actionName}": must be a number or hex string, got ${value}`)
|
|
75
|
-
}
|
|
76
|
-
return value
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
if (typeof value === 'bigint') {
|
|
80
|
-
if (value < 0n) {
|
|
81
|
-
throw new Error(`Invalid '${fieldName}' for action "${actionName}": must be non-negative, got ${value}`)
|
|
82
|
-
}
|
|
83
|
-
return value
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
throw new Error(`Invalid '${fieldName}' type for action "${actionName}": expected number, string, or bigint, got ${typeof value}`)
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* Validates that a value is a valid raw transaction string.
|
|
91
|
-
*/
|
|
92
|
-
export function validateRawTransaction(value: unknown, actionName: string): string {
|
|
93
|
-
if (typeof value !== 'string') {
|
|
94
|
-
throw new Error(`Invalid raw transaction for action "${actionName}": expected string, got ${typeof value}`)
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
// Normalize: trim whitespace and allow with or without 0x prefix
|
|
98
|
-
const trimmed = value.trim()
|
|
99
|
-
const withoutPrefix = trimmed.startsWith('0x') ? trimmed.slice(2) : trimmed
|
|
100
|
-
|
|
101
|
-
if (withoutPrefix.length === 0) {
|
|
102
|
-
// Empty data is allowed as '0x'
|
|
103
|
-
return '0x'
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
// Validate hex characters only
|
|
107
|
-
if (!/^[a-fA-F0-9]+$/.test(withoutPrefix)) {
|
|
108
|
-
// Pinpoint first invalid character for easier debugging
|
|
109
|
-
const idx = withoutPrefix.search(/[^a-fA-F0-9]/)
|
|
110
|
-
const marker = idx >= 0 ? ` at index ${idx} ('${withoutPrefix[idx]}')` : ''
|
|
111
|
-
throw new Error(`Invalid raw transaction format for action "${actionName}": contains non-hex characters${marker}: ${value}`)
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
// Ensure canonical 0x-prefixed output
|
|
115
|
-
return '0x' + withoutPrefix
|
|
116
|
-
}
|
|
@@ -1,210 +0,0 @@
|
|
|
1
|
-
import { ProjectLoader } from '../core/loader'
|
|
2
|
-
import { Action, Template, Job, JobAction, Value } from '../types'
|
|
3
|
-
|
|
4
|
-
export interface MissingContractReference {
|
|
5
|
-
reference: string
|
|
6
|
-
location: string
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export interface UsedContractReference {
|
|
10
|
-
reference: string
|
|
11
|
-
location: string
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Extracts all Contract() references actually used in the project
|
|
16
|
-
*/
|
|
17
|
-
export async function extractUsedContractReferences(loader: ProjectLoader): Promise<UsedContractReference[]> {
|
|
18
|
-
const usedRefs: UsedContractReference[] = []
|
|
19
|
-
|
|
20
|
-
// Extract from jobs
|
|
21
|
-
for (const [jobName, job] of loader.jobs.entries()) {
|
|
22
|
-
extractJobActionsContractReferences(job.actions, `job '${jobName}'`, job._path, usedRefs)
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
// Extract from templates
|
|
26
|
-
for (const [templateName, template] of loader.templates.entries()) {
|
|
27
|
-
extractActionsContractReferences(template.actions, `template '${templateName}'`, template._path, usedRefs)
|
|
28
|
-
|
|
29
|
-
// Extract from template setup actions if they exist
|
|
30
|
-
if (template.setup?.actions) {
|
|
31
|
-
extractActionsContractReferences(template.setup.actions, `template '${templateName}' setup`, template._path, usedRefs)
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
// Extract from template outputs
|
|
35
|
-
if (template.outputs) {
|
|
36
|
-
extractValueContractReferences(template.outputs, `template '${templateName}' outputs`, template._path, usedRefs)
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
return usedRefs
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* Validates that all Contract() references in the project point to existing contracts
|
|
45
|
-
*/
|
|
46
|
-
export async function validateContractReferences(loader: ProjectLoader): Promise<MissingContractReference[]> {
|
|
47
|
-
const missingRefs: MissingContractReference[] = []
|
|
48
|
-
|
|
49
|
-
// Validate jobs
|
|
50
|
-
for (const [jobName, job] of loader.jobs.entries()) {
|
|
51
|
-
validateJobActionsForMissingContracts(job.actions, `job '${jobName}'`, job._path, loader, missingRefs)
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
// Validate templates
|
|
55
|
-
for (const [templateName, template] of loader.templates.entries()) {
|
|
56
|
-
validateActionsForMissingContracts(template.actions, `template '${templateName}'`, template._path, loader, missingRefs)
|
|
57
|
-
|
|
58
|
-
// Validate template setup actions if they exist
|
|
59
|
-
if (template.setup?.actions) {
|
|
60
|
-
validateActionsForMissingContracts(template.setup.actions, `template '${templateName}' setup`, template._path, loader, missingRefs)
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
// Validate template outputs
|
|
64
|
-
if (template.outputs) {
|
|
65
|
-
validateValueForMissingContracts(template.outputs, `template '${templateName}' outputs`, template._path, loader, missingRefs)
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
return missingRefs
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* Extracts contract references from job actions
|
|
74
|
-
*/
|
|
75
|
-
function extractJobActionsContractReferences(
|
|
76
|
-
actions: JobAction[],
|
|
77
|
-
locationPrefix: string,
|
|
78
|
-
contextPath: string | undefined,
|
|
79
|
-
usedRefs: UsedContractReference[]
|
|
80
|
-
): void {
|
|
81
|
-
for (let i = 0; i < actions.length; i++) {
|
|
82
|
-
const action = actions[i]
|
|
83
|
-
const actionLocation = `${locationPrefix}, action ${i + 1}${action.name ? ` '${action.name}'` : ''}`
|
|
84
|
-
|
|
85
|
-
extractValueContractReferences(action.arguments, actionLocation, contextPath, usedRefs)
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* Extracts contract references from template actions
|
|
91
|
-
*/
|
|
92
|
-
function extractActionsContractReferences(
|
|
93
|
-
actions: Action[],
|
|
94
|
-
locationPrefix: string,
|
|
95
|
-
contextPath: string | undefined,
|
|
96
|
-
usedRefs: UsedContractReference[]
|
|
97
|
-
): void {
|
|
98
|
-
for (let i = 0; i < actions.length; i++) {
|
|
99
|
-
const action = actions[i]
|
|
100
|
-
const actionLocation = `${locationPrefix}, action ${i + 1}${action.name ? ` '${action.name}'` : ''}`
|
|
101
|
-
|
|
102
|
-
extractValueContractReferences(action.arguments, actionLocation, contextPath, usedRefs)
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
/**
|
|
107
|
-
* Recursively extracts contract references from a value (or nested object/array)
|
|
108
|
-
*/
|
|
109
|
-
function extractValueContractReferences(
|
|
110
|
-
value: any,
|
|
111
|
-
location: string,
|
|
112
|
-
contextPath: string | undefined,
|
|
113
|
-
usedRefs: UsedContractReference[]
|
|
114
|
-
): void {
|
|
115
|
-
if (typeof value === 'string') {
|
|
116
|
-
// Check for Contract() expressions
|
|
117
|
-
const contractMatch = value.match(/^{{Contract\((.*?)\)(?:\.\w+)?}}$/)
|
|
118
|
-
if (contractMatch) {
|
|
119
|
-
const reference = contractMatch[1].trim()
|
|
120
|
-
usedRefs.push({
|
|
121
|
-
reference,
|
|
122
|
-
location: `${location}, Contract(${reference})`
|
|
123
|
-
})
|
|
124
|
-
}
|
|
125
|
-
} else if (Array.isArray(value)) {
|
|
126
|
-
// Recursively check array elements
|
|
127
|
-
for (let i = 0; i < value.length; i++) {
|
|
128
|
-
extractValueContractReferences(value[i], `${location}[${i}]`, contextPath, usedRefs)
|
|
129
|
-
}
|
|
130
|
-
} else if (typeof value === 'object' && value !== null) {
|
|
131
|
-
// Recursively check object properties
|
|
132
|
-
for (const [key, val] of Object.entries(value)) {
|
|
133
|
-
extractValueContractReferences(val, `${location}.${key}`, contextPath, usedRefs)
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
/**
|
|
139
|
-
* Validates a list of job actions for missing contract references
|
|
140
|
-
*/
|
|
141
|
-
function validateJobActionsForMissingContracts(
|
|
142
|
-
actions: JobAction[],
|
|
143
|
-
locationPrefix: string,
|
|
144
|
-
contextPath: string | undefined,
|
|
145
|
-
loader: ProjectLoader,
|
|
146
|
-
missingRefs: MissingContractReference[]
|
|
147
|
-
): void {
|
|
148
|
-
for (let i = 0; i < actions.length; i++) {
|
|
149
|
-
const action = actions[i]
|
|
150
|
-
const actionLocation = `${locationPrefix}, action ${i + 1}${action.name ? ` '${action.name}'` : ''}`
|
|
151
|
-
|
|
152
|
-
validateValueForMissingContracts(action.arguments, actionLocation, contextPath, loader, missingRefs)
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
/**
|
|
157
|
-
* Validates a list of template actions for missing contract references
|
|
158
|
-
*/
|
|
159
|
-
function validateActionsForMissingContracts(
|
|
160
|
-
actions: Action[],
|
|
161
|
-
locationPrefix: string,
|
|
162
|
-
contextPath: string | undefined,
|
|
163
|
-
loader: ProjectLoader,
|
|
164
|
-
missingRefs: MissingContractReference[]
|
|
165
|
-
): void {
|
|
166
|
-
for (let i = 0; i < actions.length; i++) {
|
|
167
|
-
const action = actions[i]
|
|
168
|
-
const actionLocation = `${locationPrefix}, action ${i + 1}${action.name ? ` '${action.name}'` : ''}`
|
|
169
|
-
|
|
170
|
-
validateValueForMissingContracts(action.arguments, actionLocation, contextPath, loader, missingRefs)
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
/**
|
|
175
|
-
* Recursively validates a value (or nested object/array) for missing contract references
|
|
176
|
-
*/
|
|
177
|
-
function validateValueForMissingContracts(
|
|
178
|
-
value: any,
|
|
179
|
-
location: string,
|
|
180
|
-
contextPath: string | undefined,
|
|
181
|
-
loader: ProjectLoader,
|
|
182
|
-
missingRefs: MissingContractReference[]
|
|
183
|
-
): void {
|
|
184
|
-
if (typeof value === 'string') {
|
|
185
|
-
// Check for Contract() expressions
|
|
186
|
-
const contractMatch = value.match(/^{{Contract\((.*?)\)(?:\.\w+)?}}$/)
|
|
187
|
-
if (contractMatch) {
|
|
188
|
-
const reference = contractMatch[1].trim()
|
|
189
|
-
|
|
190
|
-
// Try to lookup the contract
|
|
191
|
-
const contract = loader.contractRepository.lookup(reference, contextPath)
|
|
192
|
-
if (!contract) {
|
|
193
|
-
missingRefs.push({
|
|
194
|
-
reference,
|
|
195
|
-
location: `${location}, Contract(${reference})`
|
|
196
|
-
})
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
} else if (Array.isArray(value)) {
|
|
200
|
-
// Recursively check array elements
|
|
201
|
-
for (let i = 0; i < value.length; i++) {
|
|
202
|
-
validateValueForMissingContracts(value[i], `${location}[${i}]`, contextPath, loader, missingRefs)
|
|
203
|
-
}
|
|
204
|
-
} else if (typeof value === 'object' && value !== null) {
|
|
205
|
-
// Recursively check object properties
|
|
206
|
-
for (const [key, val] of Object.entries(value)) {
|
|
207
|
-
validateValueForMissingContracts(val, `${location}.${key}`, contextPath, loader, missingRefs)
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
// No exports - validation logic is now integrated into ContractRepository
|