@tokamak-private-dapps/private-state-cli 0.1.5 → 0.1.8
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 +20 -0
- package/README.md +15 -1
- package/package.json +5 -5
- package/private-state-bridge-cli.mjs +539 -57
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.1.8 - 2026-04-30
|
|
4
|
+
|
|
5
|
+
- Reused common proof backend version helpers for Tokamak and Groth16 compatibility checks.
|
|
6
|
+
- Reused common npm registry metadata lookup during proof backend runtime installation.
|
|
7
|
+
|
|
8
|
+
## 0.1.7 - 2026-04-29
|
|
9
|
+
|
|
10
|
+
- Required Groth16 channel verifier and installed CRS compatibility versions to use canonical major.minor form.
|
|
11
|
+
- Matched Groth16 channel verifier compatibility against the installed CRS major.minor compatibility version.
|
|
12
|
+
- Required the Groth16 package version with verified public CRS archive selection.
|
|
13
|
+
- Required Tokamak zk-EVM channel verifier and CLI package compatibility versions to use canonical major.minor form.
|
|
14
|
+
|
|
15
|
+
## 0.1.6 - 2026-04-29
|
|
16
|
+
|
|
17
|
+
- Added `--groth16-cli-version` and `--tokamak-zk-evm-cli-version` install options with npm latest defaults.
|
|
18
|
+
- Installed selected proof backend package versions into managed runtime directories.
|
|
19
|
+
- Downloaded Groth16 CRS artifacts matching the selected Groth16 CLI version.
|
|
20
|
+
- Checked channel verifier compatible backend versions before local proof generation.
|
|
21
|
+
- Reported selected proof backend runtime versions from `--doctor`.
|
|
22
|
+
|
|
3
23
|
## 0.1.5 - 2026-04-28
|
|
4
24
|
|
|
5
25
|
- Switched channel balance proof generation to invoke `tokamak-groth16 --prove` instead of importing Groth16 proof internals directly.
|
package/README.md
CHANGED
|
@@ -15,6 +15,18 @@ 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 whose major.minor compatibility version matches the
|
|
26
|
+
selected Groth16 CLI package version.
|
|
27
|
+
The Tokamak zk-EVM installer requires the selected CLI package to declare
|
|
28
|
+
`tokamakZkEvm.compatibleBackendVersion` as a canonical major.minor version matching the selected package version.
|
|
29
|
+
|
|
18
30
|
`--install` downloads public deployment artifacts from the configured artifact index. It does not read repository-local
|
|
19
31
|
`deployment/` outputs by default. Repository development workflows that need local anvil artifacts can opt in explicitly:
|
|
20
32
|
|
|
@@ -52,7 +64,7 @@ A common private-state flow is:
|
|
|
52
64
|
Use `private-state-cli --help` for the full command list and required options.
|
|
53
65
|
|
|
54
66
|
`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
|
|
67
|
+
`private-state-cli --install`, selected proof backend runtime versions, current dependency versions through `tokamak-l2js`, and Tokamak zk-EVM runtime
|
|
56
68
|
install mode, Docker mode, CUDA runtime metadata, live `nvidia-smi` and Docker GPU probe results, and Groth16
|
|
57
69
|
runtime health. The doctor check fails when the Tokamak Docker `useGpus` metadata does not match the live GPU probes.
|
|
58
70
|
|
|
@@ -138,6 +150,8 @@ using bridge-facing commands on a new machine.
|
|
|
138
150
|
Channel balance commands such as `deposit-channel` and `withdraw-channel` use the installed Groth16 runtime workspace
|
|
139
151
|
directly. Proof generation writes to the fixed workspace paths under `~/tokamak-private-channels/groth16/proof`; the CLI
|
|
140
152
|
does not pass custom `--zkey`, proof-output, or public-output paths to the Groth16 prover.
|
|
153
|
+
Before proof generation, the CLI compares the target channel's verifier compatibility versions with the installed
|
|
154
|
+
Tokamak zk-EVM and Groth16 major.minor compatibility versions.
|
|
141
155
|
|
|
142
156
|
Release order matters for npm publication. `@tokamak-private-dapps/common-library` and
|
|
143
157
|
`@tokamak-private-dapps/groth16` must be published before this package version.
|
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.8",
|
|
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",
|
|
@@ -41,10 +41,10 @@
|
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
43
|
"@ethereumjs/util": "^10.1.1",
|
|
44
|
-
"@noble/curves": "
|
|
45
|
-
"@tokamak-private-dapps/common-library": "^0.1.
|
|
46
|
-
"@tokamak-private-dapps/groth16": "^0.1.
|
|
47
|
-
"@tokamak-zk-evm/cli": "^2.0.
|
|
44
|
+
"@noble/curves": "1.9.7",
|
|
45
|
+
"@tokamak-private-dapps/common-library": "^0.1.1",
|
|
46
|
+
"@tokamak-private-dapps/groth16": "^0.1.4",
|
|
47
|
+
"@tokamak-zk-evm/cli": "^2.0.13",
|
|
48
48
|
"ethers": "^6.14.1",
|
|
49
49
|
"tokamak-l2js": "^0.1.3"
|
|
50
50
|
},
|
|
@@ -44,12 +44,17 @@ import {
|
|
|
44
44
|
hexToBytes,
|
|
45
45
|
} from "@ethereumjs/util";
|
|
46
46
|
import { deriveRpcUrl, resolveCliNetwork } from "@tokamak-private-dapps/common-library/network-config";
|
|
47
|
+
import { fetchNpmPackageMetadata } from "@tokamak-private-dapps/common-library/npm-registry";
|
|
48
|
+
import {
|
|
49
|
+
normalizePackageVersionToCompatibleBackendVersion,
|
|
50
|
+
readTokamakZkEvmCompatibleBackendVersionFromPackageJson,
|
|
51
|
+
requireCanonicalCompatibleBackendVersion,
|
|
52
|
+
requireExactSemverVersion,
|
|
53
|
+
} from "@tokamak-private-dapps/common-library/proof-backend-versioning";
|
|
47
54
|
import {
|
|
48
|
-
buildTokamakCliInvocation,
|
|
49
55
|
resolveTokamakBlockInputConfig,
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
resolveTokamakCliRuntimeRoot,
|
|
56
|
+
resolveTokamakCliEntryPath,
|
|
57
|
+
resolveTokamakCliPackageRoot as resolveBundledTokamakCliPackageRoot,
|
|
53
58
|
} from "@tokamak-private-dapps/common-library/tokamak-runtime-paths";
|
|
54
59
|
import {
|
|
55
60
|
DEFAULT_PUBLIC_ARTIFACT_INDEX_FILE_ID,
|
|
@@ -66,6 +71,9 @@ import { toGroth16SolidityProof } from "@tokamak-private-dapps/common-library/gr
|
|
|
66
71
|
import {
|
|
67
72
|
PUBLIC_GROTH16_MPC_DRIVE_FOLDER_ID,
|
|
68
73
|
downloadLatestPublicGroth16MpcArtifacts,
|
|
74
|
+
downloadPublicGroth16MpcArtifactsByVersion,
|
|
75
|
+
readGroth16CompatibleBackendVersionFromPackageJson,
|
|
76
|
+
requireCanonicalGroth16CompatibleBackendVersion,
|
|
69
77
|
} from "@tokamak-private-dapps/groth16/public-drive-crs";
|
|
70
78
|
import {
|
|
71
79
|
CHANNEL_BOUND_L2_DERIVATION_MODE,
|
|
@@ -85,17 +93,20 @@ const require = createRequire(import.meta.url);
|
|
|
85
93
|
const defaultCommandCwd = process.cwd();
|
|
86
94
|
const privateStateCliPackageRoot = path.dirname(require.resolve("./package.json"));
|
|
87
95
|
const workspaceRoot = path.resolve(os.homedir(), "tokamak-private-channels", "workspace");
|
|
88
|
-
const tokamakCliInvocation = buildTokamakCliInvocation();
|
|
89
|
-
const tokamakCliCommand = tokamakCliInvocation.command;
|
|
90
|
-
const tokamakCliBaseArgs = tokamakCliInvocation.args;
|
|
91
96
|
const flatDeploymentArtifactPathsByChainId = new Map();
|
|
92
97
|
const DOCKER_CUDA_PROBE_IMAGE = "nvidia/cuda:12.2.0-base-ubuntu22.04";
|
|
93
98
|
const DOCTOR_GPU_PROBE_TIMEOUT_MS = 120000;
|
|
99
|
+
const GROTH16_PACKAGE_NAME = "@tokamak-private-dapps/groth16";
|
|
100
|
+
const TOKAMAK_ZKEVM_CLI_PACKAGE_NAME = "@tokamak-zk-evm/cli";
|
|
94
101
|
|
|
95
102
|
const abiCoder = AbiCoder.defaultAbiCoder();
|
|
96
103
|
const erc20MetadataAbi = [
|
|
97
104
|
"function decimals() view returns (uint8)",
|
|
98
105
|
];
|
|
106
|
+
const channelVerifierVersionAbi = [
|
|
107
|
+
"function grothVerifierCompatibleBackendVersion() view returns (string)",
|
|
108
|
+
"function tokamakVerifierCompatibleBackendVersion() view returns (string)",
|
|
109
|
+
];
|
|
99
110
|
const {
|
|
100
111
|
aPubBlockLength: TOKAMAK_APUB_BLOCK_LENGTH,
|
|
101
112
|
previousBlockHashCount: TOKAMAK_PREVIOUS_BLOCK_HASH_COUNT,
|
|
@@ -952,31 +963,36 @@ function clearWalletRecoveryArtifacts(walletDir) {
|
|
|
952
963
|
}
|
|
953
964
|
|
|
954
965
|
async function handleInstallZkEvm({ args }) {
|
|
955
|
-
const
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
const
|
|
961
|
-
|
|
966
|
+
const selectedVersions = await resolvePrivateStateInstallRuntimeVersions(args);
|
|
967
|
+
const tokamakCliRuntime = await installTokamakCliRuntimeForPrivateState({
|
|
968
|
+
version: selectedVersions.tokamak,
|
|
969
|
+
docker: Boolean(args.docker),
|
|
970
|
+
});
|
|
971
|
+
const groth16Runtime = await installGroth16RuntimeForPrivateState({
|
|
972
|
+
version: selectedVersions.groth16,
|
|
962
973
|
docker: Boolean(args.docker),
|
|
963
974
|
});
|
|
964
975
|
const localDeploymentBaseRoot = args.includeLocalArtifacts ? process.cwd() : null;
|
|
965
976
|
const deploymentArtifacts = await installPrivateStateCliArtifacts({
|
|
966
977
|
dappName: PRIVATE_STATE_DAPP_LABEL,
|
|
967
978
|
localDeploymentBaseRoot,
|
|
979
|
+
groth16CrsVersion: groth16Runtime.compatibleBackendVersion,
|
|
968
980
|
});
|
|
969
981
|
const installManifest = writePrivateStateCliInstallManifest({
|
|
970
982
|
dockerRequested: Boolean(args.docker),
|
|
971
983
|
includeLocalArtifacts: Boolean(args.includeLocalArtifacts),
|
|
972
984
|
localDeploymentBaseRoot,
|
|
973
985
|
deploymentArtifacts,
|
|
986
|
+
selectedVersions,
|
|
987
|
+
tokamakCliRuntime,
|
|
974
988
|
groth16Runtime,
|
|
975
989
|
});
|
|
976
990
|
printJson({
|
|
977
991
|
action: "install",
|
|
978
|
-
|
|
979
|
-
|
|
992
|
+
selectedVersions,
|
|
993
|
+
tokamakCli: tokamakCliRuntime.entryPath,
|
|
994
|
+
runtimeRoot: tokamakCliRuntime.runtimeRoot,
|
|
995
|
+
tokamakCliRuntime,
|
|
980
996
|
groth16Runtime,
|
|
981
997
|
docker: Boolean(args.docker),
|
|
982
998
|
includeLocalArtifacts: Boolean(args.includeLocalArtifacts),
|
|
@@ -996,12 +1012,13 @@ async function handleInstallZkEvm({ args }) {
|
|
|
996
1012
|
|
|
997
1013
|
async function handleUninstallZkEvm() {
|
|
998
1014
|
let runtimeRoot = null;
|
|
1015
|
+
const invocation = buildTokamakCliInvocationForPackageRoot();
|
|
999
1016
|
try {
|
|
1000
|
-
runtimeRoot =
|
|
1017
|
+
runtimeRoot = inspectTokamakCliRuntime({ packageRoot: invocation.packageRoot }).runtimeRoot;
|
|
1001
1018
|
} catch {
|
|
1002
1019
|
runtimeRoot = null;
|
|
1003
1020
|
}
|
|
1004
|
-
run(
|
|
1021
|
+
run(invocation.command, [...invocation.args, "--uninstall"], { cwd: invocation.packageRoot });
|
|
1005
1022
|
|
|
1006
1023
|
printJson({
|
|
1007
1024
|
action: "uninstall-zk-evm",
|
|
@@ -1309,10 +1326,16 @@ async function handleGrothVaultMove({ args, provider, direction }) {
|
|
|
1309
1326
|
const contextResult = await loadPreferredWalletChannelContext({ walletContext, provider });
|
|
1310
1327
|
const context = contextResult.context;
|
|
1311
1328
|
const network = contextResult.network;
|
|
1329
|
+
const operationName = args.command === "withdraw-channel"
|
|
1330
|
+
? "withdraw-channel"
|
|
1331
|
+
: direction === "deposit"
|
|
1332
|
+
? "deposit-channel"
|
|
1333
|
+
: "withdraw";
|
|
1312
1334
|
expect(
|
|
1313
1335
|
ethers.toBigInt(walletContext.wallet.channelId) === ethers.toBigInt(context.workspace.channelId),
|
|
1314
1336
|
"The provided wallet does not belong to the selected channel.",
|
|
1315
1337
|
);
|
|
1338
|
+
await assertChannelProofBackendVersionCompatibility({ context, operationName });
|
|
1316
1339
|
|
|
1317
1340
|
const { signer, l2Identity } = restoreWalletParticipant(walletContext, provider);
|
|
1318
1341
|
const amountInput = requireArg(args.amount, "--amount");
|
|
@@ -1364,11 +1387,6 @@ async function handleGrothVaultMove({ args, provider, direction }) {
|
|
|
1364
1387
|
nextValue = currentValue - amount;
|
|
1365
1388
|
}
|
|
1366
1389
|
|
|
1367
|
-
const operationName = args.command === "withdraw-channel"
|
|
1368
|
-
? "withdraw-channel"
|
|
1369
|
-
: direction === "deposit"
|
|
1370
|
-
? "deposit-channel"
|
|
1371
|
-
: "withdraw";
|
|
1372
1390
|
const operationDir = createWalletOperationDir(
|
|
1373
1391
|
walletContext.walletName,
|
|
1374
1392
|
walletContext.wallet.network,
|
|
@@ -3057,6 +3075,7 @@ async function executeWalletTemplateSend({
|
|
|
3057
3075
|
}) {
|
|
3058
3076
|
await assertWorkspaceAlignedWithChain(context, signer.provider);
|
|
3059
3077
|
assertWalletMatchesChannelContext(wallet, l2Identity, context);
|
|
3078
|
+
await assertChannelProofBackendVersionCompatibility({ context, operationName });
|
|
3060
3079
|
|
|
3061
3080
|
const controllerAbi = readJson(
|
|
3062
3081
|
requireLatestDappDeployArtifactPath(context.workspace.chainId, path.basename(templatePayload.abiFile)),
|
|
@@ -3428,6 +3447,145 @@ async function assertWorkspaceAlignedWithChain(context) {
|
|
|
3428
3447
|
);
|
|
3429
3448
|
}
|
|
3430
3449
|
|
|
3450
|
+
async function assertChannelProofBackendVersionCompatibility({ context, operationName }) {
|
|
3451
|
+
const channelVersions = await readChannelVerifierCompatibleBackendVersions(context);
|
|
3452
|
+
const localVersions = readLocalProofBackendPackageVersions();
|
|
3453
|
+
const checks = [
|
|
3454
|
+
{
|
|
3455
|
+
label: "Groth16",
|
|
3456
|
+
packageName: GROTH16_PACKAGE_NAME,
|
|
3457
|
+
versionKind: "compatible backend version",
|
|
3458
|
+
channelVersion: requireCanonicalGroth16CompatibleBackendVersion(
|
|
3459
|
+
channelVersions.groth16,
|
|
3460
|
+
"channel Groth16 verifier compatibleBackendVersion",
|
|
3461
|
+
),
|
|
3462
|
+
localVersion: localVersions.groth16.compatibleBackendVersion,
|
|
3463
|
+
},
|
|
3464
|
+
{
|
|
3465
|
+
label: "Tokamak zk-EVM",
|
|
3466
|
+
packageName: TOKAMAK_ZKEVM_CLI_PACKAGE_NAME,
|
|
3467
|
+
versionKind: "compatible backend version",
|
|
3468
|
+
channelVersion: requireCanonicalCompatibleBackendVersion(
|
|
3469
|
+
channelVersions.tokamak,
|
|
3470
|
+
"channel Tokamak verifier compatibleBackendVersion",
|
|
3471
|
+
),
|
|
3472
|
+
localVersion: localVersions.tokamak.compatibleBackendVersion,
|
|
3473
|
+
},
|
|
3474
|
+
];
|
|
3475
|
+
const mismatches = checks.filter(({ channelVersion, localVersion }) => channelVersion !== localVersion);
|
|
3476
|
+
if (mismatches.length === 0) {
|
|
3477
|
+
return;
|
|
3478
|
+
}
|
|
3479
|
+
|
|
3480
|
+
throw new Error(
|
|
3481
|
+
[
|
|
3482
|
+
`Channel proof backend version mismatch before ${operationName} proof generation.`,
|
|
3483
|
+
`Channel: ${context.workspace.channelName ?? context.workspaceName ?? context.workspace.channelId}.`,
|
|
3484
|
+
...mismatches.map(({ label, packageName, versionKind, channelVersion, localVersion }) => (
|
|
3485
|
+
`${label} verifier expects ${packageName} ${versionKind} ${channelVersion}, `
|
|
3486
|
+
+ `but the local installed ${versionKind} is ${localVersion ?? "<missing>"}.`
|
|
3487
|
+
)),
|
|
3488
|
+
"Install proof backend runtimes compatible with this channel before generating proofs.",
|
|
3489
|
+
].join(" "),
|
|
3490
|
+
);
|
|
3491
|
+
}
|
|
3492
|
+
|
|
3493
|
+
async function readChannelVerifierCompatibleBackendVersions(context) {
|
|
3494
|
+
const channelManagerAddress = getAddress(context.workspace.channelManager);
|
|
3495
|
+
const channelManager = new Contract(
|
|
3496
|
+
channelManagerAddress,
|
|
3497
|
+
channelVerifierVersionAbi,
|
|
3498
|
+
context.channelManager.runner,
|
|
3499
|
+
);
|
|
3500
|
+
try {
|
|
3501
|
+
const [groth16, tokamak] = await Promise.all([
|
|
3502
|
+
channelManager.grothVerifierCompatibleBackendVersion(),
|
|
3503
|
+
channelManager.tokamakVerifierCompatibleBackendVersion(),
|
|
3504
|
+
]);
|
|
3505
|
+
return {
|
|
3506
|
+
groth16: requireVersionString(groth16, "channel Groth16 verifier compatibleBackendVersion"),
|
|
3507
|
+
tokamak: requireVersionString(tokamak, "channel Tokamak verifier compatibleBackendVersion"),
|
|
3508
|
+
};
|
|
3509
|
+
} catch (error) {
|
|
3510
|
+
throw new Error(
|
|
3511
|
+
[
|
|
3512
|
+
`Unable to read verifier compatibleBackendVersion values from channel manager ${channelManagerAddress}.`,
|
|
3513
|
+
"The target channel must expose grothVerifierCompatibleBackendVersion() and tokamakVerifierCompatibleBackendVersion().",
|
|
3514
|
+
].join(" "),
|
|
3515
|
+
{ cause: error },
|
|
3516
|
+
);
|
|
3517
|
+
}
|
|
3518
|
+
}
|
|
3519
|
+
|
|
3520
|
+
function readLocalProofBackendPackageVersions() {
|
|
3521
|
+
const groth16Runtime = inspectGroth16Runtime();
|
|
3522
|
+
const tokamakPackageReport = readTokamakCliPackageReport();
|
|
3523
|
+
return {
|
|
3524
|
+
groth16: {
|
|
3525
|
+
packageVersion: groth16Runtime.packageVersion,
|
|
3526
|
+
compatibleBackendVersion: groth16Runtime.crsCompatibleBackendVersion
|
|
3527
|
+
?? groth16Runtime.compatibleBackendVersion,
|
|
3528
|
+
},
|
|
3529
|
+
tokamak: {
|
|
3530
|
+
packageVersion: requirePackageReportVersion(tokamakPackageReport),
|
|
3531
|
+
compatibleBackendVersion: requirePackageReportCompatibleBackendVersion(tokamakPackageReport),
|
|
3532
|
+
},
|
|
3533
|
+
};
|
|
3534
|
+
}
|
|
3535
|
+
|
|
3536
|
+
function readTokamakCliPackageReport(packageRoot = null) {
|
|
3537
|
+
try {
|
|
3538
|
+
const resolvedPackageRoot = packageRoot ?? resolveActiveTokamakCliPackageRoot();
|
|
3539
|
+
const packageJsonPath = path.join(resolvedPackageRoot, "package.json");
|
|
3540
|
+
const packageJson = readJson(packageJsonPath);
|
|
3541
|
+
const report = readPackageReport({
|
|
3542
|
+
name: TOKAMAK_ZKEVM_CLI_PACKAGE_NAME,
|
|
3543
|
+
packageJsonPath,
|
|
3544
|
+
packageJson,
|
|
3545
|
+
});
|
|
3546
|
+
return {
|
|
3547
|
+
...report,
|
|
3548
|
+
compatibleBackendVersion: readTokamakZkEvmCompatibleBackendVersionFromPackageJson(
|
|
3549
|
+
packageJson,
|
|
3550
|
+
TOKAMAK_ZKEVM_CLI_PACKAGE_NAME,
|
|
3551
|
+
),
|
|
3552
|
+
};
|
|
3553
|
+
} catch (error) {
|
|
3554
|
+
return {
|
|
3555
|
+
name: TOKAMAK_ZKEVM_CLI_PACKAGE_NAME,
|
|
3556
|
+
version: null,
|
|
3557
|
+
packageRoot: null,
|
|
3558
|
+
compatibleBackendVersion: null,
|
|
3559
|
+
error: error.message,
|
|
3560
|
+
ok: false,
|
|
3561
|
+
};
|
|
3562
|
+
}
|
|
3563
|
+
}
|
|
3564
|
+
|
|
3565
|
+
function requirePackageReportVersion(report) {
|
|
3566
|
+
if (!report.version) {
|
|
3567
|
+
throw new Error(
|
|
3568
|
+
`Unable to determine local ${report.name} package version${report.error ? `: ${report.error}` : "."}`,
|
|
3569
|
+
);
|
|
3570
|
+
}
|
|
3571
|
+
return requireVersionString(report.version, `${report.name} package version`);
|
|
3572
|
+
}
|
|
3573
|
+
|
|
3574
|
+
function requirePackageReportCompatibleBackendVersion(report) {
|
|
3575
|
+
if (!report.compatibleBackendVersion) {
|
|
3576
|
+
throw new Error(
|
|
3577
|
+
`Unable to determine local ${report.name} compatible backend version${report.error ? `: ${report.error}` : "."}`,
|
|
3578
|
+
);
|
|
3579
|
+
}
|
|
3580
|
+
return requireVersionString(report.compatibleBackendVersion, `${report.name} compatible backend version`);
|
|
3581
|
+
}
|
|
3582
|
+
|
|
3583
|
+
function requireVersionString(value, label) {
|
|
3584
|
+
const normalized = String(value ?? "").trim();
|
|
3585
|
+
expect(normalized.length > 0, `${label} is missing.`);
|
|
3586
|
+
return normalized;
|
|
3587
|
+
}
|
|
3588
|
+
|
|
3431
3589
|
async function buildGrothTransition({ operationDir, workspace, stateManager, vaultAddress, keyHex, nextValue }) {
|
|
3432
3590
|
const vaultAddressObj = createAddressFromString(vaultAddress);
|
|
3433
3591
|
const keyBigInt = ethers.toBigInt(keyHex);
|
|
@@ -3504,7 +3662,7 @@ function runCaptured(command, args, { cwd = defaultCommandCwd, env = process.env
|
|
|
3504
3662
|
}
|
|
3505
3663
|
|
|
3506
3664
|
function runGroth16UpdateTreeProof(inputPath) {
|
|
3507
|
-
const packageRoot =
|
|
3665
|
+
const packageRoot = resolveActiveGroth16PackageRoot();
|
|
3508
3666
|
const entryPath = resolveGroth16CliEntryPath(packageRoot);
|
|
3509
3667
|
run(process.execPath, [entryPath, "--prove", inputPath], { cwd: packageRoot });
|
|
3510
3668
|
const manifestPath = groth16ProofManifestPath();
|
|
@@ -3557,7 +3715,8 @@ function printLocalProofGenerationNotice(operationName) {
|
|
|
3557
3715
|
}
|
|
3558
3716
|
|
|
3559
3717
|
function runTokamakCliStage({ operationDir, stageName, args }) {
|
|
3560
|
-
const
|
|
3718
|
+
const invocation = buildTokamakCliInvocationForPackageRoot();
|
|
3719
|
+
const result = runCaptured(invocation.command, [...invocation.args, ...args], { cwd: invocation.packageRoot });
|
|
3561
3720
|
const logPath = writeTokamakCliStageLog(operationDir, stageName, result);
|
|
3562
3721
|
if (result.status !== 0) {
|
|
3563
3722
|
throw new Error(
|
|
@@ -3616,6 +3775,7 @@ function findTokamakConsoleError({ stdout, stderr }) {
|
|
|
3616
3775
|
function copyTokamakOperationArtifacts(operationDir) {
|
|
3617
3776
|
const resourceRoot = path.join(operationDir, "resource");
|
|
3618
3777
|
fs.rmSync(resourceRoot, { recursive: true, force: true });
|
|
3778
|
+
const runtimeRoot = requireActiveTokamakCliRuntimeRoot();
|
|
3619
3779
|
|
|
3620
3780
|
const requiredFiles = [
|
|
3621
3781
|
["preprocess", "output", "preprocess.json"],
|
|
@@ -3625,7 +3785,7 @@ function copyTokamakOperationArtifacts(operationDir) {
|
|
|
3625
3785
|
];
|
|
3626
3786
|
|
|
3627
3787
|
for (const segments of requiredFiles) {
|
|
3628
|
-
const sourcePath =
|
|
3788
|
+
const sourcePath = resolveTokamakCliResourceDirForRuntimeRoot(runtimeRoot, ...segments);
|
|
3629
3789
|
const targetPath = path.join(resourceRoot, ...segments);
|
|
3630
3790
|
ensureDir(path.dirname(targetPath));
|
|
3631
3791
|
fs.copyFileSync(sourcePath, targetPath);
|
|
@@ -3747,10 +3907,6 @@ function normalizeBytes16Hex(value) {
|
|
|
3747
3907
|
return normalizeBytesHex(value, 16);
|
|
3748
3908
|
}
|
|
3749
3909
|
|
|
3750
|
-
function normalizeBytes20Hex(value) {
|
|
3751
|
-
return normalizeBytesHex(value, 20);
|
|
3752
|
-
}
|
|
3753
|
-
|
|
3754
3910
|
function normalizeBytes32Hex(hexValue) {
|
|
3755
3911
|
return normalizeBytesHex(hexValue, 32);
|
|
3756
3912
|
}
|
|
@@ -4589,9 +4745,23 @@ function assertInstallZkEvmArgs(args) {
|
|
|
4589
4745
|
assertAllowedCommandKeys(
|
|
4590
4746
|
args,
|
|
4591
4747
|
"--install",
|
|
4592
|
-
new Set([
|
|
4593
|
-
|
|
4748
|
+
new Set([
|
|
4749
|
+
"command",
|
|
4750
|
+
"positional",
|
|
4751
|
+
"install",
|
|
4752
|
+
"docker",
|
|
4753
|
+
"includeLocalArtifacts",
|
|
4754
|
+
"groth16CliVersion",
|
|
4755
|
+
"tokamakZkEvmCliVersion",
|
|
4756
|
+
]),
|
|
4757
|
+
"optional --docker, --include-local-artifacts, --groth16-cli-version, and --tokamak-zk-evm-cli-version",
|
|
4594
4758
|
);
|
|
4759
|
+
if (args.groth16CliVersion !== undefined) {
|
|
4760
|
+
requireSemverVersion(args.groth16CliVersion, "--groth16-cli-version");
|
|
4761
|
+
}
|
|
4762
|
+
if (args.tokamakZkEvmCliVersion !== undefined) {
|
|
4763
|
+
requireSemverVersion(args.tokamakZkEvmCliVersion, "--tokamak-zk-evm-cli-version");
|
|
4764
|
+
}
|
|
4595
4765
|
}
|
|
4596
4766
|
|
|
4597
4767
|
function assertUninstallZkEvmArgs(args) {
|
|
@@ -4801,8 +4971,9 @@ function persistCurrentState(context) {
|
|
|
4801
4971
|
function printHelp() {
|
|
4802
4972
|
console.log(`
|
|
4803
4973
|
Commands:
|
|
4804
|
-
--install [--docker] [--include-local-artifacts]
|
|
4974
|
+
--install [--docker] [--include-local-artifacts] [--groth16-cli-version <VERSION>] [--tokamak-zk-evm-cli-version <VERSION>]
|
|
4805
4975
|
Install the Tokamak zk-EVM CLI runtime, Groth16 runtime, and private-state deployment artifacts
|
|
4976
|
+
Version options install exact CLI package versions; omitted versions resolve to npm registry latest
|
|
4806
4977
|
Use --docker on Linux to forward Docker mode to the Tokamak zk-EVM and Groth16 runtimes
|
|
4807
4978
|
Use --include-local-artifacts to also install local deployment/ artifacts from the current working directory
|
|
4808
4979
|
|
|
@@ -5065,6 +5236,10 @@ function expect(condition, message) {
|
|
|
5065
5236
|
}
|
|
5066
5237
|
}
|
|
5067
5238
|
|
|
5239
|
+
function requireSemverVersion(value, label) {
|
|
5240
|
+
return requireExactSemverVersion(value, label);
|
|
5241
|
+
}
|
|
5242
|
+
|
|
5068
5243
|
function resolveArtifactCacheBaseRoot(
|
|
5069
5244
|
cacheBaseRoot = process.env.PRIVATE_STATE_ARTIFACT_CACHE_ROOT
|
|
5070
5245
|
?? process.env.TOKAMAK_PRIVATE_CHANNELS_ROOT
|
|
@@ -5077,6 +5252,10 @@ function privateStateCliArtifactRoot(cacheBaseRoot = resolveArtifactCacheBaseRoo
|
|
|
5077
5252
|
return path.join(resolveArtifactCacheBaseRoot(cacheBaseRoot), "dapps", "private-state");
|
|
5078
5253
|
}
|
|
5079
5254
|
|
|
5255
|
+
function privateStateCliRuntimeRoot(cacheBaseRoot = resolveArtifactCacheBaseRoot()) {
|
|
5256
|
+
return path.join(privateStateCliArtifactRoot(cacheBaseRoot), "runtimes");
|
|
5257
|
+
}
|
|
5258
|
+
|
|
5080
5259
|
function privateStateCliArtifactChainDir(cacheBaseRoot = resolveArtifactCacheBaseRoot(), chainId) {
|
|
5081
5260
|
return path.join(privateStateCliArtifactRoot(cacheBaseRoot), `chain-id-${requireChainId(chainId)}`);
|
|
5082
5261
|
}
|
|
@@ -5101,11 +5280,17 @@ function privateStateCliInstallManifestPath(cacheBaseRoot = resolveArtifactCache
|
|
|
5101
5280
|
return path.join(privateStateCliArtifactRoot(cacheBaseRoot), "install-manifest.json");
|
|
5102
5281
|
}
|
|
5103
5282
|
|
|
5283
|
+
function readPrivateStateCliInstallManifest(cacheBaseRoot = resolveArtifactCacheBaseRoot()) {
|
|
5284
|
+
return readJsonIfExists(privateStateCliInstallManifestPath(cacheBaseRoot));
|
|
5285
|
+
}
|
|
5286
|
+
|
|
5104
5287
|
function writePrivateStateCliInstallManifest({
|
|
5105
5288
|
dockerRequested,
|
|
5106
5289
|
includeLocalArtifacts,
|
|
5107
5290
|
localDeploymentBaseRoot,
|
|
5108
5291
|
deploymentArtifacts,
|
|
5292
|
+
selectedVersions,
|
|
5293
|
+
tokamakCliRuntime,
|
|
5109
5294
|
groth16Runtime,
|
|
5110
5295
|
}) {
|
|
5111
5296
|
const manifestPath = privateStateCliInstallManifestPath(deploymentArtifacts.cacheBaseRoot);
|
|
@@ -5121,6 +5306,8 @@ function writePrivateStateCliInstallManifest({
|
|
|
5121
5306
|
includeLocalArtifacts,
|
|
5122
5307
|
localDeploymentBaseRoot,
|
|
5123
5308
|
artifactCacheRoot: deploymentArtifacts.cacheBaseRoot,
|
|
5309
|
+
selectedVersions,
|
|
5310
|
+
tokamakCliRuntime,
|
|
5124
5311
|
groth16Runtime,
|
|
5125
5312
|
installedDeploymentArtifacts: deploymentArtifacts.installed.map((entry) => ({
|
|
5126
5313
|
chainId: entry.chainId,
|
|
@@ -5149,6 +5336,11 @@ function buildDoctorReport() {
|
|
|
5149
5336
|
const tokamakCli = inspectTokamakCliRuntime();
|
|
5150
5337
|
const groth16Runtime = inspectGroth16Runtime();
|
|
5151
5338
|
const gpuDockerReadiness = inspectGpuDockerReadiness(tokamakCli);
|
|
5339
|
+
const selectedRuntimeVersionCheck = buildSelectedRuntimeVersionCheck({
|
|
5340
|
+
installManifest,
|
|
5341
|
+
tokamakCli,
|
|
5342
|
+
groth16Runtime,
|
|
5343
|
+
});
|
|
5152
5344
|
const checks = [
|
|
5153
5345
|
{
|
|
5154
5346
|
name: "dependency package versions",
|
|
@@ -5161,6 +5353,7 @@ function buildDoctorReport() {
|
|
|
5161
5353
|
error: entry.error,
|
|
5162
5354
|
})),
|
|
5163
5355
|
},
|
|
5356
|
+
selectedRuntimeVersionCheck,
|
|
5164
5357
|
{
|
|
5165
5358
|
name: "tokamak zk-evm runtime",
|
|
5166
5359
|
ok: tokamakCli.installed,
|
|
@@ -5214,6 +5407,9 @@ function buildDoctorReport() {
|
|
|
5214
5407
|
installedAt: installManifest?.installedAt ?? null,
|
|
5215
5408
|
dockerRequested: installManifest?.install?.dockerRequested ?? null,
|
|
5216
5409
|
includeLocalArtifacts: installManifest?.install?.includeLocalArtifacts ?? null,
|
|
5410
|
+
selectedVersions: installManifest?.install?.selectedVersions ?? null,
|
|
5411
|
+
tokamakCliRuntime: installManifest?.install?.tokamakCliRuntime ?? null,
|
|
5412
|
+
groth16Runtime: installManifest?.install?.groth16Runtime ?? null,
|
|
5217
5413
|
},
|
|
5218
5414
|
dependencies: dependencyReports,
|
|
5219
5415
|
tokamakCli,
|
|
@@ -5223,17 +5419,221 @@ function buildDoctorReport() {
|
|
|
5223
5419
|
};
|
|
5224
5420
|
}
|
|
5225
5421
|
|
|
5226
|
-
function
|
|
5227
|
-
const
|
|
5422
|
+
function buildSelectedRuntimeVersionCheck({ installManifest, tokamakCli, groth16Runtime }) {
|
|
5423
|
+
const selectedVersions = installManifest?.install?.selectedVersions ?? null;
|
|
5424
|
+
const selectedTokamakCompatibleBackendVersion = selectedVersions?.tokamak
|
|
5425
|
+
? normalizePackageVersionToCompatibleBackendVersion(
|
|
5426
|
+
selectedVersions.tokamak,
|
|
5427
|
+
"selected Tokamak zk-EVM CLI version",
|
|
5428
|
+
)
|
|
5429
|
+
: null;
|
|
5430
|
+
const selectedGroth16CompatibleBackendVersion = selectedVersions?.groth16
|
|
5431
|
+
? normalizePackageVersionToCompatibleBackendVersion(selectedVersions.groth16, "selected Groth16 CLI version")
|
|
5432
|
+
: null;
|
|
5433
|
+
const details = [
|
|
5434
|
+
{
|
|
5435
|
+
name: TOKAMAK_ZKEVM_CLI_PACKAGE_NAME,
|
|
5436
|
+
selectedVersion: selectedVersions?.tokamak ?? null,
|
|
5437
|
+
selectedCompatibleBackendVersion: selectedTokamakCompatibleBackendVersion,
|
|
5438
|
+
installedVersion: tokamakCli.packageVersion ?? null,
|
|
5439
|
+
compatibleBackendVersion: tokamakCli.compatibleBackendVersion ?? null,
|
|
5440
|
+
ok: !selectedVersions?.tokamak
|
|
5441
|
+
|| (
|
|
5442
|
+
selectedVersions.tokamak === tokamakCli.packageVersion
|
|
5443
|
+
&& selectedTokamakCompatibleBackendVersion === tokamakCli.compatibleBackendVersion
|
|
5444
|
+
),
|
|
5445
|
+
},
|
|
5446
|
+
{
|
|
5447
|
+
name: GROTH16_PACKAGE_NAME,
|
|
5448
|
+
selectedVersion: selectedVersions?.groth16 ?? null,
|
|
5449
|
+
selectedCompatibleBackendVersion: selectedGroth16CompatibleBackendVersion,
|
|
5450
|
+
installedVersion: groth16Runtime.packageVersion ?? null,
|
|
5451
|
+
compatibleBackendVersion: groth16Runtime.compatibleBackendVersion ?? null,
|
|
5452
|
+
crsVersion: groth16Runtime.crsVersion ?? null,
|
|
5453
|
+
crsCompatibleBackendVersion: groth16Runtime.crsCompatibleBackendVersion ?? null,
|
|
5454
|
+
ok: !selectedVersions?.groth16
|
|
5455
|
+
|| (
|
|
5456
|
+
selectedVersions.groth16 === groth16Runtime.packageVersion
|
|
5457
|
+
&& selectedGroth16CompatibleBackendVersion === groth16Runtime.compatibleBackendVersion
|
|
5458
|
+
&& selectedGroth16CompatibleBackendVersion === groth16Runtime.crsCompatibleBackendVersion
|
|
5459
|
+
),
|
|
5460
|
+
},
|
|
5461
|
+
];
|
|
5462
|
+
return {
|
|
5463
|
+
name: "selected proof backend runtime versions",
|
|
5464
|
+
ok: details.every((entry) => entry.ok),
|
|
5465
|
+
details,
|
|
5466
|
+
};
|
|
5467
|
+
}
|
|
5468
|
+
|
|
5469
|
+
async function resolvePrivateStateInstallRuntimeVersions(args) {
|
|
5470
|
+
const [groth16, tokamak] = await Promise.all([
|
|
5471
|
+
resolveRequestedNpmPackageVersion({
|
|
5472
|
+
packageName: GROTH16_PACKAGE_NAME,
|
|
5473
|
+
requestedVersion: args.groth16CliVersion,
|
|
5474
|
+
optionName: "--groth16-cli-version",
|
|
5475
|
+
}),
|
|
5476
|
+
resolveRequestedNpmPackageVersion({
|
|
5477
|
+
packageName: TOKAMAK_ZKEVM_CLI_PACKAGE_NAME,
|
|
5478
|
+
requestedVersion: args.tokamakZkEvmCliVersion,
|
|
5479
|
+
optionName: "--tokamak-zk-evm-cli-version",
|
|
5480
|
+
}),
|
|
5481
|
+
]);
|
|
5482
|
+
return { groth16, tokamak };
|
|
5483
|
+
}
|
|
5484
|
+
|
|
5485
|
+
async function resolveRequestedNpmPackageVersion({ packageName, requestedVersion, optionName }) {
|
|
5486
|
+
const metadata = await fetchNpmPackageMetadata(packageName);
|
|
5487
|
+
if (requestedVersion === undefined || requestedVersion === null) {
|
|
5488
|
+
return requireSemverVersion(metadata?.["dist-tags"]?.latest, `${packageName} npm latest version`);
|
|
5489
|
+
}
|
|
5490
|
+
|
|
5491
|
+
const normalizedVersion = requireSemverVersion(requestedVersion, optionName);
|
|
5492
|
+
if (!metadata.versions?.[normalizedVersion]) {
|
|
5493
|
+
throw new Error(`npm package ${packageName} does not contain version ${normalizedVersion}.`);
|
|
5494
|
+
}
|
|
5495
|
+
return normalizedVersion;
|
|
5496
|
+
}
|
|
5497
|
+
|
|
5498
|
+
async function installTokamakCliRuntimeForPrivateState({ version, docker }) {
|
|
5499
|
+
const packageInstall = installManagedNpmPackage({
|
|
5500
|
+
packageName: TOKAMAK_ZKEVM_CLI_PACKAGE_NAME,
|
|
5501
|
+
version,
|
|
5502
|
+
});
|
|
5503
|
+
const invocation = buildTokamakCliInvocationForPackageRoot(packageInstall.packageRoot);
|
|
5504
|
+
const installArgs = [...invocation.args, "--install"];
|
|
5505
|
+
if (docker) {
|
|
5506
|
+
installArgs.push("--docker");
|
|
5507
|
+
}
|
|
5508
|
+
run(invocation.command, installArgs, { cwd: packageInstall.packageRoot });
|
|
5509
|
+
const doctor = runCaptured(invocation.command, [...invocation.args, "--doctor"], {
|
|
5510
|
+
cwd: packageInstall.packageRoot,
|
|
5511
|
+
});
|
|
5512
|
+
const doctorOutput = stripAnsi(`${doctor.stdout}${doctor.stderr}`);
|
|
5513
|
+
const runtimeRoot = parseRuntimeRootFromTokamakDoctorOutput(doctorOutput);
|
|
5514
|
+
const compatibleBackendVersion = readTokamakCliPackageCompatibleBackendVersion(packageInstall.packageRoot);
|
|
5515
|
+
expect(
|
|
5516
|
+
doctor.status === 0 && runtimeRoot,
|
|
5517
|
+
[
|
|
5518
|
+
"Tokamak zk-EVM CLI install completed, but tokamak-cli --doctor did not report a healthy runtime.",
|
|
5519
|
+
doctorOutput.trim(),
|
|
5520
|
+
].filter(Boolean).join(" "),
|
|
5521
|
+
);
|
|
5522
|
+
return {
|
|
5523
|
+
packageName: TOKAMAK_ZKEVM_CLI_PACKAGE_NAME,
|
|
5524
|
+
packageVersion: version,
|
|
5525
|
+
compatibleBackendVersion,
|
|
5526
|
+
packageRoot: packageInstall.packageRoot,
|
|
5527
|
+
entryPath: invocation.entryPath,
|
|
5528
|
+
installPrefix: packageInstall.installPrefix,
|
|
5529
|
+
runtimeRoot,
|
|
5530
|
+
dockerRequested: Boolean(docker),
|
|
5531
|
+
};
|
|
5532
|
+
}
|
|
5533
|
+
|
|
5534
|
+
async function installGroth16RuntimeForPrivateState({ version, docker }) {
|
|
5535
|
+
const packageInstall = installManagedNpmPackage({
|
|
5536
|
+
packageName: GROTH16_PACKAGE_NAME,
|
|
5537
|
+
version,
|
|
5538
|
+
});
|
|
5539
|
+
const packageRoot = packageInstall.packageRoot;
|
|
5228
5540
|
const entryPath = resolveGroth16CliEntryPath(packageRoot);
|
|
5229
|
-
const args = [entryPath, "--install"];
|
|
5541
|
+
const args = [entryPath, "--install", "--no-setup"];
|
|
5230
5542
|
if (docker) {
|
|
5231
5543
|
args.push("--docker");
|
|
5232
5544
|
}
|
|
5233
5545
|
run(process.execPath, args, { cwd: packageRoot });
|
|
5234
|
-
const
|
|
5546
|
+
const compatibleBackendVersion = readGroth16PackageCompatibleBackendVersion(packageRoot);
|
|
5547
|
+
const crsInstall = await installGroth16CrsForPrivateStateVersion(compatibleBackendVersion);
|
|
5548
|
+
const runtime = inspectGroth16Runtime({ packageRoot });
|
|
5235
5549
|
expect(runtime.installed, "Groth16 runtime install completed, but tokamak-groth16 --doctor still reports an unhealthy runtime.");
|
|
5236
|
-
return
|
|
5550
|
+
return {
|
|
5551
|
+
...runtime,
|
|
5552
|
+
packageName: GROTH16_PACKAGE_NAME,
|
|
5553
|
+
packageVersion: version,
|
|
5554
|
+
compatibleBackendVersion,
|
|
5555
|
+
packageRoot,
|
|
5556
|
+
entryPath,
|
|
5557
|
+
installPrefix: packageInstall.installPrefix,
|
|
5558
|
+
crsVersion: crsInstall.version,
|
|
5559
|
+
crs: crsInstall,
|
|
5560
|
+
dockerRequested: Boolean(docker),
|
|
5561
|
+
};
|
|
5562
|
+
}
|
|
5563
|
+
|
|
5564
|
+
async function installGroth16CrsForPrivateStateVersion(version) {
|
|
5565
|
+
const workspaceRoot = defaultGroth16WorkspaceRoot();
|
|
5566
|
+
const crsDir = path.join(workspaceRoot, "crs");
|
|
5567
|
+
const crsInstall = await downloadPublicGroth16MpcArtifactsByVersion({
|
|
5568
|
+
version,
|
|
5569
|
+
outputDir: crsDir,
|
|
5570
|
+
selectedFiles: [
|
|
5571
|
+
"circuit_final.zkey",
|
|
5572
|
+
"verification_key.json",
|
|
5573
|
+
"metadata.json",
|
|
5574
|
+
"zkey_provenance.json",
|
|
5575
|
+
],
|
|
5576
|
+
});
|
|
5577
|
+
const manifestPath = path.join(workspaceRoot, "install-manifest.json");
|
|
5578
|
+
const manifest = readJsonIfExists(manifestPath) ?? {};
|
|
5579
|
+
writeJson(manifestPath, {
|
|
5580
|
+
...manifest,
|
|
5581
|
+
workspaceRoot,
|
|
5582
|
+
crsSource: "public-drive-mpc",
|
|
5583
|
+
crs: crsInstall,
|
|
5584
|
+
});
|
|
5585
|
+
return crsInstall;
|
|
5586
|
+
}
|
|
5587
|
+
|
|
5588
|
+
function installManagedNpmPackage({ packageName, version, cacheBaseRoot = resolveArtifactCacheBaseRoot() }) {
|
|
5589
|
+
const normalizedPackageName = requireNonEmptyString(packageName, "packageName");
|
|
5590
|
+
const normalizedVersion = requireSemverVersion(version, `${normalizedPackageName} version`);
|
|
5591
|
+
const installPrefix = managedNpmPackageInstallPrefix({
|
|
5592
|
+
packageName: normalizedPackageName,
|
|
5593
|
+
version: normalizedVersion,
|
|
5594
|
+
cacheBaseRoot,
|
|
5595
|
+
});
|
|
5596
|
+
fs.mkdirSync(installPrefix, { recursive: true });
|
|
5597
|
+
run("npm", [
|
|
5598
|
+
"install",
|
|
5599
|
+
"--prefix",
|
|
5600
|
+
installPrefix,
|
|
5601
|
+
"--omit=dev",
|
|
5602
|
+
"--no-audit",
|
|
5603
|
+
"--fund=false",
|
|
5604
|
+
`${normalizedPackageName}@${normalizedVersion}`,
|
|
5605
|
+
]);
|
|
5606
|
+
const packageRoot = path.join(installPrefix, "node_modules", ...normalizedPackageName.split("/"));
|
|
5607
|
+
const packageJsonPath = path.join(packageRoot, "package.json");
|
|
5608
|
+
const packageJson = readJson(packageJsonPath);
|
|
5609
|
+
expect(
|
|
5610
|
+
packageJson.name === normalizedPackageName && packageJson.version === normalizedVersion,
|
|
5611
|
+
`Installed package ${packageJsonPath} does not match ${normalizedPackageName}@${normalizedVersion}.`,
|
|
5612
|
+
);
|
|
5613
|
+
return {
|
|
5614
|
+
packageName: normalizedPackageName,
|
|
5615
|
+
version: normalizedVersion,
|
|
5616
|
+
installPrefix,
|
|
5617
|
+
packageRoot,
|
|
5618
|
+
};
|
|
5619
|
+
}
|
|
5620
|
+
|
|
5621
|
+
function managedNpmPackageInstallPrefix({ packageName, version, cacheBaseRoot = resolveArtifactCacheBaseRoot() }) {
|
|
5622
|
+
const safePackageName = requireNonEmptyString(packageName, "packageName")
|
|
5623
|
+
.replace(/^@/, "")
|
|
5624
|
+
.replace(/[^A-Za-z0-9._-]+/g, "__");
|
|
5625
|
+
return path.join(privateStateCliRuntimeRoot(cacheBaseRoot), "npm", safePackageName, requireSemverVersion(version, "version"));
|
|
5626
|
+
}
|
|
5627
|
+
|
|
5628
|
+
async function downloadGroth16CrsArtifactsForPrivateState({
|
|
5629
|
+
version,
|
|
5630
|
+
outputDir,
|
|
5631
|
+
selectedFiles,
|
|
5632
|
+
}) {
|
|
5633
|
+
if (version === undefined || version === null) {
|
|
5634
|
+
return downloadLatestPublicGroth16MpcArtifacts({ outputDir, selectedFiles });
|
|
5635
|
+
}
|
|
5636
|
+
return downloadPublicGroth16MpcArtifactsByVersion({ version, outputDir, selectedFiles });
|
|
5237
5637
|
}
|
|
5238
5638
|
|
|
5239
5639
|
function collectDependencyPackageReports(installManifest = null) {
|
|
@@ -5244,11 +5644,11 @@ function collectDependencyPackageReports(installManifest = null) {
|
|
|
5244
5644
|
);
|
|
5245
5645
|
const targets = [
|
|
5246
5646
|
{
|
|
5247
|
-
name:
|
|
5248
|
-
packageJsonPath: path.join(
|
|
5647
|
+
name: TOKAMAK_ZKEVM_CLI_PACKAGE_NAME,
|
|
5648
|
+
packageJsonPath: path.join(resolveBundledTokamakCliPackageRoot(), "package.json"),
|
|
5249
5649
|
},
|
|
5250
5650
|
{
|
|
5251
|
-
name:
|
|
5651
|
+
name: GROTH16_PACKAGE_NAME,
|
|
5252
5652
|
resolveTarget: "@tokamak-private-dapps/groth16/public-drive-crs",
|
|
5253
5653
|
},
|
|
5254
5654
|
{
|
|
@@ -5269,15 +5669,15 @@ function collectDependencyPackageReports(installManifest = null) {
|
|
|
5269
5669
|
});
|
|
5270
5670
|
}
|
|
5271
5671
|
|
|
5272
|
-
function readPackageReport({ name, packageJsonPath = null, resolveTarget = null }) {
|
|
5672
|
+
function readPackageReport({ name, packageJsonPath = null, packageJson = null, resolveTarget = null }) {
|
|
5273
5673
|
try {
|
|
5274
5674
|
const resolvedPackageJsonPath = packageJsonPath
|
|
5275
5675
|
? path.resolve(packageJsonPath)
|
|
5276
5676
|
: findPackageJsonForName(path.dirname(require.resolve(resolveTarget ?? name)), name);
|
|
5277
|
-
const
|
|
5677
|
+
const resolvedPackageJson = packageJson ?? readJson(resolvedPackageJsonPath);
|
|
5278
5678
|
return {
|
|
5279
|
-
name:
|
|
5280
|
-
version:
|
|
5679
|
+
name: resolvedPackageJson.name ?? name,
|
|
5680
|
+
version: resolvedPackageJson.version ?? null,
|
|
5281
5681
|
packageRoot: path.dirname(resolvedPackageJsonPath),
|
|
5282
5682
|
error: null,
|
|
5283
5683
|
};
|
|
@@ -5312,21 +5712,63 @@ function resolveGroth16PackageRoot() {
|
|
|
5312
5712
|
return path.dirname(findPackageJsonForName(path.dirname(publicDriveCrsPath), "@tokamak-private-dapps/groth16"));
|
|
5313
5713
|
}
|
|
5314
5714
|
|
|
5715
|
+
function readGroth16PackageCompatibleBackendVersion(packageRoot = resolveActiveGroth16PackageRoot()) {
|
|
5716
|
+
return readGroth16CompatibleBackendVersionFromPackageJson(
|
|
5717
|
+
readJson(path.join(packageRoot, "package.json")),
|
|
5718
|
+
GROTH16_PACKAGE_NAME,
|
|
5719
|
+
);
|
|
5720
|
+
}
|
|
5721
|
+
|
|
5722
|
+
function readTokamakCliPackageCompatibleBackendVersion(packageRoot = resolveActiveTokamakCliPackageRoot()) {
|
|
5723
|
+
return readTokamakZkEvmCompatibleBackendVersionFromPackageJson(
|
|
5724
|
+
readJson(path.join(packageRoot, "package.json")),
|
|
5725
|
+
TOKAMAK_ZKEVM_CLI_PACKAGE_NAME,
|
|
5726
|
+
);
|
|
5727
|
+
}
|
|
5728
|
+
|
|
5729
|
+
function resolveActiveGroth16PackageRoot() {
|
|
5730
|
+
const manifestPackageRoot = readPrivateStateCliInstallManifest()?.install?.groth16Runtime?.packageRoot;
|
|
5731
|
+
if (manifestPackageRoot && fs.existsSync(path.join(manifestPackageRoot, "package.json"))) {
|
|
5732
|
+
return manifestPackageRoot;
|
|
5733
|
+
}
|
|
5734
|
+
return resolveGroth16PackageRoot();
|
|
5735
|
+
}
|
|
5736
|
+
|
|
5315
5737
|
function resolveGroth16CliEntryPath(packageRoot = resolveGroth16PackageRoot()) {
|
|
5316
5738
|
return path.join(packageRoot, "cli", "tokamak-groth16-cli.mjs");
|
|
5317
5739
|
}
|
|
5318
5740
|
|
|
5319
|
-
function
|
|
5320
|
-
|
|
5741
|
+
function defaultGroth16WorkspaceRoot() {
|
|
5742
|
+
return path.join(os.homedir(), "tokamak-private-channels", "groth16");
|
|
5743
|
+
}
|
|
5744
|
+
|
|
5745
|
+
function inspectGroth16Runtime({ packageRoot = resolveActiveGroth16PackageRoot() } = {}) {
|
|
5321
5746
|
const entryPath = resolveGroth16CliEntryPath(packageRoot);
|
|
5322
5747
|
const doctor = runCaptured(process.execPath, [entryPath, "--doctor", "--verbose"], { cwd: packageRoot });
|
|
5323
5748
|
const stdout = stripAnsi(doctor.stdout).trim();
|
|
5324
5749
|
const stderr = stripAnsi(doctor.stderr).trim();
|
|
5325
5750
|
const report = parseJsonReport(stdout);
|
|
5751
|
+
const workspaceRoot = report?.workspaceRoot ?? defaultGroth16WorkspaceRoot();
|
|
5752
|
+
const workspaceManifest = readJsonIfExists(path.join(workspaceRoot, "install-manifest.json"));
|
|
5753
|
+
const crsVersion = workspaceManifest?.crs?.version ?? null;
|
|
5754
|
+
const packageReport = readPackageReport({
|
|
5755
|
+
name: GROTH16_PACKAGE_NAME,
|
|
5756
|
+
packageJsonPath: path.join(packageRoot, "package.json"),
|
|
5757
|
+
});
|
|
5758
|
+
const compatibleBackendVersion = readGroth16PackageCompatibleBackendVersion(packageRoot);
|
|
5759
|
+
const crsCompatibleBackendVersion = crsVersion
|
|
5760
|
+
? requireCanonicalGroth16CompatibleBackendVersion(crsVersion, "installed Groth16 CRS version")
|
|
5761
|
+
: null;
|
|
5326
5762
|
return {
|
|
5327
5763
|
installed: doctor.status === 0 && report?.ok === true,
|
|
5764
|
+
packageVersion: packageReport.version,
|
|
5765
|
+
compatibleBackendVersion,
|
|
5328
5766
|
packageRoot,
|
|
5767
|
+
entryPath,
|
|
5329
5768
|
workspaceRoot: report?.workspaceRoot ?? null,
|
|
5769
|
+
crsVersion,
|
|
5770
|
+
crsCompatibleBackendVersion,
|
|
5771
|
+
crs: workspaceManifest?.crs ?? null,
|
|
5330
5772
|
checks: report?.checks ?? [],
|
|
5331
5773
|
doctor: {
|
|
5332
5774
|
status: doctor.status,
|
|
@@ -5336,9 +5778,42 @@ function inspectGroth16Runtime() {
|
|
|
5336
5778
|
};
|
|
5337
5779
|
}
|
|
5338
5780
|
|
|
5339
|
-
function
|
|
5340
|
-
const
|
|
5341
|
-
|
|
5781
|
+
function resolveActiveTokamakCliPackageRoot() {
|
|
5782
|
+
const manifestPackageRoot = readPrivateStateCliInstallManifest()?.install?.tokamakCliRuntime?.packageRoot;
|
|
5783
|
+
if (manifestPackageRoot && fs.existsSync(path.join(manifestPackageRoot, "package.json"))) {
|
|
5784
|
+
return manifestPackageRoot;
|
|
5785
|
+
}
|
|
5786
|
+
return resolveBundledTokamakCliPackageRoot();
|
|
5787
|
+
}
|
|
5788
|
+
|
|
5789
|
+
function buildTokamakCliInvocationForPackageRoot(packageRoot = resolveActiveTokamakCliPackageRoot()) {
|
|
5790
|
+
const resolvedPackageRoot = path.resolve(packageRoot);
|
|
5791
|
+
const entryPath = resolvedPackageRoot === resolveBundledTokamakCliPackageRoot()
|
|
5792
|
+
? resolveTokamakCliEntryPath()
|
|
5793
|
+
: path.join(resolvedPackageRoot, "dist", "cli.js");
|
|
5794
|
+
return {
|
|
5795
|
+
command: process.execPath,
|
|
5796
|
+
args: [entryPath],
|
|
5797
|
+
entryPath,
|
|
5798
|
+
packageRoot: resolvedPackageRoot,
|
|
5799
|
+
};
|
|
5800
|
+
}
|
|
5801
|
+
|
|
5802
|
+
function resolveTokamakCliResourceDirForRuntimeRoot(runtimeRoot, ...segments) {
|
|
5803
|
+
return path.join(runtimeRoot, "resource", ...segments);
|
|
5804
|
+
}
|
|
5805
|
+
|
|
5806
|
+
function requireActiveTokamakCliRuntimeRoot() {
|
|
5807
|
+
const runtime = inspectTokamakCliRuntime();
|
|
5808
|
+
expect(runtime.runtimeRoot, "Unable to resolve the installed Tokamak zk-EVM runtime root. Run --install first.");
|
|
5809
|
+
return runtime.runtimeRoot;
|
|
5810
|
+
}
|
|
5811
|
+
|
|
5812
|
+
function inspectTokamakCliRuntime({ packageRoot = resolveActiveTokamakCliPackageRoot() } = {}) {
|
|
5813
|
+
const invocation = buildTokamakCliInvocationForPackageRoot(packageRoot);
|
|
5814
|
+
const packageReport = readTokamakCliPackageReport(invocation.packageRoot);
|
|
5815
|
+
const doctor = runCaptured(invocation.command, [...invocation.args, "--doctor"], {
|
|
5816
|
+
cwd: invocation.packageRoot,
|
|
5342
5817
|
});
|
|
5343
5818
|
const doctorOutput = stripAnsi(`${doctor.stdout}${doctor.stderr}`);
|
|
5344
5819
|
const runtimeRoot = parseRuntimeRootFromTokamakDoctorOutput(doctorOutput);
|
|
@@ -5349,13 +5824,13 @@ function inspectTokamakCliRuntime() {
|
|
|
5349
5824
|
|
|
5350
5825
|
return {
|
|
5351
5826
|
installed: doctor.status === 0 || installations.length > 0,
|
|
5352
|
-
packageRoot:
|
|
5827
|
+
packageRoot: invocation.packageRoot,
|
|
5828
|
+
entryPath: invocation.entryPath,
|
|
5353
5829
|
cacheRoot,
|
|
5354
5830
|
runtimeRoot,
|
|
5355
|
-
packageVersion:
|
|
5356
|
-
|
|
5357
|
-
|
|
5358
|
-
}).version,
|
|
5831
|
+
packageVersion: packageReport.version,
|
|
5832
|
+
compatibleBackendVersion: packageReport.compatibleBackendVersion,
|
|
5833
|
+
packageError: packageReport.error,
|
|
5359
5834
|
dockerModeInstalled,
|
|
5360
5835
|
cudaCompatible,
|
|
5361
5836
|
doctor: {
|
|
@@ -5495,6 +5970,7 @@ async function installPrivateStateCliArtifacts({
|
|
|
5495
5970
|
cacheBaseRoot,
|
|
5496
5971
|
localDeploymentBaseRoot,
|
|
5497
5972
|
localChainIds = [31337],
|
|
5973
|
+
groth16CrsVersion,
|
|
5498
5974
|
} = {}) {
|
|
5499
5975
|
const normalizedDappName = requireNonEmptyString(dappName, "dappName");
|
|
5500
5976
|
const normalizedCacheBaseRoot = resolveArtifactCacheBaseRoot(cacheBaseRoot);
|
|
@@ -5515,6 +5991,7 @@ async function installPrivateStateCliArtifacts({
|
|
|
5515
5991
|
dappName: normalizedDappName,
|
|
5516
5992
|
cacheBaseRoot: normalizedCacheBaseRoot,
|
|
5517
5993
|
source: "drive",
|
|
5994
|
+
groth16CrsVersion,
|
|
5518
5995
|
}));
|
|
5519
5996
|
}
|
|
5520
5997
|
|
|
@@ -5525,6 +6002,7 @@ async function installPrivateStateCliArtifacts({
|
|
|
5525
6002
|
dappName: normalizedDappName,
|
|
5526
6003
|
cacheBaseRoot: normalizedCacheBaseRoot,
|
|
5527
6004
|
localDeploymentBaseRoot: normalizedLocalDeploymentBaseRoot,
|
|
6005
|
+
groth16CrsVersion,
|
|
5528
6006
|
}));
|
|
5529
6007
|
}
|
|
5530
6008
|
}
|
|
@@ -5546,6 +6024,7 @@ async function materializePrivateStateCliDeployment({
|
|
|
5546
6024
|
dappName,
|
|
5547
6025
|
cacheBaseRoot,
|
|
5548
6026
|
source,
|
|
6027
|
+
groth16CrsVersion,
|
|
5549
6028
|
}) {
|
|
5550
6029
|
const normalizedChainId = String(requireChainId(chainId));
|
|
5551
6030
|
const normalizedDappName = requireNonEmptyString(dappName, "dappName");
|
|
@@ -5577,7 +6056,8 @@ async function materializePrivateStateCliDeployment({
|
|
|
5577
6056
|
[`groth16.${normalizedChainId}.latest.json`, path.basename(paths.grothManifestPath)],
|
|
5578
6057
|
],
|
|
5579
6058
|
});
|
|
5580
|
-
await
|
|
6059
|
+
await downloadGroth16CrsArtifactsForPrivateState({
|
|
6060
|
+
version: groth16CrsVersion,
|
|
5581
6061
|
outputDir: paths.rootDir,
|
|
5582
6062
|
selectedFiles: [
|
|
5583
6063
|
["circuit_final.zkey", path.basename(paths.grothZkeyPath)],
|
|
@@ -5609,6 +6089,7 @@ async function materializeLocalPrivateStateCliDeployment({
|
|
|
5609
6089
|
dappName,
|
|
5610
6090
|
cacheBaseRoot,
|
|
5611
6091
|
localDeploymentBaseRoot,
|
|
6092
|
+
groth16CrsVersion,
|
|
5612
6093
|
}) {
|
|
5613
6094
|
const normalizedChainId = String(requireChainId(chainId));
|
|
5614
6095
|
const normalizedDappName = requireNonEmptyString(dappName, "dappName");
|
|
@@ -5645,7 +6126,8 @@ async function materializeLocalPrivateStateCliDeployment({
|
|
|
5645
6126
|
[path.join(dappDir, `dapp-registration.${normalizedChainId}.json`), path.basename(paths.dappRegistrationPath)],
|
|
5646
6127
|
],
|
|
5647
6128
|
});
|
|
5648
|
-
await
|
|
6129
|
+
await downloadGroth16CrsArtifactsForPrivateState({
|
|
6130
|
+
version: groth16CrsVersion,
|
|
5649
6131
|
outputDir: paths.rootDir,
|
|
5650
6132
|
selectedFiles: [
|
|
5651
6133
|
["circuit_final.zkey", path.basename(paths.grothZkeyPath)],
|