quantumcoin 7.0.1 → 7.0.3
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/.gitignore +3 -0
- package/README-SDK.md +64 -10
- package/README.md +27 -4
- package/SPEC.md +3843 -0
- package/examples/AllSolidityTypes.sol +184 -0
- package/examples/SimpleIERC20.sol +74 -0
- package/examples/example-generator-sdk-js.js +95 -0
- package/examples/example-generator-sdk-ts.js +95 -0
- package/examples/example.js +2 -2
- package/examples/offline-signing.js +73 -0
- package/examples/package-lock.json +10 -1103
- package/examples/package.json +1 -2
- package/examples/read-operations.js +1 -2
- package/examples/sdk-generator-erc20.inline.json +251 -0
- package/examples/solidity-types.ts +43 -0
- package/generate-sdk.js +689 -87
- package/package.json +30 -9
- package/src/abi/interface.d.ts +18 -0
- package/src/abi/interface.js +247 -9
- package/src/abi/js-abi-coder.js +474 -0
- package/src/contract/contract-factory.d.ts +1 -1
- package/src/contract/contract-factory.js +14 -2
- package/src/contract/contract.d.ts +10 -1
- package/src/contract/contract.js +42 -0
- package/src/generator/index.js +1041 -63
- package/src/index.d.ts +16 -0
- package/src/providers/provider.d.ts +20 -11
- package/src/providers/provider.js +12 -0
- package/src/types/index.d.ts +462 -0
- package/src/types/index.js +9 -0
- package/test/e2e/all-solidity-types.dynamic.test.js +200 -0
- package/test/e2e/all-solidity-types.fixtures.js +231 -0
- package/test/e2e/all-solidity-types.generated-sdks.e2e.test.js +368 -0
- package/test/e2e/simple-erc20.generated-sdks.e2e.test.js +151 -0
- package/test/e2e/transactional.test.js +4 -4
- package/test/e2e/typed-generator.e2e.test.js +8 -6
- package/test/integration/ws-provider.test.js +1 -1
- package/test/unit/generate-contract-cli.test.js +2 -1
- package/test/unit/generate-sdk-artifacts-json.test.js +45 -0
- package/test/unit/generator.test.js +1 -0
- package/test/unit/populate-transaction.test.js +62 -0
- package/test/unit/solidity-types.test.js +46 -0
- package/test/unit/utils.test.js +1 -1
package/generate-sdk.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
3
|
+
* sdkgen
|
|
4
4
|
*
|
|
5
5
|
* NOTE: This script is the SDK generator CLI entrypoint.
|
|
6
6
|
*
|
|
@@ -20,13 +20,13 @@ const readline = require("node:readline/promises");
|
|
|
20
20
|
const { stdin, stdout } = require("node:process");
|
|
21
21
|
const { execFileSync, spawnSync } = require("node:child_process");
|
|
22
22
|
|
|
23
|
-
const { generate, generateFromArtifacts, generateTransactionalTestJs } = require("./src/generator");
|
|
23
|
+
const { generate, generateFromArtifacts, generateTransactionalTestJs, generateAllContractsTransactionalTestJs } = require("./src/generator");
|
|
24
24
|
|
|
25
25
|
function _helpText() {
|
|
26
26
|
return `
|
|
27
|
-
|
|
27
|
+
sdkgen (generate-sdk.js)
|
|
28
28
|
|
|
29
|
-
Generates TypeScript contract wrappers (plus optional package scaffold, examples and transactional tests).
|
|
29
|
+
Generates TypeScript or JavaScript contract wrappers (plus optional package scaffold, examples and transactional tests).
|
|
30
30
|
|
|
31
31
|
If you run this script with no parameters, it prints this help.
|
|
32
32
|
|
|
@@ -43,12 +43,35 @@ INPUT MODES
|
|
|
43
43
|
--sol "<A.sol,B.sol,...>" (comma-separated list; can be 1+ files)
|
|
44
44
|
--name <ContractName> (optional; if omitted, generates ALL deployable contracts found)
|
|
45
45
|
--solc <path/to/solc.exe> (optional; defaults from env; see ENV below)
|
|
46
|
+
--solc-args "<args>" (optional; extra args passed to solc, e.g. "--via-ir --evm-version london")
|
|
46
47
|
|
|
47
48
|
3) Artifacts JSON (array of ABI+BIN pairs)
|
|
48
49
|
--artifacts-json <path/to/artifacts.json>
|
|
49
50
|
The JSON file should be an array. Each entry supports:
|
|
50
|
-
- { abi: "<path|abiArray>", bin: "<path|0x...>", name?: "<ContractName>" }
|
|
51
|
+
- { abi: "<path|abiJsonString|abiArray>", bin: "<path|0x...>", name?: "<ContractName>" }
|
|
51
52
|
If "name" is omitted and abi is a path, the contract name defaults from the ABI filename.
|
|
53
|
+
|
|
54
|
+
Example artifacts.json (ABI+BIN pairs):
|
|
55
|
+
[
|
|
56
|
+
{
|
|
57
|
+
"abi": "./artifacts/Alpha.abi.json",
|
|
58
|
+
"bin": "./artifacts/Alpha.bin",
|
|
59
|
+
"name": "Alpha"
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
"abi": [
|
|
63
|
+
{
|
|
64
|
+
"type": "function",
|
|
65
|
+
"name": "set",
|
|
66
|
+
"stateMutability": "nonpayable",
|
|
67
|
+
"inputs": [{ "name": "value", "type": "uint256" }],
|
|
68
|
+
"outputs": []
|
|
69
|
+
}
|
|
70
|
+
],
|
|
71
|
+
"bin": "0x6000600055...",
|
|
72
|
+
"name": "Beta"
|
|
73
|
+
}
|
|
74
|
+
]
|
|
52
75
|
|
|
53
76
|
PACKAGE OUTPUT (optional)
|
|
54
77
|
--create-package
|
|
@@ -61,19 +84,22 @@ PACKAGE OUTPUT (optional)
|
|
|
61
84
|
|
|
62
85
|
Notes:
|
|
63
86
|
- When --create-package is used, the generator creates a complete npm package scaffold with:
|
|
64
|
-
- src/*.ts (
|
|
87
|
+
- src/*.(ts|js) (contracts + factories; depends on --lang)
|
|
65
88
|
- test/e2e/*.e2e.test.js (transactional tests)
|
|
66
89
|
- examples/ (deploy/read/write/events)
|
|
67
90
|
- artifacts/ (only when using --sol)
|
|
68
|
-
- index.js + index.d.ts
|
|
69
|
-
-
|
|
91
|
+
- index.js + index.d.ts (package entry shims; TS mode uses dist/)
|
|
92
|
+
- For --lang ts, the generator will run:
|
|
70
93
|
npm install
|
|
71
94
|
npm run build:ts
|
|
72
|
-
|
|
73
|
-
|
|
95
|
+
as the final step.
|
|
96
|
+
- For --lang js, the generator will run:
|
|
97
|
+
npm install
|
|
98
|
+
and no build step is required.
|
|
74
99
|
|
|
75
100
|
GENERAL OPTIONS
|
|
76
101
|
--out <folder> Output folder (default: ./generated-contract)
|
|
102
|
+
--lang <ts|js> Output language for generated contract sources (default: ts)
|
|
77
103
|
--non-interactive | --yes Disable prompts (required for CI)
|
|
78
104
|
-h | --help Show this help
|
|
79
105
|
|
|
@@ -112,6 +138,14 @@ function _hasFlag(argv, name) {
|
|
|
112
138
|
return argv.includes(name);
|
|
113
139
|
}
|
|
114
140
|
|
|
141
|
+
function _normalizeLang(v) {
|
|
142
|
+
const t = (v == null ? "ts" : String(v)).trim().toLowerCase();
|
|
143
|
+
if (!t) return "ts";
|
|
144
|
+
if (t === "ts" || t === "typescript") return "ts";
|
|
145
|
+
if (t === "js" || t === "javascript") return "js";
|
|
146
|
+
throw new Error(`Invalid --lang: ${v} (expected "ts" or "js")`);
|
|
147
|
+
}
|
|
148
|
+
|
|
115
149
|
function _basenameNoExt(p) {
|
|
116
150
|
const b = path.basename(p);
|
|
117
151
|
const i = b.lastIndexOf(".");
|
|
@@ -168,13 +202,26 @@ function _readArtifactsJson(fileAbs) {
|
|
|
168
202
|
let abi;
|
|
169
203
|
let abiPath = null;
|
|
170
204
|
if (typeof abiField === "string") {
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
205
|
+
// Support either:
|
|
206
|
+
// - file path to an ABI JSON file
|
|
207
|
+
// - inline ABI JSON string (encoded ABI array)
|
|
208
|
+
const maybePath = path.resolve(baseDir, abiField);
|
|
209
|
+
if (fs.existsSync(maybePath) && fs.statSync(maybePath).isFile()) {
|
|
210
|
+
abiPath = maybePath;
|
|
211
|
+
abi = _readJson(abiPath);
|
|
212
|
+
} else {
|
|
213
|
+
try {
|
|
214
|
+
abi = JSON.parse(abiField);
|
|
215
|
+
} catch (e) {
|
|
216
|
+
throw new Error(
|
|
217
|
+
`Invalid "abi" for artifacts entry ${i} (expected ABI file path or ABI JSON string). Not found: ${maybePath}`,
|
|
218
|
+
);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
174
221
|
} else if (Array.isArray(abiField)) {
|
|
175
222
|
abi = abiField;
|
|
176
223
|
} else {
|
|
177
|
-
throw new Error(`Invalid "abi" for artifacts entry ${i} (expected path or ABI array)`);
|
|
224
|
+
throw new Error(`Invalid "abi" for artifacts entry ${i} (expected path, ABI JSON string, or ABI array)`);
|
|
178
225
|
}
|
|
179
226
|
if (!Array.isArray(abi)) throw new Error(`ABI must be an array (entry ${i})`);
|
|
180
227
|
|
|
@@ -243,18 +290,52 @@ function _findConstructor(abi) {
|
|
|
243
290
|
return ctor || { type: "constructor", inputs: [] };
|
|
244
291
|
}
|
|
245
292
|
|
|
246
|
-
function _solTypeToExampleValueExpr(
|
|
247
|
-
|
|
293
|
+
function _solTypeToExampleValueExpr(param) {
|
|
294
|
+
const type = typeof param === "string" ? param : String(param && param.type ? param.type : "");
|
|
295
|
+
const internalType = typeof param === "object" && param ? String(param.internalType || "") : "";
|
|
296
|
+
if (!type) return "undefined";
|
|
297
|
+
|
|
298
|
+
// Arrays (dynamic or fixed)
|
|
248
299
|
if (type.endsWith("]")) {
|
|
249
300
|
const inner = type.slice(0, type.lastIndexOf("["));
|
|
250
|
-
|
|
301
|
+
const bracket = type.slice(type.lastIndexOf("[") + 1, type.length - 1);
|
|
302
|
+
const isFixed = bracket.length > 0;
|
|
303
|
+
const fixedLen = isFixed ? Number(bracket) : 0;
|
|
304
|
+
const elemParam = { ...(param || {}), type: inner };
|
|
305
|
+
const elemExpr = _solTypeToExampleValueExpr(elemParam);
|
|
306
|
+
if (isFixed && Number.isFinite(fixedLen) && fixedLen > 0) {
|
|
307
|
+
// Fixed arrays MUST match the exact declared length.
|
|
308
|
+
return `Array(${fixedLen}).fill(${elemExpr})`;
|
|
309
|
+
}
|
|
310
|
+
return `[${elemExpr}]`;
|
|
251
311
|
}
|
|
312
|
+
|
|
252
313
|
if (type === "address") return "wallet.address";
|
|
253
314
|
if (type === "bool") return "true";
|
|
254
315
|
if (type === "string") return JSON.stringify("hello");
|
|
255
|
-
if (type === "bytes") return JSON.stringify("
|
|
256
|
-
|
|
257
|
-
|
|
316
|
+
if (type === "bytes") return JSON.stringify("0x1234");
|
|
317
|
+
|
|
318
|
+
const mBytesN = type.match(/^bytes(\d+)$/);
|
|
319
|
+
if (mBytesN) {
|
|
320
|
+
const n = Number(mBytesN[1]);
|
|
321
|
+
if (Number.isFinite(n) && n >= 1 && n <= 32) return JSON.stringify(`0x${"11".repeat(n)}`);
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
// Use plain numbers/strings for ints/uints.
|
|
325
|
+
if (type.startsWith("uint") && /\benum\b/.test(internalType)) return "1";
|
|
326
|
+
if (type.startsWith("uint")) return "123";
|
|
327
|
+
if (type.startsWith("int")) return "-123";
|
|
328
|
+
|
|
329
|
+
if (type === "tuple") {
|
|
330
|
+
const comps = Array.isArray(param && param.components) ? param.components : [];
|
|
331
|
+
if (comps.length === 0) return "{}";
|
|
332
|
+
const fields = comps.map((c, idx) => {
|
|
333
|
+
const name = c && typeof c.name === "string" && c.name ? c.name : `field${idx}`;
|
|
334
|
+
return `${JSON.stringify(name)}: ${_solTypeToExampleValueExpr(c)}`;
|
|
335
|
+
});
|
|
336
|
+
return `{ ${fields.join(", ")} }`;
|
|
337
|
+
}
|
|
338
|
+
|
|
258
339
|
return "undefined";
|
|
259
340
|
}
|
|
260
341
|
|
|
@@ -266,6 +347,69 @@ function _parseCommaSeparatedFiles(v) {
|
|
|
266
347
|
.filter(Boolean);
|
|
267
348
|
}
|
|
268
349
|
|
|
350
|
+
function _parseSolcExtraArgs(raw) {
|
|
351
|
+
if (!raw) return [];
|
|
352
|
+
const t = String(raw).trim();
|
|
353
|
+
if (!t) return [];
|
|
354
|
+
|
|
355
|
+
// Allow a JSON array string: ["--via-ir","--evm-version","london"]
|
|
356
|
+
if (t.startsWith("[")) {
|
|
357
|
+
const arr = JSON.parse(t);
|
|
358
|
+
if (!Array.isArray(arr) || !arr.every((x) => typeof x === "string")) {
|
|
359
|
+
throw new Error(`--solc-args JSON must be a string[] (got: ${t.slice(0, 80)}${t.length > 80 ? "..." : ""})`);
|
|
360
|
+
}
|
|
361
|
+
return arr.filter((s) => s.trim()).map((s) => s.trim());
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
// Otherwise treat as a single string of space-separated args (basic quoting support).
|
|
365
|
+
/** @type {string[]} */
|
|
366
|
+
const out = [];
|
|
367
|
+
let cur = "";
|
|
368
|
+
let inQuote = null; // "'" | "\""
|
|
369
|
+
let escaping = false;
|
|
370
|
+
|
|
371
|
+
for (let i = 0; i < t.length; i++) {
|
|
372
|
+
const ch = t[i];
|
|
373
|
+
|
|
374
|
+
if (escaping) {
|
|
375
|
+
cur += ch;
|
|
376
|
+
escaping = false;
|
|
377
|
+
continue;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
if (ch === "\\") {
|
|
381
|
+
// allow escaping inside quotes (and harmless outside)
|
|
382
|
+
escaping = true;
|
|
383
|
+
continue;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
if (inQuote) {
|
|
387
|
+
if (ch === inQuote) {
|
|
388
|
+
inQuote = null;
|
|
389
|
+
} else {
|
|
390
|
+
cur += ch;
|
|
391
|
+
}
|
|
392
|
+
continue;
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
if (ch === '"' || ch === "'") {
|
|
396
|
+
inQuote = ch;
|
|
397
|
+
continue;
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
if (/\s/.test(ch)) {
|
|
401
|
+
if (cur) out.push(cur);
|
|
402
|
+
cur = "";
|
|
403
|
+
continue;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
cur += ch;
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
if (cur) out.push(cur);
|
|
410
|
+
return out;
|
|
411
|
+
}
|
|
412
|
+
|
|
269
413
|
function _resolveSolcPath(argv) {
|
|
270
414
|
const solcArg = _argValue(argv, "--solc") || _argValue(argv, "--solc-path") || _argValue(argv, "--solcPath");
|
|
271
415
|
const env =
|
|
@@ -275,7 +419,7 @@ function _resolveSolcPath(argv) {
|
|
|
275
419
|
process.env.SOLC_PATH ||
|
|
276
420
|
process.env.solc ||
|
|
277
421
|
null;
|
|
278
|
-
return env || "c:\\
|
|
422
|
+
return env || "c:\\solc\\solc.exe";
|
|
279
423
|
}
|
|
280
424
|
|
|
281
425
|
function _assertSolcExists(solcPath) {
|
|
@@ -286,9 +430,11 @@ function _assertSolcExists(solcPath) {
|
|
|
286
430
|
}
|
|
287
431
|
}
|
|
288
432
|
|
|
289
|
-
function _compileSolidityToArtifacts({ solcPath, solFilesAbs, contractNameFilter }) {
|
|
433
|
+
function _compileSolidityToArtifacts({ solcPath, solFilesAbs, contractNameFilter, solcExtraArgs }) {
|
|
290
434
|
_assertSolcExists(solcPath);
|
|
291
|
-
const
|
|
435
|
+
const extra = Array.isArray(solcExtraArgs) ? solcExtraArgs : [];
|
|
436
|
+
const base = extra.includes("--optimize") ? [] : ["--optimize"];
|
|
437
|
+
const out = execFileSync(solcPath, [...base, ...extra, "--combined-json", "abi,bin", ...solFilesAbs], { encoding: "utf8" });
|
|
292
438
|
const parsed = JSON.parse(out);
|
|
293
439
|
|
|
294
440
|
const artifacts = [];
|
|
@@ -433,16 +579,17 @@ function _extractSolDocs(solFilesAbs) {
|
|
|
433
579
|
return out;
|
|
434
580
|
}
|
|
435
581
|
|
|
436
|
-
function _renderPackageIndexJs({ artifacts }) {
|
|
582
|
+
function _renderPackageIndexJs({ artifacts, entryDir }) {
|
|
583
|
+
const dir = entryDir || "dist";
|
|
437
584
|
const lines = [];
|
|
438
585
|
lines.push("/**");
|
|
439
586
|
lines.push(" * Auto-generated typed contract package.");
|
|
440
587
|
lines.push(" *");
|
|
441
|
-
lines.push(
|
|
588
|
+
lines.push(` * This file re-exports the package entry bundle in \`${dir}/\`.`);
|
|
442
589
|
lines.push(" */");
|
|
443
590
|
lines.push("");
|
|
444
|
-
lines.push(
|
|
445
|
-
lines.push("Object.assign(exports,
|
|
591
|
+
lines.push(`const entry = require("./${dir}");`);
|
|
592
|
+
lines.push("Object.assign(exports, entry);");
|
|
446
593
|
lines.push("");
|
|
447
594
|
|
|
448
595
|
for (const a of artifacts) {
|
|
@@ -460,8 +607,8 @@ function _renderPackageIndexJs({ artifacts }) {
|
|
|
460
607
|
lines.push(` * ${a.contractName}`);
|
|
461
608
|
lines.push(" */");
|
|
462
609
|
}
|
|
463
|
-
lines.push(`exports.${a.contractName} =
|
|
464
|
-
lines.push(`exports.${a.contractName}__factory =
|
|
610
|
+
lines.push(`exports.${a.contractName} = entry.${a.contractName};`);
|
|
611
|
+
lines.push(`exports.${a.contractName}__factory = entry.${a.contractName}__factory;`);
|
|
465
612
|
lines.push("");
|
|
466
613
|
}
|
|
467
614
|
|
|
@@ -503,6 +650,7 @@ async function main() {
|
|
|
503
650
|
const abiPathArg = _argValue(argv, "--abi");
|
|
504
651
|
const binPathArg = _argValue(argv, "--bin");
|
|
505
652
|
const solArg = _argValue(argv, "--sol") || _argValue(argv, "--sol-files") || _argValue(argv, "--solFiles");
|
|
653
|
+
const solcArgsRaw = _argValue(argv, "--solc-args") || _argValue(argv, "--solcArgs");
|
|
506
654
|
const artifactsJsonArg =
|
|
507
655
|
_argValue(argv, "--artifacts-json") || _argValue(argv, "--artifactsJson") || _argValue(argv, "--artifacts");
|
|
508
656
|
const outArg = _argValue(argv, "--out");
|
|
@@ -515,6 +663,7 @@ async function main() {
|
|
|
515
663
|
const pkgAuthorArg = _argValue(argv, "--package-author") || "";
|
|
516
664
|
const pkgLicenseArg = _argValue(argv, "--package-license") || "MIT";
|
|
517
665
|
const pkgVersionArg = _argValue(argv, "--package-version") || "0.0.1";
|
|
666
|
+
const lang = _normalizeLang(_argValue(argv, "--lang") || _argValue(argv, "--language") || _argValue(argv, "--type"));
|
|
518
667
|
|
|
519
668
|
// Decide input type.
|
|
520
669
|
let inputType = null; // "abibin" | "sol" | "artifactsjson"
|
|
@@ -534,6 +683,7 @@ async function main() {
|
|
|
534
683
|
let absBin = null;
|
|
535
684
|
let solFilesAbs = [];
|
|
536
685
|
let artifactsJsonAbs = null;
|
|
686
|
+
const solcExtraArgs = solcArgsRaw ? _parseSolcExtraArgs(solcArgsRaw) : [];
|
|
537
687
|
|
|
538
688
|
if (!nonInteractive) {
|
|
539
689
|
const rl0 = readline.createInterface({ input: stdin, output: stdout });
|
|
@@ -631,6 +781,7 @@ async function main() {
|
|
|
631
781
|
pkgAuthor,
|
|
632
782
|
pkgLicense,
|
|
633
783
|
pkgVersion,
|
|
784
|
+
lang,
|
|
634
785
|
});
|
|
635
786
|
} else {
|
|
636
787
|
const target = (await rl.question("Enter the location in your existing package (relative to package root): ")).trim();
|
|
@@ -656,6 +807,7 @@ async function main() {
|
|
|
656
807
|
pkgAuthor: pkgAuthorArg,
|
|
657
808
|
pkgLicense: pkgLicenseArg,
|
|
658
809
|
pkgVersion: pkgVersionArg,
|
|
810
|
+
lang,
|
|
659
811
|
});
|
|
660
812
|
}
|
|
661
813
|
|
|
@@ -674,7 +826,7 @@ async function main() {
|
|
|
674
826
|
artifacts = [{ contractName, abi, bytecode, docs: null }];
|
|
675
827
|
} else if (inputType === "sol") {
|
|
676
828
|
const solcPath = _resolveSolcPath(argv);
|
|
677
|
-
artifacts = _compileSolidityToArtifacts({ solcPath, solFilesAbs, contractNameFilter: contractName });
|
|
829
|
+
artifacts = _compileSolidityToArtifacts({ solcPath, solFilesAbs, contractNameFilter: contractName, solcExtraArgs });
|
|
678
830
|
|
|
679
831
|
// Attach Solidity doc comments (NatSpec) to artifacts
|
|
680
832
|
const docsByContract = _extractSolDocs(solFilesAbs);
|
|
@@ -692,9 +844,9 @@ async function main() {
|
|
|
692
844
|
if (artifacts.length === 1) {
|
|
693
845
|
// Keep the old API/behavior for single-contract generation.
|
|
694
846
|
const a = artifacts[0];
|
|
695
|
-
generateFromArtifacts({ outDir: targetSrcDir, artifacts: [a] });
|
|
847
|
+
generateFromArtifacts({ outDir: targetSrcDir, artifacts: [a], lang });
|
|
696
848
|
} else {
|
|
697
|
-
generateFromArtifacts({ outDir: targetSrcDir, artifacts });
|
|
849
|
+
generateFromArtifacts({ outDir: targetSrcDir, artifacts, lang });
|
|
698
850
|
}
|
|
699
851
|
|
|
700
852
|
if (createPackage) {
|
|
@@ -703,7 +855,9 @@ async function main() {
|
|
|
703
855
|
_packageReadme({
|
|
704
856
|
pkgName: pkgNameArg || path.basename(outDir),
|
|
705
857
|
pkgDesc: pkgDescArg,
|
|
706
|
-
|
|
858
|
+
artifacts,
|
|
859
|
+
createdFromSolidity: inputType === "sol",
|
|
860
|
+
lang,
|
|
707
861
|
}),
|
|
708
862
|
);
|
|
709
863
|
|
|
@@ -711,6 +865,15 @@ async function main() {
|
|
|
711
865
|
_ensureDir(path.join(outDir, "test", "e2e"));
|
|
712
866
|
_ensureDir(path.join(outDir, "examples"));
|
|
713
867
|
|
|
868
|
+
// Shared helper for examples (keeps examples runnable via plain `node`).
|
|
869
|
+
// WARNING: test-only wallet; never use for real funds.
|
|
870
|
+
_writeText(
|
|
871
|
+
path.join(outDir, "examples", "_test-wallet.js"),
|
|
872
|
+
`const { Wallet } = require("quantumcoin");\n\n// Hardcoded test wallet (test-only; never use for real funds)\nconst TEST_WALLET_ENCRYPTED_JSON =\n ${JSON.stringify(
|
|
873
|
+
"{\"address\":\"1a846abe71c8b989e8337c55d608be81c28ab3b2e40c83eaa2a68d516049aec6\",\"crypto\":{\"cipher\":\"aes-256-ctr\",\"ciphertext\":\"ab7e620dd66cb55ac201b9c6796de92bbb06f3681b5932eabe099871f1f7d79acabe30921a39ad13bfe74f42c515734882b6723760142aa3e26e011df514a534ae47bd15d86badd9c6f17c48d4c892711d54d441ee3a0ee0e5b060f816e79c7badd13ff4c235934b1986774223ecf6e8761388969bb239c759b54c8c70e6a2e27c93a4b70129c8159f461d271ae8f3573414c78b88e4d0abfa6365ed45456636d4ed971c7a0c6b84e6f0c2621e819268b135e2bcc169a54d1847b39e6ba2ae8ec969b69f330b7db9e785ed02204d5a1185915ae5338b0f40ef2a7f4d5aaf7563d502135e57f4eb89d5ec1efa5c77e374969d6cd85be625a2ed1225d68ecdd84067bfc69adb83ecd5c6050472eca28a5a646fcdd28077165c629975bec8a79fe1457cb53389b788b25e1f8eff8b2ca326d7dfcaba3f8839225a08057c018a458891fd2caa0d2b27632cffd80f592147ccec9a10dc8a08a48fb55047bff5cf85cda39eb089096bef63842fc3686412f298a54a9e4b0bf4ad36907ba373cbd6d32e7ac494af371da5aa9d38a3463220865114c4adc5e4ac258ba9c6af9fa2ddfd1aec2e16887e4b3977c69561df8599ac9d411c9dd2a4d57f92ea4e5c02aae3f49fb3bc83e16673e6c2dbe96bb181c8dfd0f9757ade2e4ff27215a836058c5ffeab042f6f97c7c02339f76a6284680e01b4bb733690eb3347fbfcc26614b8bf755f9dfce3fea9d4e4d15b164983201732c2e87593a86bca6da6972e128490338f76ae68135888070f4e59e90db54d23834769bdbda9769213faf5357f9167a224523975a946367b68f0cec98658575609f58bfd329e420a921c06713326e4cb20a0df1d77f37e78a320a637a96c604ca3fa89e24beb42313751b8f09b14f9c14c77e4fd13fc6382505d27c771bca0d821ec7c3765acffa99d83c50140a56b0b28101c762bd682fe55cb6f23cbeb3f421d7b36021010e45ac27160dd7ead99c864a1b550c7edb1246950fe32dcc049799f9085287f0a747a6ef7a023df46a23a22f3e833bbf8d404f84344870492658256ee1dfc40fda33bb8d48fc72d4520ba9fc820c9123104a045206809037709f2a5f6723fa77d6bac5a573823d4ec3a7f1cb786a52ee2697e622e5d75962fa554d1024a6c355e21f33a63b2b72e6c4742a8b1c373aa532b40518c38c90b5373c2eb8c9d7be2a9e16047a3ee09dc9a6849deac5183ace6cfe91a9bef2ffc0a7df6ccebfd4c858c84b0e0355650d7466971e66f1e3883013e5ad1be33199b1d110b79070ac1b745ccb14cf63a08f8cca3a21c9525e626ff5f0c34746e10750fb742ad51f11f2acae3676c2111853d7250d01b77821a6ba9e04400ba2c543ca9f2d701ae6f47bfad14ffe3039ee9e71f7b2401359ade9938750ddb9c5a8b018a7929ed8d0e717ff1861446ce17535e9b17c187711190aae3388bd9490837a636c25ed4d42d7079ad1a51e13292c683d5d012abcf46965c534b83ab53f2c1f0cf5830ef7582e06863a33c19a70511df632885d63245965047ea96b56f1af5b3b94a54999f784fb9574fdfcd7c1230e07a2aaa04acd3097b2b9f8ddba05ae9734491deb5c1a513c76ed276cb78bbf4839dae3156d76af444a5805129d5df791167a9c8576a1d7f760b2d2797c4658669608706fbd0ace1be2346f74862dfc9ef518e55632e43c043186e5d070deb34d12fb9e5aba84e5cb50213dc88efd39cc35bf42455aa82d5e3b707b3140be3b8623b34fdd81d08615c188ae8438a13881fdf6bf32f2cb9ff5fa625561040c6b71d4b8eccc90bc3b99650d28dd1ee63773e49664e3d48c484996b290943635a6f2eb1ce9796d3fa144a3f00ef82faaa32d6a413668f7b521517cb68b2b017fcf56c79326fa5e4060e643631ca3f0a0dc0ed718798b6f46b130d437c33f64039e887324b6f5e604b1669d613923794edbf04b1b3caea54793b52b44b170173a4f25c7ecef3b71e2aad76e556b1cb9f1d637ec52ececfa950dd31dbb6a60828a3ad34c1beffe09eb4785786d63bad10a0b0f66ea88c57380f38ea85f018dbd7f538cf1ee7624095b9a01ec5edd528f281168af020609e651ff316aa1320a710134ddfca600cc72174dcdb846d2aa29916488aa1b537b66da92e61af526debef4eb38c984569eaf549ff2129449269b492d030cd74d885f6f5785881cc4804b4a8a09ba4ff7aefe9074ac7d0c4f05d51fe4cc0ff7388a772092b9d02d70e5433a5cf3e02f46a6bd6b818d59a07ce3b9fbbf8b5faba74563bcc5240930c2d406c9aaee3e3ce0429bf68ac2b0a57adb09414cff50817d2a48fb9fa624ab863cb0c31a8b8dc5eaf6fa68cc1d7c6c685c5a33edd5c8933b9e8ab628ee428d0743699b2ff17f25586c7ce959280bb0b8c5342251f0a30b53dbc7bf1ee426ac9619c3560f811f2268ee37f189794e2e4b3db3a2fb2e34b649e504fb467438abfd1082619cc4a0b30d66beb831077812e418d2e2148db10cf4d4a29101ca52ec445b8d83519dd7de85a98e0beae9ee537096d3f1a55a7a80cdfa93d25f07c9f98e8af18cde19ec1f99c5dd4588b717a5039ddb7f177717caf0d0fd45420a70dbd6d3146890d9e450d5224146db4c33b779e3c3a04b976c052bad042ac57dd38be45407808c0fb0d7e2a8819e6cd53c6739e6612996ddaa6f066552590aa0343bc1e62b298ff2514a0cef8be21956c2e942816f7a3a3a0935eaf9b37251409ce444c986c3817e82835555fe18239f3ae33469d7965c2bde9991fde556bd07af01df52bbde0c35bb4ef48e3b5d0db53f8ca4ed35b83f760f0a1bc4ed9f86e85d6039a17df373c85402ef956f01db00eb39c4b74bd0660d29ee746714d9780d738e05c6cca414ce3d7b40dda8036a9eea9ab1388805f913eb19bdd3f09d9e161eaa50231bd9caba61971f194332dd28c696a60458c1c6c2cc5da8b1192611c7c553e9e12fe48ce46bbb891be8bb118721c86222e671ddd1da8f0ccb2b68e02f2014b4925e904e88369aaf7466bd7033a60c265d45955944916ecbdb84bf1b522b01b0149c632e04c568a7eb627c5bb90ece052ebcf79166c28b30d23fe52da0a5ab5dea83ca479a3e3b7a9cfbbfea04dbe6137c19d067317c2ec427a8c75a6b06bec6dcd5d5c0edc9aa80b9003b8e17c088b2f3db327d3e42630d82d20120240c3ba56232280787da4aabbf5bc95a864029f00710e195f2a76460a0317d10b552fe1bea097e41d49756c680a41d6ac186e62169b6b6cd7776ea84618b5b752328a5bacaa10aa122ff9b2698b43efe73d852a899db644863c8c9bc8068ea86ea843fd6fe36272b91cdc5d5317083ef3fd1e5462a0b0d0604dc57b3bbfceb0fca4cd349625dd7b25166af30efe5ee6a0af953a74d65f4736c59918ee55a3b0d9d9d42e04c7f8a77e479109f740e20c464d5d7e3d16805f47b61f403ff7f408c9e850d9baacd8067e544536a4953480b0f9ee9cd45f41ebd67b51f78788a6470cb1e5ca72ca346ce8a50d0ca0c921d5576a4455a1afb6d0bc688004712ee122cacdb29c51e84893324c27fa4a3f1917edf5352272b4c97579a6152e4b77663d0ab532915f2eeb6a862de8b696452321b660c3f2449673d086e95a7af28845a5259b763e0fcd09f72acf7b6c811066263060e5aa5b24658e880a01fd56bda4dad5ab604e129290f7d5489728f2a40968c6168b21cebbbcd11727cc9e9160c4e92e04387d3b0d62aab06a61f26daedd9fed11816ef2180172a47f47184ac4032b88758c98a2e0fb200f70e93ba695f5ebb7a1029610ad360d3b7fa1b4640b9dc674d3625eef786da93dff19bc7991b5d6193a3896664763fde479b5dfc04812111a80782854f2cf68ca7d82765cc9eb40fba4b44640710ed6e653abf9f07b466333f4fd22784d53cf40e17120f42caa841eaa24056b237827b0f47f7257c103c35027e9f503e5acfd023e7357b600d3084d361d5ee65ba319b45c153212a54e6fed85af7e43e0a926ebcbc2edf8de7e2ec9528f00bec262ad04d5c9dafccaea06a24748d28bf1799bae0e895543084539c50b5aaa4fb50d7431d6f0c8cee2a54aaf7ee7919b55bf40adb688632e5dbe273cea09e97b19c3d8e1f4de000deb66fa1942ad03a62d3252f51992244366c156000b49c297167a6cbdedea7ebae139d295f0ad298e0864249b905b7eb812886ec70ecdb286702274b5b8574149bf3866f9e46b997ff5ed622b169a0eb071347f18d530db1663906a28f4544ee4e004ab87b65476af30ede118052ff052b8dc986ca2c93dd5d4943266a579c7698ea014f688b3e8063a107feb162d392e2177b01bff77fb5abe5feebd0607158049a5a093325b7c9ee6b4dfa7a9f65c7c2fb628920d3603a1c2dad979eaa047cd661a268af1078c9788d720e64e4ce9d12e68de1e417ef2f293323681e1071f9220e1ee43d2e29d111b870ce3439f5100ecd4551ab65ee74aa1667e564957e9bc0ae1ea193980da2a0ec2698073388c85bec25ef447f0d5e93a5203fa44dff268e5cb799ed3b66e63d5e07b487e7534f24934c73a62a243e0151843a0fd3807711a101eaa7fc71f0ba68aebb9534d57cba41b094eebfb4c31cca8eddfa426f676aa347be8a7023a4e91ddb154b35cd4d5f7dbc2e5db491de99f33fc2cff2d57029ac950e1ccd681980af6a4e8969dfe39b3c7bfcbcf8fac92f1e6ec9fe572bfa6a7d65860eab2ed10ac01a71290b52e3148e84b7376a8605cd2bb0e8681ffc54691ce087685e33921bd44d36c78291713dce17569570f62137e6904f0d68cf53aa2ec395c389a75141f08114fb293ea63950e4ffee55ec6fc83cf44876b8e7f25cdd393ff87b9eda6eb746085b61a6900de191f0ce2cb388d61ece52e78bc47368194e8e00277e0d1631e6b9d4626ef76f8522582ccd5a40be3febc699bb510acc6271d55ff0f4cf3bb7669855a72efd9ca3e1056a2fe592a5bc877cce2b1f63b58383971da87873d2d1349cf5881242cdce4e7e2c5c514755746a0e0a7c2a6d9701cde005ae3420beb17c379a3516662253554f51f0423bb1844b0b90c54ed8177ceb0e1036a6609d836e748ca06c40ca64befadc6443ec286a0ce464678e8d11eb455f7bb305acebf6cb1f50e394a9bfeb752df1687831bac9cdd811f4f112ef6658d0f8799a866374ff96c5e2b79f30e7a74f8a2bc9ed1f88f01f30e30cb78ffb2bff10108f35e910ee3be4463e9e6f0ed910e8d598326e71dfa2277ffe5579d7fe9b6018bfe295b25219eae07b3b0270665c3fa00c3e0d180812b5cd62925585de84a7c48a9a86dba96544a251654d1966e082432dc85b6149cf21e91a46020ec32b66d28ba3b6a90c0617bc6fdd55aea819af2bcf84864ad60c28fe3c9f8339d0aee68b39d97f63b6e082835d86119cf9b9fdc8b827c847ce40aa10e1577a710132316845e825345e95bdf94d0c66ec65a6c4319fce4792313663b5f7a651a6710783e6ab71608ac6cbbf3af6911adf596ccf7c172b9bd5bceb6db379967b32b143bdd11d2ee12ddf64ecef6391e0f8570e6cddd3db95204919362b89b739fa94e7c1bfde799fd5e22aa25ca6ca42e30c08e23aae2385d99ebab441072a880dcefdab74a4c9bd39d363f6d1933d59400fca161d432aa00f23b1b1c19a154be8989699d549b66d44e39896f5523443bc6ddf4a65e91f1f3fb7b52318869a05856a4fc92f3694c81ed833c972fb918f7e5\",\"cipherparams\":{\"iv\":\"8c46d6162cd4c765759aedcbce2a5874\"},\"kdf\":\"scrypt\",\"kdfparams\":{\"dklen\":32,\"n\":262144,\"p\":1,\"r\":8,\"salt\":\"82fb6cdc6917609135277badacf15baa31899d08b71a5a0fa33167167c161537\"},\"mac\":\"9187b17f7eca48e6b8c586b0cd790dbe0feb876ac8385f93faa7d5e22a3c8fc7\"},\"id\":\"92caf6ee-2d43-48c0-859e-ffa1e0e23312\",\"version\":3}",
|
|
874
|
+
)};\nconst TEST_WALLET_PASSPHRASE = \"QuantumCoinExample123!\";\n\nfunction createTestWallet(provider) {\n // Caller must have called Initialize() first.\n return Wallet.fromEncryptedJsonSync(TEST_WALLET_ENCRYPTED_JSON, TEST_WALLET_PASSPHRASE, provider);\n}\n\nmodule.exports = {\n TEST_WALLET_ENCRYPTED_JSON,\n TEST_WALLET_PASSPHRASE,\n createTestWallet,\n};\n`,
|
|
875
|
+
);
|
|
876
|
+
|
|
714
877
|
for (const a of artifacts) {
|
|
715
878
|
_writeText(
|
|
716
879
|
path.join(outDir, "test", "e2e", `${a.contractName}.e2e.test.js`),
|
|
@@ -718,74 +881,345 @@ async function main() {
|
|
|
718
881
|
);
|
|
719
882
|
}
|
|
720
883
|
|
|
884
|
+
if (artifacts.length > 1) {
|
|
885
|
+
_writeText(
|
|
886
|
+
path.join(outDir, "test", "e2e", "all-contracts.e2e.test.js"),
|
|
887
|
+
generateAllContractsTransactionalTestJs({ artifacts: artifacts.map((a) => ({ contractName: a.contractName, abi: a.abi })) }),
|
|
888
|
+
);
|
|
889
|
+
}
|
|
890
|
+
|
|
721
891
|
if (artifacts.length === 1) {
|
|
722
892
|
// Back-compat: keep original example filenames for a single-contract package.
|
|
723
893
|
const a = artifacts[0];
|
|
724
894
|
const ctor = _findConstructor(a.abi);
|
|
725
|
-
const ctorArgsExpr = (ctor.inputs || []).map((i) => _solTypeToExampleValueExpr(i
|
|
895
|
+
const ctorArgsExpr = (ctor.inputs || []).map((i) => _solTypeToExampleValueExpr(i)).join(", ");
|
|
726
896
|
|
|
727
897
|
_writeText(
|
|
728
|
-
path.join(outDir, "examples", "deploy.
|
|
729
|
-
|
|
898
|
+
path.join(outDir, "examples", "deploy.js"),
|
|
899
|
+
`/**
|
|
900
|
+
* Deploy example (generated).
|
|
901
|
+
*
|
|
902
|
+
* Requires:
|
|
903
|
+
* - QC_RPC_URL env var
|
|
904
|
+
*
|
|
905
|
+
* WARNING: uses a hardcoded test wallet (funded) for convenience.
|
|
906
|
+
*/
|
|
907
|
+
const { Initialize } = require("quantumcoin/config");
|
|
908
|
+
const { JsonRpcProvider, Wallet } = require("quantumcoin");
|
|
909
|
+
const { ${a.contractName}__factory } = require("..");
|
|
910
|
+
|
|
911
|
+
// Hardcoded test wallet (test-only; never use for real funds)
|
|
912
|
+
const TEST_WALLET_ENCRYPTED_JSON =
|
|
913
|
+
${JSON.stringify(
|
|
914
|
+
"{\"address\":\"1a846abe71c8b989e8337c55d608be81c28ab3b2e40c83eaa2a68d516049aec6\",\"crypto\":{\"cipher\":\"aes-256-ctr\",\"ciphertext\":\"ab7e620dd66cb55ac201b9c6796de92bbb06f3681b5932eabe099871f1f7d79acabe30921a39ad13bfe74f42c515734882b6723760142aa3e26e011df514a534ae47bd15d86badd9c6f17c48d4c892711d54d441ee3a0ee0e5b060f816e79c7badd13ff4c235934b1986774223ecf6e8761388969bb239c759b54c8c70e6a2e27c93a4b70129c8159f461d271ae8f3573414c78b88e4d0abfa6365ed45456636d4ed971c7a0c6b84e6f0c2621e819268b135e2bcc169a54d1847b39e6ba2ae8ec969b69f330b7db9e785ed02204d5a1185915ae5338b0f40ef2a7f4d5aaf7563d502135e57f4eb89d5ec1efa5c77e374969d6cd85be625a2ed1225d68ecdd84067bfc69adb83ecd5c6050472eca28a5a646fcdd28077165c629975bec8a79fe1457cb53389b788b25e1f8eff8b2ca326d7dfcaba3f8839225a08057c018a458891fd2caa0d2b27632cffd80f592147ccec9a10dc8a08a48fb55047bff5cf85cda39eb089096bef63842fc3686412f298a54a9e4b0bf4ad36907ba373cbd6d32e7ac494af371da5aa9d38a3463220865114c4adc5e4ac258ba9c6af9fa2ddfd1aec2e16887e4b3977c69561df8599ac9d411c9dd2a4d57f92ea4e5c02aae3f49fb3bc83e16673e6c2dbe96bb181c8dfd0f9757ade2e4ff27215a836058c5ffeab042f6f97c7c02339f76a6284680e01b4bb733690eb3347fbfcc26614b8bf755f9dfce3fea9d4e4d15b164983201732c2e87593a86bca6da6972e128490338f76ae68135888070f4e59e90db54d23834769bdbda9769213faf5357f9167a224523975a946367b68f0cec98658575609f58bfd329e420a921c06713326e4cb20a0df1d77f37e78a320a637a96c604ca3fa89e24beb42313751b8f09b14f9c14c77e4fd13fc6382505d27c771bca0d821ec7c3765acffa99d83c50140a56b0b28101c762bd682fe55cb6f23cbeb3f421d7b36021010e45ac27160dd7ead99c864a1b550c7edb1246950fe32dcc049799f9085287f0a747a6ef7a023df46a23a22f3e833bbf8d404f84344870492658256ee1dfc40fda33bb8d48fc72d4520ba9fc820c9123104a045206809037709f2a5f6723fa77d6bac5a573823d4ec3a7f1cb786a52ee2697e622e5d75962fa554d1024a6c355e21f33a63b2b72e6c4742a8b1c373aa532b40518c38c90b5373c2eb8c9d7be2a9e16047a3ee09dc9a6849deac5183ace6cfe91a9bef2ffc0a7df6ccebfd4c858c84b0e0355650d7466971e66f1e3883013e5ad1be33199b1d110b79070ac1b745ccb14cf63a08f8cca3a21c9525e626ff5f0c34746e10750fb742ad51f11f2acae3676c2111853d7250d01b77821a6ba9e04400ba2c543ca9f2d701ae6f47bfad14ffe3039ee9e71f7b2401359ade9938750ddb9c5a8b018a7929ed8d0e717ff1861446ce17535e9b17c187711190aae3388bd9490837a636c25ed4d42d7079ad1a51e13292c683d5d012abcf46965c534b83ab53f2c1f0cf5830ef7582e06863a33c19a70511df632885d63245965047ea96b56f1af5b3b94a54999f784fb9574fdfcd7c1230e07a2aaa04acd3097b2b9f8ddba05ae9734491deb5c1a513c76ed276cb78bbf4839dae3156d76af444a5805129d5df791167a9c8576a1d7f760b2d2797c4658669608706fbd0ace1be2346f74862dfc9ef518e55632e43c043186e5d070deb34d12fb9e5aba84e5cb50213dc88efd39cc35bf42455aa82d5e3b707b3140be3b8623b34fdd81d08615c188ae8438a13881fdf6bf32f2cb9ff5fa625561040c6b71d4b8eccc90bc3b99650d28dd1ee63773e49664e3d48c484996b290943635a6f2eb1ce9796d3fa144a3f00ef82faaa32d6a413668f7b521517cb68b2b017fcf56c79326fa5e4060e643631ca3f0a0dc0ed718798b6f46b130d437c33f64039e887324b6f5e604b1669d613923794edbf04b1b3caea54793b52b44b170173a4f25c7ecef3b71e2aad76e556b1cb9f1d637ec52ececfa950dd31dbb6a60828a3ad34c1beffe09eb4785786d63bad10a0b0f66ea88c57380f38ea85f018dbd7f538cf1ee7624095b9a01ec5edd528f281168af020609e651ff316aa1320a710134ddfca600cc72174dcdb846d2aa29916488aa1b537b66da92e61af526debef4eb38c984569eaf549ff2129449269b492d030cd74d885f6f5785881cc4804b4a8a09ba4ff7aefe9074ac7d0c4f05d51fe4cc0ff7388a772092b9d02d70e5433a5cf3e02f46a6bd6b818d59a07ce3b9fbbf8b5faba74563bcc5240930c2d406c9aaee3e3ce0429bf68ac2b0a57adb09414cff50817d2a48fb9fa624ab863cb0c31a8b8dc5eaf6fa68cc1d7c6c685c5a33edd5c8933b9e8ab628ee428d0743699b2ff17f25586c7ce959280bb0b8c5342251f0a30b53dbc7bf1ee426ac9619c3560f811f2268ee37f189794e2e4b3db3a2fb2e34b649e504fb467438abfd1082619cc4a0b30d66beb831077812e418d2e2148db10cf4d4a29101ca52ec445b8d83519dd7de85a98e0beae9ee537096d3f1a55a7a80cdfa93d25f07c9f98e8af18cde19ec1f99c5dd4588b717a5039ddb7f177717caf0d0fd45420a70dbd6d3146890d9e450d5224146db4c33b779e3c3a04b976c052bad042ac57dd38be45407808c0fb0d7e2a8819e6cd53c6739e6612996ddaa6f066552590aa0343bc1e62b298ff2514a0cef8be21956c2e942816f7a3a3a0935eaf9b37251409ce444c986c3817e82835555fe18239f3ae33469d7965c2bde9991fde556bd07af01df52bbde0c35bb4ef48e3b5d0db53f8ca4ed35b83f760f0a1bc4ed9f86e85d6039a17df373c85402ef956f01db00eb39c4b74bd0660d29ee746714d9780d738e05c6cca414ce3d7b40dda8036a9eea9ab1388805f913eb19bdd3f09d9e161eaa50231bd9caba61971f194332dd28c696a60458c1c6c2cc5da8b1192611c7c553e9e12fe48ce46bbb891be8bb118721c86222e671ddd1da8f0ccb2b68e02f2014b4925e904e88369aaf7466bd7033a60c265d45955944916ecbdb84bf1b522b01b0149c632e04c568a7eb627c5bb90ece052ebcf79166c28b30d23fe52da0a5ab5dea83ca479a3e3b7a9cfbbfea04dbe6137c19d067317c2ec427a8c75a6b06bec6dcd5d5c0edc9aa80b9003b8e17c088b2f3db327d3e42630d82d20120240c3ba56232280787da4aabbf5bc95a864029f00710e195f2a76460a0317d10b552fe1bea097e41d49756c680a41d6ac186e62169b6b6cd7776ea84618b5b752328a5bacaa10aa122ff9b2698b43efe73d852a899db644863c8c9bc8068ea86ea843fd6fe36272b91cdc5d5317083ef3fd1e5462a0b0d0604dc57b3bbfceb0fca4cd349625dd7b25166af30efe5ee6a0af953a74d65f4736c59918ee55a3b0d9d9d42e04c7f8a77e479109f740e20c464d5d7e3d16805f47b61f403ff7f408c9e850d9baacd8067e544536a4953480b0f9ee9cd45f41ebd67b51f78788a6470cb1e5ca72ca346ce8a50d0ca0c921d5576a4455a1afb6d0bc688004712ee122cacdb29c51e84893324c27fa4a3f1917edf5352272b4c97579a6152e4b77663d0ab532915f2eeb6a862de8b696452321b660c3f2449673d086e95a7af28845a5259b763e0fcd09f72acf7b6c811066263060e5aa5b24658e880a01fd56bda4dad5ab604e129290f7d5489728f2a40968c6168b21cebbbcd11727cc9e9160c4e92e04387d3b0d62aab06a61f26daedd9fed11816ef2180172a47f47184ac4032b88758c98a2e0fb200f70e93ba695f5ebb7a1029610ad360d3b7fa1b4640b9dc674d3625eef786da93dff19bc7991b5d6193a3896664763fde479b5dfc04812111a80782854f2cf68ca7d82765cc9eb40fba4b44640710ed6e653abf9f07b466333f4fd22784d53cf40e17120f42caa841eaa24056b237827b0f47f7257c103c35027e9f503e5acfd023e7357b600d3084d361d5ee65ba319b45c153212a54e6fed85af7e43e0a926ebcbc2edf8de7e2ec9528f00bec262ad04d5c9dafccaea06a24748d28bf1799bae0e895543084539c50b5aaa4fb50d7431d6f0c8cee2a54aaf7ee7919b55bf40adb688632e5dbe273cea09e97b19c3d8e1f4de000deb66fa1942ad03a62d3252f51992244366c156000b49c297167a6cbdedea7ebae139d295f0ad298e0864249b905b7eb812886ec70ecdb286702274b5b8574149bf3866f9e46b997ff5ed622b169a0eb071347f18d530db1663906a28f4544ee4e004ab87b65476af30ede118052ff052b8dc986ca2c93dd5d4943266a579c7698ea014f688b3e8063a107feb162d392e2177b01bff77fb5abe5feebd0607158049a5a093325b7c9ee6b4dfa7a9f65c7c2fb628920d3603a1c2dad979eaa047cd661a268af1078c9788d720e64e4ce9d12e68de1e417ef2f293323681e1071f9220e1ee43d2e29d111b870ce3439f5100ecd4551ab65ee74aa1667e564957e9bc0ae1ea193980da2a0ec2698073388c85bec25ef447f0d5e93a5203fa44dff268e5cb799ed3b66e63d5e07b487e7534f24934c73a62a243e0151843a0fd3807711a101eaa7fc71f0ba68aebb9534d57cba41b094eebfb4c31cca8eddfa426f676aa347be8a7023a4e91ddb154b35cd4d5f7dbc2e5db491de99f33fc2cff2d57029ac950e1ccd681980af6a4e8969dfe39b3c7bfcbcf8fac92f1e6ec9fe572bfa6a7d65860eab2ed10ac01a71290b52e3148e84b7376a8605cd2bb0e8681ffc54691ce087685e33921bd44d36c78291713dce17569570f62137e6904f0d68cf53aa2ec395c389a75141f08114fb293ea63950e4ffee55ec6fc83cf44876b8e7f25cdd393ff87b9eda6eb746085b61a6900de191f0ce2cb388d61ece52e78bc47368194e8e00277e0d1631e6b9d4626ef76f8522582ccd5a40be3febc699bb510acc6271d55ff0f4cf3bb7669855a72efd9ca3e1056a2fe592a5bc877cce2b1f63b58383971da87873d2d1349cf5881242cdce4e7e2c5c514755746a0e0a7c2a6d9701cde005ae3420beb17c379a3516662253554f51f0423bb1844b0b90c54ed8177ceb0e1036a6609d836e748ca06c40ca64befadc6443ec286a0ce464678e8d11eb455f7bb305acebf6cb1f50e394a9bfeb752df1687831bac9cdd811f4f112ef6658d0f8799a866374ff96c5e2b79f30e7a74f8a2bc9ed1f88f01f30e30cb78ffb2bff10108f35e910ee3be4463e9e6f0ed910e8d598326e71dfa2277ffe5579d7fe9b6018bfe295b25219eae07b3b0270665c3fa00c3e0d180812b5cd62925585de84a7c48a9a86dba96544a251654d1966e082432dc85b6149cf21e91a46020ec32b66d28ba3b6a90c0617bc6fdd55aea819af2bcf84864ad60c28fe3c9f8339d0aee68b39d97f63b6e082835d86119cf9b9fdc8b827c847ce40aa10e1577a710132316845e825345e95bdf94d0c66ec65a6c4319fce4792313663b5f7a651a6710783e6ab71608ac6cbbf3af6911adf596ccf7c172b9bd5bceb6db379967b32b143bdd11d2ee12ddf64ecef6391e0f8570e6cddd3db95204919362b89b739fa94e7c1bfde799fd5e22aa25ca6ca42e30c08e23aae2385d99ebab441072a880dcefdab74a4c9bd39d363f6d1933d59400fca161d432aa00f23b1b1c19a154be8989699d549b66d44e39896f5523443bc6ddf4a65e91f1f3fb7b52318869a05856a4fc92f3694c81ed833c972fb918f7e5\",\"cipherparams\":{\"iv\":\"8c46d6162cd4c765759aedcbce2a5874\"},\"kdf\":\"scrypt\",\"kdfparams\":{\"dklen\":32,\"n\":262144,\"p\":1,\"r\":8,\"salt\":\"82fb6cdc6917609135277badacf15baa31899d08b71a5a0fa33167167c161537\"},\"mac\":\"9187b17f7eca48e6b8c586b0cd790dbe0feb876ac8385f93faa7d5e22a3c8fc7\"},\"id\":\"92caf6ee-2d43-48c0-859e-ffa1e0e23312\",\"version\":3}",
|
|
915
|
+
)};
|
|
916
|
+
const TEST_WALLET_PASSPHRASE = "QuantumCoinExample123!";
|
|
917
|
+
|
|
918
|
+
async function main() {
|
|
919
|
+
const rpcUrl = process.env.QC_RPC_URL;
|
|
920
|
+
if (!rpcUrl) throw new Error("QC_RPC_URL is required");
|
|
921
|
+
const chainId = process.env.QC_CHAIN_ID ? Number(process.env.QC_CHAIN_ID) : 123123;
|
|
922
|
+
await Initialize(null);
|
|
923
|
+
|
|
924
|
+
const provider = new JsonRpcProvider(rpcUrl, chainId);
|
|
925
|
+
const wallet = Wallet.fromEncryptedJsonSync(TEST_WALLET_ENCRYPTED_JSON, TEST_WALLET_PASSPHRASE, provider);
|
|
926
|
+
|
|
927
|
+
const factory = new ${a.contractName}__factory(wallet);
|
|
928
|
+
const contract = await factory.deploy(${ctorArgsExpr}${ctorArgsExpr ? ", " : ""}{ gasLimit: 600000 });
|
|
929
|
+
const tx = contract.deployTransaction();
|
|
930
|
+
if (tx) await tx.wait(1, 600_000);
|
|
931
|
+
|
|
932
|
+
console.log("Deployed at:", contract.target);
|
|
933
|
+
console.log("Next:");
|
|
934
|
+
console.log(' $env:CONTRACT_ADDRESS="' + contract.target + '"');
|
|
935
|
+
console.log(" node examples/read-operations.js");
|
|
936
|
+
}
|
|
937
|
+
|
|
938
|
+
main().catch((e) => {
|
|
939
|
+
console.error(e);
|
|
940
|
+
process.exitCode = 1;
|
|
941
|
+
});
|
|
942
|
+
`,
|
|
730
943
|
);
|
|
731
944
|
|
|
732
945
|
_writeText(
|
|
733
|
-
path.join(outDir, "examples", "read-operations.
|
|
734
|
-
|
|
946
|
+
path.join(outDir, "examples", "read-operations.js"),
|
|
947
|
+
`/**
|
|
948
|
+
* Read operations example (generated).
|
|
949
|
+
*
|
|
950
|
+
* Requires:
|
|
951
|
+
* - QC_RPC_URL env var
|
|
952
|
+
* - CONTRACT_ADDRESS env var
|
|
953
|
+
*/
|
|
954
|
+
const { Initialize } = require("quantumcoin/config");
|
|
955
|
+
const { JsonRpcProvider } = require("quantumcoin");
|
|
956
|
+
const { ${a.contractName} } = require("..");
|
|
957
|
+
|
|
958
|
+
async function main() {
|
|
959
|
+
const rpcUrl = process.env.QC_RPC_URL;
|
|
960
|
+
if (!rpcUrl) throw new Error("QC_RPC_URL is required");
|
|
961
|
+
const chainId = process.env.QC_CHAIN_ID ? Number(process.env.QC_CHAIN_ID) : 123123;
|
|
962
|
+
const address = process.env.CONTRACT_ADDRESS;
|
|
963
|
+
if (!address) throw new Error("CONTRACT_ADDRESS is required");
|
|
964
|
+
await Initialize(null);
|
|
965
|
+
|
|
966
|
+
const provider = new JsonRpcProvider(rpcUrl, chainId);
|
|
967
|
+
const contract = ${a.contractName}.connect(address, provider);
|
|
968
|
+
|
|
969
|
+
console.log("Contract:", contract.target);
|
|
970
|
+
|
|
971
|
+
if (typeof contract.name === "function") {
|
|
972
|
+
console.log("name():", await contract.name());
|
|
973
|
+
}
|
|
974
|
+
if (typeof contract.symbol === "function") {
|
|
975
|
+
console.log("symbol():", await contract.symbol());
|
|
976
|
+
}
|
|
977
|
+
if (typeof contract.totalSupply === "function") {
|
|
978
|
+
// Generated wrappers already unwrap single-return values to a hard type.
|
|
979
|
+
const v = await contract.totalSupply();
|
|
980
|
+
console.log("totalSupply():", v.toString());
|
|
981
|
+
}
|
|
982
|
+
if (typeof contract.balanceOf === "function" && process.env.WALLET_ADDRESS) {
|
|
983
|
+
// Generated wrappers already unwrap single-return values to a hard type.
|
|
984
|
+
const v = await contract.balanceOf(process.env.WALLET_ADDRESS);
|
|
985
|
+
console.log("balanceOf(WALLET_ADDRESS):", v.toString());
|
|
986
|
+
}
|
|
987
|
+
}
|
|
988
|
+
|
|
989
|
+
main().catch((e) => {
|
|
990
|
+
console.error(e);
|
|
991
|
+
process.exitCode = 1;
|
|
992
|
+
});
|
|
993
|
+
`,
|
|
735
994
|
);
|
|
736
995
|
|
|
737
996
|
_writeText(
|
|
738
|
-
path.join(outDir, "examples", "write-operations.
|
|
739
|
-
|
|
997
|
+
path.join(outDir, "examples", "write-operations.js"),
|
|
998
|
+
`/**
|
|
999
|
+
* Write operations example (generated).
|
|
1000
|
+
*
|
|
1001
|
+
* Requires:
|
|
1002
|
+
* - QC_RPC_URL env var
|
|
1003
|
+
* - CONTRACT_ADDRESS env var
|
|
1004
|
+
*
|
|
1005
|
+
* WARNING: uses a hardcoded test wallet (funded) for convenience.
|
|
1006
|
+
*/
|
|
1007
|
+
const { Initialize } = require("quantumcoin/config");
|
|
1008
|
+
const { JsonRpcProvider, Wallet } = require("quantumcoin");
|
|
1009
|
+
const { ${a.contractName} } = require("..");
|
|
1010
|
+
|
|
1011
|
+
// Hardcoded test wallet (test-only; never use for real funds)
|
|
1012
|
+
const TEST_WALLET_ENCRYPTED_JSON =
|
|
1013
|
+
${JSON.stringify(
|
|
1014
|
+
"{\"address\":\"1a846abe71c8b989e8337c55d608be81c28ab3b2e40c83eaa2a68d516049aec6\",\"crypto\":{\"cipher\":\"aes-256-ctr\",\"ciphertext\":\"ab7e620dd66cb55ac201b9c6796de92bbb06f3681b5932eabe099871f1f7d79acabe30921a39ad13bfe74f42c515734882b6723760142aa3e26e011df514a534ae47bd15d86badd9c6f17c48d4c892711d54d441ee3a0ee0e5b060f816e79c7badd13ff4c235934b1986774223ecf6e8761388969bb239c759b54c8c70e6a2e27c93a4b70129c8159f461d271ae8f3573414c78b88e4d0abfa6365ed45456636d4ed971c7a0c6b84e6f0c2621e819268b135e2bcc169a54d1847b39e6ba2ae8ec969b69f330b7db9e785ed02204d5a1185915ae5338b0f40ef2a7f4d5aaf7563d502135e57f4eb89d5ec1efa5c77e374969d6cd85be625a2ed1225d68ecdd84067bfc69adb83ecd5c6050472eca28a5a646fcdd28077165c629975bec8a79fe1457cb53389b788b25e1f8eff8b2ca326d7dfcaba3f8839225a08057c018a458891fd2caa0d2b27632cffd80f592147ccec9a10dc8a08a48fb55047bff5cf85cda39eb089096bef63842fc3686412f298a54a9e4b0bf4ad36907ba373cbd6d32e7ac494af371da5aa9d38a3463220865114c4adc5e4ac258ba9c6af9fa2ddfd1aec2e16887e4b3977c69561df8599ac9d411c9dd2a4d57f92ea4e5c02aae3f49fb3bc83e16673e6c2dbe96bb181c8dfd0f9757ade2e4ff27215a836058c5ffeab042f6f97c7c02339f76a6284680e01b4bb733690eb3347fbfcc26614b8bf755f9dfce3fea9d4e4d15b164983201732c2e87593a86bca6da6972e128490338f76ae68135888070f4e59e90db54d23834769bdbda9769213faf5357f9167a224523975a946367b68f0cec98658575609f58bfd329e420a921c06713326e4cb20a0df1d77f37e78a320a637a96c604ca3fa89e24beb42313751b8f09b14f9c14c77e4fd13fc6382505d27c771bca0d821ec7c3765acffa99d83c50140a56b0b28101c762bd682fe55cb6f23cbeb3f421d7b36021010e45ac27160dd7ead99c864a1b550c7edb1246950fe32dcc049799f9085287f0a747a6ef7a023df46a23a22f3e833bbf8d404f84344870492658256ee1dfc40fda33bb8d48fc72d4520ba9fc820c9123104a045206809037709f2a5f6723fa77d6bac5a573823d4ec3a7f1cb786a52ee2697e622e5d75962fa554d1024a6c355e21f33a63b2b72e6c4742a8b1c373aa532b40518c38c90b5373c2eb8c9d7be2a9e16047a3ee09dc9a6849deac5183ace6cfe91a9bef2ffc0a7df6ccebfd4c858c84b0e0355650d7466971e66f1e3883013e5ad1be33199b1d110b79070ac1b745ccb14cf63a08f8cca3a21c9525e626ff5f0c34746e10750fb742ad51f11f2acae3676c2111853d7250d01b77821a6ba9e04400ba2c543ca9f2d701ae6f47bfad14ffe3039ee9e71f7b2401359ade9938750ddb9c5a8b018a7929ed8d0e717ff1861446ce17535e9b17c187711190aae3388bd9490837a636c25ed4d42d7079ad1a51e13292c683d5d012abcf46965c534b83ab53f2c1f0cf5830ef7582e06863a33c19a70511df632885d63245965047ea96b56f1af5b3b94a54999f784fb9574fdfcd7c1230e07a2aaa04acd3097b2b9f8ddba05ae9734491deb5c1a513c76ed276cb78bbf4839dae3156d76af444a5805129d5df791167a9c8576a1d7f760b2d2797c4658669608706fbd0ace1be2346f74862dfc9ef518e55632e43c043186e5d070deb34d12fb9e5aba84e5cb50213dc88efd39cc35bf42455aa82d5e3b707b3140be3b8623b34fdd81d08615c188ae8438a13881fdf6bf32f2cb9ff5fa625561040c6b71d4b8eccc90bc3b99650d28dd1ee63773e49664e3d48c484996b290943635a6f2eb1ce9796d3fa144a3f00ef82faaa32d6a413668f7b521517cb68b2b017fcf56c79326fa5e4060e643631ca3f0a0dc0ed718798b6f46b130d437c33f64039e887324b6f5e604b1669d613923794edbf04b1b3caea54793b52b44b170173a4f25c7ecef3b71e2aad76e556b1cb9f1d637ec52ececfa950dd31dbb6a60828a3ad34c1beffe09eb4785786d63bad10a0b0f66ea88c57380f38ea85f018dbd7f538cf1ee7624095b9a01ec5edd528f281168af020609e651ff316aa1320a710134ddfca600cc72174dcdb846d2aa29916488aa1b537b66da92e61af526debef4eb38c984569eaf549ff2129449269b492d030cd74d885f6f5785881cc4804b4a8a09ba4ff7aefe9074ac7d0c4f05d51fe4cc0ff7388a772092b9d02d70e5433a5cf3e02f46a6bd6b818d59a07ce3b9fbbf8b5faba74563bcc5240930c2d406c9aaee3e3ce0429bf68ac2b0a57adb09414cff50817d2a48fb9fa624ab863cb0c31a8b8dc5eaf6fa68cc1d7c6c685c5a33edd5c8933b9e8ab628ee428d0743699b2ff17f25586c7ce959280bb0b8c5342251f0a30b53dbc7bf1ee426ac9619c3560f811f2268ee37f189794e2e4b3db3a2fb2e34b649e504fb467438abfd1082619cc4a0b30d66beb831077812e418d2e2148db10cf4d4a29101ca52ec445b8d83519dd7de85a98e0beae9ee537096d3f1a55a7a80cdfa93d25f07c9f98e8af18cde19ec1f99c5dd4588b717a5039ddb7f177717caf0d0fd45420a70dbd6d3146890d9e450d5224146db4c33b779e3c3a04b976c052bad042ac57dd38be45407808c0fb0d7e2a8819e6cd53c6739e6612996ddaa6f066552590aa0343bc1e62b298ff2514a0cef8be21956c2e942816f7a3a3a0935eaf9b37251409ce444c986c3817e82835555fe18239f3ae33469d7965c2bde9991fde556bd07af01df52bbde0c35bb4ef48e3b5d0db53f8ca4ed35b83f760f0a1bc4ed9f86e85d6039a17df373c85402ef956f01db00eb39c4b74bd0660d29ee746714d9780d738e05c6cca414ce3d7b40dda8036a9eea9ab1388805f913eb19bdd3f09d9e161eaa50231bd9caba61971f194332dd28c696a60458c1c6c2cc5da8b1192611c7c553e9e12fe48ce46bbb891be8bb118721c86222e671ddd1da8f0ccb2b68e02f2014b4925e904e88369aaf7466bd7033a60c265d45955944916ecbdb84bf1b522b01b0149c632e04c568a7eb627c5bb90ece052ebcf79166c28b30d23fe52da0a5ab5dea83ca479a3e3b7a9cfbbfea04dbe6137c19d067317c2ec427a8c75a6b06bec6dcd5d5c0edc9aa80b9003b8e17c088b2f3db327d3e42630d82d20120240c3ba56232280787da4aabbf5bc95a864029f00710e195f2a76460a0317d10b552fe1bea097e41d49756c680a41d6ac186e62169b6b6cd7776ea84618b5b752328a5bacaa10aa122ff9b2698b43efe73d852a899db644863c8c9bc8068ea86ea843fd6fe36272b91cdc5d5317083ef3fd1e5462a0b0d0604dc57b3bbfceb0fca4cd349625dd7b25166af30efe5ee6a0af953a74d65f4736c59918ee55a3b0d9d9d42e04c7f8a77e479109f740e20c464d5d7e3d16805f47b61f403ff7f408c9e850d9baacd8067e544536a4953480b0f9ee9cd45f41ebd67b51f78788a6470cb1e5ca72ca346ce8a50d0ca0c921d5576a4455a1afb6d0bc688004712ee122cacdb29c51e84893324c27fa4a3f1917edf5352272b4c97579a6152e4b77663d0ab532915f2eeb6a862de8b696452321b660c3f2449673d086e95a7af28845a5259b763e0fcd09f72acf7b6c811066263060e5aa5b24658e880a01fd56bda4dad5ab604e129290f7d5489728f2a40968c6168b21cebbbcd11727cc9e9160c4e92e04387d3b0d62aab06a61f26daedd9fed11816ef2180172a47f47184ac4032b88758c98a2e0fb200f70e93ba695f5ebb7a1029610ad360d3b7fa1b4640b9dc674d3625eef786da93dff19bc7991b5d6193a3896664763fde479b5dfc04812111a80782854f2cf68ca7d82765cc9eb40fba4b44640710ed6e653abf9f07b466333f4fd22784d53cf40e17120f42caa841eaa24056b237827b0f47f7257c103c35027e9f503e5acfd023e7357b600d3084d361d5ee65ba319b45c153212a54e6fed85af7e43e0a926ebcbc2edf8de7e2ec9528f00bec262ad04d5c9dafccaea06a24748d28bf1799bae0e895543084539c50b5aaa4fb50d7431d6f0c8cee2a54aaf7ee7919b55bf40adb688632e5dbe273cea09e97b19c3d8e1f4de000deb66fa1942ad03a62d3252f51992244366c156000b49c297167a6cbdedea7ebae139d295f0ad298e0864249b905b7eb812886ec70ecdb286702274b5b8574149bf3866f9e46b997ff5ed622b169a0eb071347f18d530db1663906a28f4544ee4e004ab87b65476af30ede118052ff052b8dc986ca2c93dd5d4943266a579c7698ea014f688b3e8063a107feb162d392e2177b01bff77fb5abe5feebd0607158049a5a093325b7c9ee6b4dfa7a9f65c7c2fb628920d3603a1c2dad979eaa047cd661a268af1078c9788d720e64e4ce9d12e68de1e417ef2f293323681e1071f9220e1ee43d2e29d111b870ce3439f5100ecd4551ab65ee74aa1667e564957e9bc0ae1ea193980da2a0ec2698073388c85bec25ef447f0d5e93a5203fa44dff268e5cb799ed3b66e63d5e07b487e7534f24934c73a62a243e0151843a0fd3807711a101eaa7fc71f0ba68aebb9534d57cba41b094eebfb4c31cca8eddfa426f676aa347be8a7023a4e91ddb154b35cd4d5f7dbc2e5db491de99f33fc2cff2d57029ac950e1ccd681980af6a4e8969dfe39b3c7bfcbcf8fac92f1e6ec9fe572bfa6a7d65860eab2ed10ac01a71290b52e3148e84b7376a8605cd2bb0e8681ffc54691ce087685e33921bd44d36c78291713dce17569570f62137e6904f0d68cf53aa2ec395c389a75141f08114fb293ea63950e4ffee55ec6fc83cf44876b8e7f25cdd393ff87b9eda6eb746085b61a6900de191f0ce2cb388d61ece52e78bc47368194e8e00277e0d1631e6b9d4626ef76f8522582ccd5a40be3febc699bb510acc6271d55ff0f4cf3bb7669855a72efd9ca3e1056a2fe592a5bc877cce2b1f63b58383971da87873d2d1349cf5881242cdce4e7e2c5c514755746a0e0a7c2a6d9701cde005ae3420beb17c379a3516662253554f51f0423bb1844b0b90c54ed8177ceb0e1036a6609d836e748ca06c40ca64befadc6443ec286a0ce464678e8d11eb455f7bb305acebf6cb1f50e394a9bfeb752df1687831bac9cdd811f4f112ef6658d0f8799a866374ff96c5e2b79f30e7a74f8a2bc9ed1f88f01f30e30cb78ffb2bff10108f35e910ee3be4463e9e6f0ed910e8d598326e71dfa2277ffe5579d7fe9b6018bfe295b25219eae07b3b0270665c3fa00c3e0d180812b5cd62925585de84a7c48a9a86dba96544a251654d1966e082432dc85b6149cf21e91a46020ec32b66d28ba3b6a90c0617bc6fdd55aea819af2bcf84864ad60c28fe3c9f8339d0aee68b39d97f63b6e082835d86119cf9b9fdc8b827c847ce40aa10e1577a710132316845e825345e95bdf94d0c66ec65a6c4319fce4792313663b5f7a651a6710783e6ab71608ac6cbbf3af6911adf596ccf7c172b9bd5bceb6db379967b32b143bdd11d2ee12ddf64ecef6391e0f8570e6cddd3db95204919362b89b739fa94e7c1bfde799fd5e22aa25ca6ca42e30c08e23aae2385d99ebab441072a880dcefdab74a4c9bd39d363f6d1933d59400fca161d432aa00f23b1b1c19a154be8989699d549b66d44e39896f5523443bc6ddf4a65e91f1f3fb7b52318869a05856a4fc92f3694c81ed833c972fb918f7e5\",\"cipherparams\":{\"iv\":\"8c46d6162cd4c765759aedcbce2a5874\"},\"kdf\":\"scrypt\",\"kdfparams\":{\"dklen\":32,\"n\":262144,\"p\":1,\"r\":8,\"salt\":\"82fb6cdc6917609135277badacf15baa31899d08b71a5a0fa33167167c161537\"},\"mac\":\"9187b17f7eca48e6b8c586b0cd790dbe0feb876ac8385f93faa7d5e22a3c8fc7\"},\"id\":\"92caf6ee-2d43-48c0-859e-ffa1e0e23312\",\"version\":3}",
|
|
1015
|
+
)};
|
|
1016
|
+
const TEST_WALLET_PASSPHRASE = "QuantumCoinExample123!";
|
|
1017
|
+
|
|
1018
|
+
async function main() {
|
|
1019
|
+
const rpcUrl = process.env.QC_RPC_URL;
|
|
1020
|
+
if (!rpcUrl) throw new Error("QC_RPC_URL is required");
|
|
1021
|
+
const chainId = process.env.QC_CHAIN_ID ? Number(process.env.QC_CHAIN_ID) : 123123;
|
|
1022
|
+
const address = process.env.CONTRACT_ADDRESS;
|
|
1023
|
+
if (!address) throw new Error("CONTRACT_ADDRESS is required");
|
|
1024
|
+
await Initialize(null);
|
|
1025
|
+
|
|
1026
|
+
const provider = new JsonRpcProvider(rpcUrl, chainId);
|
|
1027
|
+
const wallet = Wallet.fromEncryptedJsonSync(TEST_WALLET_ENCRYPTED_JSON, TEST_WALLET_PASSPHRASE, provider);
|
|
1028
|
+
const contract = ${a.contractName}.connect(address, wallet);
|
|
1029
|
+
|
|
1030
|
+
if (typeof contract.approve === "function") {
|
|
1031
|
+
const tx = await contract.approve(wallet.address, 123, { gasLimit: 200000 });
|
|
1032
|
+
await tx.wait(1, 600_000);
|
|
1033
|
+
console.log("approve(wallet.address, 123) succeeded");
|
|
1034
|
+
return;
|
|
1035
|
+
}
|
|
1036
|
+
|
|
1037
|
+
console.log("No known write method template for this ABI.");
|
|
1038
|
+
}
|
|
1039
|
+
|
|
1040
|
+
main().catch((e) => {
|
|
1041
|
+
console.error(e);
|
|
1042
|
+
process.exitCode = 1;
|
|
1043
|
+
});
|
|
1044
|
+
`,
|
|
740
1045
|
);
|
|
741
1046
|
|
|
742
1047
|
_writeText(
|
|
743
|
-
path.join(outDir, "examples", "
|
|
744
|
-
|
|
1048
|
+
path.join(outDir, "examples", "offline-signing.js"),
|
|
1049
|
+
`/**
|
|
1050
|
+
* Offline signing example (generated).
|
|
1051
|
+
*
|
|
1052
|
+
* Demonstrates:
|
|
1053
|
+
* - ${a.contractName}__factory.getDeployTransaction(...)
|
|
1054
|
+
* - contract.populateTransaction.<method>(...)
|
|
1055
|
+
* - wallet.signTransaction(txReq) (offline) + provider.sendRawTransaction(rawTx)
|
|
1056
|
+
*
|
|
1057
|
+
* Requires:
|
|
1058
|
+
* - QC_RPC_URL env var
|
|
1059
|
+
*
|
|
1060
|
+
* WARNING: uses a hardcoded test wallet (funded) for convenience.
|
|
1061
|
+
*/
|
|
1062
|
+
const { Initialize } = require("quantumcoin/config");
|
|
1063
|
+
const { JsonRpcProvider, Wallet, getCreateAddress } = require("quantumcoin");
|
|
1064
|
+
const { ${a.contractName}, ${a.contractName}__factory } = require("..");
|
|
1065
|
+
|
|
1066
|
+
// Hardcoded test wallet (test-only; never use for real funds)
|
|
1067
|
+
const TEST_WALLET_ENCRYPTED_JSON =
|
|
1068
|
+
${JSON.stringify(
|
|
1069
|
+
"{\"address\":\"1a846abe71c8b989e8337c55d608be81c28ab3b2e40c83eaa2a68d516049aec6\",\"crypto\":{\"cipher\":\"aes-256-ctr\",\"ciphertext\":\"ab7e620dd66cb55ac201b9c6796de92bbb06f3681b5932eabe099871f1f7d79acabe30921a39ad13bfe74f42c515734882b6723760142aa3e26e011df514a534ae47bd15d86badd9c6f17c48d4c892711d54d441ee3a0ee0e5b060f816e79c7badd13ff4c235934b1986774223ecf6e8761388969bb239c759b54c8c70e6a2e27c93a4b70129c8159f461d271ae8f3573414c78b88e4d0abfa6365ed45456636d4ed971c7a0c6b84e6f0c2621e819268b135e2bcc169a54d1847b39e6ba2ae8ec969b69f330b7db9e785ed02204d5a1185915ae5338b0f40ef2a7f4d5aaf7563d502135e57f4eb89d5ec1efa5c77e374969d6cd85be625a2ed1225d68ecdd84067bfc69adb83ecd5c6050472eca28a5a646fcdd28077165c629975bec8a79fe1457cb53389b788b25e1f8eff8b2ca326d7dfcaba3f8839225a08057c018a458891fd2caa0d2b27632cffd80f592147ccec9a10dc8a08a48fb55047bff5cf85cda39eb089096bef63842fc3686412f298a54a9e4b0bf4ad36907ba373cbd6d32e7ac494af371da5aa9d38a3463220865114c4adc5e4ac258ba9c6af9fa2ddfd1aec2e16887e4b3977c69561df8599ac9d411c9dd2a4d57f92ea4e5c02aae3f49fb3bc83e16673e6c2dbe96bb181c8dfd0f9757ade2e4ff27215a836058c5ffeab042f6f97c7c02339f76a6284680e01b4bb733690eb3347fbfcc26614b8bf755f9dfce3fea9d4e4d15b164983201732c2e87593a86bca6da6972e128490338f76ae68135888070f4e59e90db54d23834769bdbda9769213faf5357f9167a224523975a946367b68f0cec98658575609f58bfd329e420a921c06713326e4cb20a0df1d77f37e78a320a637a96c604ca3fa89e24beb42313751b8f09b14f9c14c77e4fd13fc6382505d27c771bca0d821ec7c3765acffa99d83c50140a56b0b28101c762bd682fe55cb6f23cbeb3f421d7b36021010e45ac27160dd7ead99c864a1b550c7edb1246950fe32dcc049799f9085287f0a747a6ef7a023df46a23a22f3e833bbf8d404f84344870492658256ee1dfc40fda33bb8d48fc72d4520ba9fc820c9123104a045206809037709f2a5f6723fa77d6bac5a573823d4ec3a7f1cb786a52ee2697e622e5d75962fa554d1024a6c355e21f33a63b2b72e6c4742a8b1c373aa532b40518c38c90b5373c2eb8c9d7be2a9e16047a3ee09dc9a6849deac5183ace6cfe91a9bef2ffc0a7df6ccebfd4c858c84b0e0355650d7466971e66f1e3883013e5ad1be33199b1d110b79070ac1b745ccb14cf63a08f8cca3a21c9525e626ff5f0c34746e10750fb742ad51f11f2acae3676c2111853d7250d01b77821a6ba9e04400ba2c543ca9f2d701ae6f47bfad14ffe3039ee9e71f7b2401359ade9938750ddb9c5a8b018a7929ed8d0e717ff1861446ce17535e9b17c187711190aae3388bd9490837a636c25ed4d42d7079ad1a51e13292c683d5d012abcf46965c534b83ab53f2c1f0cf5830ef7582e06863a33c19a70511df632885d63245965047ea96b56f1af5b3b94a54999f784fb9574fdfcd7c1230e07a2aaa04acd3097b2b9f8ddba05ae9734491deb5c1a513c76ed276cb78bbf4839dae3156d76af444a5805129d5df791167a9c8576a1d7f760b2d2797c4658669608706fbd0ace1be2346f74862dfc9ef518e55632e43c043186e5d070deb34d12fb9e5aba84e5cb50213dc88efd39cc35bf42455aa82d5e3b707b3140be3b8623b34fdd81d08615c188ae8438a13881fdf6bf32f2cb9ff5fa625561040c6b71d4b8eccc90bc3b99650d28dd1ee63773e49664e3d48c484996b290943635a6f2eb1ce9796d3fa144a3f00ef82faaa32d6a413668f7b521517cb68b2b017fcf56c79326fa5e4060e643631ca3f0a0dc0ed718798b6f46b130d437c33f64039e887324b6f5e604b1669d613923794edbf04b1b3caea54793b52b44b170173a4f25c7ecef3b71e2aad76e556b1cb9f1d637ec52ececfa950dd31dbb6a60828a3ad34c1beffe09eb4785786d63bad10a0b0f66ea88c57380f38ea85f018dbd7f538cf1ee7624095b9a01ec5edd528f281168af020609e651ff316aa1320a710134ddfca600cc72174dcdb846d2aa29916488aa1b537b66da92e61af526debef4eb38c984569eaf549ff2129449269b492d030cd74d885f6f5785881cc4804b4a8a09ba4ff7aefe9074ac7d0c4f05d51fe4cc0ff7388a772092b9d02d70e5433a5cf3e02f46a6bd6b818d59a07ce3b9fbbf8b5faba74563bcc5240930c2d406c9aaee3e3ce0429bf68ac2b0a57adb09414cff50817d2a48fb9fa624ab863cb0c31a8b8dc5eaf6fa68cc1d7c6c685c5a33edd5c8933b9e8ab628ee428d0743699b2ff17f25586c7ce959280bb0b8c5342251f0a30b53dbc7bf1ee426ac9619c3560f811f2268ee37f189794e2e4b3db3a2fb2e34b649e504fb467438abfd1082619cc4a0b30d66beb831077812e418d2e2148db10cf4d4a29101ca52ec445b8d83519dd7de85a98e0beae9ee537096d3f1a55a7a80cdfa93d25f07c9f98e8af18cde19ec1f99c5dd4588b717a5039ddb7f177717caf0d0fd45420a70dbd6d3146890d9e450d5224146db4c33b779e3c3a04b976c052bad042ac57dd38be45407808c0fb0d7e2a8819e6cd53c6739e6612996ddaa6f066552590aa0343bc1e62b298ff2514a0cef8be21956c2e942816f7a3a3a0935eaf9b37251409ce444c986c3817e82835555fe18239f3ae33469d7965c2bde9991fde556bd07af01df52bbde0c35bb4ef48e3b5d0db53f8ca4ed35b83f760f0a1bc4ed9f86e85d6039a17df373c85402ef956f01db00eb39c4b74bd0660d29ee746714d9780d738e05c6cca414ce3d7b40dda8036a9eea9ab1388805f913eb19bdd3f09d9e161eaa50231bd9caba61971f194332dd28c696a60458c1c6c2cc5da8b1192611c7c553e9e12fe48ce46bbb891be8bb118721c86222e671ddd1da8f0ccb2b68e02f2014b4925e904e88369aaf7466bd7033a60c265d45955944916ecbdb84bf1b522b01b0149c632e04c568a7eb627c5bb90ece052ebcf79166c28b30d23fe52da0a5ab5dea83ca479a3e3b7a9cfbbfea04dbe6137c19d067317c2ec427a8c75a6b06bec6dcd5d5c0edc9aa80b9003b8e17c088b2f3db327d3e42630d82d20120240c3ba56232280787da4aabbf5bc95a864029f00710e195f2a76460a0317d10b552fe1bea097e41d49756c680a41d6ac186e62169b6b6cd7776ea84618b5b752328a5bacaa10aa122ff9b2698b43efe73d852a899db644863c8c9bc8068ea86ea843fd6fe36272b91cdc5d5317083ef3fd1e5462a0b0d0604dc57b3bbfceb0fca4cd349625dd7b25166af30efe5ee6a0af953a74d65f4736c59918ee55a3b0d9d9d42e04c7f8a77e479109f740e20c464d5d7e3d16805f47b61f403ff7f408c9e850d9baacd8067e544536a4953480b0f9ee9cd45f41ebd67b51f78788a6470cb1e5ca72ca346ce8a50d0ca0c921d5576a4455a1afb6d0bc688004712ee122cacdb29c51e84893324c27fa4a3f1917edf5352272b4c97579a6152e4b77663d0ab532915f2eeb6a862de8b696452321b660c3f2449673d086e95a7af28845a5259b763e0fcd09f72acf7b6c811066263060e5aa5b24658e880a01fd56bda4dad5ab604e129290f7d5489728f2a40968c6168b21cebbbcd11727cc9e9160c4e92e04387d3b0d62aab06a61f26daedd9fed11816ef2180172a47f47184ac4032b88758c98a2e0fb200f70e93ba695f5ebb7a1029610ad360d3b7fa1b4640b9dc674d3625eef786da93dff19bc7991b5d6193a3896664763fde479b5dfc04812111a80782854f2cf68ca7d82765cc9eb40fba4b44640710ed6e653abf9f07b466333f4fd22784d53cf40e17120f42caa841eaa24056b237827b0f47f7257c103c35027e9f503e5acfd023e7357b600d3084d361d5ee65ba319b45c153212a54e6fed85af7e43e0a926ebcbc2edf8de7e2ec9528f00bec262ad04d5c9dafccaea06a24748d28bf1799bae0e895543084539c50b5aaa4fb50d7431d6f0c8cee2a54aaf7ee7919b55bf40adb688632e5dbe273cea09e97b19c3d8e1f4de000deb66fa1942ad03a62d3252f51992244366c156000b49c297167a6cbdedea7ebae139d295f0ad298e0864249b905b7eb812886ec70ecdb286702274b5b8574149bf3866f9e46b997ff5ed622b169a0eb071347f18d530db1663906a28f4544ee4e004ab87b65476af30ede118052ff052b8dc986ca2c93dd5d4943266a579c7698ea014f688b3e8063a107feb162d392e2177b01bff77fb5abe5feebd0607158049a5a093325b7c9ee6b4dfa7a9f65c7c2fb628920d3603a1c2dad979eaa047cd661a268af1078c9788d720e64e4ce9d12e68de1e417ef2f293323681e1071f9220e1ee43d2e29d111b870ce3439f5100ecd4551ab65ee74aa1667e564957e9bc0ae1ea193980da2a0ec2698073388c85bec25ef447f0d5e93a5203fa44dff268e5cb799ed3b66e63d5e07b487e7534f24934c73a62a243e0151843a0fd3807711a101eaa7fc71f0ba68aebb9534d57cba41b094eebfb4c31cca8eddfa426f676aa347be8a7023a4e91ddb154b35cd4d5f7dbc2e5db491de99f33fc2cff2d57029ac950e1ccd681980af6a4e8969dfe39b3c7bfcbcf8fac92f1e6ec9fe572bfa6a7d65860eab2ed10ac01a71290b52e3148e84b7376a8605cd2bb0e8681ffc54691ce087685e33921bd44d36c78291713dce17569570f62137e6904f0d68cf53aa2ec395c389a75141f08114fb293ea63950e4ffee55ec6fc83cf44876b8e7f25cdd393ff87b9eda6eb746085b61a6900de191f0ce2cb388d61ece52e78bc47368194e8e00277e0d1631e6b9d4626ef76f8522582ccd5a40be3febc699bb510acc6271d55ff0f4cf3bb7669855a72efd9ca3e1056a2fe592a5bc877cce2b1f63b58383971da87873d2d1349cf5881242cdce4e7e2c5c514755746a0e0a7c2a6d9701cde005ae3420beb17c379a3516662253554f51f0423bb1844b0b90c54ed8177ceb0e1036a6609d836e748ca06c40ca64befadc6443ec286a0ce464678e8d11eb455f7bb305acebf6cb1f50e394a9bfeb752df1687831bac9cdd811f4f112ef6658d0f8799a866374ff96c5e2b79f30e7a74f8a2bc9ed1f88f01f30e30cb78ffb2bff10108f35e910ee3be4463e9e6f0ed910e8d598326e71dfa2277ffe5579d7fe9b6018bfe295b25219eae07b3b0270665c3fa00c3e0d180812b5cd62925585de84a7c48a9a86dba96544a251654d1966e082432dc85b6149cf21e91a46020ec32b66d28ba3b6a90c0617bc6fdd55aea819af2bcf84864ad60c28fe3c9f8339d0aee68b39d97f63b6e082835d86119cf9b9fdc8b827c847ce40aa10e1577a710132316845e825345e95bdf94d0c66ec65a6c4319fce4792313663b5f7a651a6710783e6ab71608ac6cbbf3af6911adf596ccf7c172b9bd5bceb6db379967b32b143bdd11d2ee12ddf64ecef6391e0f8570e6cddd3db95204919362b89b739fa94e7c1bfde799fd5e22aa25ca6ca42e30c08e23aae2385d99ebab441072a880dcefdab74a4c9bd39d363f6d1933d59400fca161d432aa00f23b1b1c19a154be8989699d549b66d44e39896f5523443bc6ddf4a65e91f1f3fb7b52318869a05856a4fc92f3694c81ed833c972fb918f7e5\",\"cipherparams\":{\"iv\":\"8c46d6162cd4c765759aedcbce2a5874\"},\"kdf\":\"scrypt\",\"kdfparams\":{\"dklen\":32,\"n\":262144,\"p\":1,\"r\":8,\"salt\":\"82fb6cdc6917609135277badacf15baa31899d08b71a5a0fa33167167c161537\"},\"mac\":\"9187b17f7eca48e6b8c586b0cd790dbe0feb876ac8385f93faa7d5e22a3c8fc7\"},\"id\":\"92caf6ee-2d43-48c0-859e-ffa1e0e23312\",\"version\":3}",
|
|
1070
|
+
)};
|
|
1071
|
+
const TEST_WALLET_PASSPHRASE = "QuantumCoinExample123!";
|
|
1072
|
+
|
|
1073
|
+
async function main() {
|
|
1074
|
+
const rpcUrl = process.env.QC_RPC_URL;
|
|
1075
|
+
if (!rpcUrl) throw new Error("QC_RPC_URL is required");
|
|
1076
|
+
const chainId = process.env.QC_CHAIN_ID ? Number(process.env.QC_CHAIN_ID) : 123123;
|
|
1077
|
+
|
|
1078
|
+
await Initialize(null);
|
|
1079
|
+
const provider = new JsonRpcProvider(rpcUrl, chainId);
|
|
1080
|
+
|
|
1081
|
+
// Offline wallet (no provider attached). We'll resolve nonce from provider manually.
|
|
1082
|
+
const wallet = Wallet.fromEncryptedJsonSync(TEST_WALLET_ENCRYPTED_JSON, TEST_WALLET_PASSPHRASE);
|
|
1083
|
+
const from = wallet.address;
|
|
1084
|
+
|
|
1085
|
+
const factory = new ${a.contractName}__factory(wallet);
|
|
1086
|
+
const deployTxReq = factory.getDeployTransaction(${ctorArgsExpr});
|
|
1087
|
+
|
|
1088
|
+
let gasLimit = 600000;
|
|
1089
|
+
try {
|
|
1090
|
+
const est = await provider.estimateGas({ from, data: deployTxReq.data });
|
|
1091
|
+
gasLimit = Number(est + 200_000n);
|
|
1092
|
+
} catch {
|
|
1093
|
+
gasLimit = 6_000_000;
|
|
1094
|
+
}
|
|
1095
|
+
const bytecodeSize = (${a.contractName}.bytecode || "").length;
|
|
1096
|
+
if (bytecodeSize > 20000 && gasLimit < 6_000_000) gasLimit = 6_000_000;
|
|
1097
|
+
|
|
1098
|
+
const nonce0 = await provider.getTransactionCount(from, "pending");
|
|
1099
|
+
const predicted = getCreateAddress({ from, nonce: nonce0 });
|
|
1100
|
+
|
|
1101
|
+
const rawDeploy = await wallet.signTransaction({
|
|
1102
|
+
...deployTxReq,
|
|
1103
|
+
nonce: nonce0,
|
|
1104
|
+
chainId,
|
|
1105
|
+
gasLimit,
|
|
1106
|
+
gasPrice: 1n,
|
|
1107
|
+
});
|
|
1108
|
+
|
|
1109
|
+
const sentDeploy = await provider.sendRawTransaction(rawDeploy);
|
|
1110
|
+
console.log("deploy tx hash:", sentDeploy.hash);
|
|
1111
|
+
await sentDeploy.wait(1, 600_000);
|
|
1112
|
+
|
|
1113
|
+
const contract = ${a.contractName}.connect(predicted, provider);
|
|
1114
|
+
console.log("deployed at:", contract.target);
|
|
1115
|
+
|
|
1116
|
+
// Optional: offline-sign a write method if present (ERC20-like approve)
|
|
1117
|
+
if (contract.populateTransaction && typeof contract.populateTransaction.approve === "function") {
|
|
1118
|
+
const txReq = await contract.populateTransaction.approve(from, 123, { gasLimit: 200000 });
|
|
1119
|
+
const nonce1 = await provider.getTransactionCount(from, "pending");
|
|
1120
|
+
const raw = await wallet.signTransaction({ ...txReq, nonce: nonce1, chainId, gasPrice: 1n });
|
|
1121
|
+
const sent = await provider.sendRawTransaction(raw);
|
|
1122
|
+
console.log("approve tx hash:", sent.hash);
|
|
1123
|
+
await sent.wait(1, 600_000);
|
|
1124
|
+
console.log("approve succeeded");
|
|
1125
|
+
} else {
|
|
1126
|
+
console.log("No known write method for offline-signing demo (skipping write tx).");
|
|
1127
|
+
}
|
|
1128
|
+
}
|
|
1129
|
+
|
|
1130
|
+
main().catch((e) => {
|
|
1131
|
+
console.error(e);
|
|
1132
|
+
process.exitCode = 1;
|
|
1133
|
+
});
|
|
1134
|
+
`,
|
|
1135
|
+
);
|
|
1136
|
+
|
|
1137
|
+
_writeText(
|
|
1138
|
+
path.join(outDir, "examples", "events.js"),
|
|
1139
|
+
`/**
|
|
1140
|
+
* Events/logs example (generated).
|
|
1141
|
+
*
|
|
1142
|
+
* Requires:
|
|
1143
|
+
* - QC_RPC_URL env var
|
|
1144
|
+
* - CONTRACT_ADDRESS env var
|
|
1145
|
+
*/
|
|
1146
|
+
const { Initialize } = require("quantumcoin/config");
|
|
1147
|
+
const { JsonRpcProvider } = require("quantumcoin");
|
|
1148
|
+
const { ${a.contractName} } = require("..");
|
|
1149
|
+
|
|
1150
|
+
async function main() {
|
|
1151
|
+
const rpcUrl = process.env.QC_RPC_URL;
|
|
1152
|
+
if (!rpcUrl) throw new Error("QC_RPC_URL is required");
|
|
1153
|
+
const chainId = process.env.QC_CHAIN_ID ? Number(process.env.QC_CHAIN_ID) : 123123;
|
|
1154
|
+
const address = process.env.CONTRACT_ADDRESS;
|
|
1155
|
+
if (!address) throw new Error("CONTRACT_ADDRESS is required");
|
|
1156
|
+
await Initialize(null);
|
|
1157
|
+
|
|
1158
|
+
const provider = new JsonRpcProvider(rpcUrl, chainId);
|
|
1159
|
+
const contract = ${a.contractName}.connect(address, provider);
|
|
1160
|
+
|
|
1161
|
+
const fromBlock = process.env.FROM_BLOCK ? Number(process.env.FROM_BLOCK) : "latest";
|
|
1162
|
+
const toBlock = process.env.TO_BLOCK ? Number(process.env.TO_BLOCK) : "latest";
|
|
1163
|
+
|
|
1164
|
+
const logs = await contract.queryFilter("Transfer", fromBlock, toBlock);
|
|
1165
|
+
console.log("Logs:", logs.length);
|
|
1166
|
+
for (const l of logs.slice(0, 10)) {
|
|
1167
|
+
console.log(l);
|
|
1168
|
+
}
|
|
1169
|
+
}
|
|
1170
|
+
|
|
1171
|
+
main().catch((e) => {
|
|
1172
|
+
console.error(e);
|
|
1173
|
+
process.exitCode = 1;
|
|
1174
|
+
});
|
|
1175
|
+
`,
|
|
745
1176
|
);
|
|
746
1177
|
} else {
|
|
747
1178
|
// Multi-contract: avoid filename collisions.
|
|
748
1179
|
for (const a of artifacts) {
|
|
749
1180
|
const ctor = _findConstructor(a.abi);
|
|
750
|
-
const ctorArgsExpr = (ctor.inputs || []).map((i) => _solTypeToExampleValueExpr(i
|
|
1181
|
+
const ctorArgsExpr = (ctor.inputs || []).map((i) => _solTypeToExampleValueExpr(i)).join(", ");
|
|
1182
|
+
|
|
1183
|
+
_writeText(
|
|
1184
|
+
path.join(outDir, "examples", `deploy-${a.contractName}.js`),
|
|
1185
|
+
`const { Initialize } = require("quantumcoin/config");\nconst { JsonRpcProvider } = require("quantumcoin");\nconst { createTestWallet } = require("./_test-wallet");\nconst { ${a.contractName}__factory } = require("..");\n\nasync function main() {\n const rpcUrl = process.env.QC_RPC_URL;\n if (!rpcUrl) throw new Error("QC_RPC_URL is required");\n const chainId = process.env.QC_CHAIN_ID ? Number(process.env.QC_CHAIN_ID) : 123123;\n await Initialize(null);\n\n const provider = new JsonRpcProvider(rpcUrl, chainId);\n const wallet = createTestWallet(provider);\n\n const factory = new ${a.contractName}__factory(wallet);\n const contract = await factory.deploy(${ctorArgsExpr}${ctorArgsExpr ? ", " : ""}{ gasLimit: 600000 });\n const tx = contract.deployTransaction();\n if (tx) await tx.wait(1, 600_000);\n\n console.log("Deployed ${a.contractName} at:", contract.target);\n}\n\nmain().catch((e) => { console.error(e); process.exitCode = 1; });\n`,
|
|
1186
|
+
);
|
|
751
1187
|
|
|
752
1188
|
_writeText(
|
|
753
|
-
path.join(outDir, "examples", `
|
|
754
|
-
`
|
|
1189
|
+
path.join(outDir, "examples", `read-operations-${a.contractName}.js`),
|
|
1190
|
+
`const { Initialize } = require("quantumcoin/config");\nconst { JsonRpcProvider } = require("quantumcoin");\nconst { ${a.contractName} } = require("..");\n\nasync function main() {\n const rpcUrl = process.env.QC_RPC_URL;\n if (!rpcUrl) throw new Error("QC_RPC_URL is required");\n const chainId = process.env.QC_CHAIN_ID ? Number(process.env.QC_CHAIN_ID) : 123123;\n const address = process.env.CONTRACT_ADDRESS;\n if (!address) throw new Error("CONTRACT_ADDRESS is required");\n await Initialize(null);\n\n const provider = new JsonRpcProvider(rpcUrl, chainId);\n const contract = ${a.contractName}.connect(address, provider);\n\n console.log("${a.contractName}:", contract.target);\n}\n\nmain().catch((e) => { console.error(e); process.exitCode = 1; });\n`,
|
|
755
1191
|
);
|
|
756
1192
|
|
|
757
1193
|
_writeText(
|
|
758
|
-
path.join(outDir, "examples", `
|
|
759
|
-
`
|
|
1194
|
+
path.join(outDir, "examples", `write-operations-${a.contractName}.js`),
|
|
1195
|
+
`const { Initialize } = require("quantumcoin/config");\nconst { JsonRpcProvider } = require("quantumcoin");\nconst { createTestWallet } = require("./_test-wallet");\nconst { ${a.contractName} } = require("..");\n\nasync function main() {\n const rpcUrl = process.env.QC_RPC_URL;\n if (!rpcUrl) throw new Error("QC_RPC_URL is required");\n const chainId = process.env.QC_CHAIN_ID ? Number(process.env.QC_CHAIN_ID) : 123123;\n const address = process.env.CONTRACT_ADDRESS;\n if (!address) throw new Error("CONTRACT_ADDRESS is required");\n await Initialize(null);\n\n const provider = new JsonRpcProvider(rpcUrl, chainId);\n const wallet = createTestWallet(provider);\n const contract = ${a.contractName}.connect(address, wallet);\n\n console.log("Connected:", contract.target);\n console.log("Done");\n}\n\nmain().catch((e) => { console.error(e); process.exitCode = 1; });\n`,
|
|
760
1196
|
);
|
|
761
1197
|
|
|
762
1198
|
_writeText(
|
|
763
|
-
path.join(outDir, "examples", `
|
|
764
|
-
`
|
|
1199
|
+
path.join(outDir, "examples", `offline-signing-${a.contractName}.js`),
|
|
1200
|
+
`const { Initialize } = require("quantumcoin/config");\nconst { JsonRpcProvider, Wallet, getCreateAddress } = require("quantumcoin");\nconst { TEST_WALLET_ENCRYPTED_JSON, TEST_WALLET_PASSPHRASE } = require("./_test-wallet");\nconst { ${a.contractName}__factory, ${a.contractName} } = require("..");\n\nasync function main() {\n const rpcUrl = process.env.QC_RPC_URL;\n if (!rpcUrl) throw new Error("QC_RPC_URL is required");\n const chainId = process.env.QC_CHAIN_ID ? Number(process.env.QC_CHAIN_ID) : 123123;\n await Initialize(null);\n\n const provider = new JsonRpcProvider(rpcUrl, chainId);\n const wallet = Wallet.fromEncryptedJsonSync(TEST_WALLET_ENCRYPTED_JSON, TEST_WALLET_PASSPHRASE);\n const from = wallet.address;\n\n const factory = new ${a.contractName}__factory(wallet);\n const deployTxReq = factory.getDeployTransaction();\n const nonce0 = await provider.getTransactionCount(from, \"pending\");\n const predicted = getCreateAddress({ from, nonce: nonce0 });\n\n const rawDeploy = await wallet.signTransaction({ ...deployTxReq, nonce: nonce0, chainId, gasLimit: 6_000_000, gasPrice: 1n });\n const sentDeploy = await provider.sendRawTransaction(rawDeploy);\n await sentDeploy.wait(1, 600_000);\n\n const contract = ${a.contractName}.connect(predicted, provider);\n console.log(\"deployed at:\", contract.target);\n}\n\nmain().catch((e) => { console.error(e); process.exitCode = 1; });\n`,
|
|
765
1201
|
);
|
|
766
1202
|
|
|
767
1203
|
_writeText(
|
|
768
|
-
path.join(outDir, "examples", `events-${a.contractName}.
|
|
769
|
-
`
|
|
1204
|
+
path.join(outDir, "examples", `events-${a.contractName}.js`),
|
|
1205
|
+
`const { Initialize } = require("quantumcoin/config");\nconst { JsonRpcProvider } = require("quantumcoin");\nconst { ${a.contractName} } = require("..");\n\nasync function main() {\n const rpcUrl = process.env.QC_RPC_URL;\n if (!rpcUrl) throw new Error("QC_RPC_URL is required");\n const chainId = process.env.QC_CHAIN_ID ? Number(process.env.QC_CHAIN_ID) : 123123;\n const address = process.env.CONTRACT_ADDRESS;\n if (!address) throw new Error("CONTRACT_ADDRESS is required");\n await Initialize(null);\n\n const provider = new JsonRpcProvider(rpcUrl, chainId);\n const contract = ${a.contractName}.connect(address, provider);\n\n const logs = await contract.queryFilter("Transfer", "latest", "latest");\n console.log("Logs:", logs.length);\n}\n\nmain().catch((e) => { console.error(e); process.exitCode = 1; });\n`,
|
|
770
1206
|
);
|
|
771
1207
|
}
|
|
772
1208
|
}
|
|
773
1209
|
|
|
774
|
-
// Write an index.js
|
|
775
|
-
_writeText(path.join(outDir, "index.js"), _renderPackageIndexJs({ artifacts }));
|
|
1210
|
+
// Write an index.js re-export shim, then install and run build scripts.
|
|
1211
|
+
_writeText(path.join(outDir, "index.js"), _renderPackageIndexJs({ artifacts, entryDir: lang === "ts" ? "dist" : "src" }));
|
|
776
1212
|
}
|
|
777
1213
|
|
|
778
|
-
// Final step: after package creation,
|
|
1214
|
+
// Final step: after package creation, emit types.
|
|
779
1215
|
if (createPackage) {
|
|
780
1216
|
_runNpm(["install", "--no-fund", "--no-audit"], outDir);
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
_runNpm(["run", "build-powershell"], outDir);
|
|
784
|
-
} else {
|
|
785
|
-
_runNpm(["run", "build"], outDir);
|
|
1217
|
+
if (lang === "ts") {
|
|
1218
|
+
_runNpm(["run", "build:ts"], outDir);
|
|
786
1219
|
}
|
|
787
1220
|
}
|
|
788
1221
|
|
|
1222
|
+
console.warn("This is an experimental SDK. Use at your own risk.");
|
|
789
1223
|
console.log(`Generated contract files in: ${targetSrcDir}`);
|
|
790
1224
|
}
|
|
791
1225
|
|
|
@@ -793,26 +1227,173 @@ function _cap(s) {
|
|
|
793
1227
|
return s ? s[0].toUpperCase() + s.slice(1) : s;
|
|
794
1228
|
}
|
|
795
1229
|
|
|
796
|
-
function
|
|
797
|
-
|
|
798
|
-
|
|
1230
|
+
function _abiParamSig(p, { includeName = true } = {}) {
|
|
1231
|
+
if (!p || typeof p !== "object") return "";
|
|
1232
|
+
const t = typeof p.type === "string" ? p.type : "";
|
|
1233
|
+
const n = includeName && typeof p.name === "string" && p.name ? ` ${p.name}` : "";
|
|
1234
|
+
const indexed = p.indexed ? " indexed" : "";
|
|
1235
|
+
return `${t}${indexed}${n}`.trim();
|
|
1236
|
+
}
|
|
1237
|
+
|
|
1238
|
+
function _abiFnSig(f) {
|
|
1239
|
+
const inputs = (f.inputs || []).map((p) => _abiParamSig(p)).filter(Boolean).join(", ");
|
|
1240
|
+
const outputs = (f.outputs || []).map((p) => _abiParamSig(p, { includeName: false })).filter(Boolean).join(", ");
|
|
1241
|
+
const mut = f.stateMutability && f.stateMutability !== "nonpayable" ? ` ${f.stateMutability}` : "";
|
|
1242
|
+
const returns = outputs ? ` returns (${outputs})` : "";
|
|
1243
|
+
return `${f.name}(${inputs})${mut}${returns}`.trim();
|
|
1244
|
+
}
|
|
1245
|
+
|
|
1246
|
+
function _abiEventSig(e) {
|
|
1247
|
+
const inputs = (e.inputs || []).map((p) => _abiParamSig(p)).filter(Boolean).join(", ");
|
|
1248
|
+
return `${e.name}(${inputs})`.trim();
|
|
1249
|
+
}
|
|
1250
|
+
|
|
1251
|
+
function _abiErrorSig(er) {
|
|
1252
|
+
const inputs = (er.inputs || []).map((p) => _abiParamSig(p)).filter(Boolean).join(", ");
|
|
1253
|
+
return `${er.name}(${inputs})`.trim();
|
|
1254
|
+
}
|
|
1255
|
+
|
|
1256
|
+
function _firstLine(s) {
|
|
1257
|
+
if (!s) return "";
|
|
1258
|
+
const t = String(s).trim();
|
|
1259
|
+
if (!t) return "";
|
|
1260
|
+
return t.split(/\r?\n/g)[0].trim();
|
|
1261
|
+
}
|
|
1262
|
+
|
|
1263
|
+
function _packageReadme({ pkgName, pkgDesc, artifacts, createdFromSolidity, lang = "ts" }) {
|
|
1264
|
+
const outLang = _normalizeLang(lang);
|
|
1265
|
+
const srcExt = outLang === "js" ? "js" : "ts";
|
|
1266
|
+
const list = (artifacts || []).map((a) => a.contractName).filter(Boolean);
|
|
1267
|
+
const hasMultiple = list.length > 1;
|
|
1268
|
+
|
|
1269
|
+
const contractLinks = list.length
|
|
1270
|
+
? list.map((n) => `- [\`${n}\`](#${n.toLowerCase()})`).join("\n")
|
|
1271
|
+
: "- (none)";
|
|
1272
|
+
|
|
1273
|
+
const envBlock = `- \`QC_RPC_URL\` (required for transactional tests)\n- \`QC_CHAIN_ID\` (optional; defaults are used if omitted)\n`;
|
|
1274
|
+
|
|
1275
|
+
const commonExamples = hasMultiple
|
|
1276
|
+
? `Examples are generated per contract (e.g. \`examples/deploy-<Contract>.js\`).`
|
|
1277
|
+
: `- [deploy](./examples/deploy.js)\n- [read operations](./examples/read-operations.js)\n- [write operations](./examples/write-operations.js)\n- [events](./examples/events.js)\n`;
|
|
1278
|
+
|
|
1279
|
+
const contractsMd = (artifacts || [])
|
|
1280
|
+
.map((a) => {
|
|
1281
|
+
const name = a.contractName;
|
|
1282
|
+
const desc = a.docs && typeof a.docs.contract === "string" && a.docs.contract.trim() ? a.docs.contract.trim() : "";
|
|
1283
|
+
|
|
1284
|
+
const fnDocs = (a.docs && a.docs.functions) || {};
|
|
1285
|
+
const abi = Array.isArray(a.abi) ? a.abi : [];
|
|
1286
|
+
const functions = abi.filter((x) => x && x.type === "function").sort((x, y) => String(x.name).localeCompare(String(y.name)));
|
|
1287
|
+
const events = abi.filter((x) => x && x.type === "event").sort((x, y) => String(x.name).localeCompare(String(y.name)));
|
|
1288
|
+
const errors = abi.filter((x) => x && x.type === "error").sort((x, y) => String(x.name).localeCompare(String(y.name)));
|
|
1289
|
+
const ctor = abi.find((x) => x && x.type === "constructor");
|
|
1290
|
+
|
|
1291
|
+
const examples = hasMultiple
|
|
1292
|
+
? `- [deploy](./examples/deploy-${name}.js)\n- [read operations](./examples/read-operations-${name}.js)\n- [write operations](./examples/write-operations-${name}.js)\n- [events](./examples/events-${name}.js)\n`
|
|
1293
|
+
: `- [deploy](./examples/deploy.js)\n- [read operations](./examples/read-operations.js)\n- [write operations](./examples/write-operations.js)\n- [events](./examples/events.js)\n`;
|
|
1294
|
+
|
|
1295
|
+
const testLink = `- [transactional test](./test/e2e/${name}.e2e.test.js)\n`;
|
|
1296
|
+
|
|
1297
|
+
const fileLinks = [
|
|
1298
|
+
`- [\`src/${name}.${srcExt}\`](./src/${name}.${srcExt})`,
|
|
1299
|
+
`- [\`src/${name}__factory.${srcExt}\`](./src/${name}__factory.${srcExt})`,
|
|
1300
|
+
createdFromSolidity ? `- [\`artifacts/${name}.abi.json\`](./artifacts/${name}.abi.json)` : null,
|
|
1301
|
+
createdFromSolidity ? `- [\`artifacts/${name}.bin\`](./artifacts/${name}.bin)` : null,
|
|
1302
|
+
]
|
|
1303
|
+
.filter(Boolean)
|
|
1304
|
+
.join("\n");
|
|
1305
|
+
|
|
1306
|
+
const ctorSig = ctor
|
|
1307
|
+
? `\`constructor(${(ctor.inputs || []).map((p) => _abiParamSig(p)).filter(Boolean).join(", ")})\``
|
|
1308
|
+
: "`constructor()`";
|
|
1309
|
+
|
|
1310
|
+
const fnList = functions.length
|
|
1311
|
+
? functions
|
|
1312
|
+
.map((f) => {
|
|
1313
|
+
const doc = fnDocs && typeof fnDocs[f.name] === "string" ? _firstLine(fnDocs[f.name]) : "";
|
|
1314
|
+
return `- \`${_abiFnSig(f)}\`${doc ? ` — ${doc}` : ""}`;
|
|
1315
|
+
})
|
|
1316
|
+
.join("\n")
|
|
1317
|
+
: "- (none)";
|
|
1318
|
+
|
|
1319
|
+
const eventList = events.length ? events.map((e) => `- \`${_abiEventSig(e)}\``).join("\n") : "- (none)";
|
|
1320
|
+
const errorList = errors.length ? errors.map((er) => `- \`${_abiErrorSig(er)}\``).join("\n") : "- (none)";
|
|
1321
|
+
|
|
1322
|
+
return [
|
|
1323
|
+
`## ${name}`,
|
|
1324
|
+
desc ? `\n${desc}\n` : "",
|
|
1325
|
+
`- **Exports**: \`${name}\`, \`${name}__factory\``,
|
|
1326
|
+
`- **Constructor**: ${ctorSig}`,
|
|
1327
|
+
"",
|
|
1328
|
+
"### Files",
|
|
1329
|
+
fileLinks,
|
|
1330
|
+
"",
|
|
1331
|
+
"### Examples",
|
|
1332
|
+
examples.trimEnd(),
|
|
1333
|
+
"",
|
|
1334
|
+
"### Tests",
|
|
1335
|
+
testLink.trimEnd(),
|
|
1336
|
+
"",
|
|
1337
|
+
"### Functions",
|
|
1338
|
+
fnList,
|
|
1339
|
+
"",
|
|
1340
|
+
"### Events",
|
|
1341
|
+
eventList,
|
|
1342
|
+
"",
|
|
1343
|
+
"### Errors",
|
|
1344
|
+
errorList,
|
|
1345
|
+
"",
|
|
1346
|
+
]
|
|
1347
|
+
.filter(Boolean)
|
|
1348
|
+
.join("\n");
|
|
1349
|
+
})
|
|
1350
|
+
.join("\n");
|
|
1351
|
+
|
|
1352
|
+
return (
|
|
1353
|
+
`# ${pkgName}\n\n` +
|
|
1354
|
+
`${pkgDesc || ""}\n\n` +
|
|
1355
|
+
"> **Note:** This is an experimental SDK. Use at your own risk.\n\n" +
|
|
1356
|
+
"## What’s in this package\n\n" +
|
|
1357
|
+
(outLang === "ts"
|
|
1358
|
+
? "- Typed contract wrappers and factories in `src/` (compiled output in `dist/`)\n"
|
|
1359
|
+
: "- JavaScript contract wrappers and factories in `src/` (TypeScript types via `.d.ts`)\n") +
|
|
1360
|
+
"- Transactional tests in `test/e2e/`\n" +
|
|
1361
|
+
`- Example scripts in \`examples/\`\n` +
|
|
1362
|
+
(createdFromSolidity ? "- ABI/BIN artifacts in `artifacts/`\n" : "") +
|
|
1363
|
+
"\n" +
|
|
1364
|
+
"## Install\n\n" +
|
|
1365
|
+
"- `npm install`\n\n" +
|
|
1366
|
+
"## Build\n\n" +
|
|
1367
|
+
(outLang === "ts" ? "- `npm run build:ts`\n\n" : "- (no build step required)\n\n") +
|
|
1368
|
+
"## Run tests\n\n" +
|
|
1369
|
+
"- `npm test`\n\n" +
|
|
1370
|
+
"Transactional tests require:\n" +
|
|
1371
|
+
envBlock +
|
|
1372
|
+
"\n" +
|
|
1373
|
+
"## Examples\n\n" +
|
|
1374
|
+
(hasMultiple ? `${commonExamples}\n\n` : `${commonExamples}\n`) +
|
|
1375
|
+
"## Contracts\n\n" +
|
|
1376
|
+
contractLinks +
|
|
1377
|
+
"\n\n" +
|
|
1378
|
+
(contractsMd ? contractsMd : "") +
|
|
1379
|
+
"\n"
|
|
1380
|
+
);
|
|
799
1381
|
}
|
|
800
1382
|
|
|
801
|
-
function _createPackageScaffold({ outDir, pkgName, pkgDesc, pkgAuthor, pkgLicense, pkgVersion }) {
|
|
1383
|
+
function _createPackageScaffold({ outDir, pkgName, pkgDesc, pkgAuthor, pkgLicense, pkgVersion, lang = "ts" }) {
|
|
802
1384
|
_ensureDir(outDir);
|
|
803
1385
|
_ensureDir(path.join(outDir, "src"));
|
|
804
1386
|
_ensureDir(path.join(outDir, "test", "e2e"));
|
|
805
1387
|
_ensureDir(path.join(outDir, "examples"));
|
|
806
1388
|
|
|
1389
|
+
const outLang = _normalizeLang(lang);
|
|
1390
|
+
const isTs = outLang === "ts";
|
|
1391
|
+
|
|
807
1392
|
const rootPkg = _readRootPackageJson();
|
|
808
1393
|
const rootDeps = _rewriteFileDepsToAbsolute(rootPkg.dependencies || {}, __dirname);
|
|
809
1394
|
|
|
810
1395
|
// Ensure the generated package depends on this repo's quantumcoin via absolute file path.
|
|
811
1396
|
rootDeps.quantumcoin = `file:${__dirname.replace(/\\\\/g, "/")}`;
|
|
812
|
-
// Ensure docs tool is present (required by build scripts below).
|
|
813
|
-
if (!rootDeps["jsdoc-to-markdown"]) {
|
|
814
|
-
rootDeps["jsdoc-to-markdown"] = "latest";
|
|
815
|
-
}
|
|
816
1397
|
|
|
817
1398
|
const pkgJson = {
|
|
818
1399
|
name: pkgName,
|
|
@@ -820,37 +1401,56 @@ function _createPackageScaffold({ outDir, pkgName, pkgDesc, pkgAuthor, pkgLicens
|
|
|
820
1401
|
description: pkgDesc,
|
|
821
1402
|
author: pkgAuthor,
|
|
822
1403
|
license: pkgLicense,
|
|
823
|
-
main: "dist/index.js",
|
|
824
|
-
types: "dist/index.d.ts",
|
|
1404
|
+
main: isTs ? "dist/index.js" : "src/index.js",
|
|
1405
|
+
types: isTs ? "dist/index.d.ts" : "src/index.d.ts",
|
|
825
1406
|
scripts: {
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
1407
|
+
...(isTs
|
|
1408
|
+
? {
|
|
1409
|
+
"build:ts": "npx -p typescript tsc -p tsconfig.json",
|
|
1410
|
+
build: "npm run build:ts",
|
|
1411
|
+
"build-powershell": "npm run build:ts",
|
|
1412
|
+
test: "npm run build:ts && node --test --test-concurrency=1 \"test/**/*.test.js\"",
|
|
1413
|
+
"test:e2e": "npm run build:ts && node --test --test-concurrency=1 \"test/e2e/**/*.test.js\"",
|
|
1414
|
+
}
|
|
1415
|
+
: {
|
|
1416
|
+
build: "node -e \"console.log('JS package: no build step required')\"",
|
|
1417
|
+
"build-powershell": "node -e \"console.log('JS package: no build step required')\"",
|
|
1418
|
+
test: "node --test --test-concurrency=1 \"test/**/*.test.js\"",
|
|
1419
|
+
"test:e2e": "node --test --test-concurrency=1 \"test/e2e/**/*.test.js\"",
|
|
1420
|
+
}),
|
|
831
1421
|
},
|
|
832
1422
|
dependencies: rootDeps,
|
|
833
1423
|
devDependencies: {},
|
|
834
1424
|
};
|
|
835
1425
|
|
|
836
1426
|
_writeJson(path.join(outDir, "package.json"), pkgJson);
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
1427
|
+
if (isTs) {
|
|
1428
|
+
_writeJson(path.join(outDir, "tsconfig.json"), {
|
|
1429
|
+
compilerOptions: {
|
|
1430
|
+
target: "ES2022",
|
|
1431
|
+
lib: ["ES2022"],
|
|
1432
|
+
module: "CommonJS",
|
|
1433
|
+
declaration: true,
|
|
1434
|
+
outDir: "dist",
|
|
1435
|
+
strict: true,
|
|
1436
|
+
esModuleInterop: true,
|
|
1437
|
+
skipLibCheck: true,
|
|
1438
|
+
},
|
|
1439
|
+
include: ["src/**/*.ts"],
|
|
1440
|
+
});
|
|
1441
|
+
}
|
|
849
1442
|
|
|
850
|
-
_writeText(
|
|
1443
|
+
_writeText(
|
|
1444
|
+
path.join(outDir, "README.md"),
|
|
1445
|
+
_packageReadme({ pkgName, pkgDesc, artifacts: [], createdFromSolidity: false, lang: outLang }),
|
|
1446
|
+
);
|
|
851
1447
|
|
|
852
1448
|
_writeText(path.join(outDir, ".gitignore"), `node_modules\n/dist\n*.log\n`);
|
|
853
1449
|
|
|
1450
|
+
// Provide a root index.d.ts without needing a separate build step.
|
|
1451
|
+
// This is mainly for convenience and for tooling that expects a top-level .d.ts.
|
|
1452
|
+
_writeText(path.join(outDir, "index.d.ts"), `export * from "./${isTs ? "dist" : "src"}";\n`);
|
|
1453
|
+
|
|
854
1454
|
// Minimal shims so the generated TypeScript can compile even though `quantumcoin`
|
|
855
1455
|
// is a JavaScript package (no bundled .d.ts in this repo).
|
|
856
1456
|
_writeText(
|
|
@@ -865,6 +1465,8 @@ function _createPackageScaffold({ outDir, pkgName, pkgDesc, pkgAuthor, pkgLicens
|
|
|
865
1465
|
` constructor(address: string, abi: any, runner?: any, bytecode?: any);\n` +
|
|
866
1466
|
` target: string;\n` +
|
|
867
1467
|
` address: string;\n` +
|
|
1468
|
+
` interface: any;\n` +
|
|
1469
|
+
` populateTransaction: any;\n` +
|
|
868
1470
|
` call(methodName: string, args: any[], overrides?: TransactionRequest): Promise<any>;\n` +
|
|
869
1471
|
` send(methodName: string, args: any[], overrides?: TransactionRequest): Promise<ContractTransactionResponse>;\n` +
|
|
870
1472
|
` deployTransaction(): TransactionResponse | null;\n` +
|