@caatinga/core 3.0.0 → 3.1.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/README.md +11 -11
- package/dist/{artifact.schema-CGCFfl0g.d.cts → artifact.schema-D4r8dyYK.d.cts} +1 -1
- package/dist/{artifact.schema-CGCFfl0g.d.ts → artifact.schema-D4r8dyYK.d.ts} +1 -1
- package/dist/browser.d.cts +1 -1
- package/dist/browser.d.ts +1 -1
- package/dist/index.cjs +228 -156
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +228 -156
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -53,19 +53,19 @@ export default defineConfig({
|
|
|
53
53
|
contracts: {
|
|
54
54
|
counter: {
|
|
55
55
|
path: "./contracts/counter",
|
|
56
|
-
wasm: "./contracts/counter/target/wasm32v1-none/release/counter.wasm"
|
|
57
|
-
}
|
|
56
|
+
wasm: "./contracts/counter/target/wasm32v1-none/release/counter.wasm",
|
|
57
|
+
},
|
|
58
58
|
},
|
|
59
59
|
networks: {
|
|
60
60
|
testnet: {
|
|
61
61
|
rpcUrl: "https://soroban-testnet.stellar.org",
|
|
62
|
-
networkPassphrase: "Test SDF Network ; September 2015"
|
|
63
|
-
}
|
|
62
|
+
networkPassphrase: "Test SDF Network ; September 2015",
|
|
63
|
+
},
|
|
64
64
|
},
|
|
65
65
|
frontend: {
|
|
66
66
|
framework: "vite-react",
|
|
67
|
-
bindingsOutput: "./contracts/generated"
|
|
68
|
-
}
|
|
67
|
+
bindingsOutput: "./contracts/generated",
|
|
68
|
+
},
|
|
69
69
|
});
|
|
70
70
|
```
|
|
71
71
|
|
|
@@ -73,11 +73,11 @@ Multi-contract projects may declare `dependsOn` and `${contracts.<name>.contract
|
|
|
73
73
|
|
|
74
74
|
## Consumer guidance
|
|
75
75
|
|
|
76
|
-
| Goal
|
|
77
|
-
|
|
|
78
|
-
| End-user CLI workflow
|
|
79
|
-
| Browser / Node client over generated bindings
|
|
80
|
-
| `caatinga.config.ts` in a Caatinga project
|
|
76
|
+
| Goal | Package |
|
|
77
|
+
| ------------------------------------------------------------------------ | --------------------------------------------------- |
|
|
78
|
+
| End-user CLI workflow | `@caatinga/cli` |
|
|
79
|
+
| Browser / Node client over generated bindings | `@caatinga/client` |
|
|
80
|
+
| `caatinga.config.ts` in a Caatinga project | `defineConfig` from `@caatinga/core` |
|
|
81
81
|
| Custom tooling on deploy graphs, artifacts, or Stellar CLI orchestration | `@caatinga/core` (advanced; track releases closely) |
|
|
82
82
|
|
|
83
83
|
## Error codes
|
|
@@ -52,7 +52,7 @@ declare const CaatingaErrorCode: {
|
|
|
52
52
|
readonly DOCTOR_PARTIAL_DEPLOY: "CAATINGA_DOCTOR_PARTIAL_DEPLOY";
|
|
53
53
|
readonly MULTI_AUTH_REQUIRED: "CAATINGA_MULTI_AUTH_REQUIRED";
|
|
54
54
|
};
|
|
55
|
-
type CaatingaErrorCodeValue = typeof CaatingaErrorCode[keyof typeof CaatingaErrorCode];
|
|
55
|
+
type CaatingaErrorCodeValue = (typeof CaatingaErrorCode)[keyof typeof CaatingaErrorCode];
|
|
56
56
|
|
|
57
57
|
declare class CaatingaError extends Error {
|
|
58
58
|
readonly code: CaatingaErrorCodeValue;
|
|
@@ -52,7 +52,7 @@ declare const CaatingaErrorCode: {
|
|
|
52
52
|
readonly DOCTOR_PARTIAL_DEPLOY: "CAATINGA_DOCTOR_PARTIAL_DEPLOY";
|
|
53
53
|
readonly MULTI_AUTH_REQUIRED: "CAATINGA_MULTI_AUTH_REQUIRED";
|
|
54
54
|
};
|
|
55
|
-
type CaatingaErrorCodeValue = typeof CaatingaErrorCode[keyof typeof CaatingaErrorCode];
|
|
55
|
+
type CaatingaErrorCodeValue = (typeof CaatingaErrorCode)[keyof typeof CaatingaErrorCode];
|
|
56
56
|
|
|
57
57
|
declare class CaatingaError extends Error {
|
|
58
58
|
readonly code: CaatingaErrorCodeValue;
|
package/dist/browser.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { C as CaatingaArtifacts, a as CaatingaError, b as CaatingaErrorCode, c as ContractArtifact, f as formatCaatingaError, t as toCaatingaError } from './artifact.schema-
|
|
1
|
+
export { C as CaatingaArtifacts, a as CaatingaError, b as CaatingaErrorCode, c as ContractArtifact, f as formatCaatingaError, t as toCaatingaError } from './artifact.schema-D4r8dyYK.cjs';
|
|
2
2
|
import 'zod';
|
|
3
3
|
|
|
4
4
|
declare function assertSorobanSymbol(value: string, paramName?: string): void;
|
package/dist/browser.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { C as CaatingaArtifacts, a as CaatingaError, b as CaatingaErrorCode, c as ContractArtifact, f as formatCaatingaError, t as toCaatingaError } from './artifact.schema-
|
|
1
|
+
export { C as CaatingaArtifacts, a as CaatingaError, b as CaatingaErrorCode, c as ContractArtifact, f as formatCaatingaError, t as toCaatingaError } from './artifact.schema-D4r8dyYK.js';
|
|
2
2
|
import 'zod';
|
|
3
3
|
|
|
4
4
|
declare function assertSorobanSymbol(value: string, paramName?: string): void;
|
package/dist/index.cjs
CHANGED
|
@@ -211,9 +211,7 @@ function formatCause(cause) {
|
|
|
211
211
|
// src/version.ts
|
|
212
212
|
var import_node_module = require("module");
|
|
213
213
|
var import_meta = {};
|
|
214
|
-
var require2 = (0, import_node_module.createRequire)(
|
|
215
|
-
typeof __filename === "string" ? __filename : import_meta.url
|
|
216
|
-
);
|
|
214
|
+
var require2 = (0, import_node_module.createRequire)(typeof __filename === "string" ? __filename : import_meta.url);
|
|
217
215
|
var CAATINGA_CORE_VERSION = require2("../package.json").version;
|
|
218
216
|
|
|
219
217
|
// src/config/config.schema.ts
|
|
@@ -861,12 +859,7 @@ function matchesWellKnownNetwork(name, config) {
|
|
|
861
859
|
return known.rpcUrl === config.rpcUrl && known.networkPassphrase === config.networkPassphrase;
|
|
862
860
|
}
|
|
863
861
|
function buildRpcNetworkArgs(config) {
|
|
864
|
-
return [
|
|
865
|
-
"--rpc-url",
|
|
866
|
-
config.rpcUrl,
|
|
867
|
-
"--network-passphrase",
|
|
868
|
-
config.networkPassphrase
|
|
869
|
-
];
|
|
862
|
+
return ["--rpc-url", config.rpcUrl, "--network-passphrase", config.networkPassphrase];
|
|
870
863
|
}
|
|
871
864
|
function buildStellarNetworkArgsFromConfig(config) {
|
|
872
865
|
for (const [name, known] of Object.entries(WELL_KNOWN_NETWORKS)) {
|
|
@@ -920,19 +913,23 @@ async function fetchCreateContractSalt(horizonUrl, transactionHash, fetchImpl =
|
|
|
920
913
|
}
|
|
921
914
|
async function resolveContractIdFromDeploySalt(options) {
|
|
922
915
|
const saltHex = decimalSaltToHex(options.salt);
|
|
923
|
-
const result = await runCommand(
|
|
924
|
-
"
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
916
|
+
const result = await runCommand(
|
|
917
|
+
"stellar",
|
|
918
|
+
[
|
|
919
|
+
"contract",
|
|
920
|
+
"id",
|
|
921
|
+
"wasm",
|
|
922
|
+
"--salt",
|
|
923
|
+
saltHex,
|
|
924
|
+
"--source-account",
|
|
925
|
+
options.source,
|
|
926
|
+
...buildStellarNetworkArgsFromConfig(options.network)
|
|
927
|
+
],
|
|
928
|
+
{
|
|
929
|
+
cwd: options.cwd,
|
|
930
|
+
skipStellarVersionCheck: true
|
|
931
|
+
}
|
|
932
|
+
);
|
|
936
933
|
return parseContractId(result.all || `${result.stdout}
|
|
937
934
|
${result.stderr}`);
|
|
938
935
|
}
|
|
@@ -1080,8 +1077,12 @@ function buildAlternateWasmCandidates(configuredWasmPath, options) {
|
|
|
1080
1077
|
addCandidate(import_node_path8.default.join(cargoTargetDir, LEGACY_RUST_WASM_TARGET, "release", fileName));
|
|
1081
1078
|
}
|
|
1082
1079
|
if (options?.sourcePath) {
|
|
1083
|
-
addCandidate(
|
|
1084
|
-
|
|
1080
|
+
addCandidate(
|
|
1081
|
+
import_node_path8.default.join(options.sourcePath, "target", CURRENT_RUST_WASM_TARGET, "release", fileName)
|
|
1082
|
+
);
|
|
1083
|
+
addCandidate(
|
|
1084
|
+
import_node_path8.default.join(options.sourcePath, "target", LEGACY_RUST_WASM_TARGET, "release", fileName)
|
|
1085
|
+
);
|
|
1085
1086
|
}
|
|
1086
1087
|
return candidates;
|
|
1087
1088
|
}
|
|
@@ -1496,17 +1497,21 @@ function toSkippedContract(name, contractId, network) {
|
|
|
1496
1497
|
// src/contracts/verify-dependency-contract.ts
|
|
1497
1498
|
async function verifyDependencyContract(options) {
|
|
1498
1499
|
try {
|
|
1499
|
-
await runCommand(
|
|
1500
|
-
"
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1500
|
+
await runCommand(
|
|
1501
|
+
"stellar",
|
|
1502
|
+
[
|
|
1503
|
+
"contract",
|
|
1504
|
+
"info",
|
|
1505
|
+
"interface",
|
|
1506
|
+
"--contract-id",
|
|
1507
|
+
options.contractId,
|
|
1508
|
+
...buildStellarNetworkArgs(options.network)
|
|
1509
|
+
],
|
|
1510
|
+
{
|
|
1511
|
+
cwd: options.cwd,
|
|
1512
|
+
failureCode: CaatingaErrorCode.DEPENDENCY_CONTRACT_NOT_FOUND
|
|
1513
|
+
}
|
|
1514
|
+
);
|
|
1510
1515
|
} catch (error) {
|
|
1511
1516
|
if (error instanceof CaatingaError && error.code === CaatingaErrorCode.DEPENDENCY_CONTRACT_NOT_FOUND) {
|
|
1512
1517
|
throw new CaatingaError(
|
|
@@ -1568,9 +1573,7 @@ async function deployContractGraph(options) {
|
|
|
1568
1573
|
network: network.name
|
|
1569
1574
|
});
|
|
1570
1575
|
if (existing?.contractId && !options.force) {
|
|
1571
|
-
skippedContracts.push(
|
|
1572
|
-
toSkippedContract(contractName, existing.contractId, network.name)
|
|
1573
|
-
);
|
|
1576
|
+
skippedContracts.push(toSkippedContract(contractName, existing.contractId, network.name));
|
|
1574
1577
|
continue;
|
|
1575
1578
|
}
|
|
1576
1579
|
const result = await deployContract({
|
|
@@ -1591,9 +1594,7 @@ async function deployContractGraph(options) {
|
|
|
1591
1594
|
});
|
|
1592
1595
|
}
|
|
1593
1596
|
if (result.skipped) {
|
|
1594
|
-
skippedContracts.push(
|
|
1595
|
-
toSkippedContract(contractName, result.contractId, network.name)
|
|
1596
|
-
);
|
|
1597
|
+
skippedContracts.push(toSkippedContract(contractName, result.contractId, network.name));
|
|
1597
1598
|
} else {
|
|
1598
1599
|
deployedContracts.push({ name: contractName, contractId: result.contractId });
|
|
1599
1600
|
}
|
|
@@ -1654,22 +1655,26 @@ async function generateBindings(options) {
|
|
|
1654
1655
|
}
|
|
1655
1656
|
const outputDir = import_node_path10.default.resolve(cwd, options.config.frontend.bindingsOutput, options.contractName);
|
|
1656
1657
|
await (0, import_promises7.mkdir)(outputDir, { recursive: true });
|
|
1657
|
-
const result = await runCommand(
|
|
1658
|
-
"
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1658
|
+
const result = await runCommand(
|
|
1659
|
+
"npx",
|
|
1660
|
+
[
|
|
1661
|
+
"--yes",
|
|
1662
|
+
"@stellar/stellar-sdk",
|
|
1663
|
+
"generate",
|
|
1664
|
+
"--contract-id",
|
|
1665
|
+
contractArtifact.contractId,
|
|
1666
|
+
"--output-dir",
|
|
1667
|
+
outputDir,
|
|
1668
|
+
"--contract-name",
|
|
1669
|
+
options.contractName,
|
|
1670
|
+
"--overwrite",
|
|
1671
|
+
...buildGenerateNetworkArgs(network)
|
|
1672
|
+
],
|
|
1673
|
+
{
|
|
1674
|
+
cwd,
|
|
1675
|
+
failureCode: CaatingaErrorCode.BINDINGS_FAILED
|
|
1676
|
+
}
|
|
1677
|
+
);
|
|
1673
1678
|
const legacyStubRemoved = await removeLegacyBindingStub(
|
|
1674
1679
|
cwd,
|
|
1675
1680
|
options.config.frontend.bindingsOutput,
|
|
@@ -1781,21 +1786,25 @@ async function invokeContract(options) {
|
|
|
1781
1786
|
await checkBinary("stellar", "Install Stellar CLI before running caatinga invoke.");
|
|
1782
1787
|
let result;
|
|
1783
1788
|
try {
|
|
1784
|
-
result = await runCommand(
|
|
1785
|
-
"
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1789
|
+
result = await runCommand(
|
|
1790
|
+
"stellar",
|
|
1791
|
+
[
|
|
1792
|
+
"contract",
|
|
1793
|
+
"invoke",
|
|
1794
|
+
"--id",
|
|
1795
|
+
contractArtifact.contractId,
|
|
1796
|
+
"--source-account",
|
|
1797
|
+
source,
|
|
1798
|
+
...buildStellarNetworkArgs(network),
|
|
1799
|
+
"--",
|
|
1800
|
+
target.method,
|
|
1801
|
+
...options.args ?? []
|
|
1802
|
+
],
|
|
1803
|
+
{
|
|
1804
|
+
cwd,
|
|
1805
|
+
failureCode: CaatingaErrorCode.INVOKE_FAILED
|
|
1806
|
+
}
|
|
1807
|
+
);
|
|
1799
1808
|
} catch (error) {
|
|
1800
1809
|
if (error instanceof CaatingaError && error.code === CaatingaErrorCode.INVOKE_FAILED && isReadCallFailure(error)) {
|
|
1801
1810
|
throw new CaatingaError(
|
|
@@ -1940,12 +1949,7 @@ function formatTemplateCompatibilityHint(issue) {
|
|
|
1940
1949
|
}
|
|
1941
1950
|
|
|
1942
1951
|
// src/templates/create-project-from-template.ts
|
|
1943
|
-
var TEMPLATE_COPY_EXCLUDED_DIRS = /* @__PURE__ */ new Set([
|
|
1944
|
-
"target",
|
|
1945
|
-
"test_snapshots",
|
|
1946
|
-
"node_modules",
|
|
1947
|
-
".git"
|
|
1948
|
-
]);
|
|
1952
|
+
var TEMPLATE_COPY_EXCLUDED_DIRS = /* @__PURE__ */ new Set(["target", "test_snapshots", "node_modules", ".git"]);
|
|
1949
1953
|
async function createProjectFromTemplate(options) {
|
|
1950
1954
|
const targetDir = import_node_path11.default.resolve(options.targetDir);
|
|
1951
1955
|
const templateDir = import_node_path11.default.resolve(options.templateDir);
|
|
@@ -1963,8 +1967,8 @@ async function createProjectFromTemplate(options) {
|
|
|
1963
1967
|
await (0, import_promises8.mkdir)(targetDir, { recursive: true });
|
|
1964
1968
|
await (0, import_promises8.cp)(templateDir, targetDir, {
|
|
1965
1969
|
recursive: true,
|
|
1966
|
-
force:
|
|
1967
|
-
errorOnExist:
|
|
1970
|
+
force: true,
|
|
1971
|
+
errorOnExist: false,
|
|
1968
1972
|
filter: (source) => shouldCopyTemplateEntry(templateDir, source, options.filter)
|
|
1969
1973
|
});
|
|
1970
1974
|
await replaceTemplateVariables(targetDir, options.projectName);
|
|
@@ -1979,7 +1983,10 @@ async function ensureArtifacts(targetDir, projectName) {
|
|
|
1979
1983
|
await writeArtifacts({ ...artifacts, project: projectName }, targetDir);
|
|
1980
1984
|
} catch (error) {
|
|
1981
1985
|
if (error instanceof CaatingaError && error.code === CaatingaErrorCode.ARTIFACT_NOT_FOUND) {
|
|
1982
|
-
await writeArtifacts(
|
|
1986
|
+
await writeArtifacts(
|
|
1987
|
+
createInitialArtifacts(projectName, { networks: ["testnet"] }),
|
|
1988
|
+
targetDir
|
|
1989
|
+
);
|
|
1983
1990
|
return;
|
|
1984
1991
|
}
|
|
1985
1992
|
throw error;
|
|
@@ -2022,19 +2029,21 @@ async function readTemplateManifest(templateDir) {
|
|
|
2022
2029
|
}
|
|
2023
2030
|
async function replaceTemplateVariables(dir, projectName) {
|
|
2024
2031
|
const entries = await (0, import_promises8.readdir)(dir);
|
|
2025
|
-
await Promise.all(
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2032
|
+
await Promise.all(
|
|
2033
|
+
entries.map(async (entry) => {
|
|
2034
|
+
const entryPath = import_node_path11.default.join(dir, entry);
|
|
2035
|
+
const entryStat = await (0, import_promises8.stat)(entryPath);
|
|
2036
|
+
if (entryStat.isDirectory()) {
|
|
2037
|
+
await replaceTemplateVariables(entryPath, projectName);
|
|
2038
|
+
return;
|
|
2039
|
+
}
|
|
2040
|
+
if (!isTextTemplateFile(entryPath)) {
|
|
2041
|
+
return;
|
|
2042
|
+
}
|
|
2043
|
+
const content = await (0, import_promises8.readFile)(entryPath, "utf8");
|
|
2044
|
+
await (0, import_promises8.writeFile)(entryPath, content.replaceAll("__PROJECT_NAME__", projectName), "utf8");
|
|
2045
|
+
})
|
|
2046
|
+
);
|
|
2038
2047
|
}
|
|
2039
2048
|
function shouldCopyTemplateEntry(templateDir, source, userFilter) {
|
|
2040
2049
|
const relativePath = import_node_path11.default.relative(templateDir, source);
|
|
@@ -2048,16 +2057,9 @@ function shouldCopyTemplateEntry(templateDir, source, userFilter) {
|
|
|
2048
2057
|
return !relativePath.split(import_node_path11.default.sep).some((segment) => TEMPLATE_COPY_EXCLUDED_DIRS.has(segment));
|
|
2049
2058
|
}
|
|
2050
2059
|
function isTextTemplateFile(filePath) {
|
|
2051
|
-
return [
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
".rs",
|
|
2055
|
-
".toml",
|
|
2056
|
-
".ts",
|
|
2057
|
-
".tsx",
|
|
2058
|
-
".css",
|
|
2059
|
-
".html"
|
|
2060
|
-
].includes(import_node_path11.default.extname(filePath));
|
|
2060
|
+
return [".json", ".md", ".rs", ".toml", ".ts", ".tsx", ".css", ".html"].includes(
|
|
2061
|
+
import_node_path11.default.extname(filePath)
|
|
2062
|
+
);
|
|
2061
2063
|
}
|
|
2062
2064
|
|
|
2063
2065
|
// src/scaffold/create-zk-project.ts
|
|
@@ -2107,23 +2109,28 @@ export default defineConfig({
|
|
|
2107
2109
|
`;
|
|
2108
2110
|
}
|
|
2109
2111
|
function packageJsonSource(projectName) {
|
|
2110
|
-
return `${JSON.stringify(
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2112
|
+
return `${JSON.stringify(
|
|
2113
|
+
{
|
|
2114
|
+
name: projectName,
|
|
2115
|
+
version: "0.1.0",
|
|
2116
|
+
private: true,
|
|
2117
|
+
type: "module",
|
|
2118
|
+
scripts: {
|
|
2119
|
+
"zk:build": "caatinga zk build main",
|
|
2120
|
+
"zk:prove": "caatinga zk prove main",
|
|
2121
|
+
build: "caatinga build verifier",
|
|
2122
|
+
deploy: "caatinga deploy verifier --network testnet --source ${CAATINGA_SOURCE:-alice}",
|
|
2123
|
+
doctor: "caatinga doctor --network testnet",
|
|
2124
|
+
test: "cargo test --manifest-path contracts/verifier/Cargo.toml"
|
|
2125
|
+
},
|
|
2126
|
+
devDependencies: {
|
|
2127
|
+
"@caatinga/cli": `^${CAATINGA_CORE_VERSION}`,
|
|
2128
|
+
"@caatinga/core": `^${CAATINGA_CORE_VERSION}`
|
|
2129
|
+
}
|
|
2121
2130
|
},
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
}
|
|
2126
|
-
}, null, 2)}
|
|
2131
|
+
null,
|
|
2132
|
+
2
|
|
2133
|
+
)}
|
|
2127
2134
|
`;
|
|
2128
2135
|
}
|
|
2129
2136
|
function readmeSource(projectName) {
|
|
@@ -2135,12 +2142,23 @@ Minimal Caatinga ZK project.
|
|
|
2135
2142
|
|
|
2136
2143
|
\`\`\`bash
|
|
2137
2144
|
npm install
|
|
2145
|
+
npm test
|
|
2138
2146
|
npx caatinga zk build main
|
|
2139
2147
|
npx caatinga build verifier
|
|
2140
2148
|
npx caatinga deploy verifier --network testnet --source <identity>
|
|
2141
2149
|
npx caatinga zk prove main
|
|
2142
2150
|
\`\`\`
|
|
2143
2151
|
|
|
2152
|
+
## Tests
|
|
2153
|
+
|
|
2154
|
+
Run the Rust verifier contract tests from the project root:
|
|
2155
|
+
|
|
2156
|
+
\`\`\`bash
|
|
2157
|
+
npm test
|
|
2158
|
+
# or directly:
|
|
2159
|
+
cargo test --manifest-path contracts/verifier/Cargo.toml
|
|
2160
|
+
\`\`\`
|
|
2161
|
+
|
|
2144
2162
|
Replace \`circuits/main.circom\` with your circuit. Keep the entry point named \`main\`.
|
|
2145
2163
|
`;
|
|
2146
2164
|
}
|
|
@@ -2151,10 +2169,22 @@ async function createZkProject(options) {
|
|
|
2151
2169
|
await (0, import_promises9.mkdir)(targetDir, { recursive: true });
|
|
2152
2170
|
if (projectFiles) {
|
|
2153
2171
|
await Promise.all([
|
|
2154
|
-
(0, import_promises9.writeFile)(import_node_path12.default.join(targetDir, "caatinga.config.ts"), configSource(options.projectName), {
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2172
|
+
(0, import_promises9.writeFile)(import_node_path12.default.join(targetDir, "caatinga.config.ts"), configSource(options.projectName), {
|
|
2173
|
+
encoding: "utf8",
|
|
2174
|
+
flag: force ? "w" : "wx"
|
|
2175
|
+
}),
|
|
2176
|
+
(0, import_promises9.writeFile)(import_node_path12.default.join(targetDir, "package.json"), packageJsonSource(options.projectName), {
|
|
2177
|
+
encoding: "utf8",
|
|
2178
|
+
flag: force ? "w" : "wx"
|
|
2179
|
+
}),
|
|
2180
|
+
(0, import_promises9.writeFile)(import_node_path12.default.join(targetDir, ".gitignore"), "node_modules\n.artifacts\ntarget\n", {
|
|
2181
|
+
encoding: "utf8",
|
|
2182
|
+
flag: force ? "w" : "wx"
|
|
2183
|
+
}),
|
|
2184
|
+
(0, import_promises9.writeFile)(import_node_path12.default.join(targetDir, "README.md"), readmeSource(options.projectName), {
|
|
2185
|
+
encoding: "utf8",
|
|
2186
|
+
flag: force ? "w" : "wx"
|
|
2187
|
+
})
|
|
2158
2188
|
]);
|
|
2159
2189
|
}
|
|
2160
2190
|
await (0, import_promises9.mkdir)(import_node_path12.default.join(targetDir, "contracts"), { recursive: true });
|
|
@@ -2163,13 +2193,20 @@ async function createZkProject(options) {
|
|
|
2163
2193
|
force,
|
|
2164
2194
|
errorOnExist: !force
|
|
2165
2195
|
});
|
|
2166
|
-
await (0, import_promises9.cp)(
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2196
|
+
await (0, import_promises9.cp)(
|
|
2197
|
+
import_node_path12.default.join(scaffoldRoot(), "zk-verifier"),
|
|
2198
|
+
import_node_path12.default.join(targetDir, "contracts", "verifier"),
|
|
2199
|
+
{
|
|
2200
|
+
recursive: true,
|
|
2201
|
+
force,
|
|
2202
|
+
errorOnExist: !force
|
|
2203
|
+
}
|
|
2204
|
+
);
|
|
2171
2205
|
if (projectFiles) {
|
|
2172
|
-
await writeArtifacts(
|
|
2206
|
+
await writeArtifacts(
|
|
2207
|
+
createInitialArtifacts(options.projectName, { networks: ["testnet"] }),
|
|
2208
|
+
targetDir
|
|
2209
|
+
);
|
|
2173
2210
|
}
|
|
2174
2211
|
return { targetDir };
|
|
2175
2212
|
}
|
|
@@ -2211,23 +2248,28 @@ export default defineConfig({
|
|
|
2211
2248
|
`;
|
|
2212
2249
|
}
|
|
2213
2250
|
function packageJsonSource2(projectName) {
|
|
2214
|
-
return `${JSON.stringify(
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2251
|
+
return `${JSON.stringify(
|
|
2252
|
+
{
|
|
2253
|
+
name: projectName,
|
|
2254
|
+
version: "0.1.0",
|
|
2255
|
+
private: true,
|
|
2256
|
+
type: "module",
|
|
2257
|
+
scripts: {
|
|
2258
|
+
build: "caatinga build app",
|
|
2259
|
+
deploy: "caatinga deploy app --network testnet --source ${CAATINGA_SOURCE:-alice}",
|
|
2260
|
+
doctor: "caatinga doctor --network testnet",
|
|
2261
|
+
test: "cargo test --manifest-path contracts/app/Cargo.toml",
|
|
2262
|
+
"read:hello": "caatinga read app.hello --network testnet --source ${CAATINGA_SOURCE:-alice}",
|
|
2263
|
+
"read:version": "caatinga read app.version --network testnet --source ${CAATINGA_SOURCE:-alice}"
|
|
2264
|
+
},
|
|
2265
|
+
devDependencies: {
|
|
2266
|
+
"@caatinga/cli": `^${CAATINGA_CORE_VERSION}`,
|
|
2267
|
+
"@caatinga/core": `^${CAATINGA_CORE_VERSION}`
|
|
2268
|
+
}
|
|
2225
2269
|
},
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
}
|
|
2230
|
-
}, null, 2)}
|
|
2270
|
+
null,
|
|
2271
|
+
2
|
|
2272
|
+
)}
|
|
2231
2273
|
`;
|
|
2232
2274
|
}
|
|
2233
2275
|
function readmeSource2(projectName) {
|
|
@@ -2239,6 +2281,7 @@ Minimal Caatinga project with a Soroban contract stub (no frontend template).
|
|
|
2239
2281
|
|
|
2240
2282
|
\`\`\`bash
|
|
2241
2283
|
npm install
|
|
2284
|
+
npm test
|
|
2242
2285
|
npx caatinga doctor
|
|
2243
2286
|
npx caatinga build app
|
|
2244
2287
|
npx caatinga deploy app --network testnet --source <identity>
|
|
@@ -2246,6 +2289,16 @@ npx caatinga read app.version --network testnet
|
|
|
2246
2289
|
npx caatinga read app.hello --network testnet
|
|
2247
2290
|
\`\`\`
|
|
2248
2291
|
|
|
2292
|
+
## Tests
|
|
2293
|
+
|
|
2294
|
+
Run the Rust contract tests from the project root:
|
|
2295
|
+
|
|
2296
|
+
\`\`\`bash
|
|
2297
|
+
npm test
|
|
2298
|
+
# or directly:
|
|
2299
|
+
cargo test --manifest-path contracts/app/Cargo.toml
|
|
2300
|
+
\`\`\`
|
|
2301
|
+
|
|
2249
2302
|
## Contract
|
|
2250
2303
|
|
|
2251
2304
|
- \`hello()\` \u2014 read-only; returns Soroban Symbol \`hello\`
|
|
@@ -2263,18 +2316,37 @@ async function createMinimalProject(options) {
|
|
|
2263
2316
|
const force = options.force ?? false;
|
|
2264
2317
|
await (0, import_promises10.mkdir)(targetDir, { recursive: true });
|
|
2265
2318
|
await Promise.all([
|
|
2266
|
-
(0, import_promises10.writeFile)(import_node_path13.default.join(targetDir, "caatinga.config.ts"), configSource2(options.projectName), {
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2319
|
+
(0, import_promises10.writeFile)(import_node_path13.default.join(targetDir, "caatinga.config.ts"), configSource2(options.projectName), {
|
|
2320
|
+
encoding: "utf8",
|
|
2321
|
+
flag: force ? "w" : "wx"
|
|
2322
|
+
}),
|
|
2323
|
+
(0, import_promises10.writeFile)(import_node_path13.default.join(targetDir, "package.json"), packageJsonSource2(options.projectName), {
|
|
2324
|
+
encoding: "utf8",
|
|
2325
|
+
flag: force ? "w" : "wx"
|
|
2326
|
+
}),
|
|
2327
|
+
(0, import_promises10.writeFile)(import_node_path13.default.join(targetDir, ".gitignore"), "node_modules\n.artifacts\ntarget\n", {
|
|
2328
|
+
encoding: "utf8",
|
|
2329
|
+
flag: force ? "w" : "wx"
|
|
2330
|
+
}),
|
|
2331
|
+
(0, import_promises10.writeFile)(import_node_path13.default.join(targetDir, "README.md"), readmeSource2(options.projectName), {
|
|
2332
|
+
encoding: "utf8",
|
|
2333
|
+
flag: force ? "w" : "wx"
|
|
2334
|
+
})
|
|
2270
2335
|
]);
|
|
2271
2336
|
await (0, import_promises10.mkdir)(import_node_path13.default.join(targetDir, "contracts"), { recursive: true });
|
|
2272
|
-
await (0, import_promises10.cp)(
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
|
|
2337
|
+
await (0, import_promises10.cp)(
|
|
2338
|
+
import_node_path13.default.join(scaffoldRoot2(), "soroban-contract-stub"),
|
|
2339
|
+
import_node_path13.default.join(targetDir, "contracts", "app"),
|
|
2340
|
+
{
|
|
2341
|
+
recursive: true,
|
|
2342
|
+
force,
|
|
2343
|
+
errorOnExist: !force
|
|
2344
|
+
}
|
|
2345
|
+
);
|
|
2346
|
+
await writeArtifacts(
|
|
2347
|
+
createInitialArtifacts(options.projectName, { networks: ["testnet"] }),
|
|
2348
|
+
targetDir
|
|
2349
|
+
);
|
|
2278
2350
|
return { targetDir };
|
|
2279
2351
|
}
|
|
2280
2352
|
|
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { C as CaatingaArtifacts, c as ContractArtifact, d as CaatingaErrorCodeValue, a as CaatingaError } from './artifact.schema-
|
|
2
|
-
export { e as CaatingaArtifactsSchema, b as CaatingaErrorCode, f as formatCaatingaError, t as toCaatingaError } from './artifact.schema-
|
|
1
|
+
import { C as CaatingaArtifacts, c as ContractArtifact, d as CaatingaErrorCodeValue, a as CaatingaError } from './artifact.schema-D4r8dyYK.cjs';
|
|
2
|
+
export { e as CaatingaArtifactsSchema, b as CaatingaErrorCode, f as formatCaatingaError, t as toCaatingaError } from './artifact.schema-D4r8dyYK.cjs';
|
|
3
3
|
import { z } from 'zod';
|
|
4
4
|
|
|
5
5
|
declare const CAATINGA_CORE_VERSION: string;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { C as CaatingaArtifacts, c as ContractArtifact, d as CaatingaErrorCodeValue, a as CaatingaError } from './artifact.schema-
|
|
2
|
-
export { e as CaatingaArtifactsSchema, b as CaatingaErrorCode, f as formatCaatingaError, t as toCaatingaError } from './artifact.schema-
|
|
1
|
+
import { C as CaatingaArtifacts, c as ContractArtifact, d as CaatingaErrorCodeValue, a as CaatingaError } from './artifact.schema-D4r8dyYK.js';
|
|
2
|
+
export { e as CaatingaArtifactsSchema, b as CaatingaErrorCode, f as formatCaatingaError, t as toCaatingaError } from './artifact.schema-D4r8dyYK.js';
|
|
3
3
|
import { z } from 'zod';
|
|
4
4
|
|
|
5
5
|
declare const CAATINGA_CORE_VERSION: string;
|
package/dist/index.js
CHANGED
|
@@ -121,9 +121,7 @@ function formatCause(cause) {
|
|
|
121
121
|
|
|
122
122
|
// src/version.ts
|
|
123
123
|
import { createRequire } from "module";
|
|
124
|
-
var require2 = createRequire(
|
|
125
|
-
typeof __filename === "string" ? __filename : import.meta.url
|
|
126
|
-
);
|
|
124
|
+
var require2 = createRequire(typeof __filename === "string" ? __filename : import.meta.url);
|
|
127
125
|
var CAATINGA_CORE_VERSION = require2("../package.json").version;
|
|
128
126
|
|
|
129
127
|
// src/config/config.schema.ts
|
|
@@ -770,12 +768,7 @@ function matchesWellKnownNetwork(name, config) {
|
|
|
770
768
|
return known.rpcUrl === config.rpcUrl && known.networkPassphrase === config.networkPassphrase;
|
|
771
769
|
}
|
|
772
770
|
function buildRpcNetworkArgs(config) {
|
|
773
|
-
return [
|
|
774
|
-
"--rpc-url",
|
|
775
|
-
config.rpcUrl,
|
|
776
|
-
"--network-passphrase",
|
|
777
|
-
config.networkPassphrase
|
|
778
|
-
];
|
|
771
|
+
return ["--rpc-url", config.rpcUrl, "--network-passphrase", config.networkPassphrase];
|
|
779
772
|
}
|
|
780
773
|
function buildStellarNetworkArgsFromConfig(config) {
|
|
781
774
|
for (const [name, known] of Object.entries(WELL_KNOWN_NETWORKS)) {
|
|
@@ -829,19 +822,23 @@ async function fetchCreateContractSalt(horizonUrl, transactionHash, fetchImpl =
|
|
|
829
822
|
}
|
|
830
823
|
async function resolveContractIdFromDeploySalt(options) {
|
|
831
824
|
const saltHex = decimalSaltToHex(options.salt);
|
|
832
|
-
const result = await runCommand(
|
|
833
|
-
"
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
825
|
+
const result = await runCommand(
|
|
826
|
+
"stellar",
|
|
827
|
+
[
|
|
828
|
+
"contract",
|
|
829
|
+
"id",
|
|
830
|
+
"wasm",
|
|
831
|
+
"--salt",
|
|
832
|
+
saltHex,
|
|
833
|
+
"--source-account",
|
|
834
|
+
options.source,
|
|
835
|
+
...buildStellarNetworkArgsFromConfig(options.network)
|
|
836
|
+
],
|
|
837
|
+
{
|
|
838
|
+
cwd: options.cwd,
|
|
839
|
+
skipStellarVersionCheck: true
|
|
840
|
+
}
|
|
841
|
+
);
|
|
845
842
|
return parseContractId(result.all || `${result.stdout}
|
|
846
843
|
${result.stderr}`);
|
|
847
844
|
}
|
|
@@ -989,8 +986,12 @@ function buildAlternateWasmCandidates(configuredWasmPath, options) {
|
|
|
989
986
|
addCandidate(path8.join(cargoTargetDir, LEGACY_RUST_WASM_TARGET, "release", fileName));
|
|
990
987
|
}
|
|
991
988
|
if (options?.sourcePath) {
|
|
992
|
-
addCandidate(
|
|
993
|
-
|
|
989
|
+
addCandidate(
|
|
990
|
+
path8.join(options.sourcePath, "target", CURRENT_RUST_WASM_TARGET, "release", fileName)
|
|
991
|
+
);
|
|
992
|
+
addCandidate(
|
|
993
|
+
path8.join(options.sourcePath, "target", LEGACY_RUST_WASM_TARGET, "release", fileName)
|
|
994
|
+
);
|
|
994
995
|
}
|
|
995
996
|
return candidates;
|
|
996
997
|
}
|
|
@@ -1405,17 +1406,21 @@ function toSkippedContract(name, contractId, network) {
|
|
|
1405
1406
|
// src/contracts/verify-dependency-contract.ts
|
|
1406
1407
|
async function verifyDependencyContract(options) {
|
|
1407
1408
|
try {
|
|
1408
|
-
await runCommand(
|
|
1409
|
-
"
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1409
|
+
await runCommand(
|
|
1410
|
+
"stellar",
|
|
1411
|
+
[
|
|
1412
|
+
"contract",
|
|
1413
|
+
"info",
|
|
1414
|
+
"interface",
|
|
1415
|
+
"--contract-id",
|
|
1416
|
+
options.contractId,
|
|
1417
|
+
...buildStellarNetworkArgs(options.network)
|
|
1418
|
+
],
|
|
1419
|
+
{
|
|
1420
|
+
cwd: options.cwd,
|
|
1421
|
+
failureCode: CaatingaErrorCode.DEPENDENCY_CONTRACT_NOT_FOUND
|
|
1422
|
+
}
|
|
1423
|
+
);
|
|
1419
1424
|
} catch (error) {
|
|
1420
1425
|
if (error instanceof CaatingaError && error.code === CaatingaErrorCode.DEPENDENCY_CONTRACT_NOT_FOUND) {
|
|
1421
1426
|
throw new CaatingaError(
|
|
@@ -1477,9 +1482,7 @@ async function deployContractGraph(options) {
|
|
|
1477
1482
|
network: network.name
|
|
1478
1483
|
});
|
|
1479
1484
|
if (existing?.contractId && !options.force) {
|
|
1480
|
-
skippedContracts.push(
|
|
1481
|
-
toSkippedContract(contractName, existing.contractId, network.name)
|
|
1482
|
-
);
|
|
1485
|
+
skippedContracts.push(toSkippedContract(contractName, existing.contractId, network.name));
|
|
1483
1486
|
continue;
|
|
1484
1487
|
}
|
|
1485
1488
|
const result = await deployContract({
|
|
@@ -1500,9 +1503,7 @@ async function deployContractGraph(options) {
|
|
|
1500
1503
|
});
|
|
1501
1504
|
}
|
|
1502
1505
|
if (result.skipped) {
|
|
1503
|
-
skippedContracts.push(
|
|
1504
|
-
toSkippedContract(contractName, result.contractId, network.name)
|
|
1505
|
-
);
|
|
1506
|
+
skippedContracts.push(toSkippedContract(contractName, result.contractId, network.name));
|
|
1506
1507
|
} else {
|
|
1507
1508
|
deployedContracts.push({ name: contractName, contractId: result.contractId });
|
|
1508
1509
|
}
|
|
@@ -1563,22 +1564,26 @@ async function generateBindings(options) {
|
|
|
1563
1564
|
}
|
|
1564
1565
|
const outputDir = path10.resolve(cwd, options.config.frontend.bindingsOutput, options.contractName);
|
|
1565
1566
|
await mkdir2(outputDir, { recursive: true });
|
|
1566
|
-
const result = await runCommand(
|
|
1567
|
-
"
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1567
|
+
const result = await runCommand(
|
|
1568
|
+
"npx",
|
|
1569
|
+
[
|
|
1570
|
+
"--yes",
|
|
1571
|
+
"@stellar/stellar-sdk",
|
|
1572
|
+
"generate",
|
|
1573
|
+
"--contract-id",
|
|
1574
|
+
contractArtifact.contractId,
|
|
1575
|
+
"--output-dir",
|
|
1576
|
+
outputDir,
|
|
1577
|
+
"--contract-name",
|
|
1578
|
+
options.contractName,
|
|
1579
|
+
"--overwrite",
|
|
1580
|
+
...buildGenerateNetworkArgs(network)
|
|
1581
|
+
],
|
|
1582
|
+
{
|
|
1583
|
+
cwd,
|
|
1584
|
+
failureCode: CaatingaErrorCode.BINDINGS_FAILED
|
|
1585
|
+
}
|
|
1586
|
+
);
|
|
1582
1587
|
const legacyStubRemoved = await removeLegacyBindingStub(
|
|
1583
1588
|
cwd,
|
|
1584
1589
|
options.config.frontend.bindingsOutput,
|
|
@@ -1690,21 +1695,25 @@ async function invokeContract(options) {
|
|
|
1690
1695
|
await checkBinary("stellar", "Install Stellar CLI before running caatinga invoke.");
|
|
1691
1696
|
let result;
|
|
1692
1697
|
try {
|
|
1693
|
-
result = await runCommand(
|
|
1694
|
-
"
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1698
|
+
result = await runCommand(
|
|
1699
|
+
"stellar",
|
|
1700
|
+
[
|
|
1701
|
+
"contract",
|
|
1702
|
+
"invoke",
|
|
1703
|
+
"--id",
|
|
1704
|
+
contractArtifact.contractId,
|
|
1705
|
+
"--source-account",
|
|
1706
|
+
source,
|
|
1707
|
+
...buildStellarNetworkArgs(network),
|
|
1708
|
+
"--",
|
|
1709
|
+
target.method,
|
|
1710
|
+
...options.args ?? []
|
|
1711
|
+
],
|
|
1712
|
+
{
|
|
1713
|
+
cwd,
|
|
1714
|
+
failureCode: CaatingaErrorCode.INVOKE_FAILED
|
|
1715
|
+
}
|
|
1716
|
+
);
|
|
1708
1717
|
} catch (error) {
|
|
1709
1718
|
if (error instanceof CaatingaError && error.code === CaatingaErrorCode.INVOKE_FAILED && isReadCallFailure(error)) {
|
|
1710
1719
|
throw new CaatingaError(
|
|
@@ -1849,12 +1858,7 @@ function formatTemplateCompatibilityHint(issue) {
|
|
|
1849
1858
|
}
|
|
1850
1859
|
|
|
1851
1860
|
// src/templates/create-project-from-template.ts
|
|
1852
|
-
var TEMPLATE_COPY_EXCLUDED_DIRS = /* @__PURE__ */ new Set([
|
|
1853
|
-
"target",
|
|
1854
|
-
"test_snapshots",
|
|
1855
|
-
"node_modules",
|
|
1856
|
-
".git"
|
|
1857
|
-
]);
|
|
1861
|
+
var TEMPLATE_COPY_EXCLUDED_DIRS = /* @__PURE__ */ new Set(["target", "test_snapshots", "node_modules", ".git"]);
|
|
1858
1862
|
async function createProjectFromTemplate(options) {
|
|
1859
1863
|
const targetDir = path11.resolve(options.targetDir);
|
|
1860
1864
|
const templateDir = path11.resolve(options.templateDir);
|
|
@@ -1872,8 +1876,8 @@ async function createProjectFromTemplate(options) {
|
|
|
1872
1876
|
await mkdir3(targetDir, { recursive: true });
|
|
1873
1877
|
await cp(templateDir, targetDir, {
|
|
1874
1878
|
recursive: true,
|
|
1875
|
-
force:
|
|
1876
|
-
errorOnExist:
|
|
1879
|
+
force: true,
|
|
1880
|
+
errorOnExist: false,
|
|
1877
1881
|
filter: (source) => shouldCopyTemplateEntry(templateDir, source, options.filter)
|
|
1878
1882
|
});
|
|
1879
1883
|
await replaceTemplateVariables(targetDir, options.projectName);
|
|
@@ -1888,7 +1892,10 @@ async function ensureArtifacts(targetDir, projectName) {
|
|
|
1888
1892
|
await writeArtifacts({ ...artifacts, project: projectName }, targetDir);
|
|
1889
1893
|
} catch (error) {
|
|
1890
1894
|
if (error instanceof CaatingaError && error.code === CaatingaErrorCode.ARTIFACT_NOT_FOUND) {
|
|
1891
|
-
await writeArtifacts(
|
|
1895
|
+
await writeArtifacts(
|
|
1896
|
+
createInitialArtifacts(projectName, { networks: ["testnet"] }),
|
|
1897
|
+
targetDir
|
|
1898
|
+
);
|
|
1892
1899
|
return;
|
|
1893
1900
|
}
|
|
1894
1901
|
throw error;
|
|
@@ -1931,19 +1938,21 @@ async function readTemplateManifest(templateDir) {
|
|
|
1931
1938
|
}
|
|
1932
1939
|
async function replaceTemplateVariables(dir, projectName) {
|
|
1933
1940
|
const entries = await readdir3(dir);
|
|
1934
|
-
await Promise.all(
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1941
|
+
await Promise.all(
|
|
1942
|
+
entries.map(async (entry) => {
|
|
1943
|
+
const entryPath = path11.join(dir, entry);
|
|
1944
|
+
const entryStat = await stat2(entryPath);
|
|
1945
|
+
if (entryStat.isDirectory()) {
|
|
1946
|
+
await replaceTemplateVariables(entryPath, projectName);
|
|
1947
|
+
return;
|
|
1948
|
+
}
|
|
1949
|
+
if (!isTextTemplateFile(entryPath)) {
|
|
1950
|
+
return;
|
|
1951
|
+
}
|
|
1952
|
+
const content = await readFile4(entryPath, "utf8");
|
|
1953
|
+
await writeFile3(entryPath, content.replaceAll("__PROJECT_NAME__", projectName), "utf8");
|
|
1954
|
+
})
|
|
1955
|
+
);
|
|
1947
1956
|
}
|
|
1948
1957
|
function shouldCopyTemplateEntry(templateDir, source, userFilter) {
|
|
1949
1958
|
const relativePath = path11.relative(templateDir, source);
|
|
@@ -1957,16 +1966,9 @@ function shouldCopyTemplateEntry(templateDir, source, userFilter) {
|
|
|
1957
1966
|
return !relativePath.split(path11.sep).some((segment) => TEMPLATE_COPY_EXCLUDED_DIRS.has(segment));
|
|
1958
1967
|
}
|
|
1959
1968
|
function isTextTemplateFile(filePath) {
|
|
1960
|
-
return [
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
".rs",
|
|
1964
|
-
".toml",
|
|
1965
|
-
".ts",
|
|
1966
|
-
".tsx",
|
|
1967
|
-
".css",
|
|
1968
|
-
".html"
|
|
1969
|
-
].includes(path11.extname(filePath));
|
|
1969
|
+
return [".json", ".md", ".rs", ".toml", ".ts", ".tsx", ".css", ".html"].includes(
|
|
1970
|
+
path11.extname(filePath)
|
|
1971
|
+
);
|
|
1970
1972
|
}
|
|
1971
1973
|
|
|
1972
1974
|
// src/scaffold/create-zk-project.ts
|
|
@@ -2015,23 +2017,28 @@ export default defineConfig({
|
|
|
2015
2017
|
`;
|
|
2016
2018
|
}
|
|
2017
2019
|
function packageJsonSource(projectName) {
|
|
2018
|
-
return `${JSON.stringify(
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2020
|
+
return `${JSON.stringify(
|
|
2021
|
+
{
|
|
2022
|
+
name: projectName,
|
|
2023
|
+
version: "0.1.0",
|
|
2024
|
+
private: true,
|
|
2025
|
+
type: "module",
|
|
2026
|
+
scripts: {
|
|
2027
|
+
"zk:build": "caatinga zk build main",
|
|
2028
|
+
"zk:prove": "caatinga zk prove main",
|
|
2029
|
+
build: "caatinga build verifier",
|
|
2030
|
+
deploy: "caatinga deploy verifier --network testnet --source ${CAATINGA_SOURCE:-alice}",
|
|
2031
|
+
doctor: "caatinga doctor --network testnet",
|
|
2032
|
+
test: "cargo test --manifest-path contracts/verifier/Cargo.toml"
|
|
2033
|
+
},
|
|
2034
|
+
devDependencies: {
|
|
2035
|
+
"@caatinga/cli": `^${CAATINGA_CORE_VERSION}`,
|
|
2036
|
+
"@caatinga/core": `^${CAATINGA_CORE_VERSION}`
|
|
2037
|
+
}
|
|
2029
2038
|
},
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
}
|
|
2034
|
-
}, null, 2)}
|
|
2039
|
+
null,
|
|
2040
|
+
2
|
|
2041
|
+
)}
|
|
2035
2042
|
`;
|
|
2036
2043
|
}
|
|
2037
2044
|
function readmeSource(projectName) {
|
|
@@ -2043,12 +2050,23 @@ Minimal Caatinga ZK project.
|
|
|
2043
2050
|
|
|
2044
2051
|
\`\`\`bash
|
|
2045
2052
|
npm install
|
|
2053
|
+
npm test
|
|
2046
2054
|
npx caatinga zk build main
|
|
2047
2055
|
npx caatinga build verifier
|
|
2048
2056
|
npx caatinga deploy verifier --network testnet --source <identity>
|
|
2049
2057
|
npx caatinga zk prove main
|
|
2050
2058
|
\`\`\`
|
|
2051
2059
|
|
|
2060
|
+
## Tests
|
|
2061
|
+
|
|
2062
|
+
Run the Rust verifier contract tests from the project root:
|
|
2063
|
+
|
|
2064
|
+
\`\`\`bash
|
|
2065
|
+
npm test
|
|
2066
|
+
# or directly:
|
|
2067
|
+
cargo test --manifest-path contracts/verifier/Cargo.toml
|
|
2068
|
+
\`\`\`
|
|
2069
|
+
|
|
2052
2070
|
Replace \`circuits/main.circom\` with your circuit. Keep the entry point named \`main\`.
|
|
2053
2071
|
`;
|
|
2054
2072
|
}
|
|
@@ -2059,10 +2077,22 @@ async function createZkProject(options) {
|
|
|
2059
2077
|
await mkdir4(targetDir, { recursive: true });
|
|
2060
2078
|
if (projectFiles) {
|
|
2061
2079
|
await Promise.all([
|
|
2062
|
-
writeFile4(path12.join(targetDir, "caatinga.config.ts"), configSource(options.projectName), {
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2080
|
+
writeFile4(path12.join(targetDir, "caatinga.config.ts"), configSource(options.projectName), {
|
|
2081
|
+
encoding: "utf8",
|
|
2082
|
+
flag: force ? "w" : "wx"
|
|
2083
|
+
}),
|
|
2084
|
+
writeFile4(path12.join(targetDir, "package.json"), packageJsonSource(options.projectName), {
|
|
2085
|
+
encoding: "utf8",
|
|
2086
|
+
flag: force ? "w" : "wx"
|
|
2087
|
+
}),
|
|
2088
|
+
writeFile4(path12.join(targetDir, ".gitignore"), "node_modules\n.artifacts\ntarget\n", {
|
|
2089
|
+
encoding: "utf8",
|
|
2090
|
+
flag: force ? "w" : "wx"
|
|
2091
|
+
}),
|
|
2092
|
+
writeFile4(path12.join(targetDir, "README.md"), readmeSource(options.projectName), {
|
|
2093
|
+
encoding: "utf8",
|
|
2094
|
+
flag: force ? "w" : "wx"
|
|
2095
|
+
})
|
|
2066
2096
|
]);
|
|
2067
2097
|
}
|
|
2068
2098
|
await mkdir4(path12.join(targetDir, "contracts"), { recursive: true });
|
|
@@ -2071,13 +2101,20 @@ async function createZkProject(options) {
|
|
|
2071
2101
|
force,
|
|
2072
2102
|
errorOnExist: !force
|
|
2073
2103
|
});
|
|
2074
|
-
await cp2(
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2104
|
+
await cp2(
|
|
2105
|
+
path12.join(scaffoldRoot(), "zk-verifier"),
|
|
2106
|
+
path12.join(targetDir, "contracts", "verifier"),
|
|
2107
|
+
{
|
|
2108
|
+
recursive: true,
|
|
2109
|
+
force,
|
|
2110
|
+
errorOnExist: !force
|
|
2111
|
+
}
|
|
2112
|
+
);
|
|
2079
2113
|
if (projectFiles) {
|
|
2080
|
-
await writeArtifacts(
|
|
2114
|
+
await writeArtifacts(
|
|
2115
|
+
createInitialArtifacts(options.projectName, { networks: ["testnet"] }),
|
|
2116
|
+
targetDir
|
|
2117
|
+
);
|
|
2081
2118
|
}
|
|
2082
2119
|
return { targetDir };
|
|
2083
2120
|
}
|
|
@@ -2118,23 +2155,28 @@ export default defineConfig({
|
|
|
2118
2155
|
`;
|
|
2119
2156
|
}
|
|
2120
2157
|
function packageJsonSource2(projectName) {
|
|
2121
|
-
return `${JSON.stringify(
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2158
|
+
return `${JSON.stringify(
|
|
2159
|
+
{
|
|
2160
|
+
name: projectName,
|
|
2161
|
+
version: "0.1.0",
|
|
2162
|
+
private: true,
|
|
2163
|
+
type: "module",
|
|
2164
|
+
scripts: {
|
|
2165
|
+
build: "caatinga build app",
|
|
2166
|
+
deploy: "caatinga deploy app --network testnet --source ${CAATINGA_SOURCE:-alice}",
|
|
2167
|
+
doctor: "caatinga doctor --network testnet",
|
|
2168
|
+
test: "cargo test --manifest-path contracts/app/Cargo.toml",
|
|
2169
|
+
"read:hello": "caatinga read app.hello --network testnet --source ${CAATINGA_SOURCE:-alice}",
|
|
2170
|
+
"read:version": "caatinga read app.version --network testnet --source ${CAATINGA_SOURCE:-alice}"
|
|
2171
|
+
},
|
|
2172
|
+
devDependencies: {
|
|
2173
|
+
"@caatinga/cli": `^${CAATINGA_CORE_VERSION}`,
|
|
2174
|
+
"@caatinga/core": `^${CAATINGA_CORE_VERSION}`
|
|
2175
|
+
}
|
|
2132
2176
|
},
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
}
|
|
2137
|
-
}, null, 2)}
|
|
2177
|
+
null,
|
|
2178
|
+
2
|
|
2179
|
+
)}
|
|
2138
2180
|
`;
|
|
2139
2181
|
}
|
|
2140
2182
|
function readmeSource2(projectName) {
|
|
@@ -2146,6 +2188,7 @@ Minimal Caatinga project with a Soroban contract stub (no frontend template).
|
|
|
2146
2188
|
|
|
2147
2189
|
\`\`\`bash
|
|
2148
2190
|
npm install
|
|
2191
|
+
npm test
|
|
2149
2192
|
npx caatinga doctor
|
|
2150
2193
|
npx caatinga build app
|
|
2151
2194
|
npx caatinga deploy app --network testnet --source <identity>
|
|
@@ -2153,6 +2196,16 @@ npx caatinga read app.version --network testnet
|
|
|
2153
2196
|
npx caatinga read app.hello --network testnet
|
|
2154
2197
|
\`\`\`
|
|
2155
2198
|
|
|
2199
|
+
## Tests
|
|
2200
|
+
|
|
2201
|
+
Run the Rust contract tests from the project root:
|
|
2202
|
+
|
|
2203
|
+
\`\`\`bash
|
|
2204
|
+
npm test
|
|
2205
|
+
# or directly:
|
|
2206
|
+
cargo test --manifest-path contracts/app/Cargo.toml
|
|
2207
|
+
\`\`\`
|
|
2208
|
+
|
|
2156
2209
|
## Contract
|
|
2157
2210
|
|
|
2158
2211
|
- \`hello()\` \u2014 read-only; returns Soroban Symbol \`hello\`
|
|
@@ -2170,18 +2223,37 @@ async function createMinimalProject(options) {
|
|
|
2170
2223
|
const force = options.force ?? false;
|
|
2171
2224
|
await mkdir5(targetDir, { recursive: true });
|
|
2172
2225
|
await Promise.all([
|
|
2173
|
-
writeFile5(path13.join(targetDir, "caatinga.config.ts"), configSource2(options.projectName), {
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2226
|
+
writeFile5(path13.join(targetDir, "caatinga.config.ts"), configSource2(options.projectName), {
|
|
2227
|
+
encoding: "utf8",
|
|
2228
|
+
flag: force ? "w" : "wx"
|
|
2229
|
+
}),
|
|
2230
|
+
writeFile5(path13.join(targetDir, "package.json"), packageJsonSource2(options.projectName), {
|
|
2231
|
+
encoding: "utf8",
|
|
2232
|
+
flag: force ? "w" : "wx"
|
|
2233
|
+
}),
|
|
2234
|
+
writeFile5(path13.join(targetDir, ".gitignore"), "node_modules\n.artifacts\ntarget\n", {
|
|
2235
|
+
encoding: "utf8",
|
|
2236
|
+
flag: force ? "w" : "wx"
|
|
2237
|
+
}),
|
|
2238
|
+
writeFile5(path13.join(targetDir, "README.md"), readmeSource2(options.projectName), {
|
|
2239
|
+
encoding: "utf8",
|
|
2240
|
+
flag: force ? "w" : "wx"
|
|
2241
|
+
})
|
|
2177
2242
|
]);
|
|
2178
2243
|
await mkdir5(path13.join(targetDir, "contracts"), { recursive: true });
|
|
2179
|
-
await cp3(
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2244
|
+
await cp3(
|
|
2245
|
+
path13.join(scaffoldRoot2(), "soroban-contract-stub"),
|
|
2246
|
+
path13.join(targetDir, "contracts", "app"),
|
|
2247
|
+
{
|
|
2248
|
+
recursive: true,
|
|
2249
|
+
force,
|
|
2250
|
+
errorOnExist: !force
|
|
2251
|
+
}
|
|
2252
|
+
);
|
|
2253
|
+
await writeArtifacts(
|
|
2254
|
+
createInitialArtifacts(options.projectName, { networks: ["testnet"] }),
|
|
2255
|
+
targetDir
|
|
2256
|
+
);
|
|
2185
2257
|
return { targetDir };
|
|
2186
2258
|
}
|
|
2187
2259
|
|