hardhat-external-artifacts 0.0.5 → 0.0.6
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/dist/artifacts/converter.d.ts +4 -2
- package/dist/artifacts/converter.d.ts.map +1 -1
- package/dist/artifacts/converter.js +225 -181
- package/dist/artifacts/converter.js.map +1 -1
- package/dist/artifacts/types.d.ts +20 -2
- package/dist/artifacts/types.d.ts.map +1 -1
- package/dist/artifacts/types.js +19 -3
- package/dist/artifacts/types.js.map +1 -1
- package/dist/hooks/network.js +3 -3
- package/dist/hooks/network.js.map +1 -1
- package/package.json +6 -3
- package/src/artifacts/converter.test.ts +294 -0
- package/src/artifacts/converter.ts +260 -205
- package/src/artifacts/types.ts +26 -4
- package/src/hooks/network.ts +3 -3
package/dist/artifacts/types.js
CHANGED
|
@@ -1,7 +1,23 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Type guard to check if an artifact
|
|
2
|
+
* Type guard to check if an artifact has solcInput.
|
|
3
|
+
* Note: The converter now handles artifacts flexibly, extracting
|
|
4
|
+
* available data from solcInput, metadata, or evm fields without
|
|
5
|
+
* requiring a strict "rich" vs "simple" classification.
|
|
3
6
|
*/
|
|
4
|
-
export function
|
|
5
|
-
return 'solcInput' in artifact && artifact.solcInput
|
|
7
|
+
export function hasSolcInput(artifact) {
|
|
8
|
+
return 'solcInput' in artifact && typeof artifact.solcInput === 'string';
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Type guard to check if an artifact has metadata.
|
|
12
|
+
* Metadata can be used as a fallback for compiler settings when solcInput is not available.
|
|
13
|
+
*/
|
|
14
|
+
export function hasMetadata(artifact) {
|
|
15
|
+
return 'metadata' in artifact && typeof artifact.metadata === 'string';
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Type guard to check if an artifact has EVM data.
|
|
19
|
+
*/
|
|
20
|
+
export function hasEvmData(artifact) {
|
|
21
|
+
return 'evm' in artifact && artifact.evm !== undefined;
|
|
6
22
|
}
|
|
7
23
|
//# sourceMappingURL=types.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/artifacts/types.ts"],"names":[],"mappings":"AAoFA
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/artifacts/types.ts"],"names":[],"mappings":"AAoFA;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAC3B,QAA0B;IAE1B,OAAO,WAAW,IAAI,QAAQ,IAAI,OAAQ,QAAyB,CAAC,SAAS,KAAK,QAAQ,CAAC;AAC5F,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,WAAW,CAC1B,QAA0B;IAE1B,OAAO,UAAU,IAAI,QAAQ,IAAI,OAAQ,QAAyB,CAAC,QAAQ,KAAK,QAAQ,CAAC;AAC1F,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,UAAU,CACzB,QAA0B;IAE1B,OAAO,KAAK,IAAI,QAAQ,IAAK,QAAyB,CAAC,GAAG,KAAK,SAAS,CAAC;AAC1E,CAAC"}
|
package/dist/hooks/network.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ArtifactLoader } from '../artifacts/loader.js';
|
|
2
2
|
import { artifactsToCompilations, } from '../artifacts/converter.js';
|
|
3
|
-
import {
|
|
3
|
+
import { hasSolcInput } from '../artifacts/types.js';
|
|
4
4
|
export default async () => {
|
|
5
5
|
const handlers = {
|
|
6
6
|
newConnection: async (context, next) => {
|
|
@@ -28,9 +28,9 @@ export default async () => {
|
|
|
28
28
|
}
|
|
29
29
|
log(`[hardhat-external-artifacts] Loaded ${artifacts.length} artifact(s):`);
|
|
30
30
|
for (const artifact of artifacts) {
|
|
31
|
-
const
|
|
31
|
+
const hasSolc = hasSolcInput(artifact);
|
|
32
32
|
const deployedBytecodeLength = artifact.deployedBytecode?.length || 0;
|
|
33
|
-
log(` - ${artifact.sourceName}:${artifact.contractName} (${
|
|
33
|
+
log(` - ${artifact.sourceName}:${artifact.contractName} (${hasSolc ? 'with solcInput' : 'minimal'}, deployedBytecode: ${deployedBytecodeLength} chars)`);
|
|
34
34
|
}
|
|
35
35
|
// Convert to compilation format(s)
|
|
36
36
|
// Rich artifacts with solcInput get their own compilations
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"network.js","sourceRoot":"","sources":["../../src/hooks/network.ts"],"names":[],"mappings":"AAEA,OAAO,EAAC,cAAc,EAAC,MAAM,wBAAwB,CAAC;AACtD,OAAO,EACN,uBAAuB,GAEvB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAC,
|
|
1
|
+
{"version":3,"file":"network.js","sourceRoot":"","sources":["../../src/hooks/network.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hardhat-external-artifacts",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.6",
|
|
4
4
|
"description": "Hardhat plugin that allow hardhat to know about them",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"hardhat",
|
|
@@ -48,7 +48,8 @@
|
|
|
48
48
|
"prettier": "^3.8.1",
|
|
49
49
|
"rimraf": "^6.1.3",
|
|
50
50
|
"set-defaults": "^0.0.5",
|
|
51
|
-
"typescript": "^5.9.3"
|
|
51
|
+
"typescript": "^5.9.3",
|
|
52
|
+
"vitest": "^4.0.18"
|
|
52
53
|
},
|
|
53
54
|
"peerDependencies": {
|
|
54
55
|
"hardhat": "^3.1.8"
|
|
@@ -60,6 +61,8 @@
|
|
|
60
61
|
},
|
|
61
62
|
"scripts": {
|
|
62
63
|
"build": "tsc --project tsconfig.json",
|
|
63
|
-
"dev": "as-soon -w src pnpm build"
|
|
64
|
+
"dev": "as-soon -w src pnpm build",
|
|
65
|
+
"test": "vitest run",
|
|
66
|
+
"test:watch": "vitest"
|
|
64
67
|
}
|
|
65
68
|
}
|
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
import {describe, it, expect} from 'vitest';
|
|
2
|
+
import {artifactsToCompilations} from './converter.js';
|
|
3
|
+
import type {ExternalArtifact, RichArtifact} from './types.js';
|
|
4
|
+
import {hasSolcInput, hasMetadata, hasEvmData} from './types.js';
|
|
5
|
+
|
|
6
|
+
// Helper to create a minimal artifact
|
|
7
|
+
function createMinimalArtifact(
|
|
8
|
+
name: string,
|
|
9
|
+
sourceName: string = `contracts/${name}.sol`,
|
|
10
|
+
): ExternalArtifact {
|
|
11
|
+
return {
|
|
12
|
+
contractName: name,
|
|
13
|
+
sourceName,
|
|
14
|
+
abi: [{type: 'function', name: 'test', inputs: [], outputs: []}],
|
|
15
|
+
bytecode: '0x608060405234801561001057600080fd5b50',
|
|
16
|
+
deployedBytecode: '0x608060405234801561001057600080fd5b50',
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// Helper to create a rich artifact with solcInput
|
|
21
|
+
function createRichArtifactWithSolcInput(
|
|
22
|
+
name: string,
|
|
23
|
+
sourceName: string = `contracts/${name}.sol`,
|
|
24
|
+
): RichArtifact {
|
|
25
|
+
const solcInput = JSON.stringify({
|
|
26
|
+
language: 'Solidity',
|
|
27
|
+
sources: {[sourceName]: {content: `contract ${name} {}`}},
|
|
28
|
+
settings: {
|
|
29
|
+
optimizer: {enabled: true, runs: 200},
|
|
30
|
+
outputSelection: {'*': {'*': ['abi', 'evm.bytecode']}},
|
|
31
|
+
},
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
const metadata = JSON.stringify({
|
|
35
|
+
compiler: {version: '0.8.20+commit.a1b79de6'},
|
|
36
|
+
language: 'Solidity',
|
|
37
|
+
settings: {
|
|
38
|
+
optimizer: {enabled: true, runs: 200},
|
|
39
|
+
},
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
return {
|
|
43
|
+
...createMinimalArtifact(name, sourceName),
|
|
44
|
+
solcInput,
|
|
45
|
+
metadata,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Helper to create an artifact with only metadata (no solcInput)
|
|
50
|
+
function createArtifactWithMetadata(
|
|
51
|
+
name: string,
|
|
52
|
+
sourceName: string = `contracts/${name}.sol`,
|
|
53
|
+
): RichArtifact {
|
|
54
|
+
const metadata = JSON.stringify({
|
|
55
|
+
compiler: {version: '0.8.19+commit.7dd6d404'},
|
|
56
|
+
language: 'Solidity',
|
|
57
|
+
settings: {
|
|
58
|
+
optimizer: {enabled: false},
|
|
59
|
+
evmVersion: 'paris',
|
|
60
|
+
},
|
|
61
|
+
sources: {[sourceName]: {keccak256: '0x1234'}},
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
return {
|
|
65
|
+
...createMinimalArtifact(name, sourceName),
|
|
66
|
+
metadata,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Helper to create an artifact with EVM data
|
|
71
|
+
function createArtifactWithEvmData(
|
|
72
|
+
name: string,
|
|
73
|
+
sourceName: string = `contracts/${name}.sol`,
|
|
74
|
+
): RichArtifact {
|
|
75
|
+
return {
|
|
76
|
+
...createMinimalArtifact(name, sourceName),
|
|
77
|
+
evm: {
|
|
78
|
+
bytecode: {
|
|
79
|
+
object: '608060405234801561001057600080fd5b50',
|
|
80
|
+
opcodes: 'PUSH1 0x80 PUSH1 0x40 MSTORE',
|
|
81
|
+
sourceMap: '1:100:0:-:0;',
|
|
82
|
+
linkReferences: {},
|
|
83
|
+
generatedSources: [],
|
|
84
|
+
},
|
|
85
|
+
deployedBytecode: {
|
|
86
|
+
object: '608060405234801561001057600080fd5b50',
|
|
87
|
+
opcodes: 'PUSH1 0x80 PUSH1 0x40 MSTORE',
|
|
88
|
+
sourceMap: '1:100:0:-:0;',
|
|
89
|
+
linkReferences: {},
|
|
90
|
+
immutableReferences: {
|
|
91
|
+
'42': [{start: 10, length: 32}],
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
},
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
describe('Type Guards', () => {
|
|
99
|
+
describe('hasSolcInput', () => {
|
|
100
|
+
it('returns true for artifacts with solcInput string', () => {
|
|
101
|
+
const artifact = createRichArtifactWithSolcInput('TestContract');
|
|
102
|
+
expect(hasSolcInput(artifact)).toBe(true);
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
it('returns false for artifacts without solcInput', () => {
|
|
106
|
+
const artifact = createMinimalArtifact('TestContract');
|
|
107
|
+
expect(hasSolcInput(artifact)).toBe(false);
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
it('returns false for artifacts with undefined solcInput', () => {
|
|
111
|
+
const artifact: RichArtifact = {
|
|
112
|
+
...createMinimalArtifact('TestContract'),
|
|
113
|
+
solcInput: undefined,
|
|
114
|
+
};
|
|
115
|
+
expect(hasSolcInput(artifact)).toBe(false);
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
describe('hasMetadata', () => {
|
|
120
|
+
it('returns true for artifacts with metadata string', () => {
|
|
121
|
+
const artifact = createArtifactWithMetadata('TestContract');
|
|
122
|
+
expect(hasMetadata(artifact)).toBe(true);
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
it('returns false for artifacts without metadata', () => {
|
|
126
|
+
const artifact = createMinimalArtifact('TestContract');
|
|
127
|
+
expect(hasMetadata(artifact)).toBe(false);
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
describe('hasEvmData', () => {
|
|
132
|
+
it('returns true for artifacts with EVM data', () => {
|
|
133
|
+
const artifact = createArtifactWithEvmData('TestContract');
|
|
134
|
+
expect(hasEvmData(artifact)).toBe(true);
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
it('returns false for artifacts without EVM data', () => {
|
|
138
|
+
const artifact = createMinimalArtifact('TestContract');
|
|
139
|
+
expect(hasEvmData(artifact)).toBe(false);
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
describe('artifactsToCompilations', () => {
|
|
145
|
+
it('processes minimal artifacts using default compilation', () => {
|
|
146
|
+
const artifacts = [
|
|
147
|
+
createMinimalArtifact('Contract1'),
|
|
148
|
+
createMinimalArtifact('Contract2'),
|
|
149
|
+
];
|
|
150
|
+
|
|
151
|
+
const compilations = artifactsToCompilations(artifacts, '0.8.20');
|
|
152
|
+
|
|
153
|
+
expect(compilations.length).toBe(1);
|
|
154
|
+
expect(compilations[0].solcVersion).toBe('0.8.20');
|
|
155
|
+
expect(Object.keys(compilations[0].compilerOutput.contracts)).toHaveLength(2);
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
it('extracts version from metadata when solcInput is available', () => {
|
|
159
|
+
const artifact = createRichArtifactWithSolcInput('TestContract');
|
|
160
|
+
const compilations = artifactsToCompilations([artifact], '0.8.15');
|
|
161
|
+
|
|
162
|
+
expect(compilations.length).toBe(1);
|
|
163
|
+
// Should use version from metadata (0.8.20) not default (0.8.15)
|
|
164
|
+
expect(compilations[0].solcVersion).toBe('0.8.20');
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
it('uses metadata for compiler settings when solcInput is missing', () => {
|
|
168
|
+
const artifact = createArtifactWithMetadata('TestContract');
|
|
169
|
+
const compilations = artifactsToCompilations([artifact], '0.8.15');
|
|
170
|
+
|
|
171
|
+
expect(compilations.length).toBe(1);
|
|
172
|
+
// Should use version from metadata (0.8.19)
|
|
173
|
+
expect(compilations[0].solcVersion).toBe('0.8.19');
|
|
174
|
+
// Should have evmVersion from metadata settings
|
|
175
|
+
expect(compilations[0].compilerInput.settings.evmVersion).toBe('paris');
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
it('uses default solcVersion when no metadata is available', () => {
|
|
179
|
+
const artifact = createMinimalArtifact('TestContract');
|
|
180
|
+
const compilations = artifactsToCompilations([artifact], '0.8.15');
|
|
181
|
+
|
|
182
|
+
expect(compilations.length).toBe(1);
|
|
183
|
+
expect(compilations[0].solcVersion).toBe('0.8.15');
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
it('groups artifacts with same compilation context', () => {
|
|
187
|
+
// Two artifacts with the same solcInput settings should be grouped
|
|
188
|
+
const artifact1 = createRichArtifactWithSolcInput('Contract1');
|
|
189
|
+
const artifact2 = createRichArtifactWithSolcInput('Contract2');
|
|
190
|
+
|
|
191
|
+
const compilations = artifactsToCompilations([artifact1, artifact2], '0.8.20');
|
|
192
|
+
|
|
193
|
+
expect(compilations.length).toBe(1);
|
|
194
|
+
const sourcesInCompilation = Object.keys(compilations[0].compilerOutput.contracts);
|
|
195
|
+
expect(sourcesInCompilation).toContain('contracts/Contract1.sol');
|
|
196
|
+
expect(sourcesInCompilation).toContain('contracts/Contract2.sol');
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
it('separates artifacts with different compilation contexts', () => {
|
|
200
|
+
const richArtifact = createRichArtifactWithSolcInput('RichContract');
|
|
201
|
+
const minimalArtifact = createMinimalArtifact('MinimalContract');
|
|
202
|
+
|
|
203
|
+
const compilations = artifactsToCompilations(
|
|
204
|
+
[richArtifact, minimalArtifact],
|
|
205
|
+
'0.8.20',
|
|
206
|
+
);
|
|
207
|
+
|
|
208
|
+
// Should have 2 compilations: one for solcInput-based, one for default
|
|
209
|
+
expect(compilations.length).toBe(2);
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
it('extracts immutableReferences from evm data', () => {
|
|
213
|
+
const artifact = createArtifactWithEvmData('TestContract');
|
|
214
|
+
const compilations = artifactsToCompilations([artifact], '0.8.20');
|
|
215
|
+
|
|
216
|
+
expect(compilations.length).toBe(1);
|
|
217
|
+
const contract =
|
|
218
|
+
compilations[0].compilerOutput.contracts['contracts/TestContract.sol'][
|
|
219
|
+
'TestContract'
|
|
220
|
+
];
|
|
221
|
+
expect(contract.evm.deployedBytecode.immutableReferences).toEqual({
|
|
222
|
+
'42': [{start: 10, length: 32}],
|
|
223
|
+
});
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
it('handles artifacts with different source names in same compilation', () => {
|
|
227
|
+
const artifact1 = createMinimalArtifact('Contract1', 'src/Contract1.sol');
|
|
228
|
+
const artifact2 = createMinimalArtifact('Contract2', 'lib/Contract2.sol');
|
|
229
|
+
|
|
230
|
+
const compilations = artifactsToCompilations([artifact1, artifact2], '0.8.20');
|
|
231
|
+
|
|
232
|
+
expect(compilations.length).toBe(1);
|
|
233
|
+
expect(compilations[0].compilerOutput.contracts['src/Contract1.sol']).toBeDefined();
|
|
234
|
+
expect(compilations[0].compilerOutput.contracts['lib/Contract2.sol']).toBeDefined();
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
it('creates valid AST with contract nodes', () => {
|
|
238
|
+
const artifact = createMinimalArtifact('TestContract');
|
|
239
|
+
const compilations = artifactsToCompilations([artifact], '0.8.20');
|
|
240
|
+
|
|
241
|
+
const ast = compilations[0].compilerOutput.sources['contracts/TestContract.sol'].ast as any;
|
|
242
|
+
expect(ast.nodeType).toBe('SourceUnit');
|
|
243
|
+
expect(ast.nodes).toHaveLength(1);
|
|
244
|
+
expect(ast.nodes[0].nodeType).toBe('ContractDefinition');
|
|
245
|
+
expect(ast.nodes[0].name).toBe('TestContract');
|
|
246
|
+
});
|
|
247
|
+
|
|
248
|
+
it('strips 0x prefix from bytecode', () => {
|
|
249
|
+
const artifact = createMinimalArtifact('TestContract');
|
|
250
|
+
const compilations = artifactsToCompilations([artifact], '0.8.20');
|
|
251
|
+
|
|
252
|
+
const contract =
|
|
253
|
+
compilations[0].compilerOutput.contracts['contracts/TestContract.sol'][
|
|
254
|
+
'TestContract'
|
|
255
|
+
];
|
|
256
|
+
expect(contract.evm.bytecode.object).not.toMatch(/^0x/);
|
|
257
|
+
expect(contract.evm.deployedBytecode.object).not.toMatch(/^0x/);
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
it('provides empty methodIdentifiers for EDR compatibility', () => {
|
|
261
|
+
const artifact = createMinimalArtifact('TestContract');
|
|
262
|
+
const compilations = artifactsToCompilations([artifact], '0.8.20');
|
|
263
|
+
|
|
264
|
+
const contract =
|
|
265
|
+
compilations[0].compilerOutput.contracts['contracts/TestContract.sol'][
|
|
266
|
+
'TestContract'
|
|
267
|
+
];
|
|
268
|
+
expect(contract.evm.methodIdentifiers).toEqual({});
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
it('handles malformed solcInput gracefully', () => {
|
|
272
|
+
const artifact: RichArtifact = {
|
|
273
|
+
...createMinimalArtifact('TestContract'),
|
|
274
|
+
solcInput: 'not valid json',
|
|
275
|
+
};
|
|
276
|
+
|
|
277
|
+
// Should not throw, should fall back to default compilation
|
|
278
|
+
const compilations = artifactsToCompilations([artifact], '0.8.20');
|
|
279
|
+
expect(compilations.length).toBe(1);
|
|
280
|
+
expect(compilations[0].solcVersion).toBe('0.8.20');
|
|
281
|
+
});
|
|
282
|
+
|
|
283
|
+
it('handles malformed metadata gracefully', () => {
|
|
284
|
+
const artifact: RichArtifact = {
|
|
285
|
+
...createMinimalArtifact('TestContract'),
|
|
286
|
+
metadata: 'not valid json',
|
|
287
|
+
};
|
|
288
|
+
|
|
289
|
+
// Should not throw, should fall back to default compilation
|
|
290
|
+
const compilations = artifactsToCompilations([artifact], '0.8.20');
|
|
291
|
+
expect(compilations.length).toBe(1);
|
|
292
|
+
expect(compilations[0].solcVersion).toBe('0.8.20');
|
|
293
|
+
});
|
|
294
|
+
});
|