@caatinga/core 3.2.0 → 3.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/artifact.schema-CIDkTrL3.d.cts +580 -0
- package/dist/artifact.schema-CIDkTrL3.d.ts +580 -0
- package/dist/browser.cjs +4 -0
- package/dist/browser.d.cts +1 -1
- package/dist/browser.d.ts +1 -1
- package/dist/browser.js +4 -0
- package/dist/index.cjs +667 -151
- package/dist/index.d.cts +195 -9
- package/dist/index.d.ts +195 -9
- package/dist/index.js +630 -126
- package/dist/runtime/requirements.cjs +4 -0
- package/dist/runtime/requirements.js +4 -0
- package/package.json +1 -1
- package/dist/artifact.schema-DZC05uy_.d.cts +0 -186
- package/dist/artifact.schema-DZC05uy_.d.ts +0 -186
package/dist/index.js
CHANGED
|
@@ -8,6 +8,8 @@ var CaatingaErrorCode = {
|
|
|
8
8
|
STELLAR_CLI_NOT_FOUND: "CAATINGA_STELLAR_CLI_NOT_FOUND",
|
|
9
9
|
STELLAR_CLI_VERSION_PARSE_FAILED: "CAATINGA_STELLAR_CLI_VERSION_PARSE_FAILED",
|
|
10
10
|
UNSUPPORTED_CLI_VERSION: "CAATINGA_UNSUPPORTED_CLI_VERSION",
|
|
11
|
+
STELLAR_SDK_VERSION_PARSE_FAILED: "CAATINGA_STELLAR_SDK_VERSION_PARSE_FAILED",
|
|
12
|
+
UNSUPPORTED_SDK_VERSION: "CAATINGA_UNSUPPORTED_SDK_VERSION",
|
|
11
13
|
RUST_NOT_FOUND: "CAATINGA_RUST_NOT_FOUND",
|
|
12
14
|
RUST_TARGET_NOT_FOUND: "CAATINGA_RUST_TARGET_NOT_FOUND",
|
|
13
15
|
DEPLOY_FAILED: "CAATINGA_DEPLOY_FAILED",
|
|
@@ -50,6 +52,8 @@ var CaatingaErrorCode = {
|
|
|
50
52
|
ZK_VERIFICATION_FAILED: "CAATINGA_ZK_VERIFICATION_FAILED",
|
|
51
53
|
ZK_DEV_CEREMONY_BLOCKED: "CAATINGA_ZK_DEV_CEREMONY_BLOCKED",
|
|
52
54
|
DOCTOR_PARTIAL_DEPLOY: "CAATINGA_DOCTOR_PARTIAL_DEPLOY",
|
|
55
|
+
ROLLBACK_TARGET_NOT_FOUND: "CAATINGA_ROLLBACK_TARGET_NOT_FOUND",
|
|
56
|
+
ESTIMATE_FAILED: "CAATINGA_ESTIMATE_FAILED",
|
|
53
57
|
MULTI_AUTH_REQUIRED: "CAATINGA_MULTI_AUTH_REQUIRED"
|
|
54
58
|
};
|
|
55
59
|
|
|
@@ -236,6 +240,14 @@ async function loadConfig(options = {}) {
|
|
|
236
240
|
|
|
237
241
|
// src/artifacts/artifact.schema.ts
|
|
238
242
|
import { z as z3 } from "zod";
|
|
243
|
+
var ArtifactSupersedeReasonSchema = z3.enum(["upgrade", "rollback", "force-redeploy"]);
|
|
244
|
+
var ContractArtifactHistoryEntrySchema = z3.object({
|
|
245
|
+
contractId: z3.string().min(1),
|
|
246
|
+
wasmHash: z3.string().min(1),
|
|
247
|
+
deployedAt: z3.string().datetime(),
|
|
248
|
+
supersededAt: z3.string().datetime(),
|
|
249
|
+
reason: ArtifactSupersedeReasonSchema.optional()
|
|
250
|
+
});
|
|
239
251
|
var ContractArtifactSchema = z3.object({
|
|
240
252
|
contractId: z3.string().min(1),
|
|
241
253
|
wasmHash: z3.string().min(1),
|
|
@@ -243,17 +255,28 @@ var ContractArtifactSchema = z3.object({
|
|
|
243
255
|
sourcePath: z3.string().min(1),
|
|
244
256
|
wasmPath: z3.string().min(1),
|
|
245
257
|
dependencies: z3.array(z3.string().min(1)).default([]),
|
|
246
|
-
resolvedDeployArgs: z3.record(z3.string().min(1), z3.union([z3.string(), z3.number(), z3.boolean()])).default({})
|
|
258
|
+
resolvedDeployArgs: z3.record(z3.string().min(1), z3.union([z3.string(), z3.number(), z3.boolean()])).default({}),
|
|
259
|
+
history: z3.array(ContractArtifactHistoryEntrySchema).optional()
|
|
247
260
|
});
|
|
248
261
|
var NetworkArtifactsSchema = z3.object({
|
|
249
262
|
contracts: z3.record(z3.string().min(1), ContractArtifactSchema).default({}),
|
|
250
263
|
dependencyGraph: z3.record(z3.string().min(1), z3.array(z3.string().min(1))).default({})
|
|
251
264
|
});
|
|
252
|
-
var
|
|
265
|
+
var CaatingaArtifactsBaseSchema = z3.object({
|
|
253
266
|
project: z3.string().min(1),
|
|
254
|
-
version: z3.literal(1),
|
|
255
267
|
networks: z3.record(z3.string().min(1), NetworkArtifactsSchema).default({})
|
|
256
268
|
});
|
|
269
|
+
var CaatingaArtifactsV1Schema = CaatingaArtifactsBaseSchema.extend({
|
|
270
|
+
version: z3.literal(1)
|
|
271
|
+
});
|
|
272
|
+
var CaatingaArtifactsV2Schema = CaatingaArtifactsBaseSchema.extend({
|
|
273
|
+
version: z3.literal(2)
|
|
274
|
+
});
|
|
275
|
+
var CaatingaArtifactsSchema = z3.union([
|
|
276
|
+
CaatingaArtifactsV1Schema,
|
|
277
|
+
CaatingaArtifactsV2Schema
|
|
278
|
+
]);
|
|
279
|
+
var CURRENT_ARTIFACTS_SCHEMA_VERSION = 2;
|
|
257
280
|
|
|
258
281
|
// src/artifacts/read-artifacts.ts
|
|
259
282
|
import { readFile } from "fs/promises";
|
|
@@ -305,29 +328,139 @@ function createInitialArtifacts(project, options = {}) {
|
|
|
305
328
|
);
|
|
306
329
|
return {
|
|
307
330
|
project,
|
|
308
|
-
version:
|
|
331
|
+
version: 2,
|
|
309
332
|
networks
|
|
310
333
|
};
|
|
311
334
|
}
|
|
312
335
|
|
|
313
336
|
// src/artifacts/update-artifact.ts
|
|
314
|
-
function
|
|
337
|
+
function appendHistory(existing, reason) {
|
|
338
|
+
if (!existing || !reason) {
|
|
339
|
+
return existing?.history;
|
|
340
|
+
}
|
|
341
|
+
const supersededAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
342
|
+
const entry = {
|
|
343
|
+
contractId: existing.contractId,
|
|
344
|
+
wasmHash: existing.wasmHash,
|
|
345
|
+
deployedAt: existing.deployedAt,
|
|
346
|
+
supersededAt,
|
|
347
|
+
reason
|
|
348
|
+
};
|
|
349
|
+
return [...existing.history ?? [], entry];
|
|
350
|
+
}
|
|
351
|
+
function updateArtifact(artifacts, networkName, contractName, contractArtifact, options = {}) {
|
|
315
352
|
const existingNetwork = artifacts.networks[networkName] ?? { contracts: {}, dependencyGraph: {} };
|
|
353
|
+
const existingContract = existingNetwork.contracts[contractName];
|
|
354
|
+
const history = appendHistory(existingContract, options.supersedeReason);
|
|
355
|
+
const nextVersion = artifacts.version === 1 && options.supersedeReason ? 2 : artifacts.version;
|
|
316
356
|
return {
|
|
317
357
|
...artifacts,
|
|
358
|
+
version: nextVersion,
|
|
318
359
|
networks: {
|
|
319
360
|
...artifacts.networks,
|
|
320
361
|
[networkName]: {
|
|
321
362
|
...existingNetwork,
|
|
322
|
-
dependencyGraph:
|
|
363
|
+
dependencyGraph: options.dependencyGraph ?? existingNetwork.dependencyGraph ?? {},
|
|
323
364
|
contracts: {
|
|
324
365
|
...existingNetwork.contracts,
|
|
325
|
-
[contractName]:
|
|
366
|
+
[contractName]: {
|
|
367
|
+
...contractArtifact,
|
|
368
|
+
history: history ?? contractArtifact.history
|
|
369
|
+
}
|
|
326
370
|
}
|
|
327
371
|
}
|
|
328
372
|
}
|
|
329
373
|
};
|
|
330
374
|
}
|
|
375
|
+
function restoreArtifactFromHistory(input) {
|
|
376
|
+
const network = input.artifacts.networks[input.networkName];
|
|
377
|
+
const current = network?.contracts[input.contractName];
|
|
378
|
+
if (!current) {
|
|
379
|
+
throw new CaatingaError(
|
|
380
|
+
`No artifact for "${input.contractName}" on "${input.networkName}".`,
|
|
381
|
+
CaatingaErrorCode.ARTIFACT_NOT_FOUND,
|
|
382
|
+
"Deploy the contract before attempting rollback."
|
|
383
|
+
);
|
|
384
|
+
}
|
|
385
|
+
if (current.contractId === input.contractId) {
|
|
386
|
+
return input.artifacts;
|
|
387
|
+
}
|
|
388
|
+
const fromHistory = (current.history ?? []).find(
|
|
389
|
+
(entry) => entry.contractId === input.contractId
|
|
390
|
+
);
|
|
391
|
+
if (!fromHistory) {
|
|
392
|
+
throw new CaatingaError(
|
|
393
|
+
`Rollback target "${input.contractId}" was not found in artifact history for "${input.contractName}".`,
|
|
394
|
+
CaatingaErrorCode.ROLLBACK_TARGET_NOT_FOUND,
|
|
395
|
+
"Use caatinga inspect to list prior contract IDs, or redeploy manually."
|
|
396
|
+
);
|
|
397
|
+
}
|
|
398
|
+
const supersededAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
399
|
+
const restoredArtifact = {
|
|
400
|
+
contractId: fromHistory.contractId,
|
|
401
|
+
wasmHash: fromHistory.wasmHash,
|
|
402
|
+
deployedAt: fromHistory.deployedAt,
|
|
403
|
+
sourcePath: current.sourcePath,
|
|
404
|
+
wasmPath: current.wasmPath,
|
|
405
|
+
dependencies: current.dependencies,
|
|
406
|
+
resolvedDeployArgs: current.resolvedDeployArgs,
|
|
407
|
+
history: [
|
|
408
|
+
...current.history ?? [],
|
|
409
|
+
{
|
|
410
|
+
contractId: current.contractId,
|
|
411
|
+
wasmHash: current.wasmHash,
|
|
412
|
+
deployedAt: current.deployedAt,
|
|
413
|
+
supersededAt,
|
|
414
|
+
reason: "rollback"
|
|
415
|
+
}
|
|
416
|
+
]
|
|
417
|
+
};
|
|
418
|
+
return {
|
|
419
|
+
...updateArtifact(input.artifacts, input.networkName, input.contractName, restoredArtifact),
|
|
420
|
+
version: 2
|
|
421
|
+
};
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
// src/artifacts/migrate-artifacts.ts
|
|
425
|
+
function migrateArtifactsToV2(artifacts) {
|
|
426
|
+
if (artifacts.version === CURRENT_ARTIFACTS_SCHEMA_VERSION) {
|
|
427
|
+
return {
|
|
428
|
+
artifacts,
|
|
429
|
+
migrated: false
|
|
430
|
+
};
|
|
431
|
+
}
|
|
432
|
+
const v1 = artifacts;
|
|
433
|
+
return {
|
|
434
|
+
artifacts: {
|
|
435
|
+
project: v1.project,
|
|
436
|
+
version: CURRENT_ARTIFACTS_SCHEMA_VERSION,
|
|
437
|
+
networks: v1.networks
|
|
438
|
+
},
|
|
439
|
+
migrated: true
|
|
440
|
+
};
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
// src/artifacts/migrate-artifacts-file.ts
|
|
444
|
+
async function migrateArtifactsFile(cwd = process.cwd()) {
|
|
445
|
+
const artifacts = await readArtifacts(cwd);
|
|
446
|
+
const { artifacts: migrated, migrated: changed } = migrateArtifactsToV2(artifacts);
|
|
447
|
+
const path17 = await writeArtifacts(migrated, cwd);
|
|
448
|
+
return { path: path17, migrated: changed, artifacts: migrated };
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
// src/artifacts/rollback-artifact.ts
|
|
452
|
+
async function rollbackContractArtifact(input) {
|
|
453
|
+
const cwd = input.cwd ?? process.cwd();
|
|
454
|
+
const artifacts = await readArtifacts(cwd);
|
|
455
|
+
const next = restoreArtifactFromHistory({
|
|
456
|
+
artifacts,
|
|
457
|
+
networkName: input.networkName,
|
|
458
|
+
contractName: input.contractName,
|
|
459
|
+
contractId: input.contractId
|
|
460
|
+
});
|
|
461
|
+
const path17 = await writeArtifacts(next, cwd);
|
|
462
|
+
return { path: path17, artifacts: next };
|
|
463
|
+
}
|
|
331
464
|
|
|
332
465
|
// src/networks/resolve-network.ts
|
|
333
466
|
function resolveNetwork(config, networkName) {
|
|
@@ -594,6 +727,35 @@ function evaluateStellarCliCompatibility(input) {
|
|
|
594
727
|
};
|
|
595
728
|
}
|
|
596
729
|
|
|
730
|
+
// src/stellar-cli/probe-stellar-cli-features.ts
|
|
731
|
+
import semver3 from "semver";
|
|
732
|
+
var STELLAR_CLI_REQUIRED_FEATURES = [
|
|
733
|
+
"contract-build",
|
|
734
|
+
"contract-deploy",
|
|
735
|
+
"contract-invoke-sign"
|
|
736
|
+
];
|
|
737
|
+
var FEATURE_COMMANDS = {
|
|
738
|
+
"contract-build": ["contract", "build", "--help"],
|
|
739
|
+
"contract-deploy": ["contract", "deploy", "--help"],
|
|
740
|
+
"contract-invoke-sign": ["contract", "invoke", "--help"]
|
|
741
|
+
};
|
|
742
|
+
async function probeMissingStellarCliFeatures(version) {
|
|
743
|
+
const missing = [];
|
|
744
|
+
if (semver3.valid(version) && semver3.lt(version, STELLAR_CLI_MIN_VERSION)) {
|
|
745
|
+
return ["contract-invoke-sign"];
|
|
746
|
+
}
|
|
747
|
+
for (const feature of STELLAR_CLI_REQUIRED_FEATURES) {
|
|
748
|
+
try {
|
|
749
|
+
await runCommand("stellar", FEATURE_COMMANDS[feature], {
|
|
750
|
+
skipStellarVersionCheck: true
|
|
751
|
+
});
|
|
752
|
+
} catch {
|
|
753
|
+
missing.push(feature);
|
|
754
|
+
}
|
|
755
|
+
}
|
|
756
|
+
return missing;
|
|
757
|
+
}
|
|
758
|
+
|
|
597
759
|
// src/stellar-cli/check-stellar-cli-version.ts
|
|
598
760
|
async function checkStellarCliVersion(input = {}) {
|
|
599
761
|
let rawOutput;
|
|
@@ -613,9 +775,12 @@ async function checkStellarCliVersion(input = {}) {
|
|
|
613
775
|
}
|
|
614
776
|
throw error;
|
|
615
777
|
}
|
|
778
|
+
const version = parseStellarCliVersion(rawOutput);
|
|
779
|
+
const probedMissing = input.probeFeatures === false ? [] : await probeMissingStellarCliFeatures(version);
|
|
780
|
+
const missingFeatures = [...input.features ?? [], ...probedMissing];
|
|
616
781
|
const report = evaluateStellarCliCompatibility({
|
|
617
|
-
version
|
|
618
|
-
features:
|
|
782
|
+
version,
|
|
783
|
+
features: missingFeatures.length > 0 ? missingFeatures : void 0,
|
|
619
784
|
lastTestedVersion: input.lastTestedVersion
|
|
620
785
|
});
|
|
621
786
|
for (const warning of report.warnings) {
|
|
@@ -761,6 +926,122 @@ function parseContractId(output) {
|
|
|
761
926
|
return match[0];
|
|
762
927
|
}
|
|
763
928
|
|
|
929
|
+
// src/stellar-sdk/check-stellar-sdk-version.ts
|
|
930
|
+
import { readFile as readFile3 } from "fs/promises";
|
|
931
|
+
import path7 from "path";
|
|
932
|
+
|
|
933
|
+
// src/stellar-sdk/compat.ts
|
|
934
|
+
import semver4 from "semver";
|
|
935
|
+
|
|
936
|
+
// src/stellar-sdk/version.ts
|
|
937
|
+
var STELLAR_SDK_MIN_VERSION = "16.0.1";
|
|
938
|
+
var STELLAR_SDK_LAST_TESTED_VERSION = "16.0.1";
|
|
939
|
+
|
|
940
|
+
// src/stellar-sdk/compat.ts
|
|
941
|
+
function evaluateStellarSdkCompatibility(input) {
|
|
942
|
+
const parsed = semver4.parse(input.version);
|
|
943
|
+
if (!parsed || !semver4.valid(input.version)) {
|
|
944
|
+
throw new CaatingaError(
|
|
945
|
+
"Could not parse @stellar/stellar-sdk version.",
|
|
946
|
+
CaatingaErrorCode.STELLAR_SDK_VERSION_PARSE_FAILED,
|
|
947
|
+
"Use a semantic version such as 16.0.1."
|
|
948
|
+
);
|
|
949
|
+
}
|
|
950
|
+
const lastTestedVersion = semver4.valid(input.lastTestedVersion ?? STELLAR_SDK_LAST_TESTED_VERSION) ?? STELLAR_SDK_LAST_TESTED_VERSION;
|
|
951
|
+
const warnings = [];
|
|
952
|
+
let status = "supported";
|
|
953
|
+
if (semver4.lt(parsed, STELLAR_SDK_MIN_VERSION)) {
|
|
954
|
+
throw new CaatingaError(
|
|
955
|
+
`@stellar/stellar-sdk ${input.version} is below the supported minimum ${STELLAR_SDK_MIN_VERSION}.`,
|
|
956
|
+
CaatingaErrorCode.UNSUPPORTED_SDK_VERSION,
|
|
957
|
+
`Install @stellar/stellar-sdk ${STELLAR_SDK_MIN_VERSION} or newer.`
|
|
958
|
+
);
|
|
959
|
+
}
|
|
960
|
+
if (semver4.gt(parsed, lastTestedVersion)) {
|
|
961
|
+
status = "untested";
|
|
962
|
+
warnings.push({
|
|
963
|
+
code: "STELLAR_SDK_UNTESTED_VERSION",
|
|
964
|
+
message: `@stellar/stellar-sdk ${input.version} is newer than the last-tested ${lastTestedVersion}; binding output may differ.`,
|
|
965
|
+
remediation: "Pin @stellar/stellar-sdk to the last-tested version in package.json, or update Caatinga fixtures after validating generate output."
|
|
966
|
+
});
|
|
967
|
+
}
|
|
968
|
+
return {
|
|
969
|
+
version: input.version,
|
|
970
|
+
status,
|
|
971
|
+
minVersion: STELLAR_SDK_MIN_VERSION,
|
|
972
|
+
lastTestedVersion,
|
|
973
|
+
warnings
|
|
974
|
+
};
|
|
975
|
+
}
|
|
976
|
+
function parseStellarSdkVersion(raw) {
|
|
977
|
+
const trimmed = raw.trim();
|
|
978
|
+
const match = trimmed.match(/(\d+\.\d+\.\d+(?:[-+][\w.-]+)?)/);
|
|
979
|
+
if (!match) {
|
|
980
|
+
throw new CaatingaError(
|
|
981
|
+
"Could not parse @stellar/stellar-sdk version.",
|
|
982
|
+
CaatingaErrorCode.STELLAR_SDK_VERSION_PARSE_FAILED,
|
|
983
|
+
"Expected output like 16.0.1."
|
|
984
|
+
);
|
|
985
|
+
}
|
|
986
|
+
return match[1];
|
|
987
|
+
}
|
|
988
|
+
|
|
989
|
+
// src/stellar-sdk/check-stellar-sdk-version.ts
|
|
990
|
+
async function readInstalledSdkVersion(cwd) {
|
|
991
|
+
try {
|
|
992
|
+
const pkgPath = path7.join(cwd, "node_modules", "@stellar", "stellar-sdk", "package.json");
|
|
993
|
+
const raw = await readFile3(pkgPath, "utf8");
|
|
994
|
+
const pkg = JSON.parse(raw);
|
|
995
|
+
return typeof pkg.version === "string" ? pkg.version : void 0;
|
|
996
|
+
} catch {
|
|
997
|
+
return void 0;
|
|
998
|
+
}
|
|
999
|
+
}
|
|
1000
|
+
async function resolveRegistrySdkVersion() {
|
|
1001
|
+
const result = await runCommand("npm", ["view", "@stellar/stellar-sdk", "version"], {
|
|
1002
|
+
skipStellarVersionCheck: true
|
|
1003
|
+
});
|
|
1004
|
+
return parseStellarSdkVersion(result.stdout || result.all);
|
|
1005
|
+
}
|
|
1006
|
+
async function checkStellarSdkVersion(input = {}) {
|
|
1007
|
+
const cwd = input.cwd ?? process.cwd();
|
|
1008
|
+
let version;
|
|
1009
|
+
try {
|
|
1010
|
+
const installed = await readInstalledSdkVersion(cwd);
|
|
1011
|
+
version = installed ?? await resolveRegistrySdkVersion();
|
|
1012
|
+
} catch (error) {
|
|
1013
|
+
if (error instanceof CaatingaError) {
|
|
1014
|
+
throw error;
|
|
1015
|
+
}
|
|
1016
|
+
throw new CaatingaError(
|
|
1017
|
+
"Could not resolve @stellar/stellar-sdk version.",
|
|
1018
|
+
CaatingaErrorCode.STELLAR_SDK_VERSION_PARSE_FAILED,
|
|
1019
|
+
"Install @stellar/stellar-sdk in your project or ensure npm registry access.",
|
|
1020
|
+
error
|
|
1021
|
+
);
|
|
1022
|
+
}
|
|
1023
|
+
const report = evaluateStellarSdkCompatibility({
|
|
1024
|
+
version,
|
|
1025
|
+
lastTestedVersion: input.lastTestedVersion
|
|
1026
|
+
});
|
|
1027
|
+
for (const warning of report.warnings) {
|
|
1028
|
+
if (input.onWarning) {
|
|
1029
|
+
input.onWarning(warning);
|
|
1030
|
+
} else {
|
|
1031
|
+
defaultEmitWarning2(warning);
|
|
1032
|
+
}
|
|
1033
|
+
}
|
|
1034
|
+
return report;
|
|
1035
|
+
}
|
|
1036
|
+
function defaultEmitWarning2(warning) {
|
|
1037
|
+
const lines = [
|
|
1038
|
+
`Warning: ${warning.message}`,
|
|
1039
|
+
warning.remediation ? ` ${warning.remediation}` : void 0
|
|
1040
|
+
].filter((line) => Boolean(line));
|
|
1041
|
+
process.stderr.write(`${lines.join("\n")}
|
|
1042
|
+
`);
|
|
1043
|
+
}
|
|
1044
|
+
|
|
764
1045
|
// src/stellar-cli/build-stellar-network-args.ts
|
|
765
1046
|
function matchesWellKnownNetwork(name, config) {
|
|
766
1047
|
const known = WELL_KNOWN_NETWORKS[name];
|
|
@@ -899,7 +1180,7 @@ function validateSourceShape(source) {
|
|
|
899
1180
|
}
|
|
900
1181
|
|
|
901
1182
|
// src/contracts/resolve-contract.ts
|
|
902
|
-
import
|
|
1183
|
+
import path8 from "path";
|
|
903
1184
|
function resolveContract(config, contractName, cwd = process.cwd()) {
|
|
904
1185
|
const contract = config.contracts[contractName];
|
|
905
1186
|
if (!contract) {
|
|
@@ -912,8 +1193,8 @@ function resolveContract(config, contractName, cwd = process.cwd()) {
|
|
|
912
1193
|
return {
|
|
913
1194
|
name: contractName,
|
|
914
1195
|
config: contract,
|
|
915
|
-
sourcePath:
|
|
916
|
-
wasmPath:
|
|
1196
|
+
sourcePath: path8.resolve(cwd, contract.path),
|
|
1197
|
+
wasmPath: path8.resolve(cwd, contract.wasm)
|
|
917
1198
|
};
|
|
918
1199
|
}
|
|
919
1200
|
|
|
@@ -932,8 +1213,8 @@ function resolveDefaultContractName(config) {
|
|
|
932
1213
|
|
|
933
1214
|
// src/contracts/wasm.ts
|
|
934
1215
|
import { createHash } from "crypto";
|
|
935
|
-
import { access as access2, readdir as readdir2, readFile as
|
|
936
|
-
import
|
|
1216
|
+
import { access as access2, readdir as readdir2, readFile as readFile4, stat } from "fs/promises";
|
|
1217
|
+
import path9 from "path";
|
|
937
1218
|
var LEGACY_RUST_WASM_TARGET = "wasm32-unknown-unknown";
|
|
938
1219
|
var CURRENT_RUST_WASM_TARGET = "wasm32v1-none";
|
|
939
1220
|
function toCurrentWasmTargetPath(wasmPath) {
|
|
@@ -964,18 +1245,18 @@ function wasmNotFoundError(configuredWasmPath, options) {
|
|
|
964
1245
|
);
|
|
965
1246
|
}
|
|
966
1247
|
function toConfigRelativeWasmPath(absoluteWasmPath) {
|
|
967
|
-
const relative =
|
|
968
|
-
return relative.startsWith("..") ? absoluteWasmPath : `./${relative.split(
|
|
1248
|
+
const relative = path9.relative(process.cwd(), absoluteWasmPath);
|
|
1249
|
+
return relative.startsWith("..") ? absoluteWasmPath : `./${relative.split(path9.sep).join("/")}`;
|
|
969
1250
|
}
|
|
970
1251
|
function wasmFileName(configuredWasmPath) {
|
|
971
|
-
return
|
|
1252
|
+
return path9.basename(configuredWasmPath);
|
|
972
1253
|
}
|
|
973
1254
|
function buildAlternateWasmCandidates(configuredWasmPath, options) {
|
|
974
1255
|
const fileName = wasmFileName(configuredWasmPath);
|
|
975
1256
|
const candidates = [];
|
|
976
1257
|
const seen = /* @__PURE__ */ new Set();
|
|
977
1258
|
function addCandidate(candidate) {
|
|
978
|
-
const resolved =
|
|
1259
|
+
const resolved = path9.resolve(candidate);
|
|
979
1260
|
if (seen.has(resolved)) {
|
|
980
1261
|
return;
|
|
981
1262
|
}
|
|
@@ -984,15 +1265,15 @@ function buildAlternateWasmCandidates(configuredWasmPath, options) {
|
|
|
984
1265
|
}
|
|
985
1266
|
const cargoTargetDir = process.env.CARGO_TARGET_DIR;
|
|
986
1267
|
if (cargoTargetDir) {
|
|
987
|
-
addCandidate(
|
|
988
|
-
addCandidate(
|
|
1268
|
+
addCandidate(path9.join(cargoTargetDir, CURRENT_RUST_WASM_TARGET, "release", fileName));
|
|
1269
|
+
addCandidate(path9.join(cargoTargetDir, LEGACY_RUST_WASM_TARGET, "release", fileName));
|
|
989
1270
|
}
|
|
990
1271
|
if (options?.sourcePath) {
|
|
991
1272
|
addCandidate(
|
|
992
|
-
|
|
1273
|
+
path9.join(options.sourcePath, "target", CURRENT_RUST_WASM_TARGET, "release", fileName)
|
|
993
1274
|
);
|
|
994
1275
|
addCandidate(
|
|
995
|
-
|
|
1276
|
+
path9.join(options.sourcePath, "target", LEGACY_RUST_WASM_TARGET, "release", fileName)
|
|
996
1277
|
);
|
|
997
1278
|
}
|
|
998
1279
|
return candidates;
|
|
@@ -1009,7 +1290,7 @@ async function firstExistingPath(paths) {
|
|
|
1009
1290
|
return void 0;
|
|
1010
1291
|
}
|
|
1011
1292
|
async function resolveWasmArtifactPath(configuredWasmPath, options) {
|
|
1012
|
-
const resolvedConfiguredPath =
|
|
1293
|
+
const resolvedConfiguredPath = path9.resolve(configuredWasmPath);
|
|
1013
1294
|
try {
|
|
1014
1295
|
await access2(resolvedConfiguredPath);
|
|
1015
1296
|
return resolvedConfiguredPath;
|
|
@@ -1033,7 +1314,7 @@ async function resolveWasmArtifactPath(configuredWasmPath, options) {
|
|
|
1033
1314
|
}
|
|
1034
1315
|
}
|
|
1035
1316
|
async function hashWasm(wasmPath) {
|
|
1036
|
-
const bytes = await
|
|
1317
|
+
const bytes = await readFile4(wasmPath);
|
|
1037
1318
|
return createHash("sha256").update(bytes).digest("hex");
|
|
1038
1319
|
}
|
|
1039
1320
|
async function getNewestMtimeInDirectory(directory) {
|
|
@@ -1046,7 +1327,7 @@ async function getNewestMtimeInDirectory(directory) {
|
|
|
1046
1327
|
async function walk(dir) {
|
|
1047
1328
|
const entries = await readdir2(dir, { withFileTypes: true });
|
|
1048
1329
|
for (const entry of entries) {
|
|
1049
|
-
const entryPath =
|
|
1330
|
+
const entryPath = path9.join(dir, entry.name);
|
|
1050
1331
|
if (entry.isDirectory()) {
|
|
1051
1332
|
await walk(entryPath);
|
|
1052
1333
|
continue;
|
|
@@ -1062,7 +1343,7 @@ async function getNewestMtimeInDirectory(directory) {
|
|
|
1062
1343
|
return newest > 0 ? newest : void 0;
|
|
1063
1344
|
}
|
|
1064
1345
|
async function isWasmOlderThanSources(input) {
|
|
1065
|
-
const srcDir =
|
|
1346
|
+
const srcDir = path9.join(input.contractPath, "src");
|
|
1066
1347
|
const newestSourceMtime = await getNewestMtimeInDirectory(srcDir);
|
|
1067
1348
|
if (newestSourceMtime === void 0) {
|
|
1068
1349
|
return false;
|
|
@@ -1137,7 +1418,38 @@ async function buildContract(options) {
|
|
|
1137
1418
|
}
|
|
1138
1419
|
|
|
1139
1420
|
// src/contracts/deploy-contract.ts
|
|
1140
|
-
import
|
|
1421
|
+
import path10 from "path";
|
|
1422
|
+
|
|
1423
|
+
// src/shell/is-transient-command-failure.ts
|
|
1424
|
+
var NO_RETRY_CAATINGA_SUBSTRINGS = [
|
|
1425
|
+
"CAATINGA_UNSUPPORTED_CLI_VERSION",
|
|
1426
|
+
"CAATINGA_STELLAR_CLI_VERSION_PARSE_FAILED",
|
|
1427
|
+
"CAATINGA_STELLAR_CLI_NOT_FOUND",
|
|
1428
|
+
"CAATINGA_INVALID_CONFIG",
|
|
1429
|
+
"CAATINGA_CONFIG_NOT_FOUND"
|
|
1430
|
+
];
|
|
1431
|
+
var TRANSIENT_COMMAND_FAILURE_PATTERN = /timeout|i\/o timeout|econnreset|connection reset|503|502|429|rate limit|temporar|bad gateway|fetch failed|network error|unavailable/i;
|
|
1432
|
+
function isTransientCommandFailure(logText) {
|
|
1433
|
+
if (!logText.trim()) {
|
|
1434
|
+
return false;
|
|
1435
|
+
}
|
|
1436
|
+
for (const marker of NO_RETRY_CAATINGA_SUBSTRINGS) {
|
|
1437
|
+
if (logText.includes(marker)) {
|
|
1438
|
+
return false;
|
|
1439
|
+
}
|
|
1440
|
+
}
|
|
1441
|
+
return TRANSIENT_COMMAND_FAILURE_PATTERN.test(logText);
|
|
1442
|
+
}
|
|
1443
|
+
|
|
1444
|
+
// src/contracts/is-transient-deploy-failure.ts
|
|
1445
|
+
function isTransientDeployFailure(error) {
|
|
1446
|
+
if (!(error instanceof CaatingaError) || error.code !== CaatingaErrorCode.DEPLOY_FAILED) {
|
|
1447
|
+
return false;
|
|
1448
|
+
}
|
|
1449
|
+
const logText = `${error.message}
|
|
1450
|
+
${error.hint ?? ""}`;
|
|
1451
|
+
return isTransientCommandFailure(logText);
|
|
1452
|
+
}
|
|
1141
1453
|
|
|
1142
1454
|
// src/contracts/dependency-graph.ts
|
|
1143
1455
|
function buildDependencyGraph(contracts) {
|
|
@@ -1199,6 +1511,12 @@ function resolveCliSource(explicit) {
|
|
|
1199
1511
|
}
|
|
1200
1512
|
|
|
1201
1513
|
// src/contracts/deploy-contract.ts
|
|
1514
|
+
var DEFAULT_DEPLOY_RETRY_DELAYS_MS = [2e3, 5e3];
|
|
1515
|
+
function sleep(ms) {
|
|
1516
|
+
return new Promise((resolve) => {
|
|
1517
|
+
setTimeout(resolve, ms);
|
|
1518
|
+
});
|
|
1519
|
+
}
|
|
1202
1520
|
function toSnakeCaseFlag(key) {
|
|
1203
1521
|
return key.replace(/([A-Z])/g, "_$1").replace(/^_/, "").toLowerCase();
|
|
1204
1522
|
}
|
|
@@ -1243,7 +1561,7 @@ async function deployContract(options) {
|
|
|
1243
1561
|
contract: contractWithWasm,
|
|
1244
1562
|
network,
|
|
1245
1563
|
contractId: existing.contractId,
|
|
1246
|
-
artifactsPath:
|
|
1564
|
+
artifactsPath: path10.resolve(cwd, "caatinga.artifacts.json"),
|
|
1247
1565
|
output: "",
|
|
1248
1566
|
skipped: true,
|
|
1249
1567
|
staleWasmWarning
|
|
@@ -1283,40 +1601,69 @@ async function deployContract(options) {
|
|
|
1283
1601
|
...buildStellarNetworkArgs(network),
|
|
1284
1602
|
...constructorArgs
|
|
1285
1603
|
];
|
|
1286
|
-
let
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1604
|
+
let deployOutcome;
|
|
1605
|
+
const retryDelaysMs = options.deployRetryDelaysMs ?? DEFAULT_DEPLOY_RETRY_DELAYS_MS;
|
|
1606
|
+
const maxDeployAttempts = retryDelaysMs.length + 1;
|
|
1607
|
+
for (let attempt = 0; attempt < maxDeployAttempts; attempt++) {
|
|
1608
|
+
try {
|
|
1609
|
+
const result = await runCommand("stellar", stellarArgs, {
|
|
1610
|
+
cwd,
|
|
1611
|
+
failureCode: CaatingaErrorCode.DEPLOY_FAILED
|
|
1612
|
+
});
|
|
1613
|
+
const output2 = result.all || `${result.stdout}
|
|
1294
1614
|
${result.stderr}`;
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1615
|
+
deployOutcome = {
|
|
1616
|
+
output: output2,
|
|
1617
|
+
contractId: parseContractId(output2)
|
|
1618
|
+
};
|
|
1619
|
+
break;
|
|
1620
|
+
} catch (error) {
|
|
1621
|
+
if (!(error instanceof CaatingaError) || error.code !== CaatingaErrorCode.DEPLOY_FAILED) {
|
|
1622
|
+
throw error;
|
|
1623
|
+
}
|
|
1624
|
+
const recoveredContractId = await tryRecoverContractIdFromDeployFailure({
|
|
1625
|
+
output: `${error.message}
|
|
1302
1626
|
${error.hint ?? ""}`,
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1627
|
+
source,
|
|
1628
|
+
network: network.config,
|
|
1629
|
+
cwd
|
|
1630
|
+
});
|
|
1631
|
+
if (recoveredContractId) {
|
|
1632
|
+
deployOutcome = {
|
|
1633
|
+
output: [
|
|
1634
|
+
error.hint ?? "",
|
|
1635
|
+
"Caatinga recovered the contract ID from the on-chain deploy transaction.",
|
|
1636
|
+
`Contract ID: ${recoveredContractId}`
|
|
1637
|
+
].filter(Boolean).join("\n"),
|
|
1638
|
+
contractId: recoveredContractId
|
|
1639
|
+
};
|
|
1640
|
+
break;
|
|
1641
|
+
}
|
|
1642
|
+
const isLastAttempt = attempt === maxDeployAttempts - 1;
|
|
1643
|
+
if (!isTransientDeployFailure(error) || isLastAttempt) {
|
|
1644
|
+
throw error;
|
|
1645
|
+
}
|
|
1646
|
+
const delayMs = retryDelaysMs[attempt] ?? retryDelaysMs[retryDelaysMs.length - 1] ?? 0;
|
|
1647
|
+
options.onTransientDeployRetry?.({
|
|
1648
|
+
attempt: attempt + 1,
|
|
1649
|
+
maxAttempts: maxDeployAttempts,
|
|
1650
|
+
delayMs
|
|
1651
|
+
});
|
|
1652
|
+
await sleep(delayMs);
|
|
1309
1653
|
}
|
|
1310
|
-
contractId = recoveredContractId;
|
|
1311
|
-
output = [
|
|
1312
|
-
error.hint ?? "",
|
|
1313
|
-
"Caatinga recovered the contract ID from the on-chain deploy transaction.",
|
|
1314
|
-
`Contract ID: ${contractId}`
|
|
1315
|
-
].filter(Boolean).join("\n");
|
|
1316
1654
|
}
|
|
1655
|
+
if (!deployOutcome) {
|
|
1656
|
+
throw new CaatingaError(
|
|
1657
|
+
"Deploy failed without a contract ID.",
|
|
1658
|
+
CaatingaErrorCode.DEPLOY_FAILED,
|
|
1659
|
+
"Re-run the deploy command with the underlying Stellar CLI for full diagnostics."
|
|
1660
|
+
);
|
|
1661
|
+
}
|
|
1662
|
+
const { output, contractId } = deployOutcome;
|
|
1317
1663
|
const wasmHash = await hashWasm(wasmPath);
|
|
1318
1664
|
const dependencyGraph = buildDependencyGraph(options.config.contracts);
|
|
1319
1665
|
const dependencies = options.dependencies ?? contract.config.dependsOn;
|
|
1666
|
+
const supersedeReason = existing?.contractId && options.force ? options.upgrade ? "upgrade" : "force-redeploy" : void 0;
|
|
1320
1667
|
const nextArtifacts = updateArtifact(
|
|
1321
1668
|
artifactsBefore,
|
|
1322
1669
|
network.name,
|
|
@@ -1330,7 +1677,7 @@ ${error.hint ?? ""}`,
|
|
|
1330
1677
|
dependencies,
|
|
1331
1678
|
resolvedDeployArgs
|
|
1332
1679
|
},
|
|
1333
|
-
{ dependencyGraph }
|
|
1680
|
+
{ dependencyGraph, supersedeReason }
|
|
1334
1681
|
);
|
|
1335
1682
|
const artifactsPath = await writeArtifacts(nextArtifacts, cwd);
|
|
1336
1683
|
return {
|
|
@@ -1494,9 +1841,11 @@ async function deployContractGraph(options) {
|
|
|
1494
1841
|
source: options.source,
|
|
1495
1842
|
cwd,
|
|
1496
1843
|
force: options.force,
|
|
1844
|
+
upgrade: options.upgrade,
|
|
1497
1845
|
checkStaleWasm: options.checkStaleWasm,
|
|
1498
1846
|
resolvedDeployArgs,
|
|
1499
|
-
dependencies: contractConfig.dependsOn
|
|
1847
|
+
dependencies: contractConfig.dependsOn,
|
|
1848
|
+
onTransientDeployRetry: options.onTransientDeployRetry
|
|
1500
1849
|
});
|
|
1501
1850
|
if (result.staleWasmWarning) {
|
|
1502
1851
|
staleWasmWarnings.push({
|
|
@@ -1520,11 +1869,11 @@ async function deployContractGraph(options) {
|
|
|
1520
1869
|
|
|
1521
1870
|
// src/contracts/generate-bindings.ts
|
|
1522
1871
|
import { access as access4, mkdir as mkdir2, unlink } from "fs/promises";
|
|
1523
|
-
import
|
|
1872
|
+
import path12 from "path";
|
|
1524
1873
|
|
|
1525
1874
|
// src/bindings/patch-generated-binding-package.ts
|
|
1526
|
-
import { access as access3, readFile as
|
|
1527
|
-
import
|
|
1875
|
+
import { access as access3, readFile as readFile5, writeFile as writeFile3 } from "fs/promises";
|
|
1876
|
+
import path11 from "path";
|
|
1528
1877
|
var BUNDLER_ENTRY = "./src/index.ts";
|
|
1529
1878
|
var ROOT_BINDING_INDEX_CONTENT = 'export * from "./src/index.js";\n';
|
|
1530
1879
|
function resolveExportEntry(exportsField) {
|
|
@@ -1559,9 +1908,9 @@ function shouldPatchPackageJson(packageJson) {
|
|
|
1559
1908
|
return pointsToDist(packageJson.main) || pointsToDist(packageJson.types) || !pointsToBundlerSource(exportEntry);
|
|
1560
1909
|
}
|
|
1561
1910
|
async function ensureRootBindingIndex(outputDir) {
|
|
1562
|
-
const rootIndexPath =
|
|
1911
|
+
const rootIndexPath = path11.join(outputDir, "index.ts");
|
|
1563
1912
|
try {
|
|
1564
|
-
const existing = await
|
|
1913
|
+
const existing = await readFile5(rootIndexPath, "utf8");
|
|
1565
1914
|
if (existing === ROOT_BINDING_INDEX_CONTENT) {
|
|
1566
1915
|
return;
|
|
1567
1916
|
}
|
|
@@ -1571,8 +1920,8 @@ async function ensureRootBindingIndex(outputDir) {
|
|
|
1571
1920
|
}
|
|
1572
1921
|
}
|
|
1573
1922
|
async function patchGeneratedBindingPackage(outputDir) {
|
|
1574
|
-
const packageJsonPath =
|
|
1575
|
-
const entryPath =
|
|
1923
|
+
const packageJsonPath = path11.join(outputDir, "package.json");
|
|
1924
|
+
const entryPath = path11.join(outputDir, "src", "index.ts");
|
|
1576
1925
|
try {
|
|
1577
1926
|
await access3(entryPath);
|
|
1578
1927
|
} catch {
|
|
@@ -1584,7 +1933,7 @@ async function patchGeneratedBindingPackage(outputDir) {
|
|
|
1584
1933
|
}
|
|
1585
1934
|
let raw;
|
|
1586
1935
|
try {
|
|
1587
|
-
raw = await
|
|
1936
|
+
raw = await readFile5(packageJsonPath, "utf8");
|
|
1588
1937
|
} catch {
|
|
1589
1938
|
throw new CaatingaError(
|
|
1590
1939
|
"Generated binding package is missing package.json.",
|
|
@@ -1625,11 +1974,11 @@ function buildGenerateNetworkArgs(network) {
|
|
|
1625
1974
|
|
|
1626
1975
|
// src/contracts/generate-bindings.ts
|
|
1627
1976
|
function toBindingImportPath(bindingsOutput, contractName) {
|
|
1628
|
-
const normalized = bindingsOutput.replace(/^\.\//, "").split(
|
|
1629
|
-
return `./${
|
|
1977
|
+
const normalized = bindingsOutput.replace(/^\.\//, "").split(path12.sep).join("/");
|
|
1978
|
+
return `./${path12.posix.join(normalized, contractName)}`;
|
|
1630
1979
|
}
|
|
1631
1980
|
async function removeLegacyBindingStub(cwd, bindingsOutput, contractName) {
|
|
1632
|
-
const legacyPath =
|
|
1981
|
+
const legacyPath = path12.resolve(cwd, bindingsOutput, `${contractName}.ts`);
|
|
1633
1982
|
try {
|
|
1634
1983
|
await access4(legacyPath);
|
|
1635
1984
|
await unlink(legacyPath);
|
|
@@ -1657,8 +2006,9 @@ async function generateBindings(options) {
|
|
|
1657
2006
|
"Run caatinga deploy for this contract and network before generating bindings."
|
|
1658
2007
|
);
|
|
1659
2008
|
}
|
|
1660
|
-
const outputDir =
|
|
2009
|
+
const outputDir = path12.resolve(cwd, options.config.frontend.bindingsOutput, options.contractName);
|
|
1661
2010
|
await mkdir2(outputDir, { recursive: true });
|
|
2011
|
+
await checkStellarSdkVersion({ cwd });
|
|
1662
2012
|
const result = await runCommand(
|
|
1663
2013
|
"npx",
|
|
1664
2014
|
[
|
|
@@ -1883,14 +2233,172 @@ async function readContract(options) {
|
|
|
1883
2233
|
};
|
|
1884
2234
|
}
|
|
1885
2235
|
|
|
2236
|
+
// src/contracts/estimate-deploy-cost.ts
|
|
2237
|
+
import path13 from "path";
|
|
2238
|
+
function toSnakeCaseFlag2(key) {
|
|
2239
|
+
return key.replace(/([A-Z])/g, "_$1").replace(/^_/, "").toLowerCase();
|
|
2240
|
+
}
|
|
2241
|
+
function formatConstructorCliArgs2(resolved) {
|
|
2242
|
+
const entries = Object.entries(resolved);
|
|
2243
|
+
if (entries.length === 0) {
|
|
2244
|
+
return [];
|
|
2245
|
+
}
|
|
2246
|
+
const tail = ["--"];
|
|
2247
|
+
for (const [key, value] of entries) {
|
|
2248
|
+
tail.push(`--${toSnakeCaseFlag2(key)}`, String(value));
|
|
2249
|
+
}
|
|
2250
|
+
return tail;
|
|
2251
|
+
}
|
|
2252
|
+
function parseFeeStroops(output) {
|
|
2253
|
+
const inclusionMatch = output.match(/inclusion[_\s-]*fee[:\s]+(\d+)/i);
|
|
2254
|
+
const resourceMatch = output.match(/resource[_\s-]*fee[:\s]+(\d+)/i);
|
|
2255
|
+
const totalMatch = output.match(/total[_\s-]*fee[:\s]+(\d+)/i);
|
|
2256
|
+
return {
|
|
2257
|
+
inclusion: inclusionMatch ? Number(inclusionMatch[1]) : void 0,
|
|
2258
|
+
resource: resourceMatch ? Number(resourceMatch[1]) : void 0,
|
|
2259
|
+
...totalMatch && !resourceMatch ? { resource: Number(totalMatch[1]) } : {}
|
|
2260
|
+
};
|
|
2261
|
+
}
|
|
2262
|
+
async function estimateDeployCost(options) {
|
|
2263
|
+
const cwd = options.cwd ?? process.cwd();
|
|
2264
|
+
const contract = resolveContract(options.config, options.contractName, cwd);
|
|
2265
|
+
const network = resolveNetwork(options.config, options.networkName);
|
|
2266
|
+
const source = assertSafeSourceAccount(options.source);
|
|
2267
|
+
await checkBinary("stellar", "Install Stellar CLI before running caatinga estimate.");
|
|
2268
|
+
const wasmPath = await resolveWasmArtifactPath(contract.wasmPath, {
|
|
2269
|
+
sourcePath: contract.sourcePath
|
|
2270
|
+
});
|
|
2271
|
+
const artifacts = await readArtifacts(cwd);
|
|
2272
|
+
const rawDeployArgs = contract.config.deployArgs;
|
|
2273
|
+
const resolvedDeployArgs = Object.keys(rawDeployArgs).length > 0 ? resolveDeployArgs({
|
|
2274
|
+
deployArgs: rawDeployArgs,
|
|
2275
|
+
artifacts,
|
|
2276
|
+
network: network.name
|
|
2277
|
+
}) : {};
|
|
2278
|
+
const constructorArgs = formatConstructorCliArgs2(resolvedDeployArgs);
|
|
2279
|
+
const deployArgs = [
|
|
2280
|
+
"contract",
|
|
2281
|
+
"deploy",
|
|
2282
|
+
"--wasm",
|
|
2283
|
+
wasmPath,
|
|
2284
|
+
"--source-account",
|
|
2285
|
+
source,
|
|
2286
|
+
"--build-only",
|
|
2287
|
+
...buildStellarNetworkArgs(network),
|
|
2288
|
+
...constructorArgs
|
|
2289
|
+
];
|
|
2290
|
+
let buildOutput;
|
|
2291
|
+
try {
|
|
2292
|
+
const buildResult = await runCommand("stellar", deployArgs, {
|
|
2293
|
+
cwd,
|
|
2294
|
+
failureCode: CaatingaErrorCode.ESTIMATE_FAILED
|
|
2295
|
+
});
|
|
2296
|
+
buildOutput = (buildResult.stdout || buildResult.all).trim();
|
|
2297
|
+
} catch (error) {
|
|
2298
|
+
if (error instanceof CaatingaError) {
|
|
2299
|
+
throw new CaatingaError(
|
|
2300
|
+
`Deploy cost estimate failed for "${contract.name}".`,
|
|
2301
|
+
CaatingaErrorCode.ESTIMATE_FAILED,
|
|
2302
|
+
error.hint ?? "Ensure WASM is built and deploy args resolve correctly.",
|
|
2303
|
+
error.cause
|
|
2304
|
+
);
|
|
2305
|
+
}
|
|
2306
|
+
throw error;
|
|
2307
|
+
}
|
|
2308
|
+
const simulateArgs = ["tx", "simulate", "--source-account", source, buildOutput];
|
|
2309
|
+
let simulateOutput = "";
|
|
2310
|
+
try {
|
|
2311
|
+
const simulateResult = await runCommand("stellar", simulateArgs, {
|
|
2312
|
+
cwd,
|
|
2313
|
+
failureCode: CaatingaErrorCode.ESTIMATE_FAILED
|
|
2314
|
+
});
|
|
2315
|
+
simulateOutput = simulateResult.all || `${simulateResult.stdout}
|
|
2316
|
+
${simulateResult.stderr}`;
|
|
2317
|
+
} catch {
|
|
2318
|
+
simulateOutput = "";
|
|
2319
|
+
}
|
|
2320
|
+
const parsed = parseFeeStroops(simulateOutput);
|
|
2321
|
+
const inclusionFeeStroops = parsed.inclusion ?? 100;
|
|
2322
|
+
const resourceFeeStroops = parsed.resource;
|
|
2323
|
+
const totalFeeStroops = inclusionFeeStroops + (resourceFeeStroops ?? 0);
|
|
2324
|
+
return {
|
|
2325
|
+
contractName: contract.name,
|
|
2326
|
+
network: network.name,
|
|
2327
|
+
wasmPath: path13.relative(cwd, wasmPath) || wasmPath,
|
|
2328
|
+
inclusionFeeStroops,
|
|
2329
|
+
resourceFeeStroops,
|
|
2330
|
+
totalFeeStroops,
|
|
2331
|
+
advisory: "Advisory estimate only \u2014 actual fees may differ under network congestion or contract complexity.",
|
|
2332
|
+
rawOutput: simulateOutput || buildOutput
|
|
2333
|
+
};
|
|
2334
|
+
}
|
|
2335
|
+
|
|
2336
|
+
// src/contracts/inspect-contract.ts
|
|
2337
|
+
async function inspectContract(options) {
|
|
2338
|
+
const cwd = options.cwd ?? process.cwd();
|
|
2339
|
+
const contract = resolveContract(options.config, options.contractName, cwd);
|
|
2340
|
+
const network = resolveNetwork(options.config, options.networkName);
|
|
2341
|
+
const artifacts = await readArtifacts(cwd);
|
|
2342
|
+
const artifact = artifacts.networks[network.name]?.contracts[contract.name];
|
|
2343
|
+
if (!artifact) {
|
|
2344
|
+
throw new CaatingaError(
|
|
2345
|
+
`No deployed artifact found for "${contract.name}" on "${network.name}".`,
|
|
2346
|
+
CaatingaErrorCode.ARTIFACT_NOT_FOUND,
|
|
2347
|
+
"Run caatinga deploy before inspect."
|
|
2348
|
+
);
|
|
2349
|
+
}
|
|
2350
|
+
await checkBinary("stellar", "Install Stellar CLI before running caatinga inspect.");
|
|
2351
|
+
let reachable = false;
|
|
2352
|
+
let detail;
|
|
2353
|
+
try {
|
|
2354
|
+
await verifyDependencyContract({
|
|
2355
|
+
dependencyName: contract.name,
|
|
2356
|
+
contractId: artifact.contractId,
|
|
2357
|
+
network,
|
|
2358
|
+
cwd
|
|
2359
|
+
});
|
|
2360
|
+
reachable = true;
|
|
2361
|
+
detail = "Contract interface reachable on network.";
|
|
2362
|
+
} catch (error) {
|
|
2363
|
+
reachable = false;
|
|
2364
|
+
detail = error instanceof CaatingaError ? error.message : "Contract not reachable on network.";
|
|
2365
|
+
}
|
|
2366
|
+
let localHash;
|
|
2367
|
+
try {
|
|
2368
|
+
const wasmPath = await resolveWasmArtifactPath(contract.wasmPath, {
|
|
2369
|
+
sourcePath: contract.sourcePath
|
|
2370
|
+
});
|
|
2371
|
+
localHash = await hashWasm(wasmPath);
|
|
2372
|
+
} catch {
|
|
2373
|
+
localHash = void 0;
|
|
2374
|
+
}
|
|
2375
|
+
return {
|
|
2376
|
+
contractName: contract.name,
|
|
2377
|
+
network: network.name,
|
|
2378
|
+
artifact: {
|
|
2379
|
+
contractId: artifact.contractId,
|
|
2380
|
+
wasmHash: artifact.wasmHash,
|
|
2381
|
+
deployedAt: artifact.deployedAt,
|
|
2382
|
+
historyCount: artifact.history?.length ?? 0
|
|
2383
|
+
},
|
|
2384
|
+
onChain: { reachable, detail },
|
|
2385
|
+
localWasm: {
|
|
2386
|
+
path: contract.config.wasm,
|
|
2387
|
+
hash: localHash,
|
|
2388
|
+
matchesArtifact: Boolean(localHash && localHash === artifact.wasmHash)
|
|
2389
|
+
},
|
|
2390
|
+
dependencies: artifact.dependencies ?? contract.config.dependsOn ?? []
|
|
2391
|
+
};
|
|
2392
|
+
}
|
|
2393
|
+
|
|
1886
2394
|
// src/templates/create-project-from-template.ts
|
|
1887
|
-
import { cp, mkdir as mkdir3, readFile as
|
|
1888
|
-
import
|
|
2395
|
+
import { cp, mkdir as mkdir3, readFile as readFile6, readdir as readdir3, stat as stat2, writeFile as writeFile4 } from "fs/promises";
|
|
2396
|
+
import path14 from "path";
|
|
1889
2397
|
import { z as z7 } from "zod";
|
|
1890
2398
|
|
|
1891
2399
|
// src/templates/template-manifest.schema.ts
|
|
1892
2400
|
import { z as z6 } from "zod";
|
|
1893
|
-
import
|
|
2401
|
+
import semver5 from "semver";
|
|
1894
2402
|
var CURRENT_TEMPLATE_VERSION = 1;
|
|
1895
2403
|
var TemplateManifestSchema = z6.object({
|
|
1896
2404
|
name: z6.string().min(1),
|
|
@@ -1914,14 +2422,14 @@ var TemplateManifestSchema = z6.object({
|
|
|
1914
2422
|
})
|
|
1915
2423
|
});
|
|
1916
2424
|
function defaultCompatibleCoreRange(coreVersion = CAATINGA_CORE_VERSION) {
|
|
1917
|
-
const version =
|
|
2425
|
+
const version = semver5.valid(semver5.coerce(coreVersion));
|
|
1918
2426
|
if (!version) {
|
|
1919
2427
|
throw new Error(`Invalid core version: ${coreVersion}`);
|
|
1920
2428
|
}
|
|
1921
2429
|
return `^${version}`;
|
|
1922
2430
|
}
|
|
1923
2431
|
function isCoreVersionCompatible(range, coreVersion = CAATINGA_CORE_VERSION) {
|
|
1924
|
-
return
|
|
2432
|
+
return semver5.satisfies(coreVersion, range);
|
|
1925
2433
|
}
|
|
1926
2434
|
function getTemplateCompatibilityIssue(manifest, coreVersion = CAATINGA_CORE_VERSION) {
|
|
1927
2435
|
if (manifest.caatinga.templateVersion !== CURRENT_TEMPLATE_VERSION) {
|
|
@@ -1956,8 +2464,8 @@ function formatTemplateCompatibilityHint(issue) {
|
|
|
1956
2464
|
// src/templates/create-project-from-template.ts
|
|
1957
2465
|
var TEMPLATE_COPY_EXCLUDED_DIRS = /* @__PURE__ */ new Set(["target", "test_snapshots", "node_modules", ".git"]);
|
|
1958
2466
|
async function createProjectFromTemplate(options) {
|
|
1959
|
-
const targetDir =
|
|
1960
|
-
const templateDir =
|
|
2467
|
+
const targetDir = path14.resolve(options.targetDir);
|
|
2468
|
+
const templateDir = path14.resolve(options.templateDir);
|
|
1961
2469
|
try {
|
|
1962
2470
|
await stat2(templateDir);
|
|
1963
2471
|
} catch {
|
|
@@ -1998,9 +2506,9 @@ async function ensureArtifacts(targetDir, projectName) {
|
|
|
1998
2506
|
}
|
|
1999
2507
|
}
|
|
2000
2508
|
async function readTemplateManifest(templateDir) {
|
|
2001
|
-
const manifestPath =
|
|
2509
|
+
const manifestPath = path14.join(templateDir, "caatinga.template.json");
|
|
2002
2510
|
try {
|
|
2003
|
-
const rawManifest = await
|
|
2511
|
+
const rawManifest = await readFile6(manifestPath, "utf8");
|
|
2004
2512
|
const manifest = TemplateManifestSchema.parse(JSON.parse(rawManifest));
|
|
2005
2513
|
const compatibilityIssue = getTemplateCompatibilityIssue(manifest);
|
|
2006
2514
|
if (compatibilityIssue) {
|
|
@@ -2036,7 +2544,7 @@ async function replaceTemplateVariables(dir, projectName) {
|
|
|
2036
2544
|
const entries = await readdir3(dir);
|
|
2037
2545
|
await Promise.all(
|
|
2038
2546
|
entries.map(async (entry) => {
|
|
2039
|
-
const entryPath =
|
|
2547
|
+
const entryPath = path14.join(dir, entry);
|
|
2040
2548
|
const entryStat = await stat2(entryPath);
|
|
2041
2549
|
if (entryStat.isDirectory()) {
|
|
2042
2550
|
await replaceTemplateVariables(entryPath, projectName);
|
|
@@ -2045,38 +2553,38 @@ async function replaceTemplateVariables(dir, projectName) {
|
|
|
2045
2553
|
if (!isTextTemplateFile(entryPath)) {
|
|
2046
2554
|
return;
|
|
2047
2555
|
}
|
|
2048
|
-
const content = await
|
|
2556
|
+
const content = await readFile6(entryPath, "utf8");
|
|
2049
2557
|
await writeFile4(entryPath, content.replaceAll("__PROJECT_NAME__", projectName), "utf8");
|
|
2050
2558
|
})
|
|
2051
2559
|
);
|
|
2052
2560
|
}
|
|
2053
2561
|
function shouldCopyTemplateEntry(templateDir, source, userFilter) {
|
|
2054
|
-
const relativePath =
|
|
2562
|
+
const relativePath = path14.relative(templateDir, source);
|
|
2055
2563
|
if (!relativePath || relativePath === ".") {
|
|
2056
2564
|
return true;
|
|
2057
2565
|
}
|
|
2058
|
-
const normalizedPath = relativePath.split(
|
|
2566
|
+
const normalizedPath = relativePath.split(path14.sep).join("/");
|
|
2059
2567
|
if (userFilter && !userFilter(normalizedPath)) {
|
|
2060
2568
|
return false;
|
|
2061
2569
|
}
|
|
2062
|
-
return !relativePath.split(
|
|
2570
|
+
return !relativePath.split(path14.sep).some((segment) => TEMPLATE_COPY_EXCLUDED_DIRS.has(segment));
|
|
2063
2571
|
}
|
|
2064
2572
|
function isTextTemplateFile(filePath) {
|
|
2065
2573
|
return [".json", ".md", ".rs", ".toml", ".ts", ".tsx", ".css", ".html"].includes(
|
|
2066
|
-
|
|
2574
|
+
path14.extname(filePath)
|
|
2067
2575
|
);
|
|
2068
2576
|
}
|
|
2069
2577
|
|
|
2070
2578
|
// src/scaffold/create-zk-project.ts
|
|
2071
2579
|
import { cp as cp2, mkdir as mkdir4, writeFile as writeFile5 } from "fs/promises";
|
|
2072
2580
|
import { existsSync as existsSync2 } from "fs";
|
|
2073
|
-
import
|
|
2581
|
+
import path15 from "path";
|
|
2074
2582
|
import { fileURLToPath } from "url";
|
|
2075
|
-
var moduleDir = typeof __dirname === "string" ? __dirname :
|
|
2583
|
+
var moduleDir = typeof __dirname === "string" ? __dirname : path15.dirname(fileURLToPath(import.meta.url));
|
|
2076
2584
|
function scaffoldRoot() {
|
|
2077
2585
|
const candidates = [
|
|
2078
|
-
|
|
2079
|
-
|
|
2586
|
+
path15.resolve(moduleDir, "../../scaffolds"),
|
|
2587
|
+
path15.resolve(moduleDir, "../scaffolds")
|
|
2080
2588
|
];
|
|
2081
2589
|
const found = candidates.find((candidate) => existsSync2(candidate));
|
|
2082
2590
|
return found ?? candidates[0];
|
|
@@ -2167,39 +2675,39 @@ Replace \`circuits/main.circom\` with your circuit. Keep the entry point named \
|
|
|
2167
2675
|
`;
|
|
2168
2676
|
}
|
|
2169
2677
|
async function createZkProject(options) {
|
|
2170
|
-
const targetDir =
|
|
2678
|
+
const targetDir = path15.resolve(options.targetDir);
|
|
2171
2679
|
const force = options.force ?? false;
|
|
2172
2680
|
const projectFiles = options.projectFiles ?? true;
|
|
2173
2681
|
await mkdir4(targetDir, { recursive: true });
|
|
2174
2682
|
if (projectFiles) {
|
|
2175
2683
|
await Promise.all([
|
|
2176
|
-
writeFile5(
|
|
2684
|
+
writeFile5(path15.join(targetDir, "caatinga.config.ts"), configSource(options.projectName), {
|
|
2177
2685
|
encoding: "utf8",
|
|
2178
2686
|
flag: force ? "w" : "wx"
|
|
2179
2687
|
}),
|
|
2180
|
-
writeFile5(
|
|
2688
|
+
writeFile5(path15.join(targetDir, "package.json"), packageJsonSource(options.projectName), {
|
|
2181
2689
|
encoding: "utf8",
|
|
2182
2690
|
flag: force ? "w" : "wx"
|
|
2183
2691
|
}),
|
|
2184
|
-
writeFile5(
|
|
2692
|
+
writeFile5(path15.join(targetDir, ".gitignore"), "node_modules\n.artifacts\ntarget\n", {
|
|
2185
2693
|
encoding: "utf8",
|
|
2186
2694
|
flag: force ? "w" : "wx"
|
|
2187
2695
|
}),
|
|
2188
|
-
writeFile5(
|
|
2696
|
+
writeFile5(path15.join(targetDir, "README.md"), readmeSource(options.projectName), {
|
|
2189
2697
|
encoding: "utf8",
|
|
2190
2698
|
flag: force ? "w" : "wx"
|
|
2191
2699
|
})
|
|
2192
2700
|
]);
|
|
2193
2701
|
}
|
|
2194
|
-
await mkdir4(
|
|
2195
|
-
await cp2(
|
|
2702
|
+
await mkdir4(path15.join(targetDir, "contracts"), { recursive: true });
|
|
2703
|
+
await cp2(path15.join(scaffoldRoot(), "zk-circuit-stub"), path15.join(targetDir, "circuits"), {
|
|
2196
2704
|
recursive: true,
|
|
2197
2705
|
force,
|
|
2198
2706
|
errorOnExist: !force
|
|
2199
2707
|
});
|
|
2200
2708
|
await cp2(
|
|
2201
|
-
|
|
2202
|
-
|
|
2709
|
+
path15.join(scaffoldRoot(), "zk-verifier"),
|
|
2710
|
+
path15.join(targetDir, "contracts", "verifier"),
|
|
2203
2711
|
{
|
|
2204
2712
|
recursive: true,
|
|
2205
2713
|
force,
|
|
@@ -2218,13 +2726,13 @@ async function createZkProject(options) {
|
|
|
2218
2726
|
// src/scaffold/create-minimal-project.ts
|
|
2219
2727
|
import { cp as cp3, mkdir as mkdir5, writeFile as writeFile6 } from "fs/promises";
|
|
2220
2728
|
import { existsSync as existsSync3 } from "fs";
|
|
2221
|
-
import
|
|
2729
|
+
import path16 from "path";
|
|
2222
2730
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
2223
|
-
var moduleDir2 = typeof __dirname === "string" ? __dirname :
|
|
2731
|
+
var moduleDir2 = typeof __dirname === "string" ? __dirname : path16.dirname(fileURLToPath2(import.meta.url));
|
|
2224
2732
|
function scaffoldRoot2() {
|
|
2225
2733
|
const candidates = [
|
|
2226
|
-
|
|
2227
|
-
|
|
2734
|
+
path16.resolve(moduleDir2, "../../scaffolds"),
|
|
2735
|
+
path16.resolve(moduleDir2, "../scaffolds")
|
|
2228
2736
|
];
|
|
2229
2737
|
const found = candidates.find((candidate) => existsSync3(candidate));
|
|
2230
2738
|
return found ?? candidates[0];
|
|
@@ -2315,31 +2823,31 @@ Edit \`contracts/app/src/lib.rs\` to customize the contract. Add a frontend late
|
|
|
2315
2823
|
`;
|
|
2316
2824
|
}
|
|
2317
2825
|
async function createMinimalProject(options) {
|
|
2318
|
-
const targetDir =
|
|
2826
|
+
const targetDir = path16.resolve(options.targetDir);
|
|
2319
2827
|
const force = options.force ?? false;
|
|
2320
2828
|
await mkdir5(targetDir, { recursive: true });
|
|
2321
2829
|
await Promise.all([
|
|
2322
|
-
writeFile6(
|
|
2830
|
+
writeFile6(path16.join(targetDir, "caatinga.config.ts"), configSource2(options.projectName), {
|
|
2323
2831
|
encoding: "utf8",
|
|
2324
2832
|
flag: force ? "w" : "wx"
|
|
2325
2833
|
}),
|
|
2326
|
-
writeFile6(
|
|
2834
|
+
writeFile6(path16.join(targetDir, "package.json"), packageJsonSource2(options.projectName), {
|
|
2327
2835
|
encoding: "utf8",
|
|
2328
2836
|
flag: force ? "w" : "wx"
|
|
2329
2837
|
}),
|
|
2330
|
-
writeFile6(
|
|
2838
|
+
writeFile6(path16.join(targetDir, ".gitignore"), "node_modules\n.artifacts\ntarget\n", {
|
|
2331
2839
|
encoding: "utf8",
|
|
2332
2840
|
flag: force ? "w" : "wx"
|
|
2333
2841
|
}),
|
|
2334
|
-
writeFile6(
|
|
2842
|
+
writeFile6(path16.join(targetDir, "README.md"), readmeSource2(options.projectName), {
|
|
2335
2843
|
encoding: "utf8",
|
|
2336
2844
|
flag: force ? "w" : "wx"
|
|
2337
2845
|
})
|
|
2338
2846
|
]);
|
|
2339
|
-
await mkdir5(
|
|
2847
|
+
await mkdir5(path16.join(targetDir, "contracts"), { recursive: true });
|
|
2340
2848
|
await cp3(
|
|
2341
|
-
|
|
2342
|
-
|
|
2849
|
+
path16.join(scaffoldRoot2(), "soroban-contract-stub"),
|
|
2850
|
+
path16.join(targetDir, "contracts", "app"),
|
|
2343
2851
|
{
|
|
2344
2852
|
recursive: true,
|
|
2345
2853
|
force,
|
|
@@ -2354,29 +2862,14 @@ async function createMinimalProject(options) {
|
|
|
2354
2862
|
}
|
|
2355
2863
|
|
|
2356
2864
|
// src/ci/is-transient-testnet-smoke-failure.ts
|
|
2357
|
-
var NO_RETRY_CAATINGA_SUBSTRINGS = [
|
|
2358
|
-
"CAATINGA_UNSUPPORTED_CLI_VERSION",
|
|
2359
|
-
"CAATINGA_STELLAR_CLI_VERSION_PARSE_FAILED",
|
|
2360
|
-
"CAATINGA_STELLAR_CLI_NOT_FOUND",
|
|
2361
|
-
"CAATINGA_INVALID_CONFIG",
|
|
2362
|
-
"CAATINGA_CONFIG_NOT_FOUND"
|
|
2363
|
-
];
|
|
2364
|
-
var TRANSIENT_PATTERN = /timeout|i\/o timeout|econnreset|connection reset|503|502|429|rate limit|temporar|bad gateway|fetch failed|network error|unavailable/i;
|
|
2365
2865
|
function isTransientTestnetSmokeFailure(logText) {
|
|
2366
|
-
|
|
2367
|
-
return false;
|
|
2368
|
-
}
|
|
2369
|
-
for (const marker of NO_RETRY_CAATINGA_SUBSTRINGS) {
|
|
2370
|
-
if (logText.includes(marker)) {
|
|
2371
|
-
return false;
|
|
2372
|
-
}
|
|
2373
|
-
}
|
|
2374
|
-
return TRANSIENT_PATTERN.test(logText);
|
|
2866
|
+
return isTransientCommandFailure(logText);
|
|
2375
2867
|
}
|
|
2376
2868
|
export {
|
|
2377
2869
|
BINDING_MARKER_FILENAME,
|
|
2378
2870
|
BindingMarkerSchema,
|
|
2379
2871
|
CAATINGA_CORE_VERSION,
|
|
2872
|
+
CURRENT_ARTIFACTS_SCHEMA_VERSION,
|
|
2380
2873
|
CaatingaArtifactsSchema,
|
|
2381
2874
|
CaatingaConfigSchema,
|
|
2382
2875
|
CaatingaError,
|
|
@@ -2384,6 +2877,8 @@ export {
|
|
|
2384
2877
|
READ_CALL_FAILURE_REGEX,
|
|
2385
2878
|
STELLAR_CLI_LAST_TESTED_VERSION,
|
|
2386
2879
|
STELLAR_CLI_MIN_VERSION,
|
|
2880
|
+
STELLAR_SDK_LAST_TESTED_VERSION,
|
|
2881
|
+
STELLAR_SDK_MIN_VERSION,
|
|
2387
2882
|
TemplateManifestSchema,
|
|
2388
2883
|
WELL_KNOWN_NETWORKS,
|
|
2389
2884
|
buildContract,
|
|
@@ -2391,6 +2886,7 @@ export {
|
|
|
2391
2886
|
buildReadCallHint,
|
|
2392
2887
|
checkBinary,
|
|
2393
2888
|
checkStellarCliVersion,
|
|
2889
|
+
checkStellarSdkVersion,
|
|
2394
2890
|
collectProjectStatus,
|
|
2395
2891
|
createInitialArtifacts,
|
|
2396
2892
|
createMinimalProject,
|
|
@@ -2399,20 +2895,26 @@ export {
|
|
|
2399
2895
|
defineConfig,
|
|
2400
2896
|
deployContract,
|
|
2401
2897
|
deployContractGraph,
|
|
2898
|
+
estimateDeployCost,
|
|
2402
2899
|
evaluateBindingFreshness,
|
|
2403
2900
|
evaluateBindingsFreshness,
|
|
2404
2901
|
evaluateStellarCliCompatibility,
|
|
2902
|
+
evaluateStellarSdkCompatibility,
|
|
2405
2903
|
formatCaatingaError,
|
|
2406
2904
|
generateBindings,
|
|
2407
2905
|
generateBindingsGraph,
|
|
2906
|
+
inspectContract,
|
|
2408
2907
|
invokeContract,
|
|
2409
2908
|
isCargoBinMissingFromPath,
|
|
2410
2909
|
isReadCallFailure,
|
|
2411
2910
|
isTransientTestnetSmokeFailure,
|
|
2412
2911
|
loadConfig,
|
|
2912
|
+
migrateArtifactsFile,
|
|
2913
|
+
migrateArtifactsToV2,
|
|
2413
2914
|
parseContractId,
|
|
2414
2915
|
parseInvokeTarget,
|
|
2415
2916
|
parseStellarCliVersion,
|
|
2917
|
+
parseStellarSdkVersion,
|
|
2416
2918
|
readArtifacts,
|
|
2417
2919
|
readBindingMarker,
|
|
2418
2920
|
readContract,
|
|
@@ -2422,6 +2924,8 @@ export {
|
|
|
2422
2924
|
resolveDeployOrder,
|
|
2423
2925
|
resolveNetwork,
|
|
2424
2926
|
resolveSubprocessEnv,
|
|
2927
|
+
restoreArtifactFromHistory,
|
|
2928
|
+
rollbackContractArtifact,
|
|
2425
2929
|
runCommand,
|
|
2426
2930
|
toCaatingaError,
|
|
2427
2931
|
updateArtifact,
|