@caatinga/core 2.3.0 → 2.4.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/{browser-Cq4ZofIq.d.cts → artifact.schema-BH5K-IiZ.d.cts} +2 -1
- package/dist/{browser-Cq4ZofIq.d.ts → artifact.schema-BH5K-IiZ.d.ts} +2 -1
- package/dist/browser.cjs +20 -0
- package/dist/browser.d.cts +5 -1
- package/dist/browser.d.ts +5 -1
- package/dist/browser.js +19 -0
- package/dist/index.cjs +440 -29
- package/dist/index.d.cts +52 -12
- package/dist/index.d.ts +52 -12
- package/dist/index.js +430 -29
- package/package.json +2 -1
- package/scaffolds/soroban-contract-stub/Cargo.toml +24 -0
- package/scaffolds/soroban-contract-stub/src/lib.rs +42 -0
- package/scaffolds/zk-circuit-stub/input.json +3 -0
- package/scaffolds/zk-circuit-stub/main.circom +9 -0
- package/scaffolds/zk-verifier/Cargo.lock +1880 -0
- package/scaffolds/zk-verifier/Cargo.toml +27 -0
- package/scaffolds/zk-verifier/src/lib.rs +64 -0
- package/scaffolds/zk-verifier/src/test.rs +100 -0
package/dist/index.cjs
CHANGED
|
@@ -37,17 +37,21 @@ __export(index_exports, {
|
|
|
37
37
|
CaatingaConfigSchema: () => CaatingaConfigSchema,
|
|
38
38
|
CaatingaError: () => CaatingaError,
|
|
39
39
|
CaatingaErrorCode: () => CaatingaErrorCode,
|
|
40
|
+
READ_CALL_FAILURE_REGEX: () => READ_CALL_FAILURE_REGEX,
|
|
40
41
|
STELLAR_CLI_LAST_TESTED_VERSION: () => STELLAR_CLI_LAST_TESTED_VERSION,
|
|
41
42
|
STELLAR_CLI_MIN_VERSION: () => STELLAR_CLI_MIN_VERSION,
|
|
42
43
|
TemplateManifestSchema: () => TemplateManifestSchema,
|
|
43
44
|
WELL_KNOWN_NETWORKS: () => WELL_KNOWN_NETWORKS,
|
|
44
45
|
buildContract: () => buildContract,
|
|
45
46
|
buildDependencyGraph: () => buildDependencyGraph,
|
|
47
|
+
buildReadCallHint: () => buildReadCallHint,
|
|
46
48
|
checkBinary: () => checkBinary,
|
|
47
49
|
checkStellarCliVersion: () => checkStellarCliVersion,
|
|
48
50
|
collectProjectStatus: () => collectProjectStatus,
|
|
49
51
|
createInitialArtifacts: () => createInitialArtifacts,
|
|
52
|
+
createMinimalProject: () => createMinimalProject,
|
|
50
53
|
createProjectFromTemplate: () => createProjectFromTemplate,
|
|
54
|
+
createZkProject: () => createZkProject,
|
|
51
55
|
defineConfig: () => defineConfig,
|
|
52
56
|
deployContract: () => deployContract,
|
|
53
57
|
deployContractGraph: () => deployContractGraph,
|
|
@@ -58,6 +62,8 @@ __export(index_exports, {
|
|
|
58
62
|
generateBindings: () => generateBindings,
|
|
59
63
|
generateBindingsGraph: () => generateBindingsGraph,
|
|
60
64
|
invokeContract: () => invokeContract,
|
|
65
|
+
isCargoBinMissingFromPath: () => isCargoBinMissingFromPath,
|
|
66
|
+
isReadCallFailure: () => isReadCallFailure,
|
|
61
67
|
isTransientTestnetSmokeFailure: () => isTransientTestnetSmokeFailure,
|
|
62
68
|
loadConfig: () => loadConfig,
|
|
63
69
|
parseContractId: () => parseContractId,
|
|
@@ -65,11 +71,13 @@ __export(index_exports, {
|
|
|
65
71
|
parseStellarCliVersion: () => parseStellarCliVersion,
|
|
66
72
|
readArtifacts: () => readArtifacts,
|
|
67
73
|
readBindingMarker: () => readBindingMarker,
|
|
74
|
+
readContract: () => readContract,
|
|
68
75
|
resolveContract: () => resolveContract,
|
|
69
76
|
resolveDefaultContractName: () => resolveDefaultContractName,
|
|
70
77
|
resolveDeployArgs: () => resolveDeployArgs,
|
|
71
78
|
resolveDeployOrder: () => resolveDeployOrder,
|
|
72
79
|
resolveNetwork: () => resolveNetwork,
|
|
80
|
+
resolveSubprocessEnv: () => resolveSubprocessEnv,
|
|
73
81
|
runCommand: () => runCommand,
|
|
74
82
|
toCaatingaError: () => toCaatingaError,
|
|
75
83
|
updateArtifact: () => updateArtifact,
|
|
@@ -82,6 +90,7 @@ module.exports = __toCommonJS(index_exports);
|
|
|
82
90
|
// src/errors/CaatingaErrorCode.ts
|
|
83
91
|
var CaatingaErrorCode = {
|
|
84
92
|
CONFIG_NOT_FOUND: "CAATINGA_CONFIG_NOT_FOUND",
|
|
93
|
+
DEPENDENCIES_NOT_INSTALLED: "CAATINGA_DEPENDENCIES_NOT_INSTALLED",
|
|
85
94
|
INVALID_CONFIG: "CAATINGA_INVALID_CONFIG",
|
|
86
95
|
COMMAND_FAILED: "CAATINGA_COMMAND_FAILED",
|
|
87
96
|
UNEXPECTED_ERROR: "CAATINGA_UNEXPECTED_ERROR",
|
|
@@ -186,7 +195,7 @@ function formatCause(cause) {
|
|
|
186
195
|
}
|
|
187
196
|
|
|
188
197
|
// src/version.ts
|
|
189
|
-
var CAATINGA_CORE_VERSION = "2.
|
|
198
|
+
var CAATINGA_CORE_VERSION = "2.4.0";
|
|
190
199
|
|
|
191
200
|
// src/config/config.schema.ts
|
|
192
201
|
var import_zod = require("zod");
|
|
@@ -224,7 +233,7 @@ var CaatingaConfigSchema = import_zod.z.object({
|
|
|
224
233
|
frontend: import_zod.z.object({
|
|
225
234
|
framework: import_zod.z.enum(["vite-react", "next", "astro"]).default("vite-react"),
|
|
226
235
|
bindingsOutput: import_zod.z.string().min(1)
|
|
227
|
-
}),
|
|
236
|
+
}).optional(),
|
|
228
237
|
zk: ZkConfigSchema
|
|
229
238
|
});
|
|
230
239
|
|
|
@@ -238,6 +247,28 @@ var import_promises = require("fs/promises");
|
|
|
238
247
|
var import_node_path = __toESM(require("path"), 1);
|
|
239
248
|
var import_jiti = require("jiti");
|
|
240
249
|
var import_zod2 = require("zod");
|
|
250
|
+
|
|
251
|
+
// src/config/is-dependencies-not-installed-error.ts
|
|
252
|
+
function isDependenciesNotInstalledError(error) {
|
|
253
|
+
if (!error || typeof error !== "object") {
|
|
254
|
+
return false;
|
|
255
|
+
}
|
|
256
|
+
const candidate = error;
|
|
257
|
+
const code = candidate.code;
|
|
258
|
+
const message = String(candidate.message ?? error);
|
|
259
|
+
if (code === "ERR_MODULE_NOT_FOUND" || code === "MODULE_NOT_FOUND") {
|
|
260
|
+
return /@caatinga\/core/.test(message);
|
|
261
|
+
}
|
|
262
|
+
if (/Cannot find (module|package).+@caatinga\/core/i.test(message)) {
|
|
263
|
+
return true;
|
|
264
|
+
}
|
|
265
|
+
if (candidate.cause !== void 0) {
|
|
266
|
+
return isDependenciesNotInstalledError(candidate.cause);
|
|
267
|
+
}
|
|
268
|
+
return false;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
// src/config/load-config.ts
|
|
241
272
|
var import_meta = {};
|
|
242
273
|
async function loadConfig(options = {}) {
|
|
243
274
|
const cwd = options.cwd ?? process.cwd();
|
|
@@ -263,6 +294,14 @@ async function loadConfig(options = {}) {
|
|
|
263
294
|
error.issues.map((issue) => `${issue.path.join(".")}: ${issue.message}`).join("; ")
|
|
264
295
|
);
|
|
265
296
|
}
|
|
297
|
+
if (isDependenciesNotInstalledError(error)) {
|
|
298
|
+
throw new CaatingaError(
|
|
299
|
+
"Project dependencies are not installed.",
|
|
300
|
+
CaatingaErrorCode.DEPENDENCIES_NOT_INSTALLED,
|
|
301
|
+
"Run npm install (or pnpm install) in the project root, then retry.",
|
|
302
|
+
error
|
|
303
|
+
);
|
|
304
|
+
}
|
|
266
305
|
throw error;
|
|
267
306
|
}
|
|
268
307
|
}
|
|
@@ -423,6 +462,15 @@ async function listGeneratedEntries(outputDir) {
|
|
|
423
462
|
}
|
|
424
463
|
async function evaluateBindingFreshness(options) {
|
|
425
464
|
const cwd = options.cwd ?? process.cwd();
|
|
465
|
+
if (!options.config.frontend) {
|
|
466
|
+
return {
|
|
467
|
+
contractName: options.contractName,
|
|
468
|
+
status: "unknown",
|
|
469
|
+
outputDir: "",
|
|
470
|
+
marker: null,
|
|
471
|
+
reason: "frontend bindings are not configured"
|
|
472
|
+
};
|
|
473
|
+
}
|
|
426
474
|
const outputDir = import_node_path5.default.resolve(cwd, options.config.frontend.bindingsOutput, options.contractName);
|
|
427
475
|
const contractArtifact = options.artifacts.networks[options.networkName]?.contracts[options.contractName];
|
|
428
476
|
if (!contractArtifact) {
|
|
@@ -660,6 +708,64 @@ function defaultEmitWarning(warning) {
|
|
|
660
708
|
`);
|
|
661
709
|
}
|
|
662
710
|
|
|
711
|
+
// src/shell/resolve-subprocess-env.ts
|
|
712
|
+
var import_node_fs = require("fs");
|
|
713
|
+
var import_node_os = __toESM(require("os"), 1);
|
|
714
|
+
var import_node_path6 = __toESM(require("path"), 1);
|
|
715
|
+
function uniquePaths(entries) {
|
|
716
|
+
const seen = /* @__PURE__ */ new Set();
|
|
717
|
+
const ordered = [];
|
|
718
|
+
for (const entry of entries) {
|
|
719
|
+
if (!entry || seen.has(entry)) {
|
|
720
|
+
continue;
|
|
721
|
+
}
|
|
722
|
+
seen.add(entry);
|
|
723
|
+
ordered.push(entry);
|
|
724
|
+
}
|
|
725
|
+
return ordered;
|
|
726
|
+
}
|
|
727
|
+
function hasExecutable(binDir, name) {
|
|
728
|
+
return (0, import_node_fs.existsSync)(import_node_path6.default.join(binDir, name));
|
|
729
|
+
}
|
|
730
|
+
function toolchainBinDirs(home, env) {
|
|
731
|
+
const candidates = [
|
|
732
|
+
import_node_path6.default.join(home, ".cargo", "bin"),
|
|
733
|
+
env.CARGO_HOME ? import_node_path6.default.join(env.CARGO_HOME, "bin") : void 0
|
|
734
|
+
];
|
|
735
|
+
return candidates.filter((entry) => Boolean(entry && (0, import_node_fs.existsSync)(entry)));
|
|
736
|
+
}
|
|
737
|
+
function buildToolchainPrepend(existingPath, toolchainBins, executableExists = hasExecutable) {
|
|
738
|
+
const prepend = [];
|
|
739
|
+
for (const binDir of toolchainBins) {
|
|
740
|
+
const externalStellarDir = existingPath.find(
|
|
741
|
+
(entry) => entry !== binDir && executableExists(entry, "stellar")
|
|
742
|
+
);
|
|
743
|
+
if (externalStellarDir && executableExists(binDir, "stellar")) {
|
|
744
|
+
prepend.push(externalStellarDir);
|
|
745
|
+
}
|
|
746
|
+
prepend.push(binDir);
|
|
747
|
+
}
|
|
748
|
+
return prepend;
|
|
749
|
+
}
|
|
750
|
+
function resolveSubprocessEnv(overrides = {}) {
|
|
751
|
+
const env = { ...process.env, ...overrides };
|
|
752
|
+
const home = env.HOME ?? import_node_os.default.homedir();
|
|
753
|
+
const existingPath = (env.PATH ?? "").split(import_node_path6.default.delimiter).filter(Boolean);
|
|
754
|
+
const toolchainBins = toolchainBinDirs(home, env);
|
|
755
|
+
const prepend = buildToolchainPrepend(existingPath, toolchainBins);
|
|
756
|
+
env.PATH = uniquePaths([...prepend, ...existingPath]).join(import_node_path6.default.delimiter);
|
|
757
|
+
return env;
|
|
758
|
+
}
|
|
759
|
+
function isCargoBinMissingFromPath(baseEnv = process.env) {
|
|
760
|
+
const home = baseEnv.HOME ?? import_node_os.default.homedir();
|
|
761
|
+
const cargoBin = import_node_path6.default.join(home, ".cargo", "bin", "cargo");
|
|
762
|
+
if (!(0, import_node_fs.existsSync)(cargoBin)) {
|
|
763
|
+
return false;
|
|
764
|
+
}
|
|
765
|
+
const pathEntries = (baseEnv.PATH ?? "").split(import_node_path6.default.delimiter);
|
|
766
|
+
return !pathEntries.some((entry) => entry === import_node_path6.default.join(home, ".cargo", "bin"));
|
|
767
|
+
}
|
|
768
|
+
|
|
663
769
|
// src/shell/run-command.ts
|
|
664
770
|
async function runCommand(command, args, options = {}) {
|
|
665
771
|
try {
|
|
@@ -668,7 +774,7 @@ async function runCommand(command, args, options = {}) {
|
|
|
668
774
|
}
|
|
669
775
|
const result = await (0, import_execa.execa)(command, args, {
|
|
670
776
|
cwd: options.cwd,
|
|
671
|
-
env: options.env,
|
|
777
|
+
env: resolveSubprocessEnv(options.env ?? {}),
|
|
672
778
|
input: options.input,
|
|
673
779
|
all: true,
|
|
674
780
|
reject: true
|
|
@@ -866,7 +972,7 @@ function validateSourceShape(source) {
|
|
|
866
972
|
}
|
|
867
973
|
|
|
868
974
|
// src/contracts/resolve-contract.ts
|
|
869
|
-
var
|
|
975
|
+
var import_node_path7 = __toESM(require("path"), 1);
|
|
870
976
|
function resolveContract(config, contractName, cwd = process.cwd()) {
|
|
871
977
|
const contract = config.contracts[contractName];
|
|
872
978
|
if (!contract) {
|
|
@@ -879,8 +985,8 @@ function resolveContract(config, contractName, cwd = process.cwd()) {
|
|
|
879
985
|
return {
|
|
880
986
|
name: contractName,
|
|
881
987
|
config: contract,
|
|
882
|
-
sourcePath:
|
|
883
|
-
wasmPath:
|
|
988
|
+
sourcePath: import_node_path7.default.resolve(cwd, contract.path),
|
|
989
|
+
wasmPath: import_node_path7.default.resolve(cwd, contract.wasm)
|
|
884
990
|
};
|
|
885
991
|
}
|
|
886
992
|
|
|
@@ -900,7 +1006,7 @@ function resolveDefaultContractName(config) {
|
|
|
900
1006
|
// src/contracts/wasm.ts
|
|
901
1007
|
var import_node_crypto = require("crypto");
|
|
902
1008
|
var import_promises6 = require("fs/promises");
|
|
903
|
-
var
|
|
1009
|
+
var import_node_path8 = __toESM(require("path"), 1);
|
|
904
1010
|
var LEGACY_RUST_WASM_TARGET = "wasm32-unknown-unknown";
|
|
905
1011
|
var CURRENT_RUST_WASM_TARGET = "wasm32v1-none";
|
|
906
1012
|
function toCurrentWasmTargetPath(wasmPath) {
|
|
@@ -923,8 +1029,8 @@ function wasmNotFoundError(configuredWasmPath, options) {
|
|
|
923
1029
|
);
|
|
924
1030
|
}
|
|
925
1031
|
function toConfigRelativeWasmPath(absoluteWasmPath) {
|
|
926
|
-
const relative =
|
|
927
|
-
return relative.startsWith("..") ? absoluteWasmPath : `./${relative.split(
|
|
1032
|
+
const relative = import_node_path8.default.relative(process.cwd(), absoluteWasmPath);
|
|
1033
|
+
return relative.startsWith("..") ? absoluteWasmPath : `./${relative.split(import_node_path8.default.sep).join("/")}`;
|
|
928
1034
|
}
|
|
929
1035
|
async function resolveWasmArtifactPath(configuredWasmPath) {
|
|
930
1036
|
try {
|
|
@@ -957,7 +1063,7 @@ async function getNewestMtimeInDirectory(directory) {
|
|
|
957
1063
|
async function walk(dir) {
|
|
958
1064
|
const entries = await (0, import_promises6.readdir)(dir, { withFileTypes: true });
|
|
959
1065
|
for (const entry of entries) {
|
|
960
|
-
const entryPath =
|
|
1066
|
+
const entryPath = import_node_path8.default.join(dir, entry.name);
|
|
961
1067
|
if (entry.isDirectory()) {
|
|
962
1068
|
await walk(entryPath);
|
|
963
1069
|
continue;
|
|
@@ -973,7 +1079,7 @@ async function getNewestMtimeInDirectory(directory) {
|
|
|
973
1079
|
return newest > 0 ? newest : void 0;
|
|
974
1080
|
}
|
|
975
1081
|
async function isWasmOlderThanSources(input) {
|
|
976
|
-
const srcDir =
|
|
1082
|
+
const srcDir = import_node_path8.default.join(input.contractPath, "src");
|
|
977
1083
|
const newestSourceMtime = await getNewestMtimeInDirectory(srcDir);
|
|
978
1084
|
if (newestSourceMtime === void 0) {
|
|
979
1085
|
return false;
|
|
@@ -1046,7 +1152,7 @@ async function buildContract(options) {
|
|
|
1046
1152
|
}
|
|
1047
1153
|
|
|
1048
1154
|
// src/contracts/deploy-contract.ts
|
|
1049
|
-
var
|
|
1155
|
+
var import_node_path9 = __toESM(require("path"), 1);
|
|
1050
1156
|
|
|
1051
1157
|
// src/contracts/dependency-graph.ts
|
|
1052
1158
|
function buildDependencyGraph(contracts) {
|
|
@@ -1103,6 +1209,9 @@ function assertSafeSourceAccount(source) {
|
|
|
1103
1209
|
}
|
|
1104
1210
|
return source;
|
|
1105
1211
|
}
|
|
1212
|
+
function resolveCliSource(explicit) {
|
|
1213
|
+
return assertSafeSourceAccount(explicit ?? process.env.CAATINGA_SOURCE ?? "alice");
|
|
1214
|
+
}
|
|
1106
1215
|
|
|
1107
1216
|
// src/contracts/deploy-contract.ts
|
|
1108
1217
|
function toSnakeCaseFlag(key) {
|
|
@@ -1147,7 +1256,7 @@ async function deployContract(options) {
|
|
|
1147
1256
|
contract: contractWithWasm,
|
|
1148
1257
|
network,
|
|
1149
1258
|
contractId: existing.contractId,
|
|
1150
|
-
artifactsPath:
|
|
1259
|
+
artifactsPath: import_node_path9.default.resolve(cwd, "caatinga.artifacts.json"),
|
|
1151
1260
|
output: "",
|
|
1152
1261
|
skipped: true,
|
|
1153
1262
|
staleWasmWarning
|
|
@@ -1424,13 +1533,13 @@ async function deployContractGraph(options) {
|
|
|
1424
1533
|
|
|
1425
1534
|
// src/contracts/generate-bindings.ts
|
|
1426
1535
|
var import_promises7 = require("fs/promises");
|
|
1427
|
-
var
|
|
1536
|
+
var import_node_path10 = __toESM(require("path"), 1);
|
|
1428
1537
|
function toBindingImportPath(bindingsOutput, contractName) {
|
|
1429
|
-
const normalized = bindingsOutput.replace(/^\.\//, "").split(
|
|
1430
|
-
return `./${
|
|
1538
|
+
const normalized = bindingsOutput.replace(/^\.\//, "").split(import_node_path10.default.sep).join("/");
|
|
1539
|
+
return `./${import_node_path10.default.posix.join(normalized, contractName, "src", "index.js")}`;
|
|
1431
1540
|
}
|
|
1432
1541
|
async function removeLegacyBindingStub(cwd, bindingsOutput, contractName) {
|
|
1433
|
-
const legacyPath =
|
|
1542
|
+
const legacyPath = import_node_path10.default.resolve(cwd, bindingsOutput, `${contractName}.ts`);
|
|
1434
1543
|
try {
|
|
1435
1544
|
await (0, import_promises7.access)(legacyPath);
|
|
1436
1545
|
await (0, import_promises7.unlink)(legacyPath);
|
|
@@ -1441,6 +1550,13 @@ async function removeLegacyBindingStub(cwd, bindingsOutput, contractName) {
|
|
|
1441
1550
|
}
|
|
1442
1551
|
async function generateBindings(options) {
|
|
1443
1552
|
const cwd = options.cwd ?? process.cwd();
|
|
1553
|
+
if (!options.config.frontend) {
|
|
1554
|
+
throw new CaatingaError(
|
|
1555
|
+
"Frontend bindings are not configured.",
|
|
1556
|
+
CaatingaErrorCode.INVALID_CONFIG,
|
|
1557
|
+
"Add a frontend.bindingsOutput entry to caatinga.config.ts before running caatinga generate."
|
|
1558
|
+
);
|
|
1559
|
+
}
|
|
1444
1560
|
const network = resolveNetwork(options.config, options.networkName);
|
|
1445
1561
|
const artifacts = await readArtifacts(cwd);
|
|
1446
1562
|
const contractArtifact = artifacts.networks[network.name]?.contracts[options.contractName];
|
|
@@ -1452,7 +1568,7 @@ async function generateBindings(options) {
|
|
|
1452
1568
|
);
|
|
1453
1569
|
}
|
|
1454
1570
|
await checkBinary("stellar", "Install Stellar CLI before running caatinga generate.");
|
|
1455
|
-
const outputDir =
|
|
1571
|
+
const outputDir = import_node_path10.default.resolve(cwd, options.config.frontend.bindingsOutput, options.contractName);
|
|
1456
1572
|
await (0, import_promises7.mkdir)(outputDir, { recursive: true });
|
|
1457
1573
|
const result = await runCommand("stellar", [
|
|
1458
1574
|
"contract",
|
|
@@ -1526,8 +1642,8 @@ async function generateBindingsGraph(options) {
|
|
|
1526
1642
|
return { network, results };
|
|
1527
1643
|
}
|
|
1528
1644
|
|
|
1529
|
-
// src/contracts/invoke-
|
|
1530
|
-
var
|
|
1645
|
+
// src/contracts/invoke-target.ts
|
|
1646
|
+
var READ_CALL_FAILURE_REGEX = /this is a read call|read-only/i;
|
|
1531
1647
|
function parseInvokeTarget(target) {
|
|
1532
1648
|
const [contractName, method, extra] = target.split(".");
|
|
1533
1649
|
if (!contractName || !method || extra) {
|
|
@@ -1539,6 +1655,29 @@ function parseInvokeTarget(target) {
|
|
|
1539
1655
|
}
|
|
1540
1656
|
return { contractName, method };
|
|
1541
1657
|
}
|
|
1658
|
+
function buildReadCallHint(target, networkName) {
|
|
1659
|
+
return [
|
|
1660
|
+
`"${target.contractName}.${target.method}" is a read-only contract method.`,
|
|
1661
|
+
"Simulate without signing instead:",
|
|
1662
|
+
` npx caatinga read ${target.contractName}.${target.method} --network ${networkName}`,
|
|
1663
|
+
" (--source is optional; Caatinga resolves CAATINGA_SOURCE or defaults to alice)",
|
|
1664
|
+
"In browser code, use:",
|
|
1665
|
+
` client.contract("${target.contractName}").read("${target.method}")`,
|
|
1666
|
+
` client.contract("${target.contractName}").simulate("${target.method}")`,
|
|
1667
|
+
"Pass method args as the second argument to read() when the contract method takes parameters.",
|
|
1668
|
+
"Only pass Stellar CLI --force when you intentionally need a signed read simulation."
|
|
1669
|
+
].join("\n");
|
|
1670
|
+
}
|
|
1671
|
+
function isReadCallFailure(error) {
|
|
1672
|
+
if (!(error instanceof CaatingaError) || error.code !== CaatingaErrorCode.INVOKE_FAILED) {
|
|
1673
|
+
return false;
|
|
1674
|
+
}
|
|
1675
|
+
return READ_CALL_FAILURE_REGEX.test(`${error.message}
|
|
1676
|
+
${error.hint ?? ""}`);
|
|
1677
|
+
}
|
|
1678
|
+
|
|
1679
|
+
// src/contracts/invoke-contract.ts
|
|
1680
|
+
var INVOKE_SIGNING_FAILURE_REGEX = /xdr processing error: xdr value invalid/i;
|
|
1542
1681
|
async function invokeContract(options) {
|
|
1543
1682
|
const cwd = options.cwd ?? process.cwd();
|
|
1544
1683
|
const network = resolveNetwork(options.config, options.networkName);
|
|
@@ -1572,6 +1711,14 @@ async function invokeContract(options) {
|
|
|
1572
1711
|
failureCode: CaatingaErrorCode.INVOKE_FAILED
|
|
1573
1712
|
});
|
|
1574
1713
|
} catch (error) {
|
|
1714
|
+
if (error instanceof CaatingaError && error.code === CaatingaErrorCode.INVOKE_FAILED && isReadCallFailure(error)) {
|
|
1715
|
+
throw new CaatingaError(
|
|
1716
|
+
error.message,
|
|
1717
|
+
error.code,
|
|
1718
|
+
buildReadCallHint(target, network.name),
|
|
1719
|
+
error
|
|
1720
|
+
);
|
|
1721
|
+
}
|
|
1575
1722
|
if (error instanceof CaatingaError && error.code === CaatingaErrorCode.INVOKE_FAILED && INVOKE_SIGNING_FAILURE_REGEX.test(`${error.message}
|
|
1576
1723
|
${error.hint ?? ""}`)) {
|
|
1577
1724
|
throw new CaatingaError(
|
|
@@ -1597,9 +1744,48 @@ ${error.hint ?? ""}`)) {
|
|
|
1597
1744
|
};
|
|
1598
1745
|
}
|
|
1599
1746
|
|
|
1747
|
+
// src/contracts/read-contract.ts
|
|
1748
|
+
async function readContract(options) {
|
|
1749
|
+
const cwd = options.cwd ?? process.cwd();
|
|
1750
|
+
const network = resolveNetwork(options.config, options.networkName);
|
|
1751
|
+
const target = parseInvokeTarget(options.target);
|
|
1752
|
+
const artifacts = await readArtifacts(cwd);
|
|
1753
|
+
const contractArtifact = artifacts.networks[network.name]?.contracts[target.contractName];
|
|
1754
|
+
if (!contractArtifact) {
|
|
1755
|
+
throw new CaatingaError(
|
|
1756
|
+
`No deployed artifact found for "${target.contractName}" on "${network.name}".`,
|
|
1757
|
+
CaatingaErrorCode.ARTIFACT_NOT_FOUND,
|
|
1758
|
+
"Run caatinga deploy for this contract and network before reading it."
|
|
1759
|
+
);
|
|
1760
|
+
}
|
|
1761
|
+
await checkBinary("stellar", "Install Stellar CLI before running caatinga read.");
|
|
1762
|
+
const stellarArgs = [
|
|
1763
|
+
"contract",
|
|
1764
|
+
"invoke",
|
|
1765
|
+
"--id",
|
|
1766
|
+
contractArtifact.contractId,
|
|
1767
|
+
"--source-account",
|
|
1768
|
+
resolveCliSource(options.source),
|
|
1769
|
+
"--send=no",
|
|
1770
|
+
...buildStellarNetworkArgs(network),
|
|
1771
|
+
"--",
|
|
1772
|
+
target.method,
|
|
1773
|
+
...options.args ?? []
|
|
1774
|
+
];
|
|
1775
|
+
const result = await runCommand("stellar", stellarArgs, {
|
|
1776
|
+
cwd,
|
|
1777
|
+
failureCode: CaatingaErrorCode.INVOKE_FAILED
|
|
1778
|
+
});
|
|
1779
|
+
return {
|
|
1780
|
+
target,
|
|
1781
|
+
network,
|
|
1782
|
+
result: result.stdout || result.all
|
|
1783
|
+
};
|
|
1784
|
+
}
|
|
1785
|
+
|
|
1600
1786
|
// src/templates/create-project-from-template.ts
|
|
1601
1787
|
var import_promises8 = require("fs/promises");
|
|
1602
|
-
var
|
|
1788
|
+
var import_node_path11 = __toESM(require("path"), 1);
|
|
1603
1789
|
var import_zod7 = require("zod");
|
|
1604
1790
|
|
|
1605
1791
|
// src/templates/template-manifest.schema.ts
|
|
@@ -1675,8 +1861,8 @@ var TEMPLATE_COPY_EXCLUDED_DIRS = /* @__PURE__ */ new Set([
|
|
|
1675
1861
|
".git"
|
|
1676
1862
|
]);
|
|
1677
1863
|
async function createProjectFromTemplate(options) {
|
|
1678
|
-
const targetDir =
|
|
1679
|
-
const templateDir =
|
|
1864
|
+
const targetDir = import_node_path11.default.resolve(options.targetDir);
|
|
1865
|
+
const templateDir = import_node_path11.default.resolve(options.templateDir);
|
|
1680
1866
|
try {
|
|
1681
1867
|
await (0, import_promises8.stat)(templateDir);
|
|
1682
1868
|
} catch {
|
|
@@ -1714,7 +1900,7 @@ async function ensureArtifacts(targetDir, projectName) {
|
|
|
1714
1900
|
}
|
|
1715
1901
|
}
|
|
1716
1902
|
async function readTemplateManifest(templateDir) {
|
|
1717
|
-
const manifestPath =
|
|
1903
|
+
const manifestPath = import_node_path11.default.join(templateDir, "caatinga.template.json");
|
|
1718
1904
|
try {
|
|
1719
1905
|
const rawManifest = await (0, import_promises8.readFile)(manifestPath, "utf8");
|
|
1720
1906
|
const manifest = TemplateManifestSchema.parse(JSON.parse(rawManifest));
|
|
@@ -1751,7 +1937,7 @@ async function readTemplateManifest(templateDir) {
|
|
|
1751
1937
|
async function replaceTemplateVariables(dir, projectName) {
|
|
1752
1938
|
const entries = await (0, import_promises8.readdir)(dir);
|
|
1753
1939
|
await Promise.all(entries.map(async (entry) => {
|
|
1754
|
-
const entryPath =
|
|
1940
|
+
const entryPath = import_node_path11.default.join(dir, entry);
|
|
1755
1941
|
const entryStat = await (0, import_promises8.stat)(entryPath);
|
|
1756
1942
|
if (entryStat.isDirectory()) {
|
|
1757
1943
|
await replaceTemplateVariables(entryPath, projectName);
|
|
@@ -1765,15 +1951,15 @@ async function replaceTemplateVariables(dir, projectName) {
|
|
|
1765
1951
|
}));
|
|
1766
1952
|
}
|
|
1767
1953
|
function shouldCopyTemplateEntry(templateDir, source, userFilter) {
|
|
1768
|
-
const relativePath =
|
|
1954
|
+
const relativePath = import_node_path11.default.relative(templateDir, source);
|
|
1769
1955
|
if (!relativePath || relativePath === ".") {
|
|
1770
1956
|
return true;
|
|
1771
1957
|
}
|
|
1772
|
-
const normalizedPath = relativePath.split(
|
|
1958
|
+
const normalizedPath = relativePath.split(import_node_path11.default.sep).join("/");
|
|
1773
1959
|
if (userFilter && !userFilter(normalizedPath)) {
|
|
1774
1960
|
return false;
|
|
1775
1961
|
}
|
|
1776
|
-
return !relativePath.split(
|
|
1962
|
+
return !relativePath.split(import_node_path11.default.sep).some((segment) => TEMPLATE_COPY_EXCLUDED_DIRS.has(segment));
|
|
1777
1963
|
}
|
|
1778
1964
|
function isTextTemplateFile(filePath) {
|
|
1779
1965
|
return [
|
|
@@ -1785,7 +1971,224 @@ function isTextTemplateFile(filePath) {
|
|
|
1785
1971
|
".tsx",
|
|
1786
1972
|
".css",
|
|
1787
1973
|
".html"
|
|
1788
|
-
].includes(
|
|
1974
|
+
].includes(import_node_path11.default.extname(filePath));
|
|
1975
|
+
}
|
|
1976
|
+
|
|
1977
|
+
// src/scaffold/create-zk-project.ts
|
|
1978
|
+
var import_promises9 = require("fs/promises");
|
|
1979
|
+
var import_node_fs2 = require("fs");
|
|
1980
|
+
var import_node_path12 = __toESM(require("path"), 1);
|
|
1981
|
+
var import_node_url = require("url");
|
|
1982
|
+
var import_meta2 = {};
|
|
1983
|
+
var moduleDir = typeof __dirname === "string" ? __dirname : import_node_path12.default.dirname((0, import_node_url.fileURLToPath)(import_meta2.url));
|
|
1984
|
+
function scaffoldRoot() {
|
|
1985
|
+
const candidates = [
|
|
1986
|
+
import_node_path12.default.resolve(moduleDir, "../../scaffolds"),
|
|
1987
|
+
import_node_path12.default.resolve(moduleDir, "../scaffolds")
|
|
1988
|
+
];
|
|
1989
|
+
const found = candidates.find((candidate) => (0, import_node_fs2.existsSync)(candidate));
|
|
1990
|
+
return found ?? candidates[0];
|
|
1991
|
+
}
|
|
1992
|
+
function configSource(projectName) {
|
|
1993
|
+
return `import { defineConfig } from "@caatinga/core";
|
|
1994
|
+
|
|
1995
|
+
export default defineConfig({
|
|
1996
|
+
project: "${projectName}",
|
|
1997
|
+
defaultNetwork: "testnet",
|
|
1998
|
+
contracts: {
|
|
1999
|
+
verifier: {
|
|
2000
|
+
path: "./contracts/verifier",
|
|
2001
|
+
wasm: "./contracts/verifier/target/wasm32v1-none/release/verifier.wasm"
|
|
2002
|
+
}
|
|
2003
|
+
},
|
|
2004
|
+
networks: {
|
|
2005
|
+
testnet: {
|
|
2006
|
+
rpcUrl: "https://soroban-testnet.stellar.org",
|
|
2007
|
+
networkPassphrase: "Test SDF Network ; September 2015"
|
|
2008
|
+
}
|
|
2009
|
+
},
|
|
2010
|
+
zk: {
|
|
2011
|
+
circuits: {
|
|
2012
|
+
main: {
|
|
2013
|
+
path: "./circuits",
|
|
2014
|
+
protocol: "groth16",
|
|
2015
|
+
curve: "bls12381",
|
|
2016
|
+
verifierContract: "verifier"
|
|
2017
|
+
}
|
|
2018
|
+
}
|
|
2019
|
+
}
|
|
2020
|
+
});
|
|
2021
|
+
`;
|
|
2022
|
+
}
|
|
2023
|
+
function packageJsonSource(projectName) {
|
|
2024
|
+
return `${JSON.stringify({
|
|
2025
|
+
name: projectName,
|
|
2026
|
+
version: "0.1.0",
|
|
2027
|
+
private: true,
|
|
2028
|
+
type: "module",
|
|
2029
|
+
scripts: {
|
|
2030
|
+
"zk:build": "caatinga zk build main",
|
|
2031
|
+
"zk:prove": "caatinga zk prove main",
|
|
2032
|
+
build: "caatinga build verifier",
|
|
2033
|
+
deploy: "caatinga deploy verifier"
|
|
2034
|
+
},
|
|
2035
|
+
devDependencies: {
|
|
2036
|
+
"@caatinga/cli": `^${CAATINGA_CORE_VERSION}`,
|
|
2037
|
+
"@caatinga/core": `^${CAATINGA_CORE_VERSION}`
|
|
2038
|
+
}
|
|
2039
|
+
}, null, 2)}
|
|
2040
|
+
`;
|
|
2041
|
+
}
|
|
2042
|
+
function readmeSource(projectName) {
|
|
2043
|
+
return `# ${projectName}
|
|
2044
|
+
|
|
2045
|
+
Minimal Caatinga ZK project.
|
|
2046
|
+
|
|
2047
|
+
## Workflow
|
|
2048
|
+
|
|
2049
|
+
\`\`\`bash
|
|
2050
|
+
npm install
|
|
2051
|
+
npx caatinga zk build main
|
|
2052
|
+
npx caatinga build verifier
|
|
2053
|
+
npx caatinga deploy verifier --network testnet
|
|
2054
|
+
npx caatinga zk prove main
|
|
2055
|
+
\`\`\`
|
|
2056
|
+
|
|
2057
|
+
Replace \`circuits/main.circom\` with your circuit. Keep the entry point named \`main\`.
|
|
2058
|
+
`;
|
|
2059
|
+
}
|
|
2060
|
+
async function createZkProject(options) {
|
|
2061
|
+
const targetDir = import_node_path12.default.resolve(options.targetDir);
|
|
2062
|
+
const force = options.force ?? false;
|
|
2063
|
+
const projectFiles = options.projectFiles ?? true;
|
|
2064
|
+
await (0, import_promises9.mkdir)(targetDir, { recursive: true });
|
|
2065
|
+
if (projectFiles) {
|
|
2066
|
+
await Promise.all([
|
|
2067
|
+
(0, import_promises9.writeFile)(import_node_path12.default.join(targetDir, "caatinga.config.ts"), configSource(options.projectName), { encoding: "utf8", flag: force ? "w" : "wx" }),
|
|
2068
|
+
(0, import_promises9.writeFile)(import_node_path12.default.join(targetDir, "package.json"), packageJsonSource(options.projectName), { encoding: "utf8", flag: force ? "w" : "wx" }),
|
|
2069
|
+
(0, import_promises9.writeFile)(import_node_path12.default.join(targetDir, ".gitignore"), "node_modules\n.artifacts\ntarget\n", { encoding: "utf8", flag: force ? "w" : "wx" }),
|
|
2070
|
+
(0, import_promises9.writeFile)(import_node_path12.default.join(targetDir, "README.md"), readmeSource(options.projectName), { encoding: "utf8", flag: force ? "w" : "wx" })
|
|
2071
|
+
]);
|
|
2072
|
+
}
|
|
2073
|
+
await (0, import_promises9.mkdir)(import_node_path12.default.join(targetDir, "contracts"), { recursive: true });
|
|
2074
|
+
await (0, import_promises9.cp)(import_node_path12.default.join(scaffoldRoot(), "zk-circuit-stub"), import_node_path12.default.join(targetDir, "circuits"), {
|
|
2075
|
+
recursive: true,
|
|
2076
|
+
force,
|
|
2077
|
+
errorOnExist: !force
|
|
2078
|
+
});
|
|
2079
|
+
await (0, import_promises9.cp)(import_node_path12.default.join(scaffoldRoot(), "zk-verifier"), import_node_path12.default.join(targetDir, "contracts", "verifier"), {
|
|
2080
|
+
recursive: true,
|
|
2081
|
+
force,
|
|
2082
|
+
errorOnExist: !force
|
|
2083
|
+
});
|
|
2084
|
+
if (projectFiles) {
|
|
2085
|
+
await writeArtifacts(createInitialArtifacts(options.projectName, { networks: ["testnet"] }), targetDir);
|
|
2086
|
+
}
|
|
2087
|
+
return { targetDir };
|
|
2088
|
+
}
|
|
2089
|
+
|
|
2090
|
+
// src/scaffold/create-minimal-project.ts
|
|
2091
|
+
var import_promises10 = require("fs/promises");
|
|
2092
|
+
var import_node_fs3 = require("fs");
|
|
2093
|
+
var import_node_path13 = __toESM(require("path"), 1);
|
|
2094
|
+
var import_node_url2 = require("url");
|
|
2095
|
+
var import_meta3 = {};
|
|
2096
|
+
var moduleDir2 = typeof __dirname === "string" ? __dirname : import_node_path13.default.dirname((0, import_node_url2.fileURLToPath)(import_meta3.url));
|
|
2097
|
+
function scaffoldRoot2() {
|
|
2098
|
+
const candidates = [
|
|
2099
|
+
import_node_path13.default.resolve(moduleDir2, "../../scaffolds"),
|
|
2100
|
+
import_node_path13.default.resolve(moduleDir2, "../scaffolds")
|
|
2101
|
+
];
|
|
2102
|
+
const found = candidates.find((candidate) => (0, import_node_fs3.existsSync)(candidate));
|
|
2103
|
+
return found ?? candidates[0];
|
|
2104
|
+
}
|
|
2105
|
+
function configSource2(projectName) {
|
|
2106
|
+
return `import { defineConfig } from "@caatinga/core";
|
|
2107
|
+
|
|
2108
|
+
export default defineConfig({
|
|
2109
|
+
project: "${projectName}",
|
|
2110
|
+
defaultNetwork: "testnet",
|
|
2111
|
+
contracts: {
|
|
2112
|
+
app: {
|
|
2113
|
+
path: "./contracts/app",
|
|
2114
|
+
wasm: "./contracts/app/target/wasm32v1-none/release/app.wasm"
|
|
2115
|
+
}
|
|
2116
|
+
},
|
|
2117
|
+
networks: {
|
|
2118
|
+
testnet: {
|
|
2119
|
+
rpcUrl: "https://soroban-testnet.stellar.org",
|
|
2120
|
+
networkPassphrase: "Test SDF Network ; September 2015"
|
|
2121
|
+
}
|
|
2122
|
+
}
|
|
2123
|
+
});
|
|
2124
|
+
`;
|
|
2125
|
+
}
|
|
2126
|
+
function packageJsonSource2(projectName) {
|
|
2127
|
+
return `${JSON.stringify({
|
|
2128
|
+
name: projectName,
|
|
2129
|
+
version: "0.1.0",
|
|
2130
|
+
private: true,
|
|
2131
|
+
type: "module",
|
|
2132
|
+
scripts: {
|
|
2133
|
+
build: "caatinga build app",
|
|
2134
|
+
deploy: "caatinga deploy app --network testnet --source ${CAATINGA_SOURCE:-alice}",
|
|
2135
|
+
doctor: "caatinga doctor",
|
|
2136
|
+
"read:hello": "caatinga read app.hello --network testnet --source ${CAATINGA_SOURCE:-alice}",
|
|
2137
|
+
"read:version": "caatinga read app.version --network testnet --source ${CAATINGA_SOURCE:-alice}"
|
|
2138
|
+
},
|
|
2139
|
+
devDependencies: {
|
|
2140
|
+
"@caatinga/cli": `^${CAATINGA_CORE_VERSION}`,
|
|
2141
|
+
"@caatinga/core": `^${CAATINGA_CORE_VERSION}`
|
|
2142
|
+
}
|
|
2143
|
+
}, null, 2)}
|
|
2144
|
+
`;
|
|
2145
|
+
}
|
|
2146
|
+
function readmeSource2(projectName) {
|
|
2147
|
+
return `# ${projectName}
|
|
2148
|
+
|
|
2149
|
+
Minimal Caatinga project with a Soroban contract stub (no frontend template).
|
|
2150
|
+
|
|
2151
|
+
## Workflow
|
|
2152
|
+
|
|
2153
|
+
\`\`\`bash
|
|
2154
|
+
npm install
|
|
2155
|
+
npx caatinga doctor
|
|
2156
|
+
npx caatinga build app
|
|
2157
|
+
npx caatinga deploy app --network testnet --source <identity>
|
|
2158
|
+
npx caatinga read app.version --network testnet
|
|
2159
|
+
npx caatinga read app.hello --network testnet
|
|
2160
|
+
\`\`\`
|
|
2161
|
+
|
|
2162
|
+
## Contract
|
|
2163
|
+
|
|
2164
|
+
- \`hello()\` \u2014 read-only; returns Soroban Symbol \`hello\`
|
|
2165
|
+
- \`version()\` \u2014 read-only; returns \`1\`
|
|
2166
|
+
|
|
2167
|
+
Use \`caatinga read\` for read-only methods. Use \`caatinga invoke\` only after you add state-changing methods to the contract.
|
|
2168
|
+
|
|
2169
|
+
Soroban \`Symbol\` parameters are generated as TypeScript \`string\` values with host-specific restrictions \u2014 see the Caatinga docs on [Soroban types](https://github.com/caatinga/caatinga/blob/main/docs/soroban-types.md).
|
|
2170
|
+
|
|
2171
|
+
Edit \`contracts/app/src/lib.rs\` to customize the contract. Add a frontend later with \`@caatinga/client\` and your chosen UI stack.
|
|
2172
|
+
`;
|
|
2173
|
+
}
|
|
2174
|
+
async function createMinimalProject(options) {
|
|
2175
|
+
const targetDir = import_node_path13.default.resolve(options.targetDir);
|
|
2176
|
+
const force = options.force ?? false;
|
|
2177
|
+
await (0, import_promises10.mkdir)(targetDir, { recursive: true });
|
|
2178
|
+
await Promise.all([
|
|
2179
|
+
(0, import_promises10.writeFile)(import_node_path13.default.join(targetDir, "caatinga.config.ts"), configSource2(options.projectName), { encoding: "utf8", flag: force ? "w" : "wx" }),
|
|
2180
|
+
(0, import_promises10.writeFile)(import_node_path13.default.join(targetDir, "package.json"), packageJsonSource2(options.projectName), { encoding: "utf8", flag: force ? "w" : "wx" }),
|
|
2181
|
+
(0, import_promises10.writeFile)(import_node_path13.default.join(targetDir, ".gitignore"), "node_modules\n.artifacts\ntarget\n", { encoding: "utf8", flag: force ? "w" : "wx" }),
|
|
2182
|
+
(0, import_promises10.writeFile)(import_node_path13.default.join(targetDir, "README.md"), readmeSource2(options.projectName), { encoding: "utf8", flag: force ? "w" : "wx" })
|
|
2183
|
+
]);
|
|
2184
|
+
await (0, import_promises10.mkdir)(import_node_path13.default.join(targetDir, "contracts"), { recursive: true });
|
|
2185
|
+
await (0, import_promises10.cp)(import_node_path13.default.join(scaffoldRoot2(), "soroban-contract-stub"), import_node_path13.default.join(targetDir, "contracts", "app"), {
|
|
2186
|
+
recursive: true,
|
|
2187
|
+
force,
|
|
2188
|
+
errorOnExist: !force
|
|
2189
|
+
});
|
|
2190
|
+
await writeArtifacts(createInitialArtifacts(options.projectName, { networks: ["testnet"] }), targetDir);
|
|
2191
|
+
return { targetDir };
|
|
1789
2192
|
}
|
|
1790
2193
|
|
|
1791
2194
|
// src/ci/is-transient-testnet-smoke-failure.ts
|
|
@@ -1817,17 +2220,21 @@ function isTransientTestnetSmokeFailure(logText) {
|
|
|
1817
2220
|
CaatingaConfigSchema,
|
|
1818
2221
|
CaatingaError,
|
|
1819
2222
|
CaatingaErrorCode,
|
|
2223
|
+
READ_CALL_FAILURE_REGEX,
|
|
1820
2224
|
STELLAR_CLI_LAST_TESTED_VERSION,
|
|
1821
2225
|
STELLAR_CLI_MIN_VERSION,
|
|
1822
2226
|
TemplateManifestSchema,
|
|
1823
2227
|
WELL_KNOWN_NETWORKS,
|
|
1824
2228
|
buildContract,
|
|
1825
2229
|
buildDependencyGraph,
|
|
2230
|
+
buildReadCallHint,
|
|
1826
2231
|
checkBinary,
|
|
1827
2232
|
checkStellarCliVersion,
|
|
1828
2233
|
collectProjectStatus,
|
|
1829
2234
|
createInitialArtifacts,
|
|
2235
|
+
createMinimalProject,
|
|
1830
2236
|
createProjectFromTemplate,
|
|
2237
|
+
createZkProject,
|
|
1831
2238
|
defineConfig,
|
|
1832
2239
|
deployContract,
|
|
1833
2240
|
deployContractGraph,
|
|
@@ -1838,6 +2245,8 @@ function isTransientTestnetSmokeFailure(logText) {
|
|
|
1838
2245
|
generateBindings,
|
|
1839
2246
|
generateBindingsGraph,
|
|
1840
2247
|
invokeContract,
|
|
2248
|
+
isCargoBinMissingFromPath,
|
|
2249
|
+
isReadCallFailure,
|
|
1841
2250
|
isTransientTestnetSmokeFailure,
|
|
1842
2251
|
loadConfig,
|
|
1843
2252
|
parseContractId,
|
|
@@ -1845,11 +2254,13 @@ function isTransientTestnetSmokeFailure(logText) {
|
|
|
1845
2254
|
parseStellarCliVersion,
|
|
1846
2255
|
readArtifacts,
|
|
1847
2256
|
readBindingMarker,
|
|
2257
|
+
readContract,
|
|
1848
2258
|
resolveContract,
|
|
1849
2259
|
resolveDefaultContractName,
|
|
1850
2260
|
resolveDeployArgs,
|
|
1851
2261
|
resolveDeployOrder,
|
|
1852
2262
|
resolveNetwork,
|
|
2263
|
+
resolveSubprocessEnv,
|
|
1853
2264
|
runCommand,
|
|
1854
2265
|
toCaatingaError,
|
|
1855
2266
|
updateArtifact,
|