@tokamak-private-dapps/private-state-cli 0.1.4 → 0.1.6
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/CHANGELOG.md +13 -0
- package/README.md +10 -1
- package/package.json +3 -3
- package/private-state-bridge-cli.mjs +479 -51
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.1.6 - 2026-04-29
|
|
4
|
+
|
|
5
|
+
- Added `--groth16-cli-version` and `--tokamak-zk-evm-cli-version` install options with npm latest defaults.
|
|
6
|
+
- Installed selected proof backend package versions into managed runtime directories.
|
|
7
|
+
- Downloaded Groth16 CRS artifacts matching the selected Groth16 CLI version.
|
|
8
|
+
- Checked channel verifier compatible backend versions before local proof generation.
|
|
9
|
+
- Reported selected proof backend runtime versions from `--doctor`.
|
|
10
|
+
|
|
11
|
+
## 0.1.5 - 2026-04-28
|
|
12
|
+
|
|
13
|
+
- Switched channel balance proof generation to invoke `tokamak-groth16 --prove` instead of importing Groth16 proof internals directly.
|
|
14
|
+
- Read proof artifacts from the fixed Groth16 runtime workspace manifest.
|
|
15
|
+
|
|
3
16
|
## 0.1.4 - 2026-04-28
|
|
4
17
|
|
|
5
18
|
- Paced chunked log recovery queries at five requests per second to avoid RPC throughput bursts.
|
package/README.md
CHANGED
|
@@ -15,6 +15,15 @@ artifacts:
|
|
|
15
15
|
private-state-cli --install
|
|
16
16
|
```
|
|
17
17
|
|
|
18
|
+
By default, `--install` resolves the latest `@tokamak-zk-evm/cli` and `@tokamak-private-dapps/groth16` versions from
|
|
19
|
+
the npm registry. To pin exact proof backend versions for a channel, pass explicit versions:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
private-state-cli --install --tokamak-zk-evm-cli-version 2.0.8 --groth16-cli-version 0.1.1
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
The Groth16 installer downloads the public Google Drive CRS archive with the same version as the selected Groth16 CLI.
|
|
26
|
+
|
|
18
27
|
`--install` downloads public deployment artifacts from the configured artifact index. It does not read repository-local
|
|
19
28
|
`deployment/` outputs by default. Repository development workflows that need local anvil artifacts can opt in explicitly:
|
|
20
29
|
|
|
@@ -52,7 +61,7 @@ A common private-state flow is:
|
|
|
52
61
|
Use `private-state-cli --help` for the full command list and required options.
|
|
53
62
|
|
|
54
63
|
`private-state-cli --doctor` reports the CLI package version, dependency versions recorded by the last
|
|
55
|
-
`private-state-cli --install`, current dependency versions through `tokamak-l2js`, and Tokamak zk-EVM runtime
|
|
64
|
+
`private-state-cli --install`, selected proof backend runtime versions, current dependency versions through `tokamak-l2js`, and Tokamak zk-EVM runtime
|
|
56
65
|
install mode, Docker mode, CUDA runtime metadata, live `nvidia-smi` and Docker GPU probe results, and Groth16
|
|
57
66
|
runtime health. The doctor check fails when the Tokamak Docker `useGpus` metadata does not match the live GPU probes.
|
|
58
67
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tokamak-private-dapps/private-state-cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.6",
|
|
4
4
|
"description": "Command-line client for the Tokamak private-state DApp.",
|
|
5
5
|
"license": "MIT OR Apache-2.0",
|
|
6
6
|
"author": "Tokamak Network",
|
|
@@ -43,8 +43,8 @@
|
|
|
43
43
|
"@ethereumjs/util": "^10.1.1",
|
|
44
44
|
"@noble/curves": "^1.2.0",
|
|
45
45
|
"@tokamak-private-dapps/common-library": "^0.1.0",
|
|
46
|
-
"@tokamak-private-dapps/groth16": "^0.1.
|
|
47
|
-
"@tokamak-zk-evm/cli": "^2.0.
|
|
46
|
+
"@tokamak-private-dapps/groth16": "^0.1.2",
|
|
47
|
+
"@tokamak-zk-evm/cli": "^2.0.12",
|
|
48
48
|
"ethers": "^6.14.1",
|
|
49
49
|
"tokamak-l2js": "^0.1.3"
|
|
50
50
|
},
|
|
@@ -45,11 +45,9 @@ import {
|
|
|
45
45
|
} from "@ethereumjs/util";
|
|
46
46
|
import { deriveRpcUrl, resolveCliNetwork } from "@tokamak-private-dapps/common-library/network-config";
|
|
47
47
|
import {
|
|
48
|
-
buildTokamakCliInvocation,
|
|
49
48
|
resolveTokamakBlockInputConfig,
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
resolveTokamakCliRuntimeRoot,
|
|
49
|
+
resolveTokamakCliEntryPath,
|
|
50
|
+
resolveTokamakCliPackageRoot as resolveBundledTokamakCliPackageRoot,
|
|
53
51
|
} from "@tokamak-private-dapps/common-library/tokamak-runtime-paths";
|
|
54
52
|
import {
|
|
55
53
|
DEFAULT_PUBLIC_ARTIFACT_INDEX_FILE_ID,
|
|
@@ -66,8 +64,8 @@ import { toGroth16SolidityProof } from "@tokamak-private-dapps/common-library/gr
|
|
|
66
64
|
import {
|
|
67
65
|
PUBLIC_GROTH16_MPC_DRIVE_FOLDER_ID,
|
|
68
66
|
downloadLatestPublicGroth16MpcArtifacts,
|
|
67
|
+
downloadPublicGroth16MpcArtifactsByVersion,
|
|
69
68
|
} from "@tokamak-private-dapps/groth16/public-drive-crs";
|
|
70
|
-
import { main as generateUpdateTreeProof } from "@tokamak-private-dapps/groth16/prover/updateTree/generateProof";
|
|
71
69
|
import {
|
|
72
70
|
CHANNEL_BOUND_L2_DERIVATION_MODE,
|
|
73
71
|
deriveChannelIdFromName,
|
|
@@ -86,17 +84,20 @@ const require = createRequire(import.meta.url);
|
|
|
86
84
|
const defaultCommandCwd = process.cwd();
|
|
87
85
|
const privateStateCliPackageRoot = path.dirname(require.resolve("./package.json"));
|
|
88
86
|
const workspaceRoot = path.resolve(os.homedir(), "tokamak-private-channels", "workspace");
|
|
89
|
-
const tokamakCliInvocation = buildTokamakCliInvocation();
|
|
90
|
-
const tokamakCliCommand = tokamakCliInvocation.command;
|
|
91
|
-
const tokamakCliBaseArgs = tokamakCliInvocation.args;
|
|
92
87
|
const flatDeploymentArtifactPathsByChainId = new Map();
|
|
93
88
|
const DOCKER_CUDA_PROBE_IMAGE = "nvidia/cuda:12.2.0-base-ubuntu22.04";
|
|
94
89
|
const DOCTOR_GPU_PROBE_TIMEOUT_MS = 120000;
|
|
90
|
+
const GROTH16_PACKAGE_NAME = "@tokamak-private-dapps/groth16";
|
|
91
|
+
const TOKAMAK_ZKEVM_CLI_PACKAGE_NAME = "@tokamak-zk-evm/cli";
|
|
95
92
|
|
|
96
93
|
const abiCoder = AbiCoder.defaultAbiCoder();
|
|
97
94
|
const erc20MetadataAbi = [
|
|
98
95
|
"function decimals() view returns (uint8)",
|
|
99
96
|
];
|
|
97
|
+
const channelVerifierVersionAbi = [
|
|
98
|
+
"function grothVerifierCompatibleBackendVersion() view returns (string)",
|
|
99
|
+
"function tokamakVerifierCompatibleBackendVersion() view returns (string)",
|
|
100
|
+
];
|
|
100
101
|
const {
|
|
101
102
|
aPubBlockLength: TOKAMAK_APUB_BLOCK_LENGTH,
|
|
102
103
|
previousBlockHashCount: TOKAMAK_PREVIOUS_BLOCK_HASH_COUNT,
|
|
@@ -953,31 +954,36 @@ function clearWalletRecoveryArtifacts(walletDir) {
|
|
|
953
954
|
}
|
|
954
955
|
|
|
955
956
|
async function handleInstallZkEvm({ args }) {
|
|
956
|
-
const
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
const
|
|
962
|
-
|
|
957
|
+
const selectedVersions = await resolvePrivateStateInstallRuntimeVersions(args);
|
|
958
|
+
const tokamakCliRuntime = await installTokamakCliRuntimeForPrivateState({
|
|
959
|
+
version: selectedVersions.tokamak,
|
|
960
|
+
docker: Boolean(args.docker),
|
|
961
|
+
});
|
|
962
|
+
const groth16Runtime = await installGroth16RuntimeForPrivateState({
|
|
963
|
+
version: selectedVersions.groth16,
|
|
963
964
|
docker: Boolean(args.docker),
|
|
964
965
|
});
|
|
965
966
|
const localDeploymentBaseRoot = args.includeLocalArtifacts ? process.cwd() : null;
|
|
966
967
|
const deploymentArtifacts = await installPrivateStateCliArtifacts({
|
|
967
968
|
dappName: PRIVATE_STATE_DAPP_LABEL,
|
|
968
969
|
localDeploymentBaseRoot,
|
|
970
|
+
groth16CrsVersion: selectedVersions.groth16,
|
|
969
971
|
});
|
|
970
972
|
const installManifest = writePrivateStateCliInstallManifest({
|
|
971
973
|
dockerRequested: Boolean(args.docker),
|
|
972
974
|
includeLocalArtifacts: Boolean(args.includeLocalArtifacts),
|
|
973
975
|
localDeploymentBaseRoot,
|
|
974
976
|
deploymentArtifacts,
|
|
977
|
+
selectedVersions,
|
|
978
|
+
tokamakCliRuntime,
|
|
975
979
|
groth16Runtime,
|
|
976
980
|
});
|
|
977
981
|
printJson({
|
|
978
982
|
action: "install",
|
|
979
|
-
|
|
980
|
-
|
|
983
|
+
selectedVersions,
|
|
984
|
+
tokamakCli: tokamakCliRuntime.entryPath,
|
|
985
|
+
runtimeRoot: tokamakCliRuntime.runtimeRoot,
|
|
986
|
+
tokamakCliRuntime,
|
|
981
987
|
groth16Runtime,
|
|
982
988
|
docker: Boolean(args.docker),
|
|
983
989
|
includeLocalArtifacts: Boolean(args.includeLocalArtifacts),
|
|
@@ -997,12 +1003,13 @@ async function handleInstallZkEvm({ args }) {
|
|
|
997
1003
|
|
|
998
1004
|
async function handleUninstallZkEvm() {
|
|
999
1005
|
let runtimeRoot = null;
|
|
1006
|
+
const invocation = buildTokamakCliInvocationForPackageRoot();
|
|
1000
1007
|
try {
|
|
1001
|
-
runtimeRoot =
|
|
1008
|
+
runtimeRoot = inspectTokamakCliRuntime({ packageRoot: invocation.packageRoot }).runtimeRoot;
|
|
1002
1009
|
} catch {
|
|
1003
1010
|
runtimeRoot = null;
|
|
1004
1011
|
}
|
|
1005
|
-
run(
|
|
1012
|
+
run(invocation.command, [...invocation.args, "--uninstall"], { cwd: invocation.packageRoot });
|
|
1006
1013
|
|
|
1007
1014
|
printJson({
|
|
1008
1015
|
action: "uninstall-zk-evm",
|
|
@@ -1310,10 +1317,16 @@ async function handleGrothVaultMove({ args, provider, direction }) {
|
|
|
1310
1317
|
const contextResult = await loadPreferredWalletChannelContext({ walletContext, provider });
|
|
1311
1318
|
const context = contextResult.context;
|
|
1312
1319
|
const network = contextResult.network;
|
|
1320
|
+
const operationName = args.command === "withdraw-channel"
|
|
1321
|
+
? "withdraw-channel"
|
|
1322
|
+
: direction === "deposit"
|
|
1323
|
+
? "deposit-channel"
|
|
1324
|
+
: "withdraw";
|
|
1313
1325
|
expect(
|
|
1314
1326
|
ethers.toBigInt(walletContext.wallet.channelId) === ethers.toBigInt(context.workspace.channelId),
|
|
1315
1327
|
"The provided wallet does not belong to the selected channel.",
|
|
1316
1328
|
);
|
|
1329
|
+
await assertChannelProofBackendVersionCompatibility({ context, operationName });
|
|
1317
1330
|
|
|
1318
1331
|
const { signer, l2Identity } = restoreWalletParticipant(walletContext, provider);
|
|
1319
1332
|
const amountInput = requireArg(args.amount, "--amount");
|
|
@@ -1365,11 +1378,6 @@ async function handleGrothVaultMove({ args, provider, direction }) {
|
|
|
1365
1378
|
nextValue = currentValue - amount;
|
|
1366
1379
|
}
|
|
1367
1380
|
|
|
1368
|
-
const operationName = args.command === "withdraw-channel"
|
|
1369
|
-
? "withdraw-channel"
|
|
1370
|
-
: direction === "deposit"
|
|
1371
|
-
? "deposit-channel"
|
|
1372
|
-
: "withdraw";
|
|
1373
1381
|
const operationDir = createWalletOperationDir(
|
|
1374
1382
|
walletContext.walletName,
|
|
1375
1383
|
walletContext.wallet.network,
|
|
@@ -3058,6 +3066,7 @@ async function executeWalletTemplateSend({
|
|
|
3058
3066
|
}) {
|
|
3059
3067
|
await assertWorkspaceAlignedWithChain(context, signer.provider);
|
|
3060
3068
|
assertWalletMatchesChannelContext(wallet, l2Identity, context);
|
|
3069
|
+
await assertChannelProofBackendVersionCompatibility({ context, operationName });
|
|
3061
3070
|
|
|
3062
3071
|
const controllerAbi = readJson(
|
|
3063
3072
|
requireLatestDappDeployArtifactPath(context.workspace.chainId, path.basename(templatePayload.abiFile)),
|
|
@@ -3429,6 +3438,111 @@ async function assertWorkspaceAlignedWithChain(context) {
|
|
|
3429
3438
|
);
|
|
3430
3439
|
}
|
|
3431
3440
|
|
|
3441
|
+
async function assertChannelProofBackendVersionCompatibility({ context, operationName }) {
|
|
3442
|
+
const channelVersions = await readChannelVerifierCompatibleBackendVersions(context);
|
|
3443
|
+
const localVersions = readLocalProofBackendPackageVersions();
|
|
3444
|
+
const checks = [
|
|
3445
|
+
{
|
|
3446
|
+
label: "Groth16",
|
|
3447
|
+
packageName: GROTH16_PACKAGE_NAME,
|
|
3448
|
+
channelVersion: channelVersions.groth16,
|
|
3449
|
+
localVersion: localVersions.groth16,
|
|
3450
|
+
},
|
|
3451
|
+
{
|
|
3452
|
+
label: "Tokamak zk-EVM",
|
|
3453
|
+
packageName: TOKAMAK_ZKEVM_CLI_PACKAGE_NAME,
|
|
3454
|
+
channelVersion: channelVersions.tokamak,
|
|
3455
|
+
localVersion: localVersions.tokamak,
|
|
3456
|
+
},
|
|
3457
|
+
];
|
|
3458
|
+
const mismatches = checks.filter(({ channelVersion, localVersion }) => channelVersion !== localVersion);
|
|
3459
|
+
if (mismatches.length === 0) {
|
|
3460
|
+
return;
|
|
3461
|
+
}
|
|
3462
|
+
|
|
3463
|
+
throw new Error(
|
|
3464
|
+
[
|
|
3465
|
+
`Channel proof backend version mismatch before ${operationName} proof generation.`,
|
|
3466
|
+
`Channel: ${context.workspace.channelName ?? context.workspaceName ?? context.workspace.channelId}.`,
|
|
3467
|
+
...mismatches.map(({ label, packageName, channelVersion, localVersion }) => (
|
|
3468
|
+
`${label} verifier expects ${packageName} ${channelVersion}, but the local installed package version is ${localVersion}.`
|
|
3469
|
+
)),
|
|
3470
|
+
"Install the matching CLI package versions before generating proofs for this channel.",
|
|
3471
|
+
].join(" "),
|
|
3472
|
+
);
|
|
3473
|
+
}
|
|
3474
|
+
|
|
3475
|
+
async function readChannelVerifierCompatibleBackendVersions(context) {
|
|
3476
|
+
const channelManagerAddress = getAddress(context.workspace.channelManager);
|
|
3477
|
+
const channelManager = new Contract(
|
|
3478
|
+
channelManagerAddress,
|
|
3479
|
+
channelVerifierVersionAbi,
|
|
3480
|
+
context.channelManager.runner,
|
|
3481
|
+
);
|
|
3482
|
+
try {
|
|
3483
|
+
const [groth16, tokamak] = await Promise.all([
|
|
3484
|
+
channelManager.grothVerifierCompatibleBackendVersion(),
|
|
3485
|
+
channelManager.tokamakVerifierCompatibleBackendVersion(),
|
|
3486
|
+
]);
|
|
3487
|
+
return {
|
|
3488
|
+
groth16: requireVersionString(groth16, "channel Groth16 verifier compatibleBackendVersion"),
|
|
3489
|
+
tokamak: requireVersionString(tokamak, "channel Tokamak verifier compatibleBackendVersion"),
|
|
3490
|
+
};
|
|
3491
|
+
} catch (error) {
|
|
3492
|
+
throw new Error(
|
|
3493
|
+
[
|
|
3494
|
+
`Unable to read verifier compatibleBackendVersion values from channel manager ${channelManagerAddress}.`,
|
|
3495
|
+
"The target channel must expose grothVerifierCompatibleBackendVersion() and tokamakVerifierCompatibleBackendVersion().",
|
|
3496
|
+
].join(" "),
|
|
3497
|
+
{ cause: error },
|
|
3498
|
+
);
|
|
3499
|
+
}
|
|
3500
|
+
}
|
|
3501
|
+
|
|
3502
|
+
function readLocalProofBackendPackageVersions() {
|
|
3503
|
+
return {
|
|
3504
|
+
groth16: requirePackageReportVersion(
|
|
3505
|
+
readPackageReport({
|
|
3506
|
+
name: GROTH16_PACKAGE_NAME,
|
|
3507
|
+
packageJsonPath: path.join(resolveActiveGroth16PackageRoot(), "package.json"),
|
|
3508
|
+
}),
|
|
3509
|
+
),
|
|
3510
|
+
tokamak: requirePackageReportVersion(readTokamakCliPackageReport()),
|
|
3511
|
+
};
|
|
3512
|
+
}
|
|
3513
|
+
|
|
3514
|
+
function readTokamakCliPackageReport() {
|
|
3515
|
+
try {
|
|
3516
|
+
return readPackageReport({
|
|
3517
|
+
name: TOKAMAK_ZKEVM_CLI_PACKAGE_NAME,
|
|
3518
|
+
packageJsonPath: path.join(resolveActiveTokamakCliPackageRoot(), "package.json"),
|
|
3519
|
+
});
|
|
3520
|
+
} catch (error) {
|
|
3521
|
+
return {
|
|
3522
|
+
name: TOKAMAK_ZKEVM_CLI_PACKAGE_NAME,
|
|
3523
|
+
version: null,
|
|
3524
|
+
packageRoot: null,
|
|
3525
|
+
error: error.message,
|
|
3526
|
+
ok: false,
|
|
3527
|
+
};
|
|
3528
|
+
}
|
|
3529
|
+
}
|
|
3530
|
+
|
|
3531
|
+
function requirePackageReportVersion(report) {
|
|
3532
|
+
if (!report.version) {
|
|
3533
|
+
throw new Error(
|
|
3534
|
+
`Unable to determine local ${report.name} package version${report.error ? `: ${report.error}` : "."}`,
|
|
3535
|
+
);
|
|
3536
|
+
}
|
|
3537
|
+
return requireVersionString(report.version, `${report.name} package version`);
|
|
3538
|
+
}
|
|
3539
|
+
|
|
3540
|
+
function requireVersionString(value, label) {
|
|
3541
|
+
const normalized = String(value ?? "").trim();
|
|
3542
|
+
expect(normalized.length > 0, `${label} is missing.`);
|
|
3543
|
+
return normalized;
|
|
3544
|
+
}
|
|
3545
|
+
|
|
3432
3546
|
async function buildGrothTransition({ operationDir, workspace, stateManager, vaultAddress, keyHex, nextValue }) {
|
|
3433
3547
|
const vaultAddressObj = createAddressFromString(vaultAddress);
|
|
3434
3548
|
const keyBigInt = ethers.toBigInt(keyHex);
|
|
@@ -3457,10 +3571,7 @@ async function buildGrothTransition({ operationDir, workspace, stateManager, vau
|
|
|
3457
3571
|
|
|
3458
3572
|
const inputPath = path.join(operationDir, "input.json");
|
|
3459
3573
|
writeJson(inputPath, input);
|
|
3460
|
-
const proofManifest =
|
|
3461
|
-
"--input",
|
|
3462
|
-
inputPath,
|
|
3463
|
-
]);
|
|
3574
|
+
const proofManifest = runGroth16UpdateTreeProof(inputPath);
|
|
3464
3575
|
|
|
3465
3576
|
const proofJson = readJson(proofManifest.proofPath);
|
|
3466
3577
|
const publicSignals = readJson(proofManifest.publicPath);
|
|
@@ -3507,6 +3618,21 @@ function runCaptured(command, args, { cwd = defaultCommandCwd, env = process.env
|
|
|
3507
3618
|
};
|
|
3508
3619
|
}
|
|
3509
3620
|
|
|
3621
|
+
function runGroth16UpdateTreeProof(inputPath) {
|
|
3622
|
+
const packageRoot = resolveActiveGroth16PackageRoot();
|
|
3623
|
+
const entryPath = resolveGroth16CliEntryPath(packageRoot);
|
|
3624
|
+
run(process.execPath, [entryPath, "--prove", inputPath], { cwd: packageRoot });
|
|
3625
|
+
const manifestPath = groth16ProofManifestPath();
|
|
3626
|
+
const manifest = readJson(manifestPath);
|
|
3627
|
+
expect(typeof manifest.proofPath === "string" && manifest.proofPath.length > 0, "Groth16 proof manifest is missing proofPath.");
|
|
3628
|
+
expect(typeof manifest.publicPath === "string" && manifest.publicPath.length > 0, "Groth16 proof manifest is missing publicPath.");
|
|
3629
|
+
return manifest;
|
|
3630
|
+
}
|
|
3631
|
+
|
|
3632
|
+
function groth16ProofManifestPath() {
|
|
3633
|
+
return path.join(os.homedir(), "tokamak-private-channels", "groth16", "proof", "proof-manifest.json");
|
|
3634
|
+
}
|
|
3635
|
+
|
|
3510
3636
|
function runTokamakProofPipeline({ operationDir, bundlePath }) {
|
|
3511
3637
|
runTokamakCliStage({
|
|
3512
3638
|
operationDir,
|
|
@@ -3546,7 +3672,8 @@ function printLocalProofGenerationNotice(operationName) {
|
|
|
3546
3672
|
}
|
|
3547
3673
|
|
|
3548
3674
|
function runTokamakCliStage({ operationDir, stageName, args }) {
|
|
3549
|
-
const
|
|
3675
|
+
const invocation = buildTokamakCliInvocationForPackageRoot();
|
|
3676
|
+
const result = runCaptured(invocation.command, [...invocation.args, ...args], { cwd: invocation.packageRoot });
|
|
3550
3677
|
const logPath = writeTokamakCliStageLog(operationDir, stageName, result);
|
|
3551
3678
|
if (result.status !== 0) {
|
|
3552
3679
|
throw new Error(
|
|
@@ -3605,6 +3732,7 @@ function findTokamakConsoleError({ stdout, stderr }) {
|
|
|
3605
3732
|
function copyTokamakOperationArtifacts(operationDir) {
|
|
3606
3733
|
const resourceRoot = path.join(operationDir, "resource");
|
|
3607
3734
|
fs.rmSync(resourceRoot, { recursive: true, force: true });
|
|
3735
|
+
const runtimeRoot = requireActiveTokamakCliRuntimeRoot();
|
|
3608
3736
|
|
|
3609
3737
|
const requiredFiles = [
|
|
3610
3738
|
["preprocess", "output", "preprocess.json"],
|
|
@@ -3614,7 +3742,7 @@ function copyTokamakOperationArtifacts(operationDir) {
|
|
|
3614
3742
|
];
|
|
3615
3743
|
|
|
3616
3744
|
for (const segments of requiredFiles) {
|
|
3617
|
-
const sourcePath =
|
|
3745
|
+
const sourcePath = resolveTokamakCliResourceDirForRuntimeRoot(runtimeRoot, ...segments);
|
|
3618
3746
|
const targetPath = path.join(resourceRoot, ...segments);
|
|
3619
3747
|
ensureDir(path.dirname(targetPath));
|
|
3620
3748
|
fs.copyFileSync(sourcePath, targetPath);
|
|
@@ -4578,9 +4706,23 @@ function assertInstallZkEvmArgs(args) {
|
|
|
4578
4706
|
assertAllowedCommandKeys(
|
|
4579
4707
|
args,
|
|
4580
4708
|
"--install",
|
|
4581
|
-
new Set([
|
|
4582
|
-
|
|
4709
|
+
new Set([
|
|
4710
|
+
"command",
|
|
4711
|
+
"positional",
|
|
4712
|
+
"install",
|
|
4713
|
+
"docker",
|
|
4714
|
+
"includeLocalArtifacts",
|
|
4715
|
+
"groth16CliVersion",
|
|
4716
|
+
"tokamakZkEvmCliVersion",
|
|
4717
|
+
]),
|
|
4718
|
+
"optional --docker, --include-local-artifacts, --groth16-cli-version, and --tokamak-zk-evm-cli-version",
|
|
4583
4719
|
);
|
|
4720
|
+
if (args.groth16CliVersion !== undefined) {
|
|
4721
|
+
requireSemverVersion(args.groth16CliVersion, "--groth16-cli-version");
|
|
4722
|
+
}
|
|
4723
|
+
if (args.tokamakZkEvmCliVersion !== undefined) {
|
|
4724
|
+
requireSemverVersion(args.tokamakZkEvmCliVersion, "--tokamak-zk-evm-cli-version");
|
|
4725
|
+
}
|
|
4584
4726
|
}
|
|
4585
4727
|
|
|
4586
4728
|
function assertUninstallZkEvmArgs(args) {
|
|
@@ -4790,8 +4932,9 @@ function persistCurrentState(context) {
|
|
|
4790
4932
|
function printHelp() {
|
|
4791
4933
|
console.log(`
|
|
4792
4934
|
Commands:
|
|
4793
|
-
--install [--docker] [--include-local-artifacts]
|
|
4935
|
+
--install [--docker] [--include-local-artifacts] [--groth16-cli-version <VERSION>] [--tokamak-zk-evm-cli-version <VERSION>]
|
|
4794
4936
|
Install the Tokamak zk-EVM CLI runtime, Groth16 runtime, and private-state deployment artifacts
|
|
4937
|
+
Version options install exact CLI package versions; omitted versions resolve to npm registry latest
|
|
4795
4938
|
Use --docker on Linux to forward Docker mode to the Tokamak zk-EVM and Groth16 runtimes
|
|
4796
4939
|
Use --include-local-artifacts to also install local deployment/ artifacts from the current working directory
|
|
4797
4940
|
|
|
@@ -5054,6 +5197,14 @@ function expect(condition, message) {
|
|
|
5054
5197
|
}
|
|
5055
5198
|
}
|
|
5056
5199
|
|
|
5200
|
+
function requireSemverVersion(value, label) {
|
|
5201
|
+
const normalized = requireNonEmptyString(value, label);
|
|
5202
|
+
if (!/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.]+)?(?:\+[0-9A-Za-z.]+)?$/.test(normalized)) {
|
|
5203
|
+
throw new Error(`${label} must be an exact semantic version. Received: ${normalized}`);
|
|
5204
|
+
}
|
|
5205
|
+
return normalized;
|
|
5206
|
+
}
|
|
5207
|
+
|
|
5057
5208
|
function resolveArtifactCacheBaseRoot(
|
|
5058
5209
|
cacheBaseRoot = process.env.PRIVATE_STATE_ARTIFACT_CACHE_ROOT
|
|
5059
5210
|
?? process.env.TOKAMAK_PRIVATE_CHANNELS_ROOT
|
|
@@ -5066,6 +5217,10 @@ function privateStateCliArtifactRoot(cacheBaseRoot = resolveArtifactCacheBaseRoo
|
|
|
5066
5217
|
return path.join(resolveArtifactCacheBaseRoot(cacheBaseRoot), "dapps", "private-state");
|
|
5067
5218
|
}
|
|
5068
5219
|
|
|
5220
|
+
function privateStateCliRuntimeRoot(cacheBaseRoot = resolveArtifactCacheBaseRoot()) {
|
|
5221
|
+
return path.join(privateStateCliArtifactRoot(cacheBaseRoot), "runtimes");
|
|
5222
|
+
}
|
|
5223
|
+
|
|
5069
5224
|
function privateStateCliArtifactChainDir(cacheBaseRoot = resolveArtifactCacheBaseRoot(), chainId) {
|
|
5070
5225
|
return path.join(privateStateCliArtifactRoot(cacheBaseRoot), `chain-id-${requireChainId(chainId)}`);
|
|
5071
5226
|
}
|
|
@@ -5090,11 +5245,17 @@ function privateStateCliInstallManifestPath(cacheBaseRoot = resolveArtifactCache
|
|
|
5090
5245
|
return path.join(privateStateCliArtifactRoot(cacheBaseRoot), "install-manifest.json");
|
|
5091
5246
|
}
|
|
5092
5247
|
|
|
5248
|
+
function readPrivateStateCliInstallManifest(cacheBaseRoot = resolveArtifactCacheBaseRoot()) {
|
|
5249
|
+
return readJsonIfExists(privateStateCliInstallManifestPath(cacheBaseRoot));
|
|
5250
|
+
}
|
|
5251
|
+
|
|
5093
5252
|
function writePrivateStateCliInstallManifest({
|
|
5094
5253
|
dockerRequested,
|
|
5095
5254
|
includeLocalArtifacts,
|
|
5096
5255
|
localDeploymentBaseRoot,
|
|
5097
5256
|
deploymentArtifacts,
|
|
5257
|
+
selectedVersions,
|
|
5258
|
+
tokamakCliRuntime,
|
|
5098
5259
|
groth16Runtime,
|
|
5099
5260
|
}) {
|
|
5100
5261
|
const manifestPath = privateStateCliInstallManifestPath(deploymentArtifacts.cacheBaseRoot);
|
|
@@ -5110,6 +5271,8 @@ function writePrivateStateCliInstallManifest({
|
|
|
5110
5271
|
includeLocalArtifacts,
|
|
5111
5272
|
localDeploymentBaseRoot,
|
|
5112
5273
|
artifactCacheRoot: deploymentArtifacts.cacheBaseRoot,
|
|
5274
|
+
selectedVersions,
|
|
5275
|
+
tokamakCliRuntime,
|
|
5113
5276
|
groth16Runtime,
|
|
5114
5277
|
installedDeploymentArtifacts: deploymentArtifacts.installed.map((entry) => ({
|
|
5115
5278
|
chainId: entry.chainId,
|
|
@@ -5138,6 +5301,11 @@ function buildDoctorReport() {
|
|
|
5138
5301
|
const tokamakCli = inspectTokamakCliRuntime();
|
|
5139
5302
|
const groth16Runtime = inspectGroth16Runtime();
|
|
5140
5303
|
const gpuDockerReadiness = inspectGpuDockerReadiness(tokamakCli);
|
|
5304
|
+
const selectedRuntimeVersionCheck = buildSelectedRuntimeVersionCheck({
|
|
5305
|
+
installManifest,
|
|
5306
|
+
tokamakCli,
|
|
5307
|
+
groth16Runtime,
|
|
5308
|
+
});
|
|
5141
5309
|
const checks = [
|
|
5142
5310
|
{
|
|
5143
5311
|
name: "dependency package versions",
|
|
@@ -5150,6 +5318,7 @@ function buildDoctorReport() {
|
|
|
5150
5318
|
error: entry.error,
|
|
5151
5319
|
})),
|
|
5152
5320
|
},
|
|
5321
|
+
selectedRuntimeVersionCheck,
|
|
5153
5322
|
{
|
|
5154
5323
|
name: "tokamak zk-evm runtime",
|
|
5155
5324
|
ok: tokamakCli.installed,
|
|
@@ -5203,6 +5372,9 @@ function buildDoctorReport() {
|
|
|
5203
5372
|
installedAt: installManifest?.installedAt ?? null,
|
|
5204
5373
|
dockerRequested: installManifest?.install?.dockerRequested ?? null,
|
|
5205
5374
|
includeLocalArtifacts: installManifest?.install?.includeLocalArtifacts ?? null,
|
|
5375
|
+
selectedVersions: installManifest?.install?.selectedVersions ?? null,
|
|
5376
|
+
tokamakCliRuntime: installManifest?.install?.tokamakCliRuntime ?? null,
|
|
5377
|
+
groth16Runtime: installManifest?.install?.groth16Runtime ?? null,
|
|
5206
5378
|
},
|
|
5207
5379
|
dependencies: dependencyReports,
|
|
5208
5380
|
tokamakCli,
|
|
@@ -5212,17 +5384,212 @@ function buildDoctorReport() {
|
|
|
5212
5384
|
};
|
|
5213
5385
|
}
|
|
5214
5386
|
|
|
5215
|
-
function
|
|
5216
|
-
const
|
|
5387
|
+
function buildSelectedRuntimeVersionCheck({ installManifest, tokamakCli, groth16Runtime }) {
|
|
5388
|
+
const selectedVersions = installManifest?.install?.selectedVersions ?? null;
|
|
5389
|
+
const details = [
|
|
5390
|
+
{
|
|
5391
|
+
name: TOKAMAK_ZKEVM_CLI_PACKAGE_NAME,
|
|
5392
|
+
selectedVersion: selectedVersions?.tokamak ?? null,
|
|
5393
|
+
installedVersion: tokamakCli.packageVersion ?? null,
|
|
5394
|
+
ok: !selectedVersions?.tokamak || selectedVersions.tokamak === tokamakCli.packageVersion,
|
|
5395
|
+
},
|
|
5396
|
+
{
|
|
5397
|
+
name: GROTH16_PACKAGE_NAME,
|
|
5398
|
+
selectedVersion: selectedVersions?.groth16 ?? null,
|
|
5399
|
+
installedVersion: groth16Runtime.packageVersion ?? null,
|
|
5400
|
+
crsVersion: groth16Runtime.crsVersion ?? null,
|
|
5401
|
+
ok: !selectedVersions?.groth16
|
|
5402
|
+
|| (
|
|
5403
|
+
selectedVersions.groth16 === groth16Runtime.packageVersion
|
|
5404
|
+
&& selectedVersions.groth16 === groth16Runtime.crsVersion
|
|
5405
|
+
),
|
|
5406
|
+
},
|
|
5407
|
+
];
|
|
5408
|
+
return {
|
|
5409
|
+
name: "selected proof backend runtime versions",
|
|
5410
|
+
ok: details.every((entry) => entry.ok),
|
|
5411
|
+
details,
|
|
5412
|
+
};
|
|
5413
|
+
}
|
|
5414
|
+
|
|
5415
|
+
async function resolvePrivateStateInstallRuntimeVersions(args) {
|
|
5416
|
+
const [groth16, tokamak] = await Promise.all([
|
|
5417
|
+
resolveRequestedNpmPackageVersion({
|
|
5418
|
+
packageName: GROTH16_PACKAGE_NAME,
|
|
5419
|
+
requestedVersion: args.groth16CliVersion,
|
|
5420
|
+
optionName: "--groth16-cli-version",
|
|
5421
|
+
}),
|
|
5422
|
+
resolveRequestedNpmPackageVersion({
|
|
5423
|
+
packageName: TOKAMAK_ZKEVM_CLI_PACKAGE_NAME,
|
|
5424
|
+
requestedVersion: args.tokamakZkEvmCliVersion,
|
|
5425
|
+
optionName: "--tokamak-zk-evm-cli-version",
|
|
5426
|
+
}),
|
|
5427
|
+
]);
|
|
5428
|
+
return { groth16, tokamak };
|
|
5429
|
+
}
|
|
5430
|
+
|
|
5431
|
+
async function resolveRequestedNpmPackageVersion({ packageName, requestedVersion, optionName }) {
|
|
5432
|
+
const metadata = await fetchNpmPackageMetadata(packageName);
|
|
5433
|
+
if (requestedVersion === undefined || requestedVersion === null) {
|
|
5434
|
+
return requireSemverVersion(metadata?.["dist-tags"]?.latest, `${packageName} npm latest version`);
|
|
5435
|
+
}
|
|
5436
|
+
|
|
5437
|
+
const normalizedVersion = requireSemverVersion(requestedVersion, optionName);
|
|
5438
|
+
if (!metadata.versions?.[normalizedVersion]) {
|
|
5439
|
+
throw new Error(`npm package ${packageName} does not contain version ${normalizedVersion}.`);
|
|
5440
|
+
}
|
|
5441
|
+
return normalizedVersion;
|
|
5442
|
+
}
|
|
5443
|
+
|
|
5444
|
+
async function fetchNpmPackageMetadata(packageName) {
|
|
5445
|
+
const normalizedPackageName = requireNonEmptyString(packageName, "packageName");
|
|
5446
|
+
const registryUrl = `https://registry.npmjs.org/${encodeURIComponent(normalizedPackageName)}`;
|
|
5447
|
+
const response = await fetch(registryUrl, { redirect: "follow" });
|
|
5448
|
+
if (!response.ok) {
|
|
5449
|
+
throw new Error(`Failed to read npm package metadata for ${normalizedPackageName}: HTTP ${response.status}.`);
|
|
5450
|
+
}
|
|
5451
|
+
try {
|
|
5452
|
+
return await response.json();
|
|
5453
|
+
} catch (error) {
|
|
5454
|
+
throw new Error(`npm package metadata for ${normalizedPackageName} is not valid JSON: ${error.message}`);
|
|
5455
|
+
}
|
|
5456
|
+
}
|
|
5457
|
+
|
|
5458
|
+
async function installTokamakCliRuntimeForPrivateState({ version, docker }) {
|
|
5459
|
+
const packageInstall = installManagedNpmPackage({
|
|
5460
|
+
packageName: TOKAMAK_ZKEVM_CLI_PACKAGE_NAME,
|
|
5461
|
+
version,
|
|
5462
|
+
});
|
|
5463
|
+
const invocation = buildTokamakCliInvocationForPackageRoot(packageInstall.packageRoot);
|
|
5464
|
+
const installArgs = [...invocation.args, "--install"];
|
|
5465
|
+
if (docker) {
|
|
5466
|
+
installArgs.push("--docker");
|
|
5467
|
+
}
|
|
5468
|
+
run(invocation.command, installArgs, { cwd: packageInstall.packageRoot });
|
|
5469
|
+
const doctor = runCaptured(invocation.command, [...invocation.args, "--doctor"], {
|
|
5470
|
+
cwd: packageInstall.packageRoot,
|
|
5471
|
+
});
|
|
5472
|
+
const doctorOutput = stripAnsi(`${doctor.stdout}${doctor.stderr}`);
|
|
5473
|
+
const runtimeRoot = parseRuntimeRootFromTokamakDoctorOutput(doctorOutput);
|
|
5474
|
+
expect(
|
|
5475
|
+
doctor.status === 0 && runtimeRoot,
|
|
5476
|
+
[
|
|
5477
|
+
"Tokamak zk-EVM CLI install completed, but tokamak-cli --doctor did not report a healthy runtime.",
|
|
5478
|
+
doctorOutput.trim(),
|
|
5479
|
+
].filter(Boolean).join(" "),
|
|
5480
|
+
);
|
|
5481
|
+
return {
|
|
5482
|
+
packageName: TOKAMAK_ZKEVM_CLI_PACKAGE_NAME,
|
|
5483
|
+
packageVersion: version,
|
|
5484
|
+
packageRoot: packageInstall.packageRoot,
|
|
5485
|
+
entryPath: invocation.entryPath,
|
|
5486
|
+
installPrefix: packageInstall.installPrefix,
|
|
5487
|
+
runtimeRoot,
|
|
5488
|
+
dockerRequested: Boolean(docker),
|
|
5489
|
+
};
|
|
5490
|
+
}
|
|
5491
|
+
|
|
5492
|
+
async function installGroth16RuntimeForPrivateState({ version, docker }) {
|
|
5493
|
+
const packageInstall = installManagedNpmPackage({
|
|
5494
|
+
packageName: GROTH16_PACKAGE_NAME,
|
|
5495
|
+
version,
|
|
5496
|
+
});
|
|
5497
|
+
const packageRoot = packageInstall.packageRoot;
|
|
5217
5498
|
const entryPath = resolveGroth16CliEntryPath(packageRoot);
|
|
5218
|
-
const args = [entryPath, "--install"];
|
|
5499
|
+
const args = [entryPath, "--install", "--no-setup"];
|
|
5219
5500
|
if (docker) {
|
|
5220
5501
|
args.push("--docker");
|
|
5221
5502
|
}
|
|
5222
5503
|
run(process.execPath, args, { cwd: packageRoot });
|
|
5223
|
-
const
|
|
5504
|
+
const crsInstall = await installGroth16CrsForPrivateStateVersion(version);
|
|
5505
|
+
const runtime = inspectGroth16Runtime({ packageRoot });
|
|
5224
5506
|
expect(runtime.installed, "Groth16 runtime install completed, but tokamak-groth16 --doctor still reports an unhealthy runtime.");
|
|
5225
|
-
return
|
|
5507
|
+
return {
|
|
5508
|
+
...runtime,
|
|
5509
|
+
packageName: GROTH16_PACKAGE_NAME,
|
|
5510
|
+
packageVersion: version,
|
|
5511
|
+
packageRoot,
|
|
5512
|
+
entryPath,
|
|
5513
|
+
installPrefix: packageInstall.installPrefix,
|
|
5514
|
+
crsVersion: crsInstall.version,
|
|
5515
|
+
crs: crsInstall,
|
|
5516
|
+
dockerRequested: Boolean(docker),
|
|
5517
|
+
};
|
|
5518
|
+
}
|
|
5519
|
+
|
|
5520
|
+
async function installGroth16CrsForPrivateStateVersion(version) {
|
|
5521
|
+
const workspaceRoot = defaultGroth16WorkspaceRoot();
|
|
5522
|
+
const crsDir = path.join(workspaceRoot, "crs");
|
|
5523
|
+
const crsInstall = await downloadPublicGroth16MpcArtifactsByVersion({
|
|
5524
|
+
version,
|
|
5525
|
+
outputDir: crsDir,
|
|
5526
|
+
selectedFiles: [
|
|
5527
|
+
"circuit_final.zkey",
|
|
5528
|
+
"verification_key.json",
|
|
5529
|
+
"metadata.json",
|
|
5530
|
+
"zkey_provenance.json",
|
|
5531
|
+
],
|
|
5532
|
+
});
|
|
5533
|
+
const manifestPath = path.join(workspaceRoot, "install-manifest.json");
|
|
5534
|
+
const manifest = readJsonIfExists(manifestPath) ?? {};
|
|
5535
|
+
writeJson(manifestPath, {
|
|
5536
|
+
...manifest,
|
|
5537
|
+
workspaceRoot,
|
|
5538
|
+
crsSource: "public-drive-mpc",
|
|
5539
|
+
crs: crsInstall,
|
|
5540
|
+
});
|
|
5541
|
+
return crsInstall;
|
|
5542
|
+
}
|
|
5543
|
+
|
|
5544
|
+
function installManagedNpmPackage({ packageName, version, cacheBaseRoot = resolveArtifactCacheBaseRoot() }) {
|
|
5545
|
+
const normalizedPackageName = requireNonEmptyString(packageName, "packageName");
|
|
5546
|
+
const normalizedVersion = requireSemverVersion(version, `${normalizedPackageName} version`);
|
|
5547
|
+
const installPrefix = managedNpmPackageInstallPrefix({
|
|
5548
|
+
packageName: normalizedPackageName,
|
|
5549
|
+
version: normalizedVersion,
|
|
5550
|
+
cacheBaseRoot,
|
|
5551
|
+
});
|
|
5552
|
+
fs.mkdirSync(installPrefix, { recursive: true });
|
|
5553
|
+
run("npm", [
|
|
5554
|
+
"install",
|
|
5555
|
+
"--prefix",
|
|
5556
|
+
installPrefix,
|
|
5557
|
+
"--omit=dev",
|
|
5558
|
+
"--no-audit",
|
|
5559
|
+
"--fund=false",
|
|
5560
|
+
`${normalizedPackageName}@${normalizedVersion}`,
|
|
5561
|
+
]);
|
|
5562
|
+
const packageRoot = path.join(installPrefix, "node_modules", ...normalizedPackageName.split("/"));
|
|
5563
|
+
const packageJsonPath = path.join(packageRoot, "package.json");
|
|
5564
|
+
const packageJson = readJson(packageJsonPath);
|
|
5565
|
+
expect(
|
|
5566
|
+
packageJson.name === normalizedPackageName && packageJson.version === normalizedVersion,
|
|
5567
|
+
`Installed package ${packageJsonPath} does not match ${normalizedPackageName}@${normalizedVersion}.`,
|
|
5568
|
+
);
|
|
5569
|
+
return {
|
|
5570
|
+
packageName: normalizedPackageName,
|
|
5571
|
+
version: normalizedVersion,
|
|
5572
|
+
installPrefix,
|
|
5573
|
+
packageRoot,
|
|
5574
|
+
};
|
|
5575
|
+
}
|
|
5576
|
+
|
|
5577
|
+
function managedNpmPackageInstallPrefix({ packageName, version, cacheBaseRoot = resolveArtifactCacheBaseRoot() }) {
|
|
5578
|
+
const safePackageName = requireNonEmptyString(packageName, "packageName")
|
|
5579
|
+
.replace(/^@/, "")
|
|
5580
|
+
.replace(/[^A-Za-z0-9._-]+/g, "__");
|
|
5581
|
+
return path.join(privateStateCliRuntimeRoot(cacheBaseRoot), "npm", safePackageName, requireSemverVersion(version, "version"));
|
|
5582
|
+
}
|
|
5583
|
+
|
|
5584
|
+
async function downloadGroth16CrsArtifactsForPrivateState({
|
|
5585
|
+
version,
|
|
5586
|
+
outputDir,
|
|
5587
|
+
selectedFiles,
|
|
5588
|
+
}) {
|
|
5589
|
+
if (version === undefined || version === null) {
|
|
5590
|
+
return downloadLatestPublicGroth16MpcArtifacts({ outputDir, selectedFiles });
|
|
5591
|
+
}
|
|
5592
|
+
return downloadPublicGroth16MpcArtifactsByVersion({ version, outputDir, selectedFiles });
|
|
5226
5593
|
}
|
|
5227
5594
|
|
|
5228
5595
|
function collectDependencyPackageReports(installManifest = null) {
|
|
@@ -5233,11 +5600,11 @@ function collectDependencyPackageReports(installManifest = null) {
|
|
|
5233
5600
|
);
|
|
5234
5601
|
const targets = [
|
|
5235
5602
|
{
|
|
5236
|
-
name:
|
|
5237
|
-
packageJsonPath: path.join(
|
|
5603
|
+
name: TOKAMAK_ZKEVM_CLI_PACKAGE_NAME,
|
|
5604
|
+
packageJsonPath: path.join(resolveBundledTokamakCliPackageRoot(), "package.json"),
|
|
5238
5605
|
},
|
|
5239
5606
|
{
|
|
5240
|
-
name:
|
|
5607
|
+
name: GROTH16_PACKAGE_NAME,
|
|
5241
5608
|
resolveTarget: "@tokamak-private-dapps/groth16/public-drive-crs",
|
|
5242
5609
|
},
|
|
5243
5610
|
{
|
|
@@ -5301,21 +5668,42 @@ function resolveGroth16PackageRoot() {
|
|
|
5301
5668
|
return path.dirname(findPackageJsonForName(path.dirname(publicDriveCrsPath), "@tokamak-private-dapps/groth16"));
|
|
5302
5669
|
}
|
|
5303
5670
|
|
|
5671
|
+
function resolveActiveGroth16PackageRoot() {
|
|
5672
|
+
const manifestPackageRoot = readPrivateStateCliInstallManifest()?.install?.groth16Runtime?.packageRoot;
|
|
5673
|
+
if (manifestPackageRoot && fs.existsSync(path.join(manifestPackageRoot, "package.json"))) {
|
|
5674
|
+
return manifestPackageRoot;
|
|
5675
|
+
}
|
|
5676
|
+
return resolveGroth16PackageRoot();
|
|
5677
|
+
}
|
|
5678
|
+
|
|
5304
5679
|
function resolveGroth16CliEntryPath(packageRoot = resolveGroth16PackageRoot()) {
|
|
5305
5680
|
return path.join(packageRoot, "cli", "tokamak-groth16-cli.mjs");
|
|
5306
5681
|
}
|
|
5307
5682
|
|
|
5308
|
-
function
|
|
5309
|
-
|
|
5683
|
+
function defaultGroth16WorkspaceRoot() {
|
|
5684
|
+
return path.join(os.homedir(), "tokamak-private-channels", "groth16");
|
|
5685
|
+
}
|
|
5686
|
+
|
|
5687
|
+
function inspectGroth16Runtime({ packageRoot = resolveActiveGroth16PackageRoot() } = {}) {
|
|
5310
5688
|
const entryPath = resolveGroth16CliEntryPath(packageRoot);
|
|
5311
5689
|
const doctor = runCaptured(process.execPath, [entryPath, "--doctor", "--verbose"], { cwd: packageRoot });
|
|
5312
5690
|
const stdout = stripAnsi(doctor.stdout).trim();
|
|
5313
5691
|
const stderr = stripAnsi(doctor.stderr).trim();
|
|
5314
5692
|
const report = parseJsonReport(stdout);
|
|
5693
|
+
const workspaceRoot = report?.workspaceRoot ?? defaultGroth16WorkspaceRoot();
|
|
5694
|
+
const workspaceManifest = readJsonIfExists(path.join(workspaceRoot, "install-manifest.json"));
|
|
5695
|
+
const packageReport = readPackageReport({
|
|
5696
|
+
name: GROTH16_PACKAGE_NAME,
|
|
5697
|
+
packageJsonPath: path.join(packageRoot, "package.json"),
|
|
5698
|
+
});
|
|
5315
5699
|
return {
|
|
5316
5700
|
installed: doctor.status === 0 && report?.ok === true,
|
|
5701
|
+
packageVersion: packageReport.version,
|
|
5317
5702
|
packageRoot,
|
|
5703
|
+
entryPath,
|
|
5318
5704
|
workspaceRoot: report?.workspaceRoot ?? null,
|
|
5705
|
+
crsVersion: workspaceManifest?.crs?.version ?? null,
|
|
5706
|
+
crs: workspaceManifest?.crs ?? null,
|
|
5319
5707
|
checks: report?.checks ?? [],
|
|
5320
5708
|
doctor: {
|
|
5321
5709
|
status: doctor.status,
|
|
@@ -5325,9 +5713,41 @@ function inspectGroth16Runtime() {
|
|
|
5325
5713
|
};
|
|
5326
5714
|
}
|
|
5327
5715
|
|
|
5328
|
-
function
|
|
5329
|
-
const
|
|
5330
|
-
|
|
5716
|
+
function resolveActiveTokamakCliPackageRoot() {
|
|
5717
|
+
const manifestPackageRoot = readPrivateStateCliInstallManifest()?.install?.tokamakCliRuntime?.packageRoot;
|
|
5718
|
+
if (manifestPackageRoot && fs.existsSync(path.join(manifestPackageRoot, "package.json"))) {
|
|
5719
|
+
return manifestPackageRoot;
|
|
5720
|
+
}
|
|
5721
|
+
return resolveBundledTokamakCliPackageRoot();
|
|
5722
|
+
}
|
|
5723
|
+
|
|
5724
|
+
function buildTokamakCliInvocationForPackageRoot(packageRoot = resolveActiveTokamakCliPackageRoot()) {
|
|
5725
|
+
const resolvedPackageRoot = path.resolve(packageRoot);
|
|
5726
|
+
const entryPath = resolvedPackageRoot === resolveBundledTokamakCliPackageRoot()
|
|
5727
|
+
? resolveTokamakCliEntryPath()
|
|
5728
|
+
: path.join(resolvedPackageRoot, "dist", "cli.js");
|
|
5729
|
+
return {
|
|
5730
|
+
command: process.execPath,
|
|
5731
|
+
args: [entryPath],
|
|
5732
|
+
entryPath,
|
|
5733
|
+
packageRoot: resolvedPackageRoot,
|
|
5734
|
+
};
|
|
5735
|
+
}
|
|
5736
|
+
|
|
5737
|
+
function resolveTokamakCliResourceDirForRuntimeRoot(runtimeRoot, ...segments) {
|
|
5738
|
+
return path.join(runtimeRoot, "resource", ...segments);
|
|
5739
|
+
}
|
|
5740
|
+
|
|
5741
|
+
function requireActiveTokamakCliRuntimeRoot() {
|
|
5742
|
+
const runtime = inspectTokamakCliRuntime();
|
|
5743
|
+
expect(runtime.runtimeRoot, "Unable to resolve the installed Tokamak zk-EVM runtime root. Run --install first.");
|
|
5744
|
+
return runtime.runtimeRoot;
|
|
5745
|
+
}
|
|
5746
|
+
|
|
5747
|
+
function inspectTokamakCliRuntime({ packageRoot = resolveActiveTokamakCliPackageRoot() } = {}) {
|
|
5748
|
+
const invocation = buildTokamakCliInvocationForPackageRoot(packageRoot);
|
|
5749
|
+
const doctor = runCaptured(invocation.command, [...invocation.args, "--doctor"], {
|
|
5750
|
+
cwd: invocation.packageRoot,
|
|
5331
5751
|
});
|
|
5332
5752
|
const doctorOutput = stripAnsi(`${doctor.stdout}${doctor.stderr}`);
|
|
5333
5753
|
const runtimeRoot = parseRuntimeRootFromTokamakDoctorOutput(doctorOutput);
|
|
@@ -5338,12 +5758,13 @@ function inspectTokamakCliRuntime() {
|
|
|
5338
5758
|
|
|
5339
5759
|
return {
|
|
5340
5760
|
installed: doctor.status === 0 || installations.length > 0,
|
|
5341
|
-
packageRoot:
|
|
5761
|
+
packageRoot: invocation.packageRoot,
|
|
5762
|
+
entryPath: invocation.entryPath,
|
|
5342
5763
|
cacheRoot,
|
|
5343
5764
|
runtimeRoot,
|
|
5344
5765
|
packageVersion: readPackageReport({
|
|
5345
|
-
name:
|
|
5346
|
-
packageJsonPath: path.join(
|
|
5766
|
+
name: TOKAMAK_ZKEVM_CLI_PACKAGE_NAME,
|
|
5767
|
+
packageJsonPath: path.join(invocation.packageRoot, "package.json"),
|
|
5347
5768
|
}).version,
|
|
5348
5769
|
dockerModeInstalled,
|
|
5349
5770
|
cudaCompatible,
|
|
@@ -5484,6 +5905,7 @@ async function installPrivateStateCliArtifacts({
|
|
|
5484
5905
|
cacheBaseRoot,
|
|
5485
5906
|
localDeploymentBaseRoot,
|
|
5486
5907
|
localChainIds = [31337],
|
|
5908
|
+
groth16CrsVersion,
|
|
5487
5909
|
} = {}) {
|
|
5488
5910
|
const normalizedDappName = requireNonEmptyString(dappName, "dappName");
|
|
5489
5911
|
const normalizedCacheBaseRoot = resolveArtifactCacheBaseRoot(cacheBaseRoot);
|
|
@@ -5504,6 +5926,7 @@ async function installPrivateStateCliArtifacts({
|
|
|
5504
5926
|
dappName: normalizedDappName,
|
|
5505
5927
|
cacheBaseRoot: normalizedCacheBaseRoot,
|
|
5506
5928
|
source: "drive",
|
|
5929
|
+
groth16CrsVersion,
|
|
5507
5930
|
}));
|
|
5508
5931
|
}
|
|
5509
5932
|
|
|
@@ -5514,6 +5937,7 @@ async function installPrivateStateCliArtifacts({
|
|
|
5514
5937
|
dappName: normalizedDappName,
|
|
5515
5938
|
cacheBaseRoot: normalizedCacheBaseRoot,
|
|
5516
5939
|
localDeploymentBaseRoot: normalizedLocalDeploymentBaseRoot,
|
|
5940
|
+
groth16CrsVersion,
|
|
5517
5941
|
}));
|
|
5518
5942
|
}
|
|
5519
5943
|
}
|
|
@@ -5535,6 +5959,7 @@ async function materializePrivateStateCliDeployment({
|
|
|
5535
5959
|
dappName,
|
|
5536
5960
|
cacheBaseRoot,
|
|
5537
5961
|
source,
|
|
5962
|
+
groth16CrsVersion,
|
|
5538
5963
|
}) {
|
|
5539
5964
|
const normalizedChainId = String(requireChainId(chainId));
|
|
5540
5965
|
const normalizedDappName = requireNonEmptyString(dappName, "dappName");
|
|
@@ -5566,7 +5991,8 @@ async function materializePrivateStateCliDeployment({
|
|
|
5566
5991
|
[`groth16.${normalizedChainId}.latest.json`, path.basename(paths.grothManifestPath)],
|
|
5567
5992
|
],
|
|
5568
5993
|
});
|
|
5569
|
-
await
|
|
5994
|
+
await downloadGroth16CrsArtifactsForPrivateState({
|
|
5995
|
+
version: groth16CrsVersion,
|
|
5570
5996
|
outputDir: paths.rootDir,
|
|
5571
5997
|
selectedFiles: [
|
|
5572
5998
|
["circuit_final.zkey", path.basename(paths.grothZkeyPath)],
|
|
@@ -5598,6 +6024,7 @@ async function materializeLocalPrivateStateCliDeployment({
|
|
|
5598
6024
|
dappName,
|
|
5599
6025
|
cacheBaseRoot,
|
|
5600
6026
|
localDeploymentBaseRoot,
|
|
6027
|
+
groth16CrsVersion,
|
|
5601
6028
|
}) {
|
|
5602
6029
|
const normalizedChainId = String(requireChainId(chainId));
|
|
5603
6030
|
const normalizedDappName = requireNonEmptyString(dappName, "dappName");
|
|
@@ -5634,7 +6061,8 @@ async function materializeLocalPrivateStateCliDeployment({
|
|
|
5634
6061
|
[path.join(dappDir, `dapp-registration.${normalizedChainId}.json`), path.basename(paths.dappRegistrationPath)],
|
|
5635
6062
|
],
|
|
5636
6063
|
});
|
|
5637
|
-
await
|
|
6064
|
+
await downloadGroth16CrsArtifactsForPrivateState({
|
|
6065
|
+
version: groth16CrsVersion,
|
|
5638
6066
|
outputDir: paths.rootDir,
|
|
5639
6067
|
selectedFiles: [
|
|
5640
6068
|
["circuit_final.zkey", path.basename(paths.grothZkeyPath)],
|