forge-pack 0.2.0 → 0.3.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/dist/cli.mjs +66 -14
- package/dist/{pack-Be_7Cz7w.mjs → codegen--WByOfZu.mjs} +68 -70
- package/dist/index.d.mts +15 -14
- package/dist/index.mjs +1 -1
- package/package.json +6 -4
package/dist/cli.mjs
CHANGED
|
@@ -1,10 +1,45 @@
|
|
|
1
|
-
import { i as
|
|
1
|
+
import { i as parseArtifact, n as resolveLibraries, r as findArtifact, t as generateDeployer } from "./codegen--WByOfZu.mjs";
|
|
2
2
|
import { parseArgs } from "node:util";
|
|
3
3
|
import { execSync } from "node:child_process";
|
|
4
|
-
import { mkdirSync, writeFileSync } from "node:fs";
|
|
4
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
5
5
|
import { join, resolve } from "node:path";
|
|
6
6
|
|
|
7
|
+
//#region src/deploy-helper.ts
|
|
8
|
+
const DEPLOY_HELPER_SOL = `// SPDX-License-Identifier: MIT
|
|
9
|
+
pragma solidity ^0.8.10;
|
|
10
|
+
|
|
11
|
+
library DeployHelper {
|
|
12
|
+
function deploy(bytes memory initcode, bytes32 salt) internal returns (address contractAddress) {
|
|
13
|
+
assembly ("memory-safe") {
|
|
14
|
+
contractAddress := create2(callvalue(), add(initcode, 32), mload(initcode), salt)
|
|
15
|
+
if iszero(contractAddress) {
|
|
16
|
+
let ptr := mload(0x40)
|
|
17
|
+
let errorSize := returndatasize()
|
|
18
|
+
returndatacopy(ptr, 0, errorSize)
|
|
19
|
+
revert(ptr, errorSize)
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function deploy(bytes memory initcode) internal returns (address contractAddress) {
|
|
25
|
+
contractAddress = deploy(initcode, bytes32(0));
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/// @dev Deploys a library using CREATE2 with zero salt.
|
|
29
|
+
/// If the library is already deployed (duplicate across contracts), returns the existing address.
|
|
30
|
+
function deployLibrary(bytes memory initcode) internal returns (address contractAddress) {
|
|
31
|
+
bytes32 salt = bytes32(0);
|
|
32
|
+
contractAddress = address(uint160(uint256(keccak256(abi.encodePacked(bytes1(0xff), address(this), salt, keccak256(initcode))))));
|
|
33
|
+
if (contractAddress.code.length > 0) return contractAddress;
|
|
34
|
+
contractAddress = deploy(initcode, salt);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
`;
|
|
38
|
+
|
|
39
|
+
//#endregion
|
|
7
40
|
//#region src/cli.ts
|
|
41
|
+
const pkgPath = new URL("../package.json", import.meta.url);
|
|
42
|
+
const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
|
|
8
43
|
const { values, positionals } = parseArgs({
|
|
9
44
|
allowPositionals: true,
|
|
10
45
|
options: {
|
|
@@ -20,11 +55,15 @@ const { values, positionals } = parseArgs({
|
|
|
20
55
|
type: "boolean",
|
|
21
56
|
default: false
|
|
22
57
|
},
|
|
23
|
-
solc: { type: "string" },
|
|
24
58
|
pragma: {
|
|
25
59
|
type: "string",
|
|
26
60
|
default: ">=0.8.0"
|
|
27
61
|
},
|
|
62
|
+
version: {
|
|
63
|
+
type: "boolean",
|
|
64
|
+
short: "v",
|
|
65
|
+
default: false
|
|
66
|
+
},
|
|
28
67
|
help: {
|
|
29
68
|
type: "boolean",
|
|
30
69
|
short: "h",
|
|
@@ -32,19 +71,22 @@ const { values, positionals } = parseArgs({
|
|
|
32
71
|
}
|
|
33
72
|
}
|
|
34
73
|
});
|
|
74
|
+
if (values.version) {
|
|
75
|
+
console.log(pkg.version);
|
|
76
|
+
process.exit(0);
|
|
77
|
+
}
|
|
35
78
|
if (values.help || positionals.length === 0) {
|
|
36
|
-
console.log(`Usage: forge-pack <ContractName
|
|
79
|
+
console.log(`Usage: forge-pack <ContractName...> [options]
|
|
37
80
|
|
|
38
81
|
Options:
|
|
39
82
|
--out <dir> Forge output directory (default: ./out)
|
|
40
|
-
--output <dir> Where to write the deployer .sol
|
|
83
|
+
--output <dir> Where to write the deployer .sol files (default: ./deployers)
|
|
41
84
|
--build Run \`forge build\` before reading artifacts
|
|
42
|
-
--
|
|
43
|
-
--
|
|
85
|
+
--pragma <range> Solidity pragma for generated files (default: >=0.8.0)
|
|
86
|
+
-v, --version Show version number
|
|
44
87
|
-h, --help Show this help message`);
|
|
45
88
|
process.exit(values.help ? 0 : 1);
|
|
46
89
|
}
|
|
47
|
-
const contractName = positionals[0];
|
|
48
90
|
const outDir = resolve(values.out);
|
|
49
91
|
const outputDir = resolve(values.output);
|
|
50
92
|
const pragma = values.pragma;
|
|
@@ -52,18 +94,27 @@ if (values.build) {
|
|
|
52
94
|
console.log("Running forge build...");
|
|
53
95
|
execSync("forge build", { stdio: "inherit" });
|
|
54
96
|
}
|
|
55
|
-
|
|
56
|
-
|
|
97
|
+
const utilsDir = join(outputDir, "utils");
|
|
98
|
+
const deployHelperPath = join(utilsDir, "DeployHelper.sol");
|
|
99
|
+
mkdirSync(utilsDir, { recursive: true });
|
|
100
|
+
if (!existsSync(deployHelperPath)) {
|
|
101
|
+
writeFileSync(deployHelperPath, DEPLOY_HELPER_SOL);
|
|
102
|
+
console.log(`Generated ${deployHelperPath}`);
|
|
103
|
+
}
|
|
104
|
+
let hasError = false;
|
|
105
|
+
for (const contractName of positionals) try {
|
|
106
|
+
const parsed = parseArtifact(findArtifact(contractName, outDir), contractName);
|
|
57
107
|
if (!parsed.bytecode) {
|
|
58
108
|
console.error(`Error: No bytecode found for "${contractName}". Is it an abstract contract or interface?`);
|
|
59
|
-
|
|
109
|
+
hasError = true;
|
|
110
|
+
continue;
|
|
60
111
|
}
|
|
61
112
|
const hasLinks = Object.keys(parsed.linkReferences).length > 0;
|
|
62
113
|
let libraries;
|
|
63
114
|
if (hasLinks) {
|
|
64
115
|
libraries = resolveLibraries(parsed.linkReferences, outDir);
|
|
65
116
|
const libNames = libraries.map((l) => l.lib);
|
|
66
|
-
console.log(`Resolved ${libNames.length} library dep(s): ${libNames.join(", ")}`);
|
|
117
|
+
console.log(`[${contractName}] Resolved ${libNames.length} library dep(s): ${libNames.join(", ")}`);
|
|
67
118
|
}
|
|
68
119
|
const solidity = generateDeployer(parsed, {
|
|
69
120
|
pragma,
|
|
@@ -74,9 +125,10 @@ try {
|
|
|
74
125
|
writeFileSync(outPath, solidity);
|
|
75
126
|
console.log(`Generated ${outPath}`);
|
|
76
127
|
} catch (err) {
|
|
77
|
-
console.error(`Error: ${err.message}`);
|
|
78
|
-
|
|
128
|
+
console.error(`Error [${contractName}]: ${err.message}`);
|
|
129
|
+
hasError = true;
|
|
79
130
|
}
|
|
131
|
+
if (hasError) process.exit(1);
|
|
80
132
|
|
|
81
133
|
//#endregion
|
|
82
134
|
export { };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { readFileSync, readdirSync, statSync } from "node:fs";
|
|
2
2
|
import { join } from "node:path";
|
|
3
3
|
|
|
4
|
-
//#region src/
|
|
5
|
-
function findArtifact(contractName, outDir
|
|
4
|
+
//#region src/artifact.ts
|
|
5
|
+
function findArtifact(contractName, outDir) {
|
|
6
6
|
const candidates = [];
|
|
7
7
|
const entries = readdirSync(outDir);
|
|
8
8
|
for (const entry of entries) {
|
|
@@ -15,11 +15,6 @@ function findArtifact(contractName, outDir, options) {
|
|
|
15
15
|
} catch {}
|
|
16
16
|
}
|
|
17
17
|
if (candidates.length === 0) throw new Error(`No artifact found for "${contractName}" in ${outDir}. Run \`forge build\` first.`);
|
|
18
|
-
if (options?.solcVersion && candidates.length > 1) {
|
|
19
|
-
for (const c of candidates) if ((JSON.parse(readFileSync(c, "utf-8"))?.metadata?.compiler?.version)?.startsWith(options.solcVersion)) return c;
|
|
20
|
-
throw new Error(`No artifact for "${contractName}" compiled with solc ${options.solcVersion}.`);
|
|
21
|
-
}
|
|
22
|
-
if (candidates.length > 1) throw new Error(`Multiple artifacts found for "${contractName}". Use --solc to disambiguate:\n` + candidates.map((c) => ` ${c}`).join("\n"));
|
|
23
18
|
return candidates[0];
|
|
24
19
|
}
|
|
25
20
|
function parseArtifact(artifactPath, contractName) {
|
|
@@ -34,6 +29,7 @@ function parseArtifact(artifactPath, contractName) {
|
|
|
34
29
|
const optimizerRuns = settings?.optimizer?.runs;
|
|
35
30
|
const viaIR = settings?.viaIR;
|
|
36
31
|
const evmVersion = settings?.evmVersion;
|
|
32
|
+
const bytecodeHash = metadata?.settings?.metadata?.bytecodeHash ?? settings?.metadata?.bytecodeHash;
|
|
37
33
|
let sourcePath;
|
|
38
34
|
if (metadata?.settings?.compilationTarget) {
|
|
39
35
|
const targets = metadata.settings.compilationTarget;
|
|
@@ -48,13 +44,13 @@ function parseArtifact(artifactPath, contractName) {
|
|
|
48
44
|
solcVersion,
|
|
49
45
|
optimizerRuns,
|
|
50
46
|
viaIR,
|
|
51
|
-
evmVersion
|
|
47
|
+
evmVersion,
|
|
48
|
+
bytecodeHash
|
|
52
49
|
};
|
|
53
50
|
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
*/
|
|
51
|
+
|
|
52
|
+
//#endregion
|
|
53
|
+
//#region src/resolve.ts
|
|
58
54
|
function collectLibIds(linkRefs) {
|
|
59
55
|
const seen = /* @__PURE__ */ new Set();
|
|
60
56
|
const result = [];
|
|
@@ -76,6 +72,7 @@ function makeParamName(libName) {
|
|
|
76
72
|
/**
|
|
77
73
|
* Recursively resolve all library dependencies for a contract's linkReferences.
|
|
78
74
|
* Returns libraries in topological order (deploy-order: leaves first).
|
|
75
|
+
* Disambiguates duplicate paramName values with numeric suffixes.
|
|
79
76
|
*/
|
|
80
77
|
function resolveLibraries(linkRefs, outDir) {
|
|
81
78
|
const resolved = /* @__PURE__ */ new Map();
|
|
@@ -105,8 +102,31 @@ function resolveLibraries(linkRefs, outDir) {
|
|
|
105
102
|
}
|
|
106
103
|
const topLevel = collectLibIds(linkRefs);
|
|
107
104
|
for (const { file, lib } of topLevel) resolve(file, lib);
|
|
108
|
-
|
|
105
|
+
const libs = Array.from(resolved.values());
|
|
106
|
+
const nameCount = /* @__PURE__ */ new Map();
|
|
107
|
+
for (const entry of libs) {
|
|
108
|
+
const count = nameCount.get(entry.paramName) ?? 0;
|
|
109
|
+
nameCount.set(entry.paramName, count + 1);
|
|
110
|
+
}
|
|
111
|
+
const collisions = /* @__PURE__ */ new Set();
|
|
112
|
+
for (const [name, count] of nameCount) if (count > 1) collisions.add(name);
|
|
113
|
+
if (collisions.size > 0) {
|
|
114
|
+
const nameIndex = /* @__PURE__ */ new Map();
|
|
115
|
+
for (const entry of libs) {
|
|
116
|
+
if (!collisions.has(entry.paramName)) continue;
|
|
117
|
+
const idx = (nameIndex.get(entry.paramName) ?? 0) + 1;
|
|
118
|
+
nameIndex.set(entry.paramName, idx);
|
|
119
|
+
if (idx > 1) entry.paramName = `${entry.paramName}${idx}`;
|
|
120
|
+
}
|
|
121
|
+
const keyToName = /* @__PURE__ */ new Map();
|
|
122
|
+
for (const entry of libs) keyToName.set(`${entry.file}:${entry.lib}`, entry.paramName);
|
|
123
|
+
for (const entry of libs) entry.deps = collectLibIds(entry.artifact.linkReferences).map((d) => keyToName.get(`${d.file}:${d.lib}`));
|
|
124
|
+
}
|
|
125
|
+
return libs;
|
|
109
126
|
}
|
|
127
|
+
|
|
128
|
+
//#endregion
|
|
129
|
+
//#region src/codegen.ts
|
|
110
130
|
function extractStructName(internalType) {
|
|
111
131
|
let name = internalType.replace(/^struct\s+/, "");
|
|
112
132
|
name = name.replace(/(\[\d*\])+$/, "");
|
|
@@ -216,13 +236,31 @@ function renderInitcodeBody(bytecode, segments, hasLinks) {
|
|
|
216
236
|
if (!hasLinks) return ` return hex"${bytecode}";`;
|
|
217
237
|
return ` return abi.encodePacked(${segments.map((seg) => seg.type === "hex" ? `hex"${seg.value}"` : seg.value).join(", ")});`;
|
|
218
238
|
}
|
|
239
|
+
function renderDeployBody(opts) {
|
|
240
|
+
const { inlineLibs, resolvedLibs, ctorParams, initcodeCallArgs } = opts;
|
|
241
|
+
const lines = [];
|
|
242
|
+
if (inlineLibs) for (const rlib of resolvedLibs) {
|
|
243
|
+
const { libParams: libLibParams } = buildBytecodeSegments(rlib.artifact.bytecode, rlib.artifact.linkReferences);
|
|
244
|
+
const callArgs = libLibParams.length > 0 ? libLibParams.map((lp) => lp.name).join(", ") : "";
|
|
245
|
+
lines.push(` address ${rlib.paramName} = DeployHelper.deployLibrary(_${rlib.paramName}Initcode(${callArgs}));`);
|
|
246
|
+
}
|
|
247
|
+
if (ctorParams.length > 0) {
|
|
248
|
+
const encodeArgs = ctorParams.map((p, i) => p.name || `arg${i}`).join(", ");
|
|
249
|
+
lines.push(` bytes memory args = abi.encode(${encodeArgs});`);
|
|
250
|
+
lines.push(` bytes memory initcode_ = abi.encodePacked(initcode(${initcodeCallArgs}), args);`);
|
|
251
|
+
} else lines.push(` bytes memory initcode_ = initcode(${initcodeCallArgs});`);
|
|
252
|
+
lines.push(` deployed = DeployHelper.deploy(initcode_, salt);`);
|
|
253
|
+
return lines.join("\n");
|
|
254
|
+
}
|
|
219
255
|
function generateDeployer(parsed, pragmaOrOpts) {
|
|
220
256
|
const opts = typeof pragmaOrOpts === "string" ? { pragma: pragmaOrOpts } : pragmaOrOpts ?? {};
|
|
221
257
|
const pragma = opts.pragma ?? ">=0.8.0";
|
|
222
258
|
const resolvedLibs = opts.libraries ?? [];
|
|
223
259
|
const { contractName, abi, bytecode, linkReferences } = parsed;
|
|
224
260
|
const libName = `${contractName}Deployer`;
|
|
225
|
-
const
|
|
261
|
+
const ctorEntry = abi.find((e) => e.type === "constructor");
|
|
262
|
+
const ctorParams = ctorEntry?.inputs ?? [];
|
|
263
|
+
const isPayable = ctorEntry?.stateMutability === "payable";
|
|
226
264
|
const structDefs = collectStructDefs(ctorParams);
|
|
227
265
|
const structNames = new Set(structDefs.map((s) => s.name));
|
|
228
266
|
const { segments: mainSegments, libParams: mainLibParams } = buildBytecodeSegments(bytecode, linkReferences);
|
|
@@ -232,8 +270,9 @@ function generateDeployer(parsed, pragmaOrOpts) {
|
|
|
232
270
|
if (parsed.sourcePath) metaLines.push(`@notice Source Contract: ${parsed.sourcePath}`);
|
|
233
271
|
if (parsed.solcVersion) metaLines.push(`- solc: ${parsed.solcVersion}`);
|
|
234
272
|
if (parsed.optimizerRuns !== void 0) metaLines.push(`- optimizer_runs: ${parsed.optimizerRuns}`);
|
|
235
|
-
|
|
273
|
+
metaLines.push(`- viaIR: ${parsed.viaIR ?? false}`);
|
|
236
274
|
if (parsed.evmVersion) metaLines.push(`- evm_version: ${parsed.evmVersion}`);
|
|
275
|
+
metaLines.push(`- bytecodeHash: ${parsed.bytecodeHash ?? "ipfs"}`);
|
|
237
276
|
const metaBlock = metaLines.length > 0 ? [
|
|
238
277
|
` /**`,
|
|
239
278
|
` * @dev autogenerated by forge-pack`,
|
|
@@ -258,74 +297,33 @@ function generateDeployer(parsed, pragmaOrOpts) {
|
|
|
258
297
|
const deployParams = [];
|
|
259
298
|
for (let i = 0; i < ctorParams.length; i++) deployParams.push(formatParamWithStructs(ctorParams[i], i, structNames));
|
|
260
299
|
if (hasLinks && !inlineLibs) for (const lp of mainLibParams) deployParams.push(`address ${lp.name}`);
|
|
261
|
-
const deployParamStr = deployParams.join(", ")
|
|
262
|
-
const deployBodyLines = [];
|
|
263
|
-
if (inlineLibs) for (const rlib of resolvedLibs) {
|
|
264
|
-
const { libParams: libLibParams } = buildBytecodeSegments(rlib.artifact.bytecode, rlib.artifact.linkReferences);
|
|
265
|
-
const callArgs = libLibParams.length > 0 ? libLibParams.map((lp) => lp.name).join(", ") : "";
|
|
266
|
-
deployBodyLines.push(` address ${rlib.paramName} = _create(_${rlib.paramName}Initcode(${callArgs}));`);
|
|
267
|
-
}
|
|
300
|
+
const deployParamStr = deployParams.length > 0 ? `${deployParams.join(", ")}, bytes32 salt` : `bytes32 salt`;
|
|
268
301
|
const initcodeCallArgs = hasLinks ? mainLibParams.map((lp) => lp.name).join(", ") : "";
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
}
|
|
278
|
-
const deployBody = deployBodyLines.join("\n");
|
|
279
|
-
const deploy2BodyLines = [];
|
|
280
|
-
if (inlineLibs) for (const rlib of resolvedLibs) {
|
|
281
|
-
const { libParams: libLibParams } = buildBytecodeSegments(rlib.artifact.bytecode, rlib.artifact.linkReferences);
|
|
282
|
-
const callArgs = libLibParams.length > 0 ? libLibParams.map((lp) => lp.name).join(", ") : "";
|
|
283
|
-
deploy2BodyLines.push(` address ${rlib.paramName} = _create(_${rlib.paramName}Initcode(${callArgs}));`);
|
|
284
|
-
}
|
|
285
|
-
if (ctorParams.length > 0) {
|
|
286
|
-
const encodeArgs = ctorParams.map((p, i) => p.name || `arg${i}`).join(", ");
|
|
287
|
-
deploy2BodyLines.push(` bytes memory args = abi.encode(${encodeArgs});`);
|
|
288
|
-
deploy2BodyLines.push(` bytes memory initcode_ = abi.encodePacked(initcode(${initcodeCallArgs}), args);`);
|
|
289
|
-
deploy2BodyLines.push(` deployed = _create2(initcode_, salt);`);
|
|
290
|
-
} else {
|
|
291
|
-
deploy2BodyLines.push(` bytes memory initcode_ = initcode(${initcodeCallArgs});`);
|
|
292
|
-
deploy2BodyLines.push(` deployed = _create2(initcode_, salt);`);
|
|
293
|
-
}
|
|
294
|
-
const deploy2Body = deploy2BodyLines.join("\n");
|
|
295
|
-
const deploy2Params = deployParams.length > 0 ? `${deployParamStr}, bytes32 salt` : `bytes32 salt`;
|
|
302
|
+
const payableModifier = isPayable ? " payable" : "";
|
|
303
|
+
const deployBody = renderDeployBody({
|
|
304
|
+
inlineLibs,
|
|
305
|
+
resolvedLibs,
|
|
306
|
+
ctorParams,
|
|
307
|
+
initcodeCallArgs,
|
|
308
|
+
isPayable
|
|
309
|
+
});
|
|
296
310
|
return `// SPDX-License-Identifier: MIT
|
|
297
311
|
pragma solidity ${pragma};
|
|
298
312
|
|
|
313
|
+
import {DeployHelper} from "./utils/DeployHelper.sol";
|
|
314
|
+
|
|
299
315
|
library ${libName} {
|
|
300
316
|
${metaBlock}${structBlock ? `\n${structBlock}\n` : ""}
|
|
301
|
-
function deploy(${deployParamStr}) internal returns (address deployed) {
|
|
317
|
+
function deploy(${deployParamStr}) internal${payableModifier} returns (address deployed) {
|
|
302
318
|
${deployBody}
|
|
303
319
|
}
|
|
304
320
|
|
|
305
|
-
function deploy2(${deploy2Params}) internal returns (address deployed) {
|
|
306
|
-
${deploy2Body}
|
|
307
|
-
}
|
|
308
|
-
|
|
309
321
|
function initcode(${initcodeParams}) internal pure returns (bytes memory) {
|
|
310
322
|
${initcodeBody}
|
|
311
323
|
}
|
|
312
|
-
${libInitcodeFns.length > 0 ? "\n" + libInitcodeFns.join("\n\n") + "\n" : ""}
|
|
313
|
-
function _create(bytes memory initcode_) private returns (address deployed) {
|
|
314
|
-
assembly {
|
|
315
|
-
deployed := create(0, add(initcode_, 0x20), mload(initcode_))
|
|
316
|
-
if iszero(deployed) { revert(0, returndatasize()) }
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
function _create2(bytes memory initcode_, bytes32 salt) private returns (address deployed) {
|
|
321
|
-
assembly {
|
|
322
|
-
deployed := create2(0, add(initcode_, 0x20), mload(initcode_), salt)
|
|
323
|
-
if iszero(deployed) { revert(0, returndatasize()) }
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
|
-
}
|
|
324
|
+
${libInitcodeFns.length > 0 ? "\n" + libInitcodeFns.join("\n\n") + "\n" : ""}}
|
|
327
325
|
`;
|
|
328
326
|
}
|
|
329
327
|
|
|
330
328
|
//#endregion
|
|
331
|
-
export {
|
|
329
|
+
export { parseArtifact as i, resolveLibraries as n, findArtifact as r, generateDeployer as t };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
//#region src/
|
|
1
|
+
//#region src/types.d.ts
|
|
2
2
|
interface LinkReference {
|
|
3
3
|
start: number;
|
|
4
4
|
length: number;
|
|
@@ -32,14 +32,8 @@ interface ParsedArtifact {
|
|
|
32
32
|
optimizerRuns?: number;
|
|
33
33
|
viaIR?: boolean;
|
|
34
34
|
evmVersion?: string;
|
|
35
|
+
bytecodeHash?: string;
|
|
35
36
|
}
|
|
36
|
-
interface FindArtifactOptions {
|
|
37
|
-
solcVersion?: string;
|
|
38
|
-
}
|
|
39
|
-
/**
|
|
40
|
-
* A library dependency resolved from linkReferences, with its own parsed
|
|
41
|
-
* artifact and the param name used in generated code.
|
|
42
|
-
*/
|
|
43
37
|
interface ResolvedLibrary {
|
|
44
38
|
/** Parameter-style name, e.g. "mathLib" */
|
|
45
39
|
paramName: string;
|
|
@@ -52,17 +46,24 @@ interface ResolvedLibrary {
|
|
|
52
46
|
/** Param names of libraries this library depends on (its own linkReferences) */
|
|
53
47
|
deps: string[];
|
|
54
48
|
}
|
|
55
|
-
|
|
49
|
+
interface GenerateDeployerOptions {
|
|
50
|
+
pragma?: string;
|
|
51
|
+
libraries?: ResolvedLibrary[];
|
|
52
|
+
}
|
|
53
|
+
//#endregion
|
|
54
|
+
//#region src/artifact.d.ts
|
|
55
|
+
declare function findArtifact(contractName: string, outDir: string): string;
|
|
56
56
|
declare function parseArtifact(artifactPath: string, contractName: string): ParsedArtifact;
|
|
57
|
+
//#endregion
|
|
58
|
+
//#region src/resolve.d.ts
|
|
57
59
|
/**
|
|
58
60
|
* Recursively resolve all library dependencies for a contract's linkReferences.
|
|
59
61
|
* Returns libraries in topological order (deploy-order: leaves first).
|
|
62
|
+
* Disambiguates duplicate paramName values with numeric suffixes.
|
|
60
63
|
*/
|
|
61
64
|
declare function resolveLibraries(linkRefs: LinkReferences, outDir: string): ResolvedLibrary[];
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
libraries?: ResolvedLibrary[];
|
|
65
|
-
}
|
|
65
|
+
//#endregion
|
|
66
|
+
//#region src/codegen.d.ts
|
|
66
67
|
declare function generateDeployer(parsed: ParsedArtifact, pragmaOrOpts?: string | GenerateDeployerOptions): string;
|
|
67
68
|
//#endregion
|
|
68
|
-
export { type AbiEntry, type AbiParam, type
|
|
69
|
+
export { type AbiEntry, type AbiParam, type GenerateDeployerOptions, type LinkReference, type LinkReferences, type ParsedArtifact, type ResolvedLibrary, findArtifact, generateDeployer, parseArtifact, resolveLibraries };
|
package/dist/index.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { i as
|
|
1
|
+
import { i as parseArtifact, n as resolveLibraries, r as findArtifact, t as generateDeployer } from "./codegen--WByOfZu.mjs";
|
|
2
2
|
|
|
3
3
|
export { findArtifact, generateDeployer, parseArtifact, resolveLibraries };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "forge-pack",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Generate self-contained Solidity deployer files from Forge build artifacts",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -34,9 +34,10 @@
|
|
|
34
34
|
"@changesets/changelog-github": "^0.5.2",
|
|
35
35
|
"@changesets/cli": "^2.29.8",
|
|
36
36
|
"@changesets/config": "^3.1.2",
|
|
37
|
+
"@types/node": "^24.10.13",
|
|
38
|
+
"prettier": "^3.8.1",
|
|
37
39
|
"tsdown": "^0.20.3",
|
|
38
|
-
"typescript": "^5.
|
|
39
|
-
"@types/node": "^24.10.13"
|
|
40
|
+
"typescript": "^5.9.3"
|
|
40
41
|
},
|
|
41
42
|
"publishConfig": {
|
|
42
43
|
"access": "public"
|
|
@@ -46,6 +47,7 @@
|
|
|
46
47
|
"dev": "tsdown --watch",
|
|
47
48
|
"changeset": "changeset",
|
|
48
49
|
"version": "changeset version",
|
|
49
|
-
"release": "changeset publish"
|
|
50
|
+
"release": "changeset publish",
|
|
51
|
+
"format": "prettier --write \"**/*.{ts,tsx,md,json}\""
|
|
50
52
|
}
|
|
51
53
|
}
|