@caatinga/core 3.2.0 → 3.3.1
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 +708 -171
- package/dist/index.d.cts +210 -9
- package/dist/index.d.ts +210 -9
- package/dist/index.js +670 -147
- 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.cjs
CHANGED
|
@@ -33,13 +33,17 @@ __export(index_exports, {
|
|
|
33
33
|
BINDING_MARKER_FILENAME: () => BINDING_MARKER_FILENAME,
|
|
34
34
|
BindingMarkerSchema: () => BindingMarkerSchema,
|
|
35
35
|
CAATINGA_CORE_VERSION: () => CAATINGA_CORE_VERSION,
|
|
36
|
+
CURRENT_ARTIFACTS_SCHEMA_VERSION: () => CURRENT_ARTIFACTS_SCHEMA_VERSION,
|
|
36
37
|
CaatingaArtifactsSchema: () => CaatingaArtifactsSchema,
|
|
37
38
|
CaatingaConfigSchema: () => CaatingaConfigSchema,
|
|
38
39
|
CaatingaError: () => CaatingaError,
|
|
39
40
|
CaatingaErrorCode: () => CaatingaErrorCode,
|
|
41
|
+
DEFAULT_CLI_SOURCE: () => DEFAULT_CLI_SOURCE,
|
|
40
42
|
READ_CALL_FAILURE_REGEX: () => READ_CALL_FAILURE_REGEX,
|
|
41
43
|
STELLAR_CLI_LAST_TESTED_VERSION: () => STELLAR_CLI_LAST_TESTED_VERSION,
|
|
42
44
|
STELLAR_CLI_MIN_VERSION: () => STELLAR_CLI_MIN_VERSION,
|
|
45
|
+
STELLAR_SDK_LAST_TESTED_VERSION: () => STELLAR_SDK_LAST_TESTED_VERSION,
|
|
46
|
+
STELLAR_SDK_MIN_VERSION: () => STELLAR_SDK_MIN_VERSION,
|
|
43
47
|
TemplateManifestSchema: () => TemplateManifestSchema,
|
|
44
48
|
WELL_KNOWN_NETWORKS: () => WELL_KNOWN_NETWORKS,
|
|
45
49
|
buildContract: () => buildContract,
|
|
@@ -47,6 +51,7 @@ __export(index_exports, {
|
|
|
47
51
|
buildReadCallHint: () => buildReadCallHint,
|
|
48
52
|
checkBinary: () => checkBinary,
|
|
49
53
|
checkStellarCliVersion: () => checkStellarCliVersion,
|
|
54
|
+
checkStellarSdkVersion: () => checkStellarSdkVersion,
|
|
50
55
|
collectProjectStatus: () => collectProjectStatus,
|
|
51
56
|
createInitialArtifacts: () => createInitialArtifacts,
|
|
52
57
|
createMinimalProject: () => createMinimalProject,
|
|
@@ -55,20 +60,27 @@ __export(index_exports, {
|
|
|
55
60
|
defineConfig: () => defineConfig,
|
|
56
61
|
deployContract: () => deployContract,
|
|
57
62
|
deployContractGraph: () => deployContractGraph,
|
|
63
|
+
describeCliSource: () => describeCliSource,
|
|
64
|
+
estimateDeployCost: () => estimateDeployCost,
|
|
58
65
|
evaluateBindingFreshness: () => evaluateBindingFreshness,
|
|
59
66
|
evaluateBindingsFreshness: () => evaluateBindingsFreshness,
|
|
60
67
|
evaluateStellarCliCompatibility: () => evaluateStellarCliCompatibility,
|
|
68
|
+
evaluateStellarSdkCompatibility: () => evaluateStellarSdkCompatibility,
|
|
61
69
|
formatCaatingaError: () => formatCaatingaError,
|
|
62
70
|
generateBindings: () => generateBindings,
|
|
63
71
|
generateBindingsGraph: () => generateBindingsGraph,
|
|
72
|
+
inspectContract: () => inspectContract,
|
|
64
73
|
invokeContract: () => invokeContract,
|
|
65
74
|
isCargoBinMissingFromPath: () => isCargoBinMissingFromPath,
|
|
66
75
|
isReadCallFailure: () => isReadCallFailure,
|
|
67
76
|
isTransientTestnetSmokeFailure: () => isTransientTestnetSmokeFailure,
|
|
68
77
|
loadConfig: () => loadConfig,
|
|
78
|
+
migrateArtifactsFile: () => migrateArtifactsFile,
|
|
79
|
+
migrateArtifactsToV2: () => migrateArtifactsToV2,
|
|
69
80
|
parseContractId: () => parseContractId,
|
|
70
81
|
parseInvokeTarget: () => parseInvokeTarget,
|
|
71
82
|
parseStellarCliVersion: () => parseStellarCliVersion,
|
|
83
|
+
parseStellarSdkVersion: () => parseStellarSdkVersion,
|
|
72
84
|
readArtifacts: () => readArtifacts,
|
|
73
85
|
readBindingMarker: () => readBindingMarker,
|
|
74
86
|
readContract: () => readContract,
|
|
@@ -78,6 +90,8 @@ __export(index_exports, {
|
|
|
78
90
|
resolveDeployOrder: () => resolveDeployOrder,
|
|
79
91
|
resolveNetwork: () => resolveNetwork,
|
|
80
92
|
resolveSubprocessEnv: () => resolveSubprocessEnv,
|
|
93
|
+
restoreArtifactFromHistory: () => restoreArtifactFromHistory,
|
|
94
|
+
rollbackContractArtifact: () => rollbackContractArtifact,
|
|
81
95
|
runCommand: () => runCommand,
|
|
82
96
|
toCaatingaError: () => toCaatingaError,
|
|
83
97
|
updateArtifact: () => updateArtifact,
|
|
@@ -97,6 +111,8 @@ var CaatingaErrorCode = {
|
|
|
97
111
|
STELLAR_CLI_NOT_FOUND: "CAATINGA_STELLAR_CLI_NOT_FOUND",
|
|
98
112
|
STELLAR_CLI_VERSION_PARSE_FAILED: "CAATINGA_STELLAR_CLI_VERSION_PARSE_FAILED",
|
|
99
113
|
UNSUPPORTED_CLI_VERSION: "CAATINGA_UNSUPPORTED_CLI_VERSION",
|
|
114
|
+
STELLAR_SDK_VERSION_PARSE_FAILED: "CAATINGA_STELLAR_SDK_VERSION_PARSE_FAILED",
|
|
115
|
+
UNSUPPORTED_SDK_VERSION: "CAATINGA_UNSUPPORTED_SDK_VERSION",
|
|
100
116
|
RUST_NOT_FOUND: "CAATINGA_RUST_NOT_FOUND",
|
|
101
117
|
RUST_TARGET_NOT_FOUND: "CAATINGA_RUST_TARGET_NOT_FOUND",
|
|
102
118
|
DEPLOY_FAILED: "CAATINGA_DEPLOY_FAILED",
|
|
@@ -139,6 +155,8 @@ var CaatingaErrorCode = {
|
|
|
139
155
|
ZK_VERIFICATION_FAILED: "CAATINGA_ZK_VERIFICATION_FAILED",
|
|
140
156
|
ZK_DEV_CEREMONY_BLOCKED: "CAATINGA_ZK_DEV_CEREMONY_BLOCKED",
|
|
141
157
|
DOCTOR_PARTIAL_DEPLOY: "CAATINGA_DOCTOR_PARTIAL_DEPLOY",
|
|
158
|
+
ROLLBACK_TARGET_NOT_FOUND: "CAATINGA_ROLLBACK_TARGET_NOT_FOUND",
|
|
159
|
+
ESTIMATE_FAILED: "CAATINGA_ESTIMATE_FAILED",
|
|
142
160
|
MULTI_AUTH_REQUIRED: "CAATINGA_MULTI_AUTH_REQUIRED"
|
|
143
161
|
};
|
|
144
162
|
|
|
@@ -327,6 +345,14 @@ async function loadConfig(options = {}) {
|
|
|
327
345
|
|
|
328
346
|
// src/artifacts/artifact.schema.ts
|
|
329
347
|
var import_zod3 = require("zod");
|
|
348
|
+
var ArtifactSupersedeReasonSchema = import_zod3.z.enum(["upgrade", "rollback", "force-redeploy"]);
|
|
349
|
+
var ContractArtifactHistoryEntrySchema = import_zod3.z.object({
|
|
350
|
+
contractId: import_zod3.z.string().min(1),
|
|
351
|
+
wasmHash: import_zod3.z.string().min(1),
|
|
352
|
+
deployedAt: import_zod3.z.string().datetime(),
|
|
353
|
+
supersededAt: import_zod3.z.string().datetime(),
|
|
354
|
+
reason: ArtifactSupersedeReasonSchema.optional()
|
|
355
|
+
});
|
|
330
356
|
var ContractArtifactSchema = import_zod3.z.object({
|
|
331
357
|
contractId: import_zod3.z.string().min(1),
|
|
332
358
|
wasmHash: import_zod3.z.string().min(1),
|
|
@@ -334,17 +360,28 @@ var ContractArtifactSchema = import_zod3.z.object({
|
|
|
334
360
|
sourcePath: import_zod3.z.string().min(1),
|
|
335
361
|
wasmPath: import_zod3.z.string().min(1),
|
|
336
362
|
dependencies: import_zod3.z.array(import_zod3.z.string().min(1)).default([]),
|
|
337
|
-
resolvedDeployArgs: import_zod3.z.record(import_zod3.z.string().min(1), import_zod3.z.union([import_zod3.z.string(), import_zod3.z.number(), import_zod3.z.boolean()])).default({})
|
|
363
|
+
resolvedDeployArgs: import_zod3.z.record(import_zod3.z.string().min(1), import_zod3.z.union([import_zod3.z.string(), import_zod3.z.number(), import_zod3.z.boolean()])).default({}),
|
|
364
|
+
history: import_zod3.z.array(ContractArtifactHistoryEntrySchema).optional()
|
|
338
365
|
});
|
|
339
366
|
var NetworkArtifactsSchema = import_zod3.z.object({
|
|
340
367
|
contracts: import_zod3.z.record(import_zod3.z.string().min(1), ContractArtifactSchema).default({}),
|
|
341
368
|
dependencyGraph: import_zod3.z.record(import_zod3.z.string().min(1), import_zod3.z.array(import_zod3.z.string().min(1))).default({})
|
|
342
369
|
});
|
|
343
|
-
var
|
|
370
|
+
var CaatingaArtifactsBaseSchema = import_zod3.z.object({
|
|
344
371
|
project: import_zod3.z.string().min(1),
|
|
345
|
-
version: import_zod3.z.literal(1),
|
|
346
372
|
networks: import_zod3.z.record(import_zod3.z.string().min(1), NetworkArtifactsSchema).default({})
|
|
347
373
|
});
|
|
374
|
+
var CaatingaArtifactsV1Schema = CaatingaArtifactsBaseSchema.extend({
|
|
375
|
+
version: import_zod3.z.literal(1)
|
|
376
|
+
});
|
|
377
|
+
var CaatingaArtifactsV2Schema = CaatingaArtifactsBaseSchema.extend({
|
|
378
|
+
version: import_zod3.z.literal(2)
|
|
379
|
+
});
|
|
380
|
+
var CaatingaArtifactsSchema = import_zod3.z.union([
|
|
381
|
+
CaatingaArtifactsV1Schema,
|
|
382
|
+
CaatingaArtifactsV2Schema
|
|
383
|
+
]);
|
|
384
|
+
var CURRENT_ARTIFACTS_SCHEMA_VERSION = 2;
|
|
348
385
|
|
|
349
386
|
// src/artifacts/read-artifacts.ts
|
|
350
387
|
var import_promises2 = require("fs/promises");
|
|
@@ -396,29 +433,139 @@ function createInitialArtifacts(project, options = {}) {
|
|
|
396
433
|
);
|
|
397
434
|
return {
|
|
398
435
|
project,
|
|
399
|
-
version:
|
|
436
|
+
version: 2,
|
|
400
437
|
networks
|
|
401
438
|
};
|
|
402
439
|
}
|
|
403
440
|
|
|
404
441
|
// src/artifacts/update-artifact.ts
|
|
405
|
-
function
|
|
442
|
+
function appendHistory(existing, reason) {
|
|
443
|
+
if (!existing || !reason) {
|
|
444
|
+
return existing?.history;
|
|
445
|
+
}
|
|
446
|
+
const supersededAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
447
|
+
const entry = {
|
|
448
|
+
contractId: existing.contractId,
|
|
449
|
+
wasmHash: existing.wasmHash,
|
|
450
|
+
deployedAt: existing.deployedAt,
|
|
451
|
+
supersededAt,
|
|
452
|
+
reason
|
|
453
|
+
};
|
|
454
|
+
return [...existing.history ?? [], entry];
|
|
455
|
+
}
|
|
456
|
+
function updateArtifact(artifacts, networkName, contractName, contractArtifact, options = {}) {
|
|
406
457
|
const existingNetwork = artifacts.networks[networkName] ?? { contracts: {}, dependencyGraph: {} };
|
|
458
|
+
const existingContract = existingNetwork.contracts[contractName];
|
|
459
|
+
const history = appendHistory(existingContract, options.supersedeReason);
|
|
460
|
+
const nextVersion = artifacts.version === 1 && options.supersedeReason ? 2 : artifacts.version;
|
|
407
461
|
return {
|
|
408
462
|
...artifacts,
|
|
463
|
+
version: nextVersion,
|
|
409
464
|
networks: {
|
|
410
465
|
...artifacts.networks,
|
|
411
466
|
[networkName]: {
|
|
412
467
|
...existingNetwork,
|
|
413
|
-
dependencyGraph:
|
|
468
|
+
dependencyGraph: options.dependencyGraph ?? existingNetwork.dependencyGraph ?? {},
|
|
414
469
|
contracts: {
|
|
415
470
|
...existingNetwork.contracts,
|
|
416
|
-
[contractName]:
|
|
471
|
+
[contractName]: {
|
|
472
|
+
...contractArtifact,
|
|
473
|
+
history: history ?? contractArtifact.history
|
|
474
|
+
}
|
|
417
475
|
}
|
|
418
476
|
}
|
|
419
477
|
}
|
|
420
478
|
};
|
|
421
479
|
}
|
|
480
|
+
function restoreArtifactFromHistory(input) {
|
|
481
|
+
const network = input.artifacts.networks[input.networkName];
|
|
482
|
+
const current = network?.contracts[input.contractName];
|
|
483
|
+
if (!current) {
|
|
484
|
+
throw new CaatingaError(
|
|
485
|
+
`No artifact for "${input.contractName}" on "${input.networkName}".`,
|
|
486
|
+
CaatingaErrorCode.ARTIFACT_NOT_FOUND,
|
|
487
|
+
"Deploy the contract before attempting rollback."
|
|
488
|
+
);
|
|
489
|
+
}
|
|
490
|
+
if (current.contractId === input.contractId) {
|
|
491
|
+
return input.artifacts;
|
|
492
|
+
}
|
|
493
|
+
const fromHistory = (current.history ?? []).find(
|
|
494
|
+
(entry) => entry.contractId === input.contractId
|
|
495
|
+
);
|
|
496
|
+
if (!fromHistory) {
|
|
497
|
+
throw new CaatingaError(
|
|
498
|
+
`Rollback target "${input.contractId}" was not found in artifact history for "${input.contractName}".`,
|
|
499
|
+
CaatingaErrorCode.ROLLBACK_TARGET_NOT_FOUND,
|
|
500
|
+
"Use caatinga inspect to list prior contract IDs, or redeploy manually."
|
|
501
|
+
);
|
|
502
|
+
}
|
|
503
|
+
const supersededAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
504
|
+
const restoredArtifact = {
|
|
505
|
+
contractId: fromHistory.contractId,
|
|
506
|
+
wasmHash: fromHistory.wasmHash,
|
|
507
|
+
deployedAt: fromHistory.deployedAt,
|
|
508
|
+
sourcePath: current.sourcePath,
|
|
509
|
+
wasmPath: current.wasmPath,
|
|
510
|
+
dependencies: current.dependencies,
|
|
511
|
+
resolvedDeployArgs: current.resolvedDeployArgs,
|
|
512
|
+
history: [
|
|
513
|
+
...current.history ?? [],
|
|
514
|
+
{
|
|
515
|
+
contractId: current.contractId,
|
|
516
|
+
wasmHash: current.wasmHash,
|
|
517
|
+
deployedAt: current.deployedAt,
|
|
518
|
+
supersededAt,
|
|
519
|
+
reason: "rollback"
|
|
520
|
+
}
|
|
521
|
+
]
|
|
522
|
+
};
|
|
523
|
+
return {
|
|
524
|
+
...updateArtifact(input.artifacts, input.networkName, input.contractName, restoredArtifact),
|
|
525
|
+
version: 2
|
|
526
|
+
};
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
// src/artifacts/migrate-artifacts.ts
|
|
530
|
+
function migrateArtifactsToV2(artifacts) {
|
|
531
|
+
if (artifacts.version === CURRENT_ARTIFACTS_SCHEMA_VERSION) {
|
|
532
|
+
return {
|
|
533
|
+
artifacts,
|
|
534
|
+
migrated: false
|
|
535
|
+
};
|
|
536
|
+
}
|
|
537
|
+
const v1 = artifacts;
|
|
538
|
+
return {
|
|
539
|
+
artifacts: {
|
|
540
|
+
project: v1.project,
|
|
541
|
+
version: CURRENT_ARTIFACTS_SCHEMA_VERSION,
|
|
542
|
+
networks: v1.networks
|
|
543
|
+
},
|
|
544
|
+
migrated: true
|
|
545
|
+
};
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
// src/artifacts/migrate-artifacts-file.ts
|
|
549
|
+
async function migrateArtifactsFile(cwd = process.cwd()) {
|
|
550
|
+
const artifacts = await readArtifacts(cwd);
|
|
551
|
+
const { artifacts: migrated, migrated: changed } = migrateArtifactsToV2(artifacts);
|
|
552
|
+
const path17 = await writeArtifacts(migrated, cwd);
|
|
553
|
+
return { path: path17, migrated: changed, artifacts: migrated };
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
// src/artifacts/rollback-artifact.ts
|
|
557
|
+
async function rollbackContractArtifact(input) {
|
|
558
|
+
const cwd = input.cwd ?? process.cwd();
|
|
559
|
+
const artifacts = await readArtifacts(cwd);
|
|
560
|
+
const next = restoreArtifactFromHistory({
|
|
561
|
+
artifacts,
|
|
562
|
+
networkName: input.networkName,
|
|
563
|
+
contractName: input.contractName,
|
|
564
|
+
contractId: input.contractId
|
|
565
|
+
});
|
|
566
|
+
const path17 = await writeArtifacts(next, cwd);
|
|
567
|
+
return { path: path17, artifacts: next };
|
|
568
|
+
}
|
|
422
569
|
|
|
423
570
|
// src/networks/resolve-network.ts
|
|
424
571
|
function resolveNetwork(config, networkName) {
|
|
@@ -685,6 +832,35 @@ function evaluateStellarCliCompatibility(input) {
|
|
|
685
832
|
};
|
|
686
833
|
}
|
|
687
834
|
|
|
835
|
+
// src/stellar-cli/probe-stellar-cli-features.ts
|
|
836
|
+
var import_semver3 = __toESM(require("semver"), 1);
|
|
837
|
+
var STELLAR_CLI_REQUIRED_FEATURES = [
|
|
838
|
+
"contract-build",
|
|
839
|
+
"contract-deploy",
|
|
840
|
+
"contract-invoke-sign"
|
|
841
|
+
];
|
|
842
|
+
var FEATURE_COMMANDS = {
|
|
843
|
+
"contract-build": ["contract", "build", "--help"],
|
|
844
|
+
"contract-deploy": ["contract", "deploy", "--help"],
|
|
845
|
+
"contract-invoke-sign": ["contract", "invoke", "--help"]
|
|
846
|
+
};
|
|
847
|
+
async function probeMissingStellarCliFeatures(version) {
|
|
848
|
+
const missing = [];
|
|
849
|
+
if (import_semver3.default.valid(version) && import_semver3.default.lt(version, STELLAR_CLI_MIN_VERSION)) {
|
|
850
|
+
return ["contract-invoke-sign"];
|
|
851
|
+
}
|
|
852
|
+
for (const feature of STELLAR_CLI_REQUIRED_FEATURES) {
|
|
853
|
+
try {
|
|
854
|
+
await runCommand("stellar", FEATURE_COMMANDS[feature], {
|
|
855
|
+
skipStellarVersionCheck: true
|
|
856
|
+
});
|
|
857
|
+
} catch {
|
|
858
|
+
missing.push(feature);
|
|
859
|
+
}
|
|
860
|
+
}
|
|
861
|
+
return missing;
|
|
862
|
+
}
|
|
863
|
+
|
|
688
864
|
// src/stellar-cli/check-stellar-cli-version.ts
|
|
689
865
|
async function checkStellarCliVersion(input = {}) {
|
|
690
866
|
let rawOutput;
|
|
@@ -704,9 +880,12 @@ async function checkStellarCliVersion(input = {}) {
|
|
|
704
880
|
}
|
|
705
881
|
throw error;
|
|
706
882
|
}
|
|
883
|
+
const version = parseStellarCliVersion(rawOutput);
|
|
884
|
+
const probedMissing = input.probeFeatures === false ? [] : await probeMissingStellarCliFeatures(version);
|
|
885
|
+
const missingFeatures = [...input.features ?? [], ...probedMissing];
|
|
707
886
|
const report = evaluateStellarCliCompatibility({
|
|
708
|
-
version
|
|
709
|
-
features:
|
|
887
|
+
version,
|
|
888
|
+
features: missingFeatures.length > 0 ? missingFeatures : void 0,
|
|
710
889
|
lastTestedVersion: input.lastTestedVersion
|
|
711
890
|
});
|
|
712
891
|
for (const warning of report.warnings) {
|
|
@@ -852,6 +1031,122 @@ function parseContractId(output) {
|
|
|
852
1031
|
return match[0];
|
|
853
1032
|
}
|
|
854
1033
|
|
|
1034
|
+
// src/stellar-sdk/check-stellar-sdk-version.ts
|
|
1035
|
+
var import_promises6 = require("fs/promises");
|
|
1036
|
+
var import_node_path7 = __toESM(require("path"), 1);
|
|
1037
|
+
|
|
1038
|
+
// src/stellar-sdk/compat.ts
|
|
1039
|
+
var import_semver4 = __toESM(require("semver"), 1);
|
|
1040
|
+
|
|
1041
|
+
// src/stellar-sdk/version.ts
|
|
1042
|
+
var STELLAR_SDK_MIN_VERSION = "16.0.1";
|
|
1043
|
+
var STELLAR_SDK_LAST_TESTED_VERSION = "16.0.1";
|
|
1044
|
+
|
|
1045
|
+
// src/stellar-sdk/compat.ts
|
|
1046
|
+
function evaluateStellarSdkCompatibility(input) {
|
|
1047
|
+
const parsed = import_semver4.default.parse(input.version);
|
|
1048
|
+
if (!parsed || !import_semver4.default.valid(input.version)) {
|
|
1049
|
+
throw new CaatingaError(
|
|
1050
|
+
"Could not parse @stellar/stellar-sdk version.",
|
|
1051
|
+
CaatingaErrorCode.STELLAR_SDK_VERSION_PARSE_FAILED,
|
|
1052
|
+
"Use a semantic version such as 16.0.1."
|
|
1053
|
+
);
|
|
1054
|
+
}
|
|
1055
|
+
const lastTestedVersion = import_semver4.default.valid(input.lastTestedVersion ?? STELLAR_SDK_LAST_TESTED_VERSION) ?? STELLAR_SDK_LAST_TESTED_VERSION;
|
|
1056
|
+
const warnings = [];
|
|
1057
|
+
let status = "supported";
|
|
1058
|
+
if (import_semver4.default.lt(parsed, STELLAR_SDK_MIN_VERSION)) {
|
|
1059
|
+
throw new CaatingaError(
|
|
1060
|
+
`@stellar/stellar-sdk ${input.version} is below the supported minimum ${STELLAR_SDK_MIN_VERSION}.`,
|
|
1061
|
+
CaatingaErrorCode.UNSUPPORTED_SDK_VERSION,
|
|
1062
|
+
`Install @stellar/stellar-sdk ${STELLAR_SDK_MIN_VERSION} or newer.`
|
|
1063
|
+
);
|
|
1064
|
+
}
|
|
1065
|
+
if (import_semver4.default.gt(parsed, lastTestedVersion)) {
|
|
1066
|
+
status = "untested";
|
|
1067
|
+
warnings.push({
|
|
1068
|
+
code: "STELLAR_SDK_UNTESTED_VERSION",
|
|
1069
|
+
message: `@stellar/stellar-sdk ${input.version} is newer than the last-tested ${lastTestedVersion}; binding output may differ.`,
|
|
1070
|
+
remediation: "Pin @stellar/stellar-sdk to the last-tested version in package.json, or update Caatinga fixtures after validating generate output."
|
|
1071
|
+
});
|
|
1072
|
+
}
|
|
1073
|
+
return {
|
|
1074
|
+
version: input.version,
|
|
1075
|
+
status,
|
|
1076
|
+
minVersion: STELLAR_SDK_MIN_VERSION,
|
|
1077
|
+
lastTestedVersion,
|
|
1078
|
+
warnings
|
|
1079
|
+
};
|
|
1080
|
+
}
|
|
1081
|
+
function parseStellarSdkVersion(raw) {
|
|
1082
|
+
const trimmed = raw.trim();
|
|
1083
|
+
const match = trimmed.match(/(\d+\.\d+\.\d+(?:[-+][\w.-]+)?)/);
|
|
1084
|
+
if (!match) {
|
|
1085
|
+
throw new CaatingaError(
|
|
1086
|
+
"Could not parse @stellar/stellar-sdk version.",
|
|
1087
|
+
CaatingaErrorCode.STELLAR_SDK_VERSION_PARSE_FAILED,
|
|
1088
|
+
"Expected output like 16.0.1."
|
|
1089
|
+
);
|
|
1090
|
+
}
|
|
1091
|
+
return match[1];
|
|
1092
|
+
}
|
|
1093
|
+
|
|
1094
|
+
// src/stellar-sdk/check-stellar-sdk-version.ts
|
|
1095
|
+
async function readInstalledSdkVersion(cwd) {
|
|
1096
|
+
try {
|
|
1097
|
+
const pkgPath = import_node_path7.default.join(cwd, "node_modules", "@stellar", "stellar-sdk", "package.json");
|
|
1098
|
+
const raw = await (0, import_promises6.readFile)(pkgPath, "utf8");
|
|
1099
|
+
const pkg = JSON.parse(raw);
|
|
1100
|
+
return typeof pkg.version === "string" ? pkg.version : void 0;
|
|
1101
|
+
} catch {
|
|
1102
|
+
return void 0;
|
|
1103
|
+
}
|
|
1104
|
+
}
|
|
1105
|
+
async function resolveRegistrySdkVersion() {
|
|
1106
|
+
const result = await runCommand("npm", ["view", "@stellar/stellar-sdk", "version"], {
|
|
1107
|
+
skipStellarVersionCheck: true
|
|
1108
|
+
});
|
|
1109
|
+
return parseStellarSdkVersion(result.stdout || result.all);
|
|
1110
|
+
}
|
|
1111
|
+
async function checkStellarSdkVersion(input = {}) {
|
|
1112
|
+
const cwd = input.cwd ?? process.cwd();
|
|
1113
|
+
let version;
|
|
1114
|
+
try {
|
|
1115
|
+
const installed = await readInstalledSdkVersion(cwd);
|
|
1116
|
+
version = installed ?? await resolveRegistrySdkVersion();
|
|
1117
|
+
} catch (error) {
|
|
1118
|
+
if (error instanceof CaatingaError) {
|
|
1119
|
+
throw error;
|
|
1120
|
+
}
|
|
1121
|
+
throw new CaatingaError(
|
|
1122
|
+
"Could not resolve @stellar/stellar-sdk version.",
|
|
1123
|
+
CaatingaErrorCode.STELLAR_SDK_VERSION_PARSE_FAILED,
|
|
1124
|
+
"Install @stellar/stellar-sdk in your project or ensure npm registry access.",
|
|
1125
|
+
error
|
|
1126
|
+
);
|
|
1127
|
+
}
|
|
1128
|
+
const report = evaluateStellarSdkCompatibility({
|
|
1129
|
+
version,
|
|
1130
|
+
lastTestedVersion: input.lastTestedVersion
|
|
1131
|
+
});
|
|
1132
|
+
for (const warning of report.warnings) {
|
|
1133
|
+
if (input.onWarning) {
|
|
1134
|
+
input.onWarning(warning);
|
|
1135
|
+
} else {
|
|
1136
|
+
defaultEmitWarning2(warning);
|
|
1137
|
+
}
|
|
1138
|
+
}
|
|
1139
|
+
return report;
|
|
1140
|
+
}
|
|
1141
|
+
function defaultEmitWarning2(warning) {
|
|
1142
|
+
const lines = [
|
|
1143
|
+
`Warning: ${warning.message}`,
|
|
1144
|
+
warning.remediation ? ` ${warning.remediation}` : void 0
|
|
1145
|
+
].filter((line) => Boolean(line));
|
|
1146
|
+
process.stderr.write(`${lines.join("\n")}
|
|
1147
|
+
`);
|
|
1148
|
+
}
|
|
1149
|
+
|
|
855
1150
|
// src/stellar-cli/build-stellar-network-args.ts
|
|
856
1151
|
function matchesWellKnownNetwork(name, config) {
|
|
857
1152
|
const known = WELL_KNOWN_NETWORKS[name];
|
|
@@ -989,8 +1284,38 @@ function validateSourceShape(source) {
|
|
|
989
1284
|
return void 0;
|
|
990
1285
|
}
|
|
991
1286
|
|
|
1287
|
+
// src/contracts/source-account.ts
|
|
1288
|
+
function assertSafeSourceAccount(source) {
|
|
1289
|
+
if (!source) {
|
|
1290
|
+
throw new CaatingaError(
|
|
1291
|
+
"A source account or Stellar CLI identity is required.",
|
|
1292
|
+
CaatingaErrorCode.SOURCE_ACCOUNT_REQUIRED,
|
|
1293
|
+
"Pass a Stellar CLI identity alias, for example: --source alice"
|
|
1294
|
+
);
|
|
1295
|
+
}
|
|
1296
|
+
const unsafeSource = validateSourceShape(source);
|
|
1297
|
+
if (unsafeSource) {
|
|
1298
|
+
throw unsafeSource;
|
|
1299
|
+
}
|
|
1300
|
+
return source;
|
|
1301
|
+
}
|
|
1302
|
+
var DEFAULT_CLI_SOURCE = "alice";
|
|
1303
|
+
function describeCliSource(explicit) {
|
|
1304
|
+
if (explicit) {
|
|
1305
|
+
return { source: assertSafeSourceAccount(explicit), origin: "explicit" };
|
|
1306
|
+
}
|
|
1307
|
+
const fromEnv = process.env.CAATINGA_SOURCE;
|
|
1308
|
+
if (fromEnv) {
|
|
1309
|
+
return { source: assertSafeSourceAccount(fromEnv), origin: "env" };
|
|
1310
|
+
}
|
|
1311
|
+
return { source: assertSafeSourceAccount(DEFAULT_CLI_SOURCE), origin: "default" };
|
|
1312
|
+
}
|
|
1313
|
+
function resolveCliSource(explicit) {
|
|
1314
|
+
return describeCliSource(explicit).source;
|
|
1315
|
+
}
|
|
1316
|
+
|
|
992
1317
|
// src/contracts/resolve-contract.ts
|
|
993
|
-
var
|
|
1318
|
+
var import_node_path8 = __toESM(require("path"), 1);
|
|
994
1319
|
function resolveContract(config, contractName, cwd = process.cwd()) {
|
|
995
1320
|
const contract = config.contracts[contractName];
|
|
996
1321
|
if (!contract) {
|
|
@@ -1003,8 +1328,8 @@ function resolveContract(config, contractName, cwd = process.cwd()) {
|
|
|
1003
1328
|
return {
|
|
1004
1329
|
name: contractName,
|
|
1005
1330
|
config: contract,
|
|
1006
|
-
sourcePath:
|
|
1007
|
-
wasmPath:
|
|
1331
|
+
sourcePath: import_node_path8.default.resolve(cwd, contract.path),
|
|
1332
|
+
wasmPath: import_node_path8.default.resolve(cwd, contract.wasm)
|
|
1008
1333
|
};
|
|
1009
1334
|
}
|
|
1010
1335
|
|
|
@@ -1023,8 +1348,8 @@ function resolveDefaultContractName(config) {
|
|
|
1023
1348
|
|
|
1024
1349
|
// src/contracts/wasm.ts
|
|
1025
1350
|
var import_node_crypto = require("crypto");
|
|
1026
|
-
var
|
|
1027
|
-
var
|
|
1351
|
+
var import_promises7 = require("fs/promises");
|
|
1352
|
+
var import_node_path9 = __toESM(require("path"), 1);
|
|
1028
1353
|
var LEGACY_RUST_WASM_TARGET = "wasm32-unknown-unknown";
|
|
1029
1354
|
var CURRENT_RUST_WASM_TARGET = "wasm32v1-none";
|
|
1030
1355
|
function toCurrentWasmTargetPath(wasmPath) {
|
|
@@ -1055,18 +1380,18 @@ function wasmNotFoundError(configuredWasmPath, options) {
|
|
|
1055
1380
|
);
|
|
1056
1381
|
}
|
|
1057
1382
|
function toConfigRelativeWasmPath(absoluteWasmPath) {
|
|
1058
|
-
const relative =
|
|
1059
|
-
return relative.startsWith("..") ? absoluteWasmPath : `./${relative.split(
|
|
1383
|
+
const relative = import_node_path9.default.relative(process.cwd(), absoluteWasmPath);
|
|
1384
|
+
return relative.startsWith("..") ? absoluteWasmPath : `./${relative.split(import_node_path9.default.sep).join("/")}`;
|
|
1060
1385
|
}
|
|
1061
1386
|
function wasmFileName(configuredWasmPath) {
|
|
1062
|
-
return
|
|
1387
|
+
return import_node_path9.default.basename(configuredWasmPath);
|
|
1063
1388
|
}
|
|
1064
1389
|
function buildAlternateWasmCandidates(configuredWasmPath, options) {
|
|
1065
1390
|
const fileName = wasmFileName(configuredWasmPath);
|
|
1066
1391
|
const candidates = [];
|
|
1067
1392
|
const seen = /* @__PURE__ */ new Set();
|
|
1068
1393
|
function addCandidate(candidate) {
|
|
1069
|
-
const resolved =
|
|
1394
|
+
const resolved = import_node_path9.default.resolve(candidate);
|
|
1070
1395
|
if (seen.has(resolved)) {
|
|
1071
1396
|
return;
|
|
1072
1397
|
}
|
|
@@ -1075,15 +1400,15 @@ function buildAlternateWasmCandidates(configuredWasmPath, options) {
|
|
|
1075
1400
|
}
|
|
1076
1401
|
const cargoTargetDir = process.env.CARGO_TARGET_DIR;
|
|
1077
1402
|
if (cargoTargetDir) {
|
|
1078
|
-
addCandidate(
|
|
1079
|
-
addCandidate(
|
|
1403
|
+
addCandidate(import_node_path9.default.join(cargoTargetDir, CURRENT_RUST_WASM_TARGET, "release", fileName));
|
|
1404
|
+
addCandidate(import_node_path9.default.join(cargoTargetDir, LEGACY_RUST_WASM_TARGET, "release", fileName));
|
|
1080
1405
|
}
|
|
1081
1406
|
if (options?.sourcePath) {
|
|
1082
1407
|
addCandidate(
|
|
1083
|
-
|
|
1408
|
+
import_node_path9.default.join(options.sourcePath, "target", CURRENT_RUST_WASM_TARGET, "release", fileName)
|
|
1084
1409
|
);
|
|
1085
1410
|
addCandidate(
|
|
1086
|
-
|
|
1411
|
+
import_node_path9.default.join(options.sourcePath, "target", LEGACY_RUST_WASM_TARGET, "release", fileName)
|
|
1087
1412
|
);
|
|
1088
1413
|
}
|
|
1089
1414
|
return candidates;
|
|
@@ -1091,7 +1416,7 @@ function buildAlternateWasmCandidates(configuredWasmPath, options) {
|
|
|
1091
1416
|
async function firstExistingPath(paths) {
|
|
1092
1417
|
for (const candidate of paths) {
|
|
1093
1418
|
try {
|
|
1094
|
-
await (0,
|
|
1419
|
+
await (0, import_promises7.access)(candidate);
|
|
1095
1420
|
return candidate;
|
|
1096
1421
|
} catch {
|
|
1097
1422
|
continue;
|
|
@@ -1100,9 +1425,9 @@ async function firstExistingPath(paths) {
|
|
|
1100
1425
|
return void 0;
|
|
1101
1426
|
}
|
|
1102
1427
|
async function resolveWasmArtifactPath(configuredWasmPath, options) {
|
|
1103
|
-
const resolvedConfiguredPath =
|
|
1428
|
+
const resolvedConfiguredPath = import_node_path9.default.resolve(configuredWasmPath);
|
|
1104
1429
|
try {
|
|
1105
|
-
await (0,
|
|
1430
|
+
await (0, import_promises7.access)(resolvedConfiguredPath);
|
|
1106
1431
|
return resolvedConfiguredPath;
|
|
1107
1432
|
} catch {
|
|
1108
1433
|
const currentTargetPath = toCurrentWasmTargetPath(resolvedConfiguredPath);
|
|
@@ -1124,20 +1449,20 @@ async function resolveWasmArtifactPath(configuredWasmPath, options) {
|
|
|
1124
1449
|
}
|
|
1125
1450
|
}
|
|
1126
1451
|
async function hashWasm(wasmPath) {
|
|
1127
|
-
const bytes = await (0,
|
|
1452
|
+
const bytes = await (0, import_promises7.readFile)(wasmPath);
|
|
1128
1453
|
return (0, import_node_crypto.createHash)("sha256").update(bytes).digest("hex");
|
|
1129
1454
|
}
|
|
1130
1455
|
async function getNewestMtimeInDirectory(directory) {
|
|
1131
1456
|
try {
|
|
1132
|
-
await (0,
|
|
1457
|
+
await (0, import_promises7.access)(directory);
|
|
1133
1458
|
} catch {
|
|
1134
1459
|
return void 0;
|
|
1135
1460
|
}
|
|
1136
1461
|
let newest = 0;
|
|
1137
1462
|
async function walk(dir) {
|
|
1138
|
-
const entries = await (0,
|
|
1463
|
+
const entries = await (0, import_promises7.readdir)(dir, { withFileTypes: true });
|
|
1139
1464
|
for (const entry of entries) {
|
|
1140
|
-
const entryPath =
|
|
1465
|
+
const entryPath = import_node_path9.default.join(dir, entry.name);
|
|
1141
1466
|
if (entry.isDirectory()) {
|
|
1142
1467
|
await walk(entryPath);
|
|
1143
1468
|
continue;
|
|
@@ -1145,7 +1470,7 @@ async function getNewestMtimeInDirectory(directory) {
|
|
|
1145
1470
|
if (!entry.isFile()) {
|
|
1146
1471
|
continue;
|
|
1147
1472
|
}
|
|
1148
|
-
const fileStat = await (0,
|
|
1473
|
+
const fileStat = await (0, import_promises7.stat)(entryPath);
|
|
1149
1474
|
newest = Math.max(newest, fileStat.mtimeMs);
|
|
1150
1475
|
}
|
|
1151
1476
|
}
|
|
@@ -1153,14 +1478,14 @@ async function getNewestMtimeInDirectory(directory) {
|
|
|
1153
1478
|
return newest > 0 ? newest : void 0;
|
|
1154
1479
|
}
|
|
1155
1480
|
async function isWasmOlderThanSources(input) {
|
|
1156
|
-
const srcDir =
|
|
1481
|
+
const srcDir = import_node_path9.default.join(input.contractPath, "src");
|
|
1157
1482
|
const newestSourceMtime = await getNewestMtimeInDirectory(srcDir);
|
|
1158
1483
|
if (newestSourceMtime === void 0) {
|
|
1159
1484
|
return false;
|
|
1160
1485
|
}
|
|
1161
1486
|
let wasmStat;
|
|
1162
1487
|
try {
|
|
1163
|
-
wasmStat = await (0,
|
|
1488
|
+
wasmStat = await (0, import_promises7.stat)(input.wasmPath);
|
|
1164
1489
|
} catch {
|
|
1165
1490
|
return false;
|
|
1166
1491
|
}
|
|
@@ -1228,7 +1553,38 @@ async function buildContract(options) {
|
|
|
1228
1553
|
}
|
|
1229
1554
|
|
|
1230
1555
|
// src/contracts/deploy-contract.ts
|
|
1231
|
-
var
|
|
1556
|
+
var import_node_path10 = __toESM(require("path"), 1);
|
|
1557
|
+
|
|
1558
|
+
// src/shell/is-transient-command-failure.ts
|
|
1559
|
+
var NO_RETRY_CAATINGA_SUBSTRINGS = [
|
|
1560
|
+
"CAATINGA_UNSUPPORTED_CLI_VERSION",
|
|
1561
|
+
"CAATINGA_STELLAR_CLI_VERSION_PARSE_FAILED",
|
|
1562
|
+
"CAATINGA_STELLAR_CLI_NOT_FOUND",
|
|
1563
|
+
"CAATINGA_INVALID_CONFIG",
|
|
1564
|
+
"CAATINGA_CONFIG_NOT_FOUND"
|
|
1565
|
+
];
|
|
1566
|
+
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;
|
|
1567
|
+
function isTransientCommandFailure(logText) {
|
|
1568
|
+
if (!logText.trim()) {
|
|
1569
|
+
return false;
|
|
1570
|
+
}
|
|
1571
|
+
for (const marker of NO_RETRY_CAATINGA_SUBSTRINGS) {
|
|
1572
|
+
if (logText.includes(marker)) {
|
|
1573
|
+
return false;
|
|
1574
|
+
}
|
|
1575
|
+
}
|
|
1576
|
+
return TRANSIENT_COMMAND_FAILURE_PATTERN.test(logText);
|
|
1577
|
+
}
|
|
1578
|
+
|
|
1579
|
+
// src/contracts/is-transient-deploy-failure.ts
|
|
1580
|
+
function isTransientDeployFailure(error) {
|
|
1581
|
+
if (!(error instanceof CaatingaError) || error.code !== CaatingaErrorCode.DEPLOY_FAILED) {
|
|
1582
|
+
return false;
|
|
1583
|
+
}
|
|
1584
|
+
const logText = `${error.message}
|
|
1585
|
+
${error.hint ?? ""}`;
|
|
1586
|
+
return isTransientCommandFailure(logText);
|
|
1587
|
+
}
|
|
1232
1588
|
|
|
1233
1589
|
// src/contracts/dependency-graph.ts
|
|
1234
1590
|
function buildDependencyGraph(contracts) {
|
|
@@ -1270,26 +1626,13 @@ function resolveDeployArgs(input) {
|
|
|
1270
1626
|
return resolved;
|
|
1271
1627
|
}
|
|
1272
1628
|
|
|
1273
|
-
// src/contracts/source-account.ts
|
|
1274
|
-
function assertSafeSourceAccount(source) {
|
|
1275
|
-
if (!source) {
|
|
1276
|
-
throw new CaatingaError(
|
|
1277
|
-
"A source account or Stellar CLI identity is required.",
|
|
1278
|
-
CaatingaErrorCode.SOURCE_ACCOUNT_REQUIRED,
|
|
1279
|
-
"Pass a Stellar CLI identity alias, for example: --source alice"
|
|
1280
|
-
);
|
|
1281
|
-
}
|
|
1282
|
-
const unsafeSource = validateSourceShape(source);
|
|
1283
|
-
if (unsafeSource) {
|
|
1284
|
-
throw unsafeSource;
|
|
1285
|
-
}
|
|
1286
|
-
return source;
|
|
1287
|
-
}
|
|
1288
|
-
function resolveCliSource(explicit) {
|
|
1289
|
-
return assertSafeSourceAccount(explicit ?? process.env.CAATINGA_SOURCE ?? "alice");
|
|
1290
|
-
}
|
|
1291
|
-
|
|
1292
1629
|
// src/contracts/deploy-contract.ts
|
|
1630
|
+
var DEFAULT_DEPLOY_RETRY_DELAYS_MS = [2e3, 5e3];
|
|
1631
|
+
function sleep(ms) {
|
|
1632
|
+
return new Promise((resolve) => {
|
|
1633
|
+
setTimeout(resolve, ms);
|
|
1634
|
+
});
|
|
1635
|
+
}
|
|
1293
1636
|
function toSnakeCaseFlag(key) {
|
|
1294
1637
|
return key.replace(/([A-Z])/g, "_$1").replace(/^_/, "").toLowerCase();
|
|
1295
1638
|
}
|
|
@@ -1334,7 +1677,7 @@ async function deployContract(options) {
|
|
|
1334
1677
|
contract: contractWithWasm,
|
|
1335
1678
|
network,
|
|
1336
1679
|
contractId: existing.contractId,
|
|
1337
|
-
artifactsPath:
|
|
1680
|
+
artifactsPath: import_node_path10.default.resolve(cwd, "caatinga.artifacts.json"),
|
|
1338
1681
|
output: "",
|
|
1339
1682
|
skipped: true,
|
|
1340
1683
|
staleWasmWarning
|
|
@@ -1374,40 +1717,69 @@ async function deployContract(options) {
|
|
|
1374
1717
|
...buildStellarNetworkArgs(network),
|
|
1375
1718
|
...constructorArgs
|
|
1376
1719
|
];
|
|
1377
|
-
let
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1720
|
+
let deployOutcome;
|
|
1721
|
+
const retryDelaysMs = options.deployRetryDelaysMs ?? DEFAULT_DEPLOY_RETRY_DELAYS_MS;
|
|
1722
|
+
const maxDeployAttempts = retryDelaysMs.length + 1;
|
|
1723
|
+
for (let attempt = 0; attempt < maxDeployAttempts; attempt++) {
|
|
1724
|
+
try {
|
|
1725
|
+
const result = await runCommand("stellar", stellarArgs, {
|
|
1726
|
+
cwd,
|
|
1727
|
+
failureCode: CaatingaErrorCode.DEPLOY_FAILED
|
|
1728
|
+
});
|
|
1729
|
+
const output2 = result.all || `${result.stdout}
|
|
1385
1730
|
${result.stderr}`;
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1731
|
+
deployOutcome = {
|
|
1732
|
+
output: output2,
|
|
1733
|
+
contractId: parseContractId(output2)
|
|
1734
|
+
};
|
|
1735
|
+
break;
|
|
1736
|
+
} catch (error) {
|
|
1737
|
+
if (!(error instanceof CaatingaError) || error.code !== CaatingaErrorCode.DEPLOY_FAILED) {
|
|
1738
|
+
throw error;
|
|
1739
|
+
}
|
|
1740
|
+
const recoveredContractId = await tryRecoverContractIdFromDeployFailure({
|
|
1741
|
+
output: `${error.message}
|
|
1393
1742
|
${error.hint ?? ""}`,
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1743
|
+
source,
|
|
1744
|
+
network: network.config,
|
|
1745
|
+
cwd
|
|
1746
|
+
});
|
|
1747
|
+
if (recoveredContractId) {
|
|
1748
|
+
deployOutcome = {
|
|
1749
|
+
output: [
|
|
1750
|
+
error.hint ?? "",
|
|
1751
|
+
"Caatinga recovered the contract ID from the on-chain deploy transaction.",
|
|
1752
|
+
`Contract ID: ${recoveredContractId}`
|
|
1753
|
+
].filter(Boolean).join("\n"),
|
|
1754
|
+
contractId: recoveredContractId
|
|
1755
|
+
};
|
|
1756
|
+
break;
|
|
1757
|
+
}
|
|
1758
|
+
const isLastAttempt = attempt === maxDeployAttempts - 1;
|
|
1759
|
+
if (!isTransientDeployFailure(error) || isLastAttempt) {
|
|
1760
|
+
throw error;
|
|
1761
|
+
}
|
|
1762
|
+
const delayMs = retryDelaysMs[attempt] ?? retryDelaysMs[retryDelaysMs.length - 1] ?? 0;
|
|
1763
|
+
options.onTransientDeployRetry?.({
|
|
1764
|
+
attempt: attempt + 1,
|
|
1765
|
+
maxAttempts: maxDeployAttempts,
|
|
1766
|
+
delayMs
|
|
1767
|
+
});
|
|
1768
|
+
await sleep(delayMs);
|
|
1400
1769
|
}
|
|
1401
|
-
contractId = recoveredContractId;
|
|
1402
|
-
output = [
|
|
1403
|
-
error.hint ?? "",
|
|
1404
|
-
"Caatinga recovered the contract ID from the on-chain deploy transaction.",
|
|
1405
|
-
`Contract ID: ${contractId}`
|
|
1406
|
-
].filter(Boolean).join("\n");
|
|
1407
1770
|
}
|
|
1771
|
+
if (!deployOutcome) {
|
|
1772
|
+
throw new CaatingaError(
|
|
1773
|
+
"Deploy failed without a contract ID.",
|
|
1774
|
+
CaatingaErrorCode.DEPLOY_FAILED,
|
|
1775
|
+
"Re-run the deploy command with the underlying Stellar CLI for full diagnostics."
|
|
1776
|
+
);
|
|
1777
|
+
}
|
|
1778
|
+
const { output, contractId } = deployOutcome;
|
|
1408
1779
|
const wasmHash = await hashWasm(wasmPath);
|
|
1409
1780
|
const dependencyGraph = buildDependencyGraph(options.config.contracts);
|
|
1410
1781
|
const dependencies = options.dependencies ?? contract.config.dependsOn;
|
|
1782
|
+
const supersedeReason = existing?.contractId && options.force ? options.upgrade ? "upgrade" : "force-redeploy" : void 0;
|
|
1411
1783
|
const nextArtifacts = updateArtifact(
|
|
1412
1784
|
artifactsBefore,
|
|
1413
1785
|
network.name,
|
|
@@ -1421,7 +1793,7 @@ ${error.hint ?? ""}`,
|
|
|
1421
1793
|
dependencies,
|
|
1422
1794
|
resolvedDeployArgs
|
|
1423
1795
|
},
|
|
1424
|
-
{ dependencyGraph }
|
|
1796
|
+
{ dependencyGraph, supersedeReason }
|
|
1425
1797
|
);
|
|
1426
1798
|
const artifactsPath = await writeArtifacts(nextArtifacts, cwd);
|
|
1427
1799
|
return {
|
|
@@ -1585,9 +1957,11 @@ async function deployContractGraph(options) {
|
|
|
1585
1957
|
source: options.source,
|
|
1586
1958
|
cwd,
|
|
1587
1959
|
force: options.force,
|
|
1960
|
+
upgrade: options.upgrade,
|
|
1588
1961
|
checkStaleWasm: options.checkStaleWasm,
|
|
1589
1962
|
resolvedDeployArgs,
|
|
1590
|
-
dependencies: contractConfig.dependsOn
|
|
1963
|
+
dependencies: contractConfig.dependsOn,
|
|
1964
|
+
onTransientDeployRetry: options.onTransientDeployRetry
|
|
1591
1965
|
});
|
|
1592
1966
|
if (result.staleWasmWarning) {
|
|
1593
1967
|
staleWasmWarnings.push({
|
|
@@ -1610,12 +1984,12 @@ async function deployContractGraph(options) {
|
|
|
1610
1984
|
}
|
|
1611
1985
|
|
|
1612
1986
|
// src/contracts/generate-bindings.ts
|
|
1613
|
-
var
|
|
1614
|
-
var
|
|
1987
|
+
var import_promises9 = require("fs/promises");
|
|
1988
|
+
var import_node_path12 = __toESM(require("path"), 1);
|
|
1615
1989
|
|
|
1616
1990
|
// src/bindings/patch-generated-binding-package.ts
|
|
1617
|
-
var
|
|
1618
|
-
var
|
|
1991
|
+
var import_promises8 = require("fs/promises");
|
|
1992
|
+
var import_node_path11 = __toESM(require("path"), 1);
|
|
1619
1993
|
var BUNDLER_ENTRY = "./src/index.ts";
|
|
1620
1994
|
var ROOT_BINDING_INDEX_CONTENT = 'export * from "./src/index.js";\n';
|
|
1621
1995
|
function resolveExportEntry(exportsField) {
|
|
@@ -1650,22 +2024,22 @@ function shouldPatchPackageJson(packageJson) {
|
|
|
1650
2024
|
return pointsToDist(packageJson.main) || pointsToDist(packageJson.types) || !pointsToBundlerSource(exportEntry);
|
|
1651
2025
|
}
|
|
1652
2026
|
async function ensureRootBindingIndex(outputDir) {
|
|
1653
|
-
const rootIndexPath =
|
|
2027
|
+
const rootIndexPath = import_node_path11.default.join(outputDir, "index.ts");
|
|
1654
2028
|
try {
|
|
1655
|
-
const existing = await (0,
|
|
2029
|
+
const existing = await (0, import_promises8.readFile)(rootIndexPath, "utf8");
|
|
1656
2030
|
if (existing === ROOT_BINDING_INDEX_CONTENT) {
|
|
1657
2031
|
return;
|
|
1658
2032
|
}
|
|
1659
2033
|
return;
|
|
1660
2034
|
} catch {
|
|
1661
|
-
await (0,
|
|
2035
|
+
await (0, import_promises8.writeFile)(rootIndexPath, ROOT_BINDING_INDEX_CONTENT, "utf8");
|
|
1662
2036
|
}
|
|
1663
2037
|
}
|
|
1664
2038
|
async function patchGeneratedBindingPackage(outputDir) {
|
|
1665
|
-
const packageJsonPath =
|
|
1666
|
-
const entryPath =
|
|
2039
|
+
const packageJsonPath = import_node_path11.default.join(outputDir, "package.json");
|
|
2040
|
+
const entryPath = import_node_path11.default.join(outputDir, "src", "index.ts");
|
|
1667
2041
|
try {
|
|
1668
|
-
await (0,
|
|
2042
|
+
await (0, import_promises8.access)(entryPath);
|
|
1669
2043
|
} catch {
|
|
1670
2044
|
throw new CaatingaError(
|
|
1671
2045
|
"Generated binding package is missing src/index.ts.",
|
|
@@ -1675,7 +2049,7 @@ async function patchGeneratedBindingPackage(outputDir) {
|
|
|
1675
2049
|
}
|
|
1676
2050
|
let raw;
|
|
1677
2051
|
try {
|
|
1678
|
-
raw = await (0,
|
|
2052
|
+
raw = await (0, import_promises8.readFile)(packageJsonPath, "utf8");
|
|
1679
2053
|
} catch {
|
|
1680
2054
|
throw new CaatingaError(
|
|
1681
2055
|
"Generated binding package is missing package.json.",
|
|
@@ -1700,7 +2074,7 @@ async function patchGeneratedBindingPackage(outputDir) {
|
|
|
1700
2074
|
...typeof packageJson.exports === "object" && packageJson.exports !== null && !Array.isArray(packageJson.exports) ? packageJson.exports : {},
|
|
1701
2075
|
".": BUNDLER_ENTRY
|
|
1702
2076
|
};
|
|
1703
|
-
await (0,
|
|
2077
|
+
await (0, import_promises8.writeFile)(packageJsonPath, `${JSON.stringify(packageJson, null, 2)}
|
|
1704
2078
|
`, "utf8");
|
|
1705
2079
|
}
|
|
1706
2080
|
await ensureRootBindingIndex(outputDir);
|
|
@@ -1716,14 +2090,14 @@ function buildGenerateNetworkArgs(network) {
|
|
|
1716
2090
|
|
|
1717
2091
|
// src/contracts/generate-bindings.ts
|
|
1718
2092
|
function toBindingImportPath(bindingsOutput, contractName) {
|
|
1719
|
-
const normalized = bindingsOutput.replace(/^\.\//, "").split(
|
|
1720
|
-
return `./${
|
|
2093
|
+
const normalized = bindingsOutput.replace(/^\.\//, "").split(import_node_path12.default.sep).join("/");
|
|
2094
|
+
return `./${import_node_path12.default.posix.join(normalized, contractName)}`;
|
|
1721
2095
|
}
|
|
1722
2096
|
async function removeLegacyBindingStub(cwd, bindingsOutput, contractName) {
|
|
1723
|
-
const legacyPath =
|
|
2097
|
+
const legacyPath = import_node_path12.default.resolve(cwd, bindingsOutput, `${contractName}.ts`);
|
|
1724
2098
|
try {
|
|
1725
|
-
await (0,
|
|
1726
|
-
await (0,
|
|
2099
|
+
await (0, import_promises9.access)(legacyPath);
|
|
2100
|
+
await (0, import_promises9.unlink)(legacyPath);
|
|
1727
2101
|
return true;
|
|
1728
2102
|
} catch {
|
|
1729
2103
|
return false;
|
|
@@ -1748,8 +2122,9 @@ async function generateBindings(options) {
|
|
|
1748
2122
|
"Run caatinga deploy for this contract and network before generating bindings."
|
|
1749
2123
|
);
|
|
1750
2124
|
}
|
|
1751
|
-
const outputDir =
|
|
1752
|
-
await (0,
|
|
2125
|
+
const outputDir = import_node_path12.default.resolve(cwd, options.config.frontend.bindingsOutput, options.contractName);
|
|
2126
|
+
await (0, import_promises9.mkdir)(outputDir, { recursive: true });
|
|
2127
|
+
await checkStellarSdkVersion({ cwd });
|
|
1753
2128
|
const result = await runCommand(
|
|
1754
2129
|
"npx",
|
|
1755
2130
|
[
|
|
@@ -1974,14 +2349,172 @@ async function readContract(options) {
|
|
|
1974
2349
|
};
|
|
1975
2350
|
}
|
|
1976
2351
|
|
|
2352
|
+
// src/contracts/estimate-deploy-cost.ts
|
|
2353
|
+
var import_node_path13 = __toESM(require("path"), 1);
|
|
2354
|
+
function toSnakeCaseFlag2(key) {
|
|
2355
|
+
return key.replace(/([A-Z])/g, "_$1").replace(/^_/, "").toLowerCase();
|
|
2356
|
+
}
|
|
2357
|
+
function formatConstructorCliArgs2(resolved) {
|
|
2358
|
+
const entries = Object.entries(resolved);
|
|
2359
|
+
if (entries.length === 0) {
|
|
2360
|
+
return [];
|
|
2361
|
+
}
|
|
2362
|
+
const tail = ["--"];
|
|
2363
|
+
for (const [key, value] of entries) {
|
|
2364
|
+
tail.push(`--${toSnakeCaseFlag2(key)}`, String(value));
|
|
2365
|
+
}
|
|
2366
|
+
return tail;
|
|
2367
|
+
}
|
|
2368
|
+
function parseFeeStroops(output) {
|
|
2369
|
+
const inclusionMatch = output.match(/inclusion[_\s-]*fee[:\s]+(\d+)/i);
|
|
2370
|
+
const resourceMatch = output.match(/resource[_\s-]*fee[:\s]+(\d+)/i);
|
|
2371
|
+
const totalMatch = output.match(/total[_\s-]*fee[:\s]+(\d+)/i);
|
|
2372
|
+
return {
|
|
2373
|
+
inclusion: inclusionMatch ? Number(inclusionMatch[1]) : void 0,
|
|
2374
|
+
resource: resourceMatch ? Number(resourceMatch[1]) : void 0,
|
|
2375
|
+
...totalMatch && !resourceMatch ? { resource: Number(totalMatch[1]) } : {}
|
|
2376
|
+
};
|
|
2377
|
+
}
|
|
2378
|
+
async function estimateDeployCost(options) {
|
|
2379
|
+
const cwd = options.cwd ?? process.cwd();
|
|
2380
|
+
const contract = resolveContract(options.config, options.contractName, cwd);
|
|
2381
|
+
const network = resolveNetwork(options.config, options.networkName);
|
|
2382
|
+
const source = assertSafeSourceAccount(options.source);
|
|
2383
|
+
await checkBinary("stellar", "Install Stellar CLI before running caatinga estimate.");
|
|
2384
|
+
const wasmPath = await resolveWasmArtifactPath(contract.wasmPath, {
|
|
2385
|
+
sourcePath: contract.sourcePath
|
|
2386
|
+
});
|
|
2387
|
+
const artifacts = await readArtifacts(cwd);
|
|
2388
|
+
const rawDeployArgs = contract.config.deployArgs;
|
|
2389
|
+
const resolvedDeployArgs = Object.keys(rawDeployArgs).length > 0 ? resolveDeployArgs({
|
|
2390
|
+
deployArgs: rawDeployArgs,
|
|
2391
|
+
artifacts,
|
|
2392
|
+
network: network.name
|
|
2393
|
+
}) : {};
|
|
2394
|
+
const constructorArgs = formatConstructorCliArgs2(resolvedDeployArgs);
|
|
2395
|
+
const deployArgs = [
|
|
2396
|
+
"contract",
|
|
2397
|
+
"deploy",
|
|
2398
|
+
"--wasm",
|
|
2399
|
+
wasmPath,
|
|
2400
|
+
"--source-account",
|
|
2401
|
+
source,
|
|
2402
|
+
"--build-only",
|
|
2403
|
+
...buildStellarNetworkArgs(network),
|
|
2404
|
+
...constructorArgs
|
|
2405
|
+
];
|
|
2406
|
+
let buildOutput;
|
|
2407
|
+
try {
|
|
2408
|
+
const buildResult = await runCommand("stellar", deployArgs, {
|
|
2409
|
+
cwd,
|
|
2410
|
+
failureCode: CaatingaErrorCode.ESTIMATE_FAILED
|
|
2411
|
+
});
|
|
2412
|
+
buildOutput = (buildResult.stdout || buildResult.all).trim();
|
|
2413
|
+
} catch (error) {
|
|
2414
|
+
if (error instanceof CaatingaError) {
|
|
2415
|
+
throw new CaatingaError(
|
|
2416
|
+
`Deploy cost estimate failed for "${contract.name}".`,
|
|
2417
|
+
CaatingaErrorCode.ESTIMATE_FAILED,
|
|
2418
|
+
error.hint ?? "Ensure WASM is built and deploy args resolve correctly.",
|
|
2419
|
+
error.cause
|
|
2420
|
+
);
|
|
2421
|
+
}
|
|
2422
|
+
throw error;
|
|
2423
|
+
}
|
|
2424
|
+
const simulateArgs = ["tx", "simulate", "--source-account", source, buildOutput];
|
|
2425
|
+
let simulateOutput = "";
|
|
2426
|
+
try {
|
|
2427
|
+
const simulateResult = await runCommand("stellar", simulateArgs, {
|
|
2428
|
+
cwd,
|
|
2429
|
+
failureCode: CaatingaErrorCode.ESTIMATE_FAILED
|
|
2430
|
+
});
|
|
2431
|
+
simulateOutput = simulateResult.all || `${simulateResult.stdout}
|
|
2432
|
+
${simulateResult.stderr}`;
|
|
2433
|
+
} catch {
|
|
2434
|
+
simulateOutput = "";
|
|
2435
|
+
}
|
|
2436
|
+
const parsed = parseFeeStroops(simulateOutput);
|
|
2437
|
+
const inclusionFeeStroops = parsed.inclusion ?? 100;
|
|
2438
|
+
const resourceFeeStroops = parsed.resource;
|
|
2439
|
+
const totalFeeStroops = inclusionFeeStroops + (resourceFeeStroops ?? 0);
|
|
2440
|
+
return {
|
|
2441
|
+
contractName: contract.name,
|
|
2442
|
+
network: network.name,
|
|
2443
|
+
wasmPath: import_node_path13.default.relative(cwd, wasmPath) || wasmPath,
|
|
2444
|
+
inclusionFeeStroops,
|
|
2445
|
+
resourceFeeStroops,
|
|
2446
|
+
totalFeeStroops,
|
|
2447
|
+
advisory: "Advisory estimate only \u2014 actual fees may differ under network congestion or contract complexity.",
|
|
2448
|
+
rawOutput: simulateOutput || buildOutput
|
|
2449
|
+
};
|
|
2450
|
+
}
|
|
2451
|
+
|
|
2452
|
+
// src/contracts/inspect-contract.ts
|
|
2453
|
+
async function inspectContract(options) {
|
|
2454
|
+
const cwd = options.cwd ?? process.cwd();
|
|
2455
|
+
const contract = resolveContract(options.config, options.contractName, cwd);
|
|
2456
|
+
const network = resolveNetwork(options.config, options.networkName);
|
|
2457
|
+
const artifacts = await readArtifacts(cwd);
|
|
2458
|
+
const artifact = artifacts.networks[network.name]?.contracts[contract.name];
|
|
2459
|
+
if (!artifact) {
|
|
2460
|
+
throw new CaatingaError(
|
|
2461
|
+
`No deployed artifact found for "${contract.name}" on "${network.name}".`,
|
|
2462
|
+
CaatingaErrorCode.ARTIFACT_NOT_FOUND,
|
|
2463
|
+
"Run caatinga deploy before inspect."
|
|
2464
|
+
);
|
|
2465
|
+
}
|
|
2466
|
+
await checkBinary("stellar", "Install Stellar CLI before running caatinga inspect.");
|
|
2467
|
+
let reachable = false;
|
|
2468
|
+
let detail;
|
|
2469
|
+
try {
|
|
2470
|
+
await verifyDependencyContract({
|
|
2471
|
+
dependencyName: contract.name,
|
|
2472
|
+
contractId: artifact.contractId,
|
|
2473
|
+
network,
|
|
2474
|
+
cwd
|
|
2475
|
+
});
|
|
2476
|
+
reachable = true;
|
|
2477
|
+
detail = "Contract interface reachable on network.";
|
|
2478
|
+
} catch (error) {
|
|
2479
|
+
reachable = false;
|
|
2480
|
+
detail = error instanceof CaatingaError ? error.message : "Contract not reachable on network.";
|
|
2481
|
+
}
|
|
2482
|
+
let localHash;
|
|
2483
|
+
try {
|
|
2484
|
+
const wasmPath = await resolveWasmArtifactPath(contract.wasmPath, {
|
|
2485
|
+
sourcePath: contract.sourcePath
|
|
2486
|
+
});
|
|
2487
|
+
localHash = await hashWasm(wasmPath);
|
|
2488
|
+
} catch {
|
|
2489
|
+
localHash = void 0;
|
|
2490
|
+
}
|
|
2491
|
+
return {
|
|
2492
|
+
contractName: contract.name,
|
|
2493
|
+
network: network.name,
|
|
2494
|
+
artifact: {
|
|
2495
|
+
contractId: artifact.contractId,
|
|
2496
|
+
wasmHash: artifact.wasmHash,
|
|
2497
|
+
deployedAt: artifact.deployedAt,
|
|
2498
|
+
historyCount: artifact.history?.length ?? 0
|
|
2499
|
+
},
|
|
2500
|
+
onChain: { reachable, detail },
|
|
2501
|
+
localWasm: {
|
|
2502
|
+
path: contract.config.wasm,
|
|
2503
|
+
hash: localHash,
|
|
2504
|
+
matchesArtifact: Boolean(localHash && localHash === artifact.wasmHash)
|
|
2505
|
+
},
|
|
2506
|
+
dependencies: artifact.dependencies ?? contract.config.dependsOn ?? []
|
|
2507
|
+
};
|
|
2508
|
+
}
|
|
2509
|
+
|
|
1977
2510
|
// src/templates/create-project-from-template.ts
|
|
1978
|
-
var
|
|
1979
|
-
var
|
|
2511
|
+
var import_promises10 = require("fs/promises");
|
|
2512
|
+
var import_node_path14 = __toESM(require("path"), 1);
|
|
1980
2513
|
var import_zod7 = require("zod");
|
|
1981
2514
|
|
|
1982
2515
|
// src/templates/template-manifest.schema.ts
|
|
1983
2516
|
var import_zod6 = require("zod");
|
|
1984
|
-
var
|
|
2517
|
+
var import_semver5 = __toESM(require("semver"), 1);
|
|
1985
2518
|
var CURRENT_TEMPLATE_VERSION = 1;
|
|
1986
2519
|
var TemplateManifestSchema = import_zod6.z.object({
|
|
1987
2520
|
name: import_zod6.z.string().min(1),
|
|
@@ -2005,14 +2538,14 @@ var TemplateManifestSchema = import_zod6.z.object({
|
|
|
2005
2538
|
})
|
|
2006
2539
|
});
|
|
2007
2540
|
function defaultCompatibleCoreRange(coreVersion = CAATINGA_CORE_VERSION) {
|
|
2008
|
-
const version =
|
|
2541
|
+
const version = import_semver5.default.valid(import_semver5.default.coerce(coreVersion));
|
|
2009
2542
|
if (!version) {
|
|
2010
2543
|
throw new Error(`Invalid core version: ${coreVersion}`);
|
|
2011
2544
|
}
|
|
2012
2545
|
return `^${version}`;
|
|
2013
2546
|
}
|
|
2014
2547
|
function isCoreVersionCompatible(range, coreVersion = CAATINGA_CORE_VERSION) {
|
|
2015
|
-
return
|
|
2548
|
+
return import_semver5.default.satisfies(coreVersion, range);
|
|
2016
2549
|
}
|
|
2017
2550
|
function getTemplateCompatibilityIssue(manifest, coreVersion = CAATINGA_CORE_VERSION) {
|
|
2018
2551
|
if (manifest.caatinga.templateVersion !== CURRENT_TEMPLATE_VERSION) {
|
|
@@ -2047,10 +2580,10 @@ function formatTemplateCompatibilityHint(issue) {
|
|
|
2047
2580
|
// src/templates/create-project-from-template.ts
|
|
2048
2581
|
var TEMPLATE_COPY_EXCLUDED_DIRS = /* @__PURE__ */ new Set(["target", "test_snapshots", "node_modules", ".git"]);
|
|
2049
2582
|
async function createProjectFromTemplate(options) {
|
|
2050
|
-
const targetDir =
|
|
2051
|
-
const templateDir =
|
|
2583
|
+
const targetDir = import_node_path14.default.resolve(options.targetDir);
|
|
2584
|
+
const templateDir = import_node_path14.default.resolve(options.templateDir);
|
|
2052
2585
|
try {
|
|
2053
|
-
await (0,
|
|
2586
|
+
await (0, import_promises10.stat)(templateDir);
|
|
2054
2587
|
} catch {
|
|
2055
2588
|
throw new CaatingaError(
|
|
2056
2589
|
`Template directory was not found: ${templateDir}`,
|
|
@@ -2060,8 +2593,8 @@ async function createProjectFromTemplate(options) {
|
|
|
2060
2593
|
}
|
|
2061
2594
|
const manifest = await readTemplateManifest(templateDir);
|
|
2062
2595
|
const mergeIntoExisting = Boolean(options.filter);
|
|
2063
|
-
await (0,
|
|
2064
|
-
await (0,
|
|
2596
|
+
await (0, import_promises10.mkdir)(targetDir, { recursive: true });
|
|
2597
|
+
await (0, import_promises10.cp)(templateDir, targetDir, {
|
|
2065
2598
|
recursive: true,
|
|
2066
2599
|
force: true,
|
|
2067
2600
|
errorOnExist: false,
|
|
@@ -2089,9 +2622,9 @@ async function ensureArtifacts(targetDir, projectName) {
|
|
|
2089
2622
|
}
|
|
2090
2623
|
}
|
|
2091
2624
|
async function readTemplateManifest(templateDir) {
|
|
2092
|
-
const manifestPath =
|
|
2625
|
+
const manifestPath = import_node_path14.default.join(templateDir, "caatinga.template.json");
|
|
2093
2626
|
try {
|
|
2094
|
-
const rawManifest = await (0,
|
|
2627
|
+
const rawManifest = await (0, import_promises10.readFile)(manifestPath, "utf8");
|
|
2095
2628
|
const manifest = TemplateManifestSchema.parse(JSON.parse(rawManifest));
|
|
2096
2629
|
const compatibilityIssue = getTemplateCompatibilityIssue(manifest);
|
|
2097
2630
|
if (compatibilityIssue) {
|
|
@@ -2124,51 +2657,57 @@ async function readTemplateManifest(templateDir) {
|
|
|
2124
2657
|
}
|
|
2125
2658
|
}
|
|
2126
2659
|
async function replaceTemplateVariables(dir, projectName) {
|
|
2127
|
-
const entries = await (0,
|
|
2660
|
+
const entries = await (0, import_promises10.readdir)(dir);
|
|
2128
2661
|
await Promise.all(
|
|
2129
2662
|
entries.map(async (entry) => {
|
|
2130
|
-
|
|
2131
|
-
|
|
2663
|
+
if (TEMPLATE_COPY_EXCLUDED_DIRS.has(entry)) {
|
|
2664
|
+
return;
|
|
2665
|
+
}
|
|
2666
|
+
const entryPath = import_node_path14.default.join(dir, entry);
|
|
2667
|
+
const entryStat = await (0, import_promises10.lstat)(entryPath);
|
|
2668
|
+
if (entryStat.isSymbolicLink()) {
|
|
2669
|
+
return;
|
|
2670
|
+
}
|
|
2132
2671
|
if (entryStat.isDirectory()) {
|
|
2133
2672
|
await replaceTemplateVariables(entryPath, projectName);
|
|
2134
2673
|
return;
|
|
2135
2674
|
}
|
|
2136
|
-
if (!isTextTemplateFile(entryPath)) {
|
|
2675
|
+
if (!entryStat.isFile() || !isTextTemplateFile(entryPath)) {
|
|
2137
2676
|
return;
|
|
2138
2677
|
}
|
|
2139
|
-
const content = await (0,
|
|
2140
|
-
await (0,
|
|
2678
|
+
const content = await (0, import_promises10.readFile)(entryPath, "utf8");
|
|
2679
|
+
await (0, import_promises10.writeFile)(entryPath, content.replaceAll("__PROJECT_NAME__", projectName), "utf8");
|
|
2141
2680
|
})
|
|
2142
2681
|
);
|
|
2143
2682
|
}
|
|
2144
2683
|
function shouldCopyTemplateEntry(templateDir, source, userFilter) {
|
|
2145
|
-
const relativePath =
|
|
2684
|
+
const relativePath = import_node_path14.default.relative(templateDir, source);
|
|
2146
2685
|
if (!relativePath || relativePath === ".") {
|
|
2147
2686
|
return true;
|
|
2148
2687
|
}
|
|
2149
|
-
const normalizedPath = relativePath.split(
|
|
2688
|
+
const normalizedPath = relativePath.split(import_node_path14.default.sep).join("/");
|
|
2150
2689
|
if (userFilter && !userFilter(normalizedPath)) {
|
|
2151
2690
|
return false;
|
|
2152
2691
|
}
|
|
2153
|
-
return !relativePath.split(
|
|
2692
|
+
return !relativePath.split(import_node_path14.default.sep).some((segment) => TEMPLATE_COPY_EXCLUDED_DIRS.has(segment));
|
|
2154
2693
|
}
|
|
2155
2694
|
function isTextTemplateFile(filePath) {
|
|
2156
2695
|
return [".json", ".md", ".rs", ".toml", ".ts", ".tsx", ".css", ".html"].includes(
|
|
2157
|
-
|
|
2696
|
+
import_node_path14.default.extname(filePath)
|
|
2158
2697
|
);
|
|
2159
2698
|
}
|
|
2160
2699
|
|
|
2161
2700
|
// src/scaffold/create-zk-project.ts
|
|
2162
|
-
var
|
|
2701
|
+
var import_promises11 = require("fs/promises");
|
|
2163
2702
|
var import_node_fs2 = require("fs");
|
|
2164
|
-
var
|
|
2703
|
+
var import_node_path15 = __toESM(require("path"), 1);
|
|
2165
2704
|
var import_node_url = require("url");
|
|
2166
2705
|
var import_meta3 = {};
|
|
2167
|
-
var moduleDir = typeof __dirname === "string" ? __dirname :
|
|
2706
|
+
var moduleDir = typeof __dirname === "string" ? __dirname : import_node_path15.default.dirname((0, import_node_url.fileURLToPath)(import_meta3.url));
|
|
2168
2707
|
function scaffoldRoot() {
|
|
2169
2708
|
const candidates = [
|
|
2170
|
-
|
|
2171
|
-
|
|
2709
|
+
import_node_path15.default.resolve(moduleDir, "../../scaffolds"),
|
|
2710
|
+
import_node_path15.default.resolve(moduleDir, "../scaffolds")
|
|
2172
2711
|
];
|
|
2173
2712
|
const found = candidates.find((candidate) => (0, import_node_fs2.existsSync)(candidate));
|
|
2174
2713
|
return found ?? candidates[0];
|
|
@@ -2259,39 +2798,39 @@ Replace \`circuits/main.circom\` with your circuit. Keep the entry point named \
|
|
|
2259
2798
|
`;
|
|
2260
2799
|
}
|
|
2261
2800
|
async function createZkProject(options) {
|
|
2262
|
-
const targetDir =
|
|
2801
|
+
const targetDir = import_node_path15.default.resolve(options.targetDir);
|
|
2263
2802
|
const force = options.force ?? false;
|
|
2264
2803
|
const projectFiles = options.projectFiles ?? true;
|
|
2265
|
-
await (0,
|
|
2804
|
+
await (0, import_promises11.mkdir)(targetDir, { recursive: true });
|
|
2266
2805
|
if (projectFiles) {
|
|
2267
2806
|
await Promise.all([
|
|
2268
|
-
(0,
|
|
2807
|
+
(0, import_promises11.writeFile)(import_node_path15.default.join(targetDir, "caatinga.config.ts"), configSource(options.projectName), {
|
|
2269
2808
|
encoding: "utf8",
|
|
2270
2809
|
flag: force ? "w" : "wx"
|
|
2271
2810
|
}),
|
|
2272
|
-
(0,
|
|
2811
|
+
(0, import_promises11.writeFile)(import_node_path15.default.join(targetDir, "package.json"), packageJsonSource(options.projectName), {
|
|
2273
2812
|
encoding: "utf8",
|
|
2274
2813
|
flag: force ? "w" : "wx"
|
|
2275
2814
|
}),
|
|
2276
|
-
(0,
|
|
2815
|
+
(0, import_promises11.writeFile)(import_node_path15.default.join(targetDir, ".gitignore"), "node_modules\n.artifacts\ntarget\n", {
|
|
2277
2816
|
encoding: "utf8",
|
|
2278
2817
|
flag: force ? "w" : "wx"
|
|
2279
2818
|
}),
|
|
2280
|
-
(0,
|
|
2819
|
+
(0, import_promises11.writeFile)(import_node_path15.default.join(targetDir, "README.md"), readmeSource(options.projectName), {
|
|
2281
2820
|
encoding: "utf8",
|
|
2282
2821
|
flag: force ? "w" : "wx"
|
|
2283
2822
|
})
|
|
2284
2823
|
]);
|
|
2285
2824
|
}
|
|
2286
|
-
await (0,
|
|
2287
|
-
await (0,
|
|
2825
|
+
await (0, import_promises11.mkdir)(import_node_path15.default.join(targetDir, "contracts"), { recursive: true });
|
|
2826
|
+
await (0, import_promises11.cp)(import_node_path15.default.join(scaffoldRoot(), "zk-circuit-stub"), import_node_path15.default.join(targetDir, "circuits"), {
|
|
2288
2827
|
recursive: true,
|
|
2289
2828
|
force,
|
|
2290
2829
|
errorOnExist: !force
|
|
2291
2830
|
});
|
|
2292
|
-
await (0,
|
|
2293
|
-
|
|
2294
|
-
|
|
2831
|
+
await (0, import_promises11.cp)(
|
|
2832
|
+
import_node_path15.default.join(scaffoldRoot(), "zk-verifier"),
|
|
2833
|
+
import_node_path15.default.join(targetDir, "contracts", "verifier"),
|
|
2295
2834
|
{
|
|
2296
2835
|
recursive: true,
|
|
2297
2836
|
force,
|
|
@@ -2308,16 +2847,16 @@ async function createZkProject(options) {
|
|
|
2308
2847
|
}
|
|
2309
2848
|
|
|
2310
2849
|
// src/scaffold/create-minimal-project.ts
|
|
2311
|
-
var
|
|
2850
|
+
var import_promises12 = require("fs/promises");
|
|
2312
2851
|
var import_node_fs3 = require("fs");
|
|
2313
|
-
var
|
|
2852
|
+
var import_node_path16 = __toESM(require("path"), 1);
|
|
2314
2853
|
var import_node_url2 = require("url");
|
|
2315
2854
|
var import_meta4 = {};
|
|
2316
|
-
var moduleDir2 = typeof __dirname === "string" ? __dirname :
|
|
2855
|
+
var moduleDir2 = typeof __dirname === "string" ? __dirname : import_node_path16.default.dirname((0, import_node_url2.fileURLToPath)(import_meta4.url));
|
|
2317
2856
|
function scaffoldRoot2() {
|
|
2318
2857
|
const candidates = [
|
|
2319
|
-
|
|
2320
|
-
|
|
2858
|
+
import_node_path16.default.resolve(moduleDir2, "../../scaffolds"),
|
|
2859
|
+
import_node_path16.default.resolve(moduleDir2, "../scaffolds")
|
|
2321
2860
|
];
|
|
2322
2861
|
const found = candidates.find((candidate) => (0, import_node_fs3.existsSync)(candidate));
|
|
2323
2862
|
return found ?? candidates[0];
|
|
@@ -2408,31 +2947,31 @@ Edit \`contracts/app/src/lib.rs\` to customize the contract. Add a frontend late
|
|
|
2408
2947
|
`;
|
|
2409
2948
|
}
|
|
2410
2949
|
async function createMinimalProject(options) {
|
|
2411
|
-
const targetDir =
|
|
2950
|
+
const targetDir = import_node_path16.default.resolve(options.targetDir);
|
|
2412
2951
|
const force = options.force ?? false;
|
|
2413
|
-
await (0,
|
|
2952
|
+
await (0, import_promises12.mkdir)(targetDir, { recursive: true });
|
|
2414
2953
|
await Promise.all([
|
|
2415
|
-
(0,
|
|
2954
|
+
(0, import_promises12.writeFile)(import_node_path16.default.join(targetDir, "caatinga.config.ts"), configSource2(options.projectName), {
|
|
2416
2955
|
encoding: "utf8",
|
|
2417
2956
|
flag: force ? "w" : "wx"
|
|
2418
2957
|
}),
|
|
2419
|
-
(0,
|
|
2958
|
+
(0, import_promises12.writeFile)(import_node_path16.default.join(targetDir, "package.json"), packageJsonSource2(options.projectName), {
|
|
2420
2959
|
encoding: "utf8",
|
|
2421
2960
|
flag: force ? "w" : "wx"
|
|
2422
2961
|
}),
|
|
2423
|
-
(0,
|
|
2962
|
+
(0, import_promises12.writeFile)(import_node_path16.default.join(targetDir, ".gitignore"), "node_modules\n.artifacts\ntarget\n", {
|
|
2424
2963
|
encoding: "utf8",
|
|
2425
2964
|
flag: force ? "w" : "wx"
|
|
2426
2965
|
}),
|
|
2427
|
-
(0,
|
|
2966
|
+
(0, import_promises12.writeFile)(import_node_path16.default.join(targetDir, "README.md"), readmeSource2(options.projectName), {
|
|
2428
2967
|
encoding: "utf8",
|
|
2429
2968
|
flag: force ? "w" : "wx"
|
|
2430
2969
|
})
|
|
2431
2970
|
]);
|
|
2432
|
-
await (0,
|
|
2433
|
-
await (0,
|
|
2434
|
-
|
|
2435
|
-
|
|
2971
|
+
await (0, import_promises12.mkdir)(import_node_path16.default.join(targetDir, "contracts"), { recursive: true });
|
|
2972
|
+
await (0, import_promises12.cp)(
|
|
2973
|
+
import_node_path16.default.join(scaffoldRoot2(), "soroban-contract-stub"),
|
|
2974
|
+
import_node_path16.default.join(targetDir, "contracts", "app"),
|
|
2436
2975
|
{
|
|
2437
2976
|
recursive: true,
|
|
2438
2977
|
force,
|
|
@@ -2447,37 +2986,25 @@ async function createMinimalProject(options) {
|
|
|
2447
2986
|
}
|
|
2448
2987
|
|
|
2449
2988
|
// src/ci/is-transient-testnet-smoke-failure.ts
|
|
2450
|
-
var NO_RETRY_CAATINGA_SUBSTRINGS = [
|
|
2451
|
-
"CAATINGA_UNSUPPORTED_CLI_VERSION",
|
|
2452
|
-
"CAATINGA_STELLAR_CLI_VERSION_PARSE_FAILED",
|
|
2453
|
-
"CAATINGA_STELLAR_CLI_NOT_FOUND",
|
|
2454
|
-
"CAATINGA_INVALID_CONFIG",
|
|
2455
|
-
"CAATINGA_CONFIG_NOT_FOUND"
|
|
2456
|
-
];
|
|
2457
|
-
var TRANSIENT_PATTERN = /timeout|i\/o timeout|econnreset|connection reset|503|502|429|rate limit|temporar|bad gateway|fetch failed|network error|unavailable/i;
|
|
2458
2989
|
function isTransientTestnetSmokeFailure(logText) {
|
|
2459
|
-
|
|
2460
|
-
return false;
|
|
2461
|
-
}
|
|
2462
|
-
for (const marker of NO_RETRY_CAATINGA_SUBSTRINGS) {
|
|
2463
|
-
if (logText.includes(marker)) {
|
|
2464
|
-
return false;
|
|
2465
|
-
}
|
|
2466
|
-
}
|
|
2467
|
-
return TRANSIENT_PATTERN.test(logText);
|
|
2990
|
+
return isTransientCommandFailure(logText);
|
|
2468
2991
|
}
|
|
2469
2992
|
// Annotate the CommonJS export names for ESM import in node:
|
|
2470
2993
|
0 && (module.exports = {
|
|
2471
2994
|
BINDING_MARKER_FILENAME,
|
|
2472
2995
|
BindingMarkerSchema,
|
|
2473
2996
|
CAATINGA_CORE_VERSION,
|
|
2997
|
+
CURRENT_ARTIFACTS_SCHEMA_VERSION,
|
|
2474
2998
|
CaatingaArtifactsSchema,
|
|
2475
2999
|
CaatingaConfigSchema,
|
|
2476
3000
|
CaatingaError,
|
|
2477
3001
|
CaatingaErrorCode,
|
|
3002
|
+
DEFAULT_CLI_SOURCE,
|
|
2478
3003
|
READ_CALL_FAILURE_REGEX,
|
|
2479
3004
|
STELLAR_CLI_LAST_TESTED_VERSION,
|
|
2480
3005
|
STELLAR_CLI_MIN_VERSION,
|
|
3006
|
+
STELLAR_SDK_LAST_TESTED_VERSION,
|
|
3007
|
+
STELLAR_SDK_MIN_VERSION,
|
|
2481
3008
|
TemplateManifestSchema,
|
|
2482
3009
|
WELL_KNOWN_NETWORKS,
|
|
2483
3010
|
buildContract,
|
|
@@ -2485,6 +3012,7 @@ function isTransientTestnetSmokeFailure(logText) {
|
|
|
2485
3012
|
buildReadCallHint,
|
|
2486
3013
|
checkBinary,
|
|
2487
3014
|
checkStellarCliVersion,
|
|
3015
|
+
checkStellarSdkVersion,
|
|
2488
3016
|
collectProjectStatus,
|
|
2489
3017
|
createInitialArtifacts,
|
|
2490
3018
|
createMinimalProject,
|
|
@@ -2493,20 +3021,27 @@ function isTransientTestnetSmokeFailure(logText) {
|
|
|
2493
3021
|
defineConfig,
|
|
2494
3022
|
deployContract,
|
|
2495
3023
|
deployContractGraph,
|
|
3024
|
+
describeCliSource,
|
|
3025
|
+
estimateDeployCost,
|
|
2496
3026
|
evaluateBindingFreshness,
|
|
2497
3027
|
evaluateBindingsFreshness,
|
|
2498
3028
|
evaluateStellarCliCompatibility,
|
|
3029
|
+
evaluateStellarSdkCompatibility,
|
|
2499
3030
|
formatCaatingaError,
|
|
2500
3031
|
generateBindings,
|
|
2501
3032
|
generateBindingsGraph,
|
|
3033
|
+
inspectContract,
|
|
2502
3034
|
invokeContract,
|
|
2503
3035
|
isCargoBinMissingFromPath,
|
|
2504
3036
|
isReadCallFailure,
|
|
2505
3037
|
isTransientTestnetSmokeFailure,
|
|
2506
3038
|
loadConfig,
|
|
3039
|
+
migrateArtifactsFile,
|
|
3040
|
+
migrateArtifactsToV2,
|
|
2507
3041
|
parseContractId,
|
|
2508
3042
|
parseInvokeTarget,
|
|
2509
3043
|
parseStellarCliVersion,
|
|
3044
|
+
parseStellarSdkVersion,
|
|
2510
3045
|
readArtifacts,
|
|
2511
3046
|
readBindingMarker,
|
|
2512
3047
|
readContract,
|
|
@@ -2516,6 +3051,8 @@ function isTransientTestnetSmokeFailure(logText) {
|
|
|
2516
3051
|
resolveDeployOrder,
|
|
2517
3052
|
resolveNetwork,
|
|
2518
3053
|
resolveSubprocessEnv,
|
|
3054
|
+
restoreArtifactFromHistory,
|
|
3055
|
+
rollbackContractArtifact,
|
|
2519
3056
|
runCommand,
|
|
2520
3057
|
toCaatingaError,
|
|
2521
3058
|
updateArtifact,
|