@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
|
@@ -1,117 +0,0 @@
|
|
|
1
|
-
import * as fs from 'fs'
|
|
2
|
-
import * as path from 'path'
|
|
3
|
-
import { parseArtifact } from '../index'
|
|
4
|
-
|
|
5
|
-
describe('Artifact Parsing', () => {
|
|
6
|
-
const fixturesDir = path.join(__dirname, 'fixtures')
|
|
7
|
-
|
|
8
|
-
// Helper function to read fixture files
|
|
9
|
-
const readFixture = (filename: string): string => {
|
|
10
|
-
return fs.readFileSync(path.join(fixturesDir, filename), 'utf-8')
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
describe('parseArtifact function', () => {
|
|
14
|
-
it('should parse a simple artifact with string bytecode', () => {
|
|
15
|
-
const content = readFixture('simple-artifact.json')
|
|
16
|
-
const result = parseArtifact(content, '/test/simple-artifact.json')
|
|
17
|
-
|
|
18
|
-
expect(result).not.toBeNull()
|
|
19
|
-
expect(result!.contractName).toBe('SimpleToken')
|
|
20
|
-
expect(result!.abi).toBeInstanceOf(Array)
|
|
21
|
-
expect(result!.abi.length).toBe(2)
|
|
22
|
-
expect(result!.bytecode).toMatch(/^0x[0-9a-fA-F]+$/)
|
|
23
|
-
expect(result!.deployedBytecode).toMatch(/^0x[0-9a-fA-F]+$/)
|
|
24
|
-
})
|
|
25
|
-
|
|
26
|
-
it('should parse a Hardhat-style artifact with bytecode object', () => {
|
|
27
|
-
const content = readFixture('hardhat-artifact.json')
|
|
28
|
-
const result = parseArtifact(content, '/test/hardhat-artifact.json')
|
|
29
|
-
|
|
30
|
-
expect(result).not.toBeNull()
|
|
31
|
-
expect(result!.contractName).toBe('ERC20Token')
|
|
32
|
-
expect(result!.sourceName).toBe('contracts/ERC20Token.sol')
|
|
33
|
-
expect(result!.abi).toBeInstanceOf(Array)
|
|
34
|
-
expect(result!.abi.length).toBe(3)
|
|
35
|
-
expect(result!.bytecode).toMatch(/^0x[0-9a-fA-F]+$/)
|
|
36
|
-
expect(result!.deployedBytecode).toMatch(/^0x[0-9a-fA-F]+$/)
|
|
37
|
-
expect(result!.compiler).toBeDefined()
|
|
38
|
-
expect(result!.compiler!.version).toBe('0.8.19+commit.7dd6d404')
|
|
39
|
-
expect(result!.source).toContain('contract ERC20Token')
|
|
40
|
-
})
|
|
41
|
-
|
|
42
|
-
it('should parse a minimal artifact with only required fields', () => {
|
|
43
|
-
const content = readFixture('minimal-artifact.json')
|
|
44
|
-
const result = parseArtifact(content, '/test/minimal-artifact.json')
|
|
45
|
-
|
|
46
|
-
expect(result).not.toBeNull()
|
|
47
|
-
expect(result!.contractName).toBe('Minimal')
|
|
48
|
-
expect(result!.abi).toBeInstanceOf(Array)
|
|
49
|
-
expect(result!.abi.length).toBe(0)
|
|
50
|
-
expect(result!.bytecode).toBe('0x608060405234801561001057600080fd5b50')
|
|
51
|
-
expect(result!.deployedBytecode).toBeUndefined()
|
|
52
|
-
expect(result!.sourceName).toBeUndefined()
|
|
53
|
-
expect(result!.source).toBeUndefined()
|
|
54
|
-
expect(result!.compiler).toBeUndefined()
|
|
55
|
-
})
|
|
56
|
-
|
|
57
|
-
it('should return null for invalid JSON', () => {
|
|
58
|
-
const content = readFixture('invalid-json.txt')
|
|
59
|
-
const result = parseArtifact(content, '/test/invalid-json.txt')
|
|
60
|
-
|
|
61
|
-
expect(result).toBeNull()
|
|
62
|
-
})
|
|
63
|
-
|
|
64
|
-
it('should derive contractName from filename when missing', () => {
|
|
65
|
-
const content = readFixture('missing-contract-name.json')
|
|
66
|
-
const result = parseArtifact(content, '/test/missing-contract-name.json')
|
|
67
|
-
|
|
68
|
-
expect(result).not.toBeNull()
|
|
69
|
-
expect(result!.contractName).toBe('missing-contract-name')
|
|
70
|
-
})
|
|
71
|
-
|
|
72
|
-
it('should return null when abi is missing', () => {
|
|
73
|
-
const content = readFixture('missing-abi.json')
|
|
74
|
-
const result = parseArtifact(content, '/test/missing-abi.json')
|
|
75
|
-
|
|
76
|
-
expect(result).toBeNull()
|
|
77
|
-
})
|
|
78
|
-
|
|
79
|
-
it('should return null when bytecode is missing', () => {
|
|
80
|
-
const content = readFixture('missing-bytecode.json')
|
|
81
|
-
const result = parseArtifact(content, '/test/missing-bytecode.json')
|
|
82
|
-
|
|
83
|
-
expect(result).toBeNull()
|
|
84
|
-
})
|
|
85
|
-
|
|
86
|
-
it('should return null when bytecode does not start with 0x', () => {
|
|
87
|
-
const content = readFixture('invalid-bytecode.json')
|
|
88
|
-
const result = parseArtifact(content, '/test/invalid-bytecode.json')
|
|
89
|
-
|
|
90
|
-
expect(result).toBeNull()
|
|
91
|
-
})
|
|
92
|
-
|
|
93
|
-
it('should return null when bytecode is empty', () => {
|
|
94
|
-
const content = readFixture('empty-bytecode.json')
|
|
95
|
-
const result = parseArtifact(content, '/test/empty-bytecode.json')
|
|
96
|
-
|
|
97
|
-
expect(result).toBeNull()
|
|
98
|
-
})
|
|
99
|
-
|
|
100
|
-
it('should return null when fields have wrong types', () => {
|
|
101
|
-
const content = readFixture('wrong-types.json')
|
|
102
|
-
const result = parseArtifact(content, '/test/wrong-types.json')
|
|
103
|
-
|
|
104
|
-
expect(result).toBeNull()
|
|
105
|
-
})
|
|
106
|
-
|
|
107
|
-
it('should handle null input gracefully', () => {
|
|
108
|
-
const result = parseArtifact('null', '/test/null.json')
|
|
109
|
-
expect(result).toBeNull()
|
|
110
|
-
})
|
|
111
|
-
|
|
112
|
-
it('should handle empty string input gracefully', () => {
|
|
113
|
-
const result = parseArtifact('', '/test/empty.json')
|
|
114
|
-
expect(result).toBeNull()
|
|
115
|
-
})
|
|
116
|
-
})
|
|
117
|
-
})
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"contractName": "ERC20Token",
|
|
3
|
-
"sourceName": "contracts/ERC20Token.sol",
|
|
4
|
-
"abi": [
|
|
5
|
-
{
|
|
6
|
-
"type": "constructor",
|
|
7
|
-
"inputs": [
|
|
8
|
-
{
|
|
9
|
-
"name": "initialSupply",
|
|
10
|
-
"type": "uint256"
|
|
11
|
-
}
|
|
12
|
-
]
|
|
13
|
-
},
|
|
14
|
-
{
|
|
15
|
-
"type": "function",
|
|
16
|
-
"name": "balanceOf",
|
|
17
|
-
"inputs": [
|
|
18
|
-
{
|
|
19
|
-
"name": "account",
|
|
20
|
-
"type": "address"
|
|
21
|
-
}
|
|
22
|
-
],
|
|
23
|
-
"outputs": [
|
|
24
|
-
{
|
|
25
|
-
"name": "",
|
|
26
|
-
"type": "uint256"
|
|
27
|
-
}
|
|
28
|
-
],
|
|
29
|
-
"stateMutability": "view"
|
|
30
|
-
},
|
|
31
|
-
{
|
|
32
|
-
"type": "event",
|
|
33
|
-
"name": "Transfer",
|
|
34
|
-
"inputs": [
|
|
35
|
-
{
|
|
36
|
-
"name": "from",
|
|
37
|
-
"type": "address",
|
|
38
|
-
"indexed": true
|
|
39
|
-
},
|
|
40
|
-
{
|
|
41
|
-
"name": "to",
|
|
42
|
-
"type": "address",
|
|
43
|
-
"indexed": true
|
|
44
|
-
},
|
|
45
|
-
{
|
|
46
|
-
"name": "value",
|
|
47
|
-
"type": "uint256",
|
|
48
|
-
"indexed": false
|
|
49
|
-
}
|
|
50
|
-
]
|
|
51
|
-
}
|
|
52
|
-
],
|
|
53
|
-
"bytecode": {
|
|
54
|
-
"object": "0x608060405234801561001057600080fd5b50604051610abc380380610abc8339818101604052810190610032919061007a565b806000819055505061009e565b600080fd5b6000819050919050565b61005681610043565b811461006157600080fd5b50565b6000815190506100738161004d565b92915050565b60006020828403121561008f5761008e61003e565b5b600061009d84828501610064565b91505092915050565b610a0f806100ad6000396000f3fe608060405234801561001057600080fd5b50600436106100575760003560e01c806318160ddd1461005c57806370a0823114610078578063a9059cbb146100a8578063dd62ed3e146100c4575b600080fd5b6100646100f4565b60405161006f919061018a565b60405180910390f35b610092600480360381019061008d91906101d6565b6100fa565b60405161009f919061018a565b60405180910390f35b6100c260048036038101906100bd919061024f565b610142565b005b6100de60048036038101906100d9919061028f565b61015c565b6040516100eb919061018a565b60405180910390f35b60005481565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b600061014f338484610181565b905092915050565b5050565b600060016000858573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050929150505600a2646970667358221220",
|
|
55
|
-
"sourceMap": "123:456:0:-:0;;;789:100;;;;;;;;;;;;;;;;;:::i;:::-;;:::o;:::-;;;;;;;:::i;:::-;;:::o;8:123:-1;5:3;2:1;21:10;18:1;14:2;11:3;8:2;123:456:0;;;;;;;",
|
|
56
|
-
"linkReferences": {}
|
|
57
|
-
},
|
|
58
|
-
"deployedBytecode": {
|
|
59
|
-
"object": "0x608060405234801561001057600080fd5b50600436106100575760003560e01c806318160ddd1461005c57806370a0823114610078578063a9059cbb146100a8578063dd62ed3e146100c4575b600080fd5b6100646100f4565b60405161006f919061018a565b60405180910390f35b610092600480360381019061008d91906101d6565b6100fa565b60405161009f919061018a565b60405180910390f35b6100c260048036038101906100bd919061024f565b610142565b005b6100de60048036038101906100d9919061028f565b61015c565b6040516100eb919061018a565b60405180910390f35b60005481565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b600061014f338484610181565b905092915050565b5050565b600060016000858573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050929150505600a2646970667358221220",
|
|
60
|
-
"sourceMap": "123:456:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::o;:::-;;;;;;;:::i;:::-;;:::o;",
|
|
61
|
-
"linkReferences": {}
|
|
62
|
-
},
|
|
63
|
-
"compiler": {
|
|
64
|
-
"version": "0.8.19+commit.7dd6d404"
|
|
65
|
-
},
|
|
66
|
-
"source": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ncontract ERC20Token {\n mapping(address => uint256) private _balances;\n mapping(address => mapping(address => uint256)) private _allowances;\n uint256 private _totalSupply;\n \n constructor(uint256 initialSupply) {\n _totalSupply = initialSupply;\n _balances[msg.sender] = initialSupply;\n }\n \n function balanceOf(address account) public view returns (uint256) {\n return _balances[account];\n }\n}\n"
|
|
67
|
-
}
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"contractName": "SimpleToken",
|
|
3
|
-
"abi": [
|
|
4
|
-
{
|
|
5
|
-
"type": "constructor",
|
|
6
|
-
"inputs": [
|
|
7
|
-
{
|
|
8
|
-
"name": "name",
|
|
9
|
-
"type": "string"
|
|
10
|
-
},
|
|
11
|
-
{
|
|
12
|
-
"name": "symbol",
|
|
13
|
-
"type": "string"
|
|
14
|
-
}
|
|
15
|
-
]
|
|
16
|
-
},
|
|
17
|
-
{
|
|
18
|
-
"type": "function",
|
|
19
|
-
"name": "transfer",
|
|
20
|
-
"inputs": [
|
|
21
|
-
{
|
|
22
|
-
"name": "to",
|
|
23
|
-
"type": "address"
|
|
24
|
-
},
|
|
25
|
-
{
|
|
26
|
-
"name": "amount",
|
|
27
|
-
"type": "uint256"
|
|
28
|
-
}
|
|
29
|
-
],
|
|
30
|
-
"outputs": [
|
|
31
|
-
{
|
|
32
|
-
"name": "",
|
|
33
|
-
"type": "bool"
|
|
34
|
-
}
|
|
35
|
-
]
|
|
36
|
-
}
|
|
37
|
-
],
|
|
38
|
-
"bytecode": "0x608060405234801561001057600080fd5b506040516103e93803806103e98339818101604052810190610032919061007a565b80600090805190602001906100489291906100ad565b50506100fb565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6100a982610060565b810181811067ffffffffffffffff821117156100c8576100c7610071565b5b80604052505050565b60006100db6100a0565b90506100e782826100a0565b919050565b6000819050919050565b6100ff816100ec565b811461010a57600080fd5b50565b60008151905061011c816100f6565b92915050565b6000602082840312156101385761013761005b565b5b60006101468482850161010d565b91505092915050565b6102df8061015f6000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063a9059cbb1461003b578063dd62ed3e14610057575b600080fd5b61005560048036038101906100509190610123565b610087565b005b610071600480360381019061006c9190610163565b6100a1565b60405161007e91906101b2565b60405180910390f35b6000610094338484610121565b50505050565b50565b600082600082815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050929150505600a26469706673582212206a",
|
|
39
|
-
"deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100365760003560e01c8063a9059cbb1461003b578063dd62ed3e14610057575b600080fd5b61005560048036038101906100509190610123565b610087565b005b610071600480360381019061006c9190610163565b6100a1565b60405161007e91906101b2565b60405180910390f35b6000610094338484610121565b50505050565b50565b600082600082815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050929150505600a26469706673582212206a"
|
|
40
|
-
}
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
import { ArtifactParser } from './types'
|
|
2
|
-
import { Artifact } from '../../types'
|
|
3
|
-
import * as path from 'path'
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* A parser for Foundry 1.2+ artifact format.
|
|
7
|
-
* Can handle artifacts with or without explicit "contractName" field.
|
|
8
|
-
* If no contractName is present, it attempts to extract it from:
|
|
9
|
-
* 1. metadata.settings.compilationTarget
|
|
10
|
-
* 2. The filename as a fallback
|
|
11
|
-
*/
|
|
12
|
-
export const foundry12Parser: ArtifactParser = (content: string, filePath: string): Omit<Artifact, '_path' | '_hash'> | null => {
|
|
13
|
-
try {
|
|
14
|
-
const json = JSON.parse(content)
|
|
15
|
-
|
|
16
|
-
// Basic validation to see if it matches our expected structure
|
|
17
|
-
if (
|
|
18
|
-
typeof json === 'object' &&
|
|
19
|
-
json !== null &&
|
|
20
|
-
Array.isArray(json.abi) &&
|
|
21
|
-
(typeof json.bytecode === 'string' || (typeof json.bytecode === 'object' && typeof json.bytecode.object === 'string'))
|
|
22
|
-
) {
|
|
23
|
-
// Handle Hardhat-style bytecode object vs. simple string
|
|
24
|
-
const bytecode = typeof json.bytecode === 'object' ? json.bytecode.object : json.bytecode
|
|
25
|
-
if (!bytecode || !bytecode.startsWith('0x')) {
|
|
26
|
-
return null // Bytecode must be a hex string
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
const deployedBytecode = typeof json.deployedBytecode === 'object' ? json.deployedBytecode?.object : json.deployedBytecode
|
|
30
|
-
|
|
31
|
-
// Extract contract name from various sources
|
|
32
|
-
let contractName = json.contractName
|
|
33
|
-
|
|
34
|
-
// If no explicit contractName, prefer filename over metadata to match file-based lookups
|
|
35
|
-
if (!contractName && filePath) {
|
|
36
|
-
const basename = path.basename(filePath, '.json')
|
|
37
|
-
contractName = basename
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
// If still no contract name, try to extract from metadata as fallback
|
|
41
|
-
if (!contractName && json.metadata?.settings?.compilationTarget) {
|
|
42
|
-
const compilationTarget = json.metadata.settings.compilationTarget
|
|
43
|
-
// compilationTarget is like {"src/Counter.sol": "Counter"}
|
|
44
|
-
const contractNames = Object.values(compilationTarget)
|
|
45
|
-
if (contractNames.length > 0) {
|
|
46
|
-
contractName = contractNames[0]
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
// Must have a contract name to proceed
|
|
51
|
-
if (!contractName) {
|
|
52
|
-
return null
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
// We have a likely match
|
|
56
|
-
return {
|
|
57
|
-
contractName: contractName,
|
|
58
|
-
sourceName: json.sourceName,
|
|
59
|
-
abi: json.abi,
|
|
60
|
-
bytecode: bytecode,
|
|
61
|
-
deployedBytecode: deployedBytecode,
|
|
62
|
-
compiler: json.compiler,
|
|
63
|
-
source: json.source,
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
return null
|
|
68
|
-
} catch (error) {
|
|
69
|
-
// Not valid JSON, so it's not for this parser
|
|
70
|
-
return null
|
|
71
|
-
}
|
|
72
|
-
}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { ArtifactParser } from './types'
|
|
2
|
-
import { foundry12Parser } from './foundry-1.2'
|
|
3
|
-
import { Artifact } from '../../types'
|
|
4
|
-
|
|
5
|
-
// Array of all available artifact parsers.
|
|
6
|
-
// To add a new format, create a new parser and add it to this list.
|
|
7
|
-
const parsers: ArtifactParser[] = [
|
|
8
|
-
foundry12Parser,
|
|
9
|
-
// Future parsers (e.g., truffleParser) would go here.
|
|
10
|
-
]
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Attempts to parse a file's content using a series of registered parsers.
|
|
14
|
-
* Returns the first successfully parsed Artifact.
|
|
15
|
-
* @param content The raw string content of the file.
|
|
16
|
-
* @param filePath The path to the file being parsed.
|
|
17
|
-
* @returns A parsed Artifact object or null if no parser succeeds.
|
|
18
|
-
*/
|
|
19
|
-
export function parseArtifact(content: string, filePath: string): Omit<Artifact, '_path' | '_hash'> | null {
|
|
20
|
-
for (const parser of parsers) {
|
|
21
|
-
const result = parser(content, filePath)
|
|
22
|
-
if (result) {
|
|
23
|
-
return result
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
return null
|
|
27
|
-
}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { Artifact } from '../../types'
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* A function that attempts to parse a file's content into a standard Artifact object.
|
|
5
|
-
* @param content The raw string content of the file.
|
|
6
|
-
* @param filePath The path to the file being parsed.
|
|
7
|
-
* @returns An object conforming to the Artifact interface (without internal properties), or null if parsing fails.
|
|
8
|
-
*/
|
|
9
|
-
export type ArtifactParser = (content: string, filePath: string) => Omit<Artifact, '_path' | '_hash'> | null
|
|
@@ -1,127 +0,0 @@
|
|
|
1
|
-
import { createHash } from 'crypto'
|
|
2
|
-
import { keccak256, toUtf8Bytes } from 'ethers'
|
|
3
|
-
import { BuildInfo, ExtractedContract } from '../types'
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Validates if a parsed object is a valid build-info file
|
|
7
|
-
* Supports standard build-info formats and factory-style formats
|
|
8
|
-
*/
|
|
9
|
-
function isValidBuildInfo(data: any): data is BuildInfo {
|
|
10
|
-
return (
|
|
11
|
-
data &&
|
|
12
|
-
typeof data === 'object' &&
|
|
13
|
-
// _format field is optional (for factory-style formats)
|
|
14
|
-
(data._format === undefined || data._format === 'hh-sol-build-info-1' || data._format === 'ethers-rs-sol-build-info-1') &&
|
|
15
|
-
typeof data.id === 'string' &&
|
|
16
|
-
typeof data.solcVersion === 'string' &&
|
|
17
|
-
// solcLongVersion is optional (for factory-style formats)
|
|
18
|
-
(data.solcLongVersion === undefined || typeof data.solcLongVersion === 'string') &&
|
|
19
|
-
data.input &&
|
|
20
|
-
typeof data.input === 'object' &&
|
|
21
|
-
data.output &&
|
|
22
|
-
typeof data.output === 'object' &&
|
|
23
|
-
data.output.contracts &&
|
|
24
|
-
typeof data.output.contracts === 'object'
|
|
25
|
-
)
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Parses a build-info file and extracts individual contracts
|
|
30
|
-
* @param content The raw string content of the build-info file
|
|
31
|
-
* @param filePath The path to the build-info file
|
|
32
|
-
* @returns Array of extracted contracts or null if parsing fails
|
|
33
|
-
*/
|
|
34
|
-
export function parseBuildInfo(content: string, filePath: string): ExtractedContract[] | null {
|
|
35
|
-
try {
|
|
36
|
-
const data = JSON.parse(content)
|
|
37
|
-
|
|
38
|
-
if (!isValidBuildInfo(data)) {
|
|
39
|
-
return null
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
const extractedContracts: ExtractedContract[] = []
|
|
43
|
-
|
|
44
|
-
// Extract contracts from output.contracts
|
|
45
|
-
for (const [sourceName, sourceContracts] of Object.entries(data.output.contracts)) {
|
|
46
|
-
for (const [contractName, contractData] of Object.entries(sourceContracts)) {
|
|
47
|
-
// Validate contract data
|
|
48
|
-
if (!contractData.abi || !Array.isArray(contractData.abi)) {
|
|
49
|
-
continue
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
// Handle both Hardhat format (with 0x prefix) and ethers-rs format (without 0x prefix)
|
|
53
|
-
if (!contractData.evm?.bytecode?.object ||
|
|
54
|
-
(!contractData.evm.bytecode.object.startsWith('0x') && !/^[0-9a-fA-F]+$/.test(contractData.evm.bytecode.object))) {
|
|
55
|
-
continue
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
// Get source content if available
|
|
59
|
-
const sourceContent = data.input.sources[sourceName]?.content
|
|
60
|
-
|
|
61
|
-
// Normalize bytecode to ensure it has 0x prefix (required by the rest of the system)
|
|
62
|
-
const bytecode = contractData.evm.bytecode.object.startsWith('0x')
|
|
63
|
-
? contractData.evm.bytecode.object
|
|
64
|
-
: '0x' + contractData.evm.bytecode.object
|
|
65
|
-
|
|
66
|
-
const deployedBytecode = contractData.evm.deployedBytecode?.object
|
|
67
|
-
? (contractData.evm.deployedBytecode.object.startsWith('0x')
|
|
68
|
-
? contractData.evm.deployedBytecode.object
|
|
69
|
-
: '0x' + contractData.evm.deployedBytecode.object)
|
|
70
|
-
: undefined
|
|
71
|
-
|
|
72
|
-
// Create the extracted contract
|
|
73
|
-
const extractedContract: ExtractedContract = {
|
|
74
|
-
contractName,
|
|
75
|
-
sourceName,
|
|
76
|
-
fullyQualifiedName: `${sourceName}:${contractName}`,
|
|
77
|
-
abi: contractData.abi,
|
|
78
|
-
bytecode,
|
|
79
|
-
deployedBytecode,
|
|
80
|
-
source: sourceContent,
|
|
81
|
-
compiler: {
|
|
82
|
-
// Use solcLongVersion if available, otherwise fallback to solcVersion
|
|
83
|
-
version: data.solcLongVersion || data.solcVersion
|
|
84
|
-
},
|
|
85
|
-
buildInfoId: data.id,
|
|
86
|
-
buildInfoPath: filePath
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
extractedContracts.push(extractedContract)
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
return extractedContracts.length > 0 ? extractedContracts : null
|
|
94
|
-
|
|
95
|
-
} catch (error) {
|
|
96
|
-
// Not valid JSON or other parsing error
|
|
97
|
-
return null
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
/**
|
|
102
|
-
* Checks if a file path looks like a build-info file
|
|
103
|
-
* Follows the conventions: artifacts/build-info/*.json or out/build-info/*.json
|
|
104
|
-
*/
|
|
105
|
-
export function isBuildInfoFile(filePath: string): boolean {
|
|
106
|
-
// Standard build-info file patterns
|
|
107
|
-
if (filePath.includes('/build-info/') && filePath.endsWith('.json')) {
|
|
108
|
-
return true
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
return false
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
/**
|
|
115
|
-
* Converts an ExtractedContract to an Artifact-compatible format
|
|
116
|
-
*/
|
|
117
|
-
export function extractedContractToArtifact(extracted: ExtractedContract): Omit<import('../types').Artifact, '_path' | '_hash'> {
|
|
118
|
-
return {
|
|
119
|
-
contractName: extracted.contractName,
|
|
120
|
-
abi: extracted.abi,
|
|
121
|
-
bytecode: extracted.bytecode,
|
|
122
|
-
deployedBytecode: extracted.deployedBytecode,
|
|
123
|
-
sourceName: extracted.sourceName,
|
|
124
|
-
source: extracted.source,
|
|
125
|
-
compiler: extracted.compiler
|
|
126
|
-
}
|
|
127
|
-
}
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import { parse as parseYaml, YAMLParseError } from 'yaml'
|
|
2
|
-
import { ConstantsDocument } from '../types'
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Parses a YAML string defining a constants document into a structured ConstantsDocument.
|
|
6
|
-
* Accepts files with `type: "constants"`, optional `name`, and required `constants` object.
|
|
7
|
-
* Returns null if the YAML is not a constants document.
|
|
8
|
-
*/
|
|
9
|
-
export function parseConstants(yamlContent: string): ConstantsDocument | null {
|
|
10
|
-
let rawObject: any
|
|
11
|
-
try {
|
|
12
|
-
rawObject = parseYaml(yamlContent)
|
|
13
|
-
} catch (e) {
|
|
14
|
-
if (e instanceof YAMLParseError) {
|
|
15
|
-
const line = (e as any).linePos?.[0]?.line ? ` at line ${(e as any).linePos[0].line}` : ''
|
|
16
|
-
throw new Error(`Failed to parse constants YAML: ${e.message}${line}.`)
|
|
17
|
-
}
|
|
18
|
-
throw e
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
if (!rawObject || typeof rawObject !== 'object') {
|
|
22
|
-
return null
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
if (rawObject.type !== 'constants') {
|
|
26
|
-
return null
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
if (rawObject.name !== undefined && typeof rawObject.name !== 'string') {
|
|
30
|
-
throw new Error('Invalid constants: "name" must be a string if provided.')
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
if (!rawObject.constants || typeof rawObject.constants !== 'object' || Array.isArray(rawObject.constants)) {
|
|
34
|
-
throw new Error('Invalid constants: "constants" field is required and must be an object.')
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
const doc: ConstantsDocument = {
|
|
38
|
-
type: 'constants',
|
|
39
|
-
name: rawObject.name,
|
|
40
|
-
constants: rawObject.constants
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
return doc
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Validates and extracts optional job-level constants from a parsed job raw object.
|
|
48
|
-
* Throws if present but not an object.
|
|
49
|
-
*/
|
|
50
|
-
export function extractJobConstants(rawJob: any, jobNameForErrors: string): Record<string, any> | undefined {
|
|
51
|
-
if (rawJob.constants === undefined) return undefined
|
|
52
|
-
if (typeof rawJob.constants !== 'object' || Array.isArray(rawJob.constants)) {
|
|
53
|
-
throw new Error(`Invalid job "${jobNameForErrors}": "constants" field must be an object if provided.`)
|
|
54
|
-
}
|
|
55
|
-
return rawJob.constants as Record<string, any>
|
|
56
|
-
}
|