@tokamak-private-dapps/private-state-cli 2.3.4 → 2.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,11 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 2.4.0 - 2026-05-29
6
+
7
+ - Removed the standalone `channel publish-workspace-mirror` command. Channel leaders now publish
8
+ mirror files through `channel recover-workspace --publish-workspace-mirror --leader-account <ACCOUNT> --output <PATH>`.
9
+
5
10
  ## 2.3.4 - 2026-05-29
6
11
 
7
12
  - Removed the implicit wallet proof context recovery path so proof-backed wallet commands require
package/README.md CHANGED
@@ -236,10 +236,10 @@ older CLI and does not contain `wallet-index.metadata.json` plus `epochs/<epoch-
236
236
  Channel leaders can optionally register a workspace mirror server so users can bootstrap recovery
237
237
  from a signed checkpoint and download only the local-to-checkpoint delta when a local recovery index
238
238
  already exists. The channel leader can build the static mirror files with
239
- `channel publish-workspace-mirror` and then deploy the output directory to the registered mirror
240
- host. If the existing mirror manifest is unreadable or invalid, the leader can use
241
- `channel publish-workspace-mirror --force` to write a full checkpoint without trusting that remote
242
- manifest as a delta base. The CLI protocol is documented at
239
+ `channel recover-workspace --publish-workspace-mirror --leader-account <ACCOUNT> --output <PATH>` after
240
+ recovering the channel workspace, and then deploy the output directory to the registered mirror host.
241
+ If the existing mirror manifest is unreadable or invalid, add `--force` to write a full checkpoint
242
+ without trusting that remote manifest as a delta base. The CLI protocol is documented at
243
243
  https://github.com/tokamak-network/Tokamak-zk-EVM-contracts/blob/main/docs/dapps/private-state/channel-workspace-mirror-protocol.md.
244
244
 
245
245
  Back up a local wallet with:
@@ -541,6 +541,9 @@ Operating rules:
541
541
  rate. Suggest re-running `set rpc` with a provider that supports a larger block range cap, such as Ankr or Chainnodes
542
542
  when appropriate, or with explicit `--log-requests-per-second` and `--block-range-cap` values from the provider's
543
543
  documentation.
544
+ - When a channel leader needs to refresh workspace mirror files, guide them to run
545
+ `channel recover-workspace --publish-workspace-mirror --leader-account <ACCOUNT> --output <PATH>`. The standalone
546
+ `channel publish-workspace-mirror` command is no longer available.
544
547
  - When a CLI command fails, read the error message and any printed `Try:` hints first. Prefer the corrective action
545
548
  suggested by the CLI before inventing a different recovery sequence.
546
549
  - When the user does not have a network RPC URL yet, explain that they need an Ethereum JSON-RPC endpoint for the
@@ -4,14 +4,12 @@ import {
4
4
  assertGetChannelArgs,
5
5
  assertJoinChannelArgs,
6
6
  assertProviderChainIdMatchesNetwork,
7
- assertPublishWorkspaceMirrorArgs,
8
7
  assertRecoverWorkspaceArgs,
9
8
  assertSetWorkspaceMirrorArgs,
10
9
  handleChannelCreate,
11
10
  handleExitChannel,
12
11
  handleGetChannel,
13
12
  handleJoinChannel,
14
- handlePublishChannelWorkspaceMirror,
15
13
  handleSetChannelWorkspaceMirror,
16
14
  handleWorkspaceInit,
17
15
  loadExplicitCommandRuntime,
@@ -40,11 +38,6 @@ export const channelCommands = Object.freeze({
40
38
  const { network, provider } = loadExplicitCommandRuntime(args, { prepareArtifacts: true });
41
39
  await handleSetChannelWorkspaceMirror({ args, network, provider });
42
40
  },
43
- "channel-publish-workspace-mirror": async (args) => {
44
- assertPublishWorkspaceMirrorArgs(args);
45
- const { network, provider } = loadExplicitCommandRuntime(args, { prepareArtifacts: true });
46
- await handlePublishChannelWorkspaceMirror({ args, network, provider });
47
- },
48
41
  "channel-join": async (args) => {
49
42
  assertJoinChannelArgs(args);
50
43
  const { network, provider, rpcUrl } = loadExplicitCommandRuntime(args, { prepareArtifacts: true });
@@ -55,6 +55,15 @@ export const PRIVATE_STATE_CLI_FIELD_CATALOG = Object.freeze({
55
55
  valueLabel: "<NAME>",
56
56
  option: "--account",
57
57
  },
58
+ leaderAccount: {
59
+ label: "Channel Leader Account",
60
+ type: "text",
61
+ placeholder: "leader-account",
62
+ valueLabel: "<ACCOUNT>",
63
+ hint: "Required with --publish-workspace-mirror. Signs the workspace mirror manifest and must match the on-chain channel leader.",
64
+ option: "--leader-account",
65
+ optional: true,
66
+ },
58
67
  txSubmitter: {
59
68
  label: "Transaction Submitter",
60
69
  type: "text",
@@ -212,6 +221,13 @@ export const PRIVATE_STATE_CLI_FIELD_CATALOG = Object.freeze({
212
221
  option: "--output-raw",
213
222
  optional: true,
214
223
  },
224
+ publishWorkspaceMirror: {
225
+ label: "Publish Workspace Mirror",
226
+ type: "checkbox",
227
+ hint: "After channel recovery, write the registered workspace mirror manifest, checkpoint, and any delta bundle.",
228
+ option: "--publish-workspace-mirror",
229
+ optional: true,
230
+ },
215
231
  source: {
216
232
  label: "Recovery Source",
217
233
  type: "select",
@@ -330,7 +346,11 @@ export const PRIVATE_STATE_CLI_COMMANDS = Object.freeze([
330
346
  fields: ["network", "channelName", "account", "wallet"],
331
347
  optionalFields: ["network", "channelName", "account", "wallet"],
332
348
  usage: "optional --network, --channel-name, --account, and --wallet",
333
- help: ["Does not accept --rpc-url and never writes RPC configuration", "Recommends bridge deposits only after a wallet is joined and needs channel liquidity"],
349
+ help: [
350
+ "Does not accept --rpc-url and never writes RPC configuration",
351
+ "Recommends bridge deposits only after a wallet is joined and needs channel liquidity",
352
+ "Channel leaders publish workspace mirror files through channel recover-workspace --publish-workspace-mirror, not a standalone publish command",
353
+ ],
334
354
  },
335
355
  {
336
356
  id: "help-observer",
@@ -405,8 +425,9 @@ export const PRIVATE_STATE_CLI_COMMANDS = Object.freeze([
405
425
  display: "channel recover-workspace",
406
426
  description: "Rebuild the local channel workspace from bridge state.",
407
427
  installMode: "read-only",
408
- fields: ["channelName", "network", "source", "fromGenesis", "outputRaw"],
409
- usage: "--channel-name, --network, optional --source, optional --from-genesis, optional --output-raw",
428
+ fields: ["channelName", "network", "source", "fromGenesis", "outputRaw", "publishWorkspaceMirror", "leaderAccount", "output", "force"],
429
+ optionalFields: ["source", "fromGenesis", "outputRaw", "publishWorkspaceMirror", "leaderAccount", "output", "force"],
430
+ usage: "--channel-name, --network, optional --source, optional --from-genesis, optional --output-raw, optional --publish-workspace-mirror with --leader-account and --output, optional --force",
410
431
  help: [
411
432
  "By default, --source rpc resumes RPC log scanning from the workspace recovery index when available",
412
433
  "--source mirror validates the channel leader's registered checkpoint manifest, downloads only the needed checkpoint or delta bundle, and then replays RPC logs to latest",
@@ -416,6 +437,10 @@ export const PRIVATE_STATE_CLI_COMMANDS = Object.freeze([
416
437
  "Use --source rpc --from-genesis to ignore the recovery index and replay logs from channel genesis",
417
438
  "--output-raw with --source rpc appends raw JSON-RPC request and response history to method-specific JSON files under the channel workspace rpcCallHistory directory; eth_getLogs is split by event",
418
439
  "--from-genesis moves the existing local channel workspace to workspace-rebuild-backups before writing the current-format workspace; local secrets are preserved",
440
+ "--publish-workspace-mirror writes manifest.json, checkpoint.zip, and any needed delta bundle after recovery",
441
+ "--publish-workspace-mirror requires --leader-account <ACCOUNT> and --output <PATH>; the leader account signs the mirror manifest and must match the on-chain channel leader",
442
+ "--force with --publish-workspace-mirror ignores an unreadable or invalid existing mirror manifest and publishes a full checkpoint without a delta",
443
+ "Workspace mirror publishing does not upload files to a remote server; deploy the output directory to the registered mirror host",
419
444
  "Prints RPC log scan progress while rebuilding the workspace",
420
445
  ],
421
446
  },
@@ -431,20 +456,6 @@ export const PRIVATE_STATE_CLI_COMMANDS = Object.freeze([
431
456
  "The URL points to a server implementing the private-state channel workspace mirror protocol",
432
457
  ],
433
458
  },
434
- {
435
- id: "channel-publish-workspace-mirror",
436
- display: "channel publish-workspace-mirror",
437
- description: "Build static workspace mirror files for the registered mirror URL.",
438
- installMode: "read-only",
439
- fields: ["channelName", "network", "account", "output", "force"],
440
- usage: "--channel-name, --network, --account, --output, optional --force",
441
- help: [
442
- "Requires the local channel workspace to be current and ahead of the registered mirror checkpoint",
443
- "--force ignores an unreadable or invalid existing mirror manifest and publishes a full checkpoint without a delta",
444
- "Writes manifest.json, checkpoint.zip, and any needed delta bundle under the workspace mirror static path",
445
- "Does not upload files to a remote server; deploy the output directory to the registered HTTPS mirror host",
446
- ],
447
- },
448
459
  {
449
460
  id: "channel-get-meta",
450
461
  display: "channel get-meta",
package/lib/runtime.mjs CHANGED
@@ -729,6 +729,8 @@ async function handleWorkspaceInit({ args, network, provider }) {
729
729
  workspaceDir,
730
730
  workspace,
731
731
  currentSnapshot,
732
+ blockInfo,
733
+ contractCodes,
732
734
  cleanRebuildBackup,
733
735
  rpcCallHistory,
734
736
  } = await syncChannelWorkspace({
@@ -746,6 +748,24 @@ async function handleWorkspaceInit({ args, network, provider }) {
746
748
  progressAction: "channel recover-workspace",
747
749
  });
748
750
 
751
+ const publishedWorkspaceMirror = args.publishWorkspaceMirror === true
752
+ ? await publishChannelWorkspaceMirrorFromRecoveredWorkspace({
753
+ args,
754
+ network,
755
+ provider,
756
+ bridgeResources,
757
+ channelName,
758
+ local: {
759
+ workspace,
760
+ stateSnapshot: currentSnapshot,
761
+ blockInfo,
762
+ contractCodes,
763
+ recoveryLastScannedBlock: workspace.recoveryLastScannedBlock,
764
+ recoveryRootVectorHash: workspace.recoveryRootVectorHash,
765
+ },
766
+ })
767
+ : null;
768
+
749
769
  printJson({
750
770
  action: "channel recover-workspace",
751
771
  source: workspace.recoverySource ?? recoverySource,
@@ -764,6 +784,7 @@ async function handleWorkspaceInit({ args, network, provider }) {
764
784
  recoveryScanRange: workspace.recoveryScanRange,
765
785
  rpcCallHistory,
766
786
  workspaceMirror: workspace.workspaceMirror ?? null,
787
+ publishedWorkspaceMirror,
767
788
  });
768
789
  }
769
790
 
@@ -875,12 +896,17 @@ async function handleSetChannelWorkspaceMirror({ args, network, provider }) {
875
896
  });
876
897
  }
877
898
 
878
- async function handlePublishChannelWorkspaceMirror({ args, network, provider }) {
879
- const channelName = requireArg(args.channelName, "--channel-name");
899
+ async function publishChannelWorkspaceMirrorFromRecoveredWorkspace({
900
+ args,
901
+ network,
902
+ provider,
903
+ bridgeResources,
904
+ channelName,
905
+ local,
906
+ }) {
880
907
  const outputRoot = path.resolve(String(requireArg(args.output, "--output")));
881
908
  const force = args.force === true;
882
- const signer = requireL1Signer(args, provider);
883
- const bridgeResources = loadBridgeResources({ chainId: network.chainId });
909
+ const { signer, account: leaderAccount } = requireLeaderSigner(args, provider);
884
910
  const { bridgeDeployment, bridgeAbiManifest } = bridgeResources;
885
911
  const bridgeCore = new Contract(
886
912
  bridgeDeployment.bridgeCore,
@@ -906,13 +932,6 @@ async function handlePublishChannelWorkspaceMirror({ args, network, provider })
906
932
  channelId,
907
933
  });
908
934
 
909
- const local = await loadPublishableLocalWorkspaceMirrorCheckpoint({
910
- channelName,
911
- network,
912
- provider,
913
- bridgeResources,
914
- channelInfo,
915
- });
916
935
  const remote = await readRemoteWorkspaceMirrorCheckpoint({
917
936
  manifestUrl,
918
937
  chainId: network.chainId,
@@ -927,9 +946,9 @@ async function handlePublishChannelWorkspaceMirror({ args, network, provider })
927
946
  expect(
928
947
  !remote.exists || Number(local.recoveryLastScannedBlock) > Number(remote.recoveryLastScannedBlock),
929
948
  [
930
- `Local workspace recovery index ${local.recoveryLastScannedBlock} is not ahead of the registered mirror`,
949
+ `Recovered workspace index ${local.recoveryLastScannedBlock} is not ahead of the registered mirror`,
931
950
  `checkpoint ${remote.exists ? remote.recoveryLastScannedBlock : "<missing>"}.`,
932
- "Run channel recover-workspace first if the local workspace is stale.",
951
+ "No newer workspace mirror checkpoint can be published.",
933
952
  ].join(" "),
934
953
  );
935
954
 
@@ -1023,11 +1042,13 @@ async function handlePublishChannelWorkspaceMirror({ args, network, provider })
1023
1042
  };
1024
1043
  writeJson(publishTarget.manifestPath, manifest);
1025
1044
 
1026
- printJson({
1027
- action: "channel publish-workspace-mirror",
1045
+ return {
1046
+ action: "channel recover-workspace publish-workspace-mirror",
1028
1047
  channelName,
1029
1048
  channelId: channelId.toString(),
1030
1049
  force,
1050
+ leaderAccount,
1051
+ leader: getAddress(signer.address),
1031
1052
  outputRoot,
1032
1053
  mirrorDir,
1033
1054
  manifestPath: publishTarget.manifestPath,
@@ -1053,7 +1074,7 @@ async function handlePublishChannelWorkspaceMirror({ args, network, provider })
1053
1074
  sizeBytes: checkpointBundle.bytes.length,
1054
1075
  },
1055
1076
  deltaBundles,
1056
- });
1077
+ };
1057
1078
  }
1058
1079
 
1059
1080
  function resolveWorkspaceRecoverySource(args) {
@@ -1084,84 +1105,6 @@ async function readChannelWorkspaceMirror({ bridgeCore, channelId }) {
1084
1105
  return String(await bridgeCore.getChannelWorkspaceMirror(channelId));
1085
1106
  }
1086
1107
 
1087
- async function loadPublishableLocalWorkspaceMirrorCheckpoint({
1088
- channelName,
1089
- network,
1090
- provider,
1091
- bridgeResources,
1092
- channelInfo,
1093
- }) {
1094
- const workspaceDir = channelWorkspacePath(networkNameFromChainId(network.chainId), channelName);
1095
- const existingArtifacts = loadExistingWorkspaceArtifacts(workspaceDir);
1096
- const workspace = existingArtifacts.workspace;
1097
- expect(workspace, `Local channel workspace is missing at ${channelWorkspaceConfigPath(workspaceDir)}.`);
1098
- const stateSnapshot = existingArtifacts.stateSnapshot;
1099
- expect(stateSnapshot, `Local channel state snapshot is missing under ${channelWorkspaceCurrentPath(workspaceDir)}.`);
1100
- expect(existingArtifacts.blockInfo, `Local channel block_info.json is missing under ${channelWorkspaceCurrentPath(workspaceDir)}.`);
1101
- expect(existingArtifacts.contractCodes, `Local channel contract_codes.json is missing under ${channelWorkspaceCurrentPath(workspaceDir)}.`);
1102
- const channelManager = new Contract(
1103
- channelInfo.manager,
1104
- bridgeResources.bridgeAbiManifest.contracts.channelManager.abi,
1105
- provider,
1106
- );
1107
- const [
1108
- currentRootVectorHash,
1109
- genesisBlockNumber,
1110
- latestBlock,
1111
- managedStorageAddresses,
1112
- ] = await Promise.all([
1113
- channelManager.currentRootVectorHash(),
1114
- channelManager.genesisBlockNumber(),
1115
- provider.getBlockNumber(),
1116
- channelManager.getManagedStorageAddresses(),
1117
- ]);
1118
- const normalizedManagedStorageAddresses = normalizedAddressVector(managedStorageAddresses);
1119
- const recoveryIndex = getUsableWorkspaceRecoveryIndex({
1120
- existingArtifacts,
1121
- genesisBlockNumber: Number(genesisBlockNumber),
1122
- latestBlock,
1123
- managedStorageAddresses: normalizedManagedStorageAddresses,
1124
- });
1125
- expect(
1126
- recoveryIndex,
1127
- [
1128
- "Local channel workspace does not contain a usable recovery index.",
1129
- `Run channel recover-workspace --channel-name ${channelName} --network ${networkNameFromChainId(network.chainId)} first.`,
1130
- ].join(" "),
1131
- );
1132
- expect(
1133
- canReuseLocalWorkspaceSnapshot({
1134
- existingArtifacts,
1135
- currentRootVectorHash,
1136
- managedStorageAddresses: normalizedManagedStorageAddresses,
1137
- }),
1138
- [
1139
- "Local channel workspace is stale relative to the on-chain channel state.",
1140
- `Run channel recover-workspace --channel-name ${channelName} --network ${networkNameFromChainId(network.chainId)} first.`,
1141
- ].join(" "),
1142
- );
1143
- expect(Number(workspace.chainId) === Number(network.chainId), "Local workspace chainId does not match --network.");
1144
- expect(ethers.toBigInt(workspace.channelId) === ethers.toBigInt(deriveChannelIdFromName(channelName)), "Local workspace channelId mismatch.");
1145
- expect(String(workspace.channelName) === channelName, "Local workspace channelName mismatch.");
1146
- expect(
1147
- ethers.toBigInt(getAddress(workspace.channelManager)) === ethers.toBigInt(getAddress(channelInfo.manager)),
1148
- "Local workspace channelManager mismatch.",
1149
- );
1150
- expect(
1151
- ethers.toBigInt(getAddress(workspace.bridgeTokenVault)) === ethers.toBigInt(getAddress(channelInfo.bridgeTokenVault)),
1152
- "Local workspace bridgeTokenVault mismatch.",
1153
- );
1154
-
1155
- return {
1156
- workspace,
1157
- stateSnapshot,
1158
- blockInfo: existingArtifacts.blockInfo,
1159
- contractCodes: existingArtifacts.contractCodes,
1160
- recoveryLastScannedBlock: recoveryIndex.nextBlock,
1161
- recoveryRootVectorHash: recoveryIndex.recoveryRootVectorHash,
1162
- };
1163
- }
1164
-
1165
1108
  async function readRemoteWorkspaceMirrorCheckpoint({
1166
1109
  manifestUrl,
1167
1110
  chainId,
@@ -3661,6 +3604,7 @@ async function handleGuide({ args }) {
3661
3604
  why: null,
3662
3605
  candidateCommands: [],
3663
3606
  privacyTip: "For wallet mint-notes, wallet transfer-notes, and wallet redeem-notes, add --tx-submitter <ACCOUNT> to let a separate local L1 account submit executeChannelTransaction and pay gas.",
3607
+ mirrorTip: "Channel leaders refresh mirror files with channel recover-workspace --publish-workspace-mirror --leader-account <ACCOUNT> --output <PATH>; the standalone channel publish-workspace-mirror command is no longer available.",
3664
3608
  };
3665
3609
 
3666
3610
  guide.state.local = inspectGuideLocalState(args);
@@ -9764,6 +9708,19 @@ function requireL1Signer(args, provider) {
9764
9708
  return new Wallet(resolvePrivateKeySource(args), provider);
9765
9709
  }
9766
9710
 
9711
+ function requireLeaderSigner(args, provider) {
9712
+ const networkName = requireNetworkName(args);
9713
+ const account = String(requireArg(args.leaderAccount, "--leader-account")).trim();
9714
+ expect(account.length > 0, "--leader-account requires a local account name.");
9715
+ return {
9716
+ signer: new Wallet(
9717
+ normalizePrivateKey(readSecretFile(accountPrivateKeyPath(networkName, account), "--leader-account")),
9718
+ provider,
9719
+ ),
9720
+ account,
9721
+ };
9722
+ }
9723
+
9767
9724
  function resolveTxSubmitterSigner({ args, ownerSigner, provider }) {
9768
9725
  if (args.txSubmitter === undefined) {
9769
9726
  expect(
@@ -10453,9 +10410,25 @@ function assertRecoverWorkspaceArgs(args) {
10453
10410
  const source = resolveWorkspaceRecoverySource(args);
10454
10411
  assertBooleanFlag(args, "fromGenesis", "channel recover-workspace option --from-genesis");
10455
10412
  assertBooleanFlag(args, "outputRaw", "channel recover-workspace option --output-raw");
10413
+ assertBooleanFlag(args, "publishWorkspaceMirror", "channel recover-workspace option --publish-workspace-mirror");
10414
+ assertBooleanFlag(args, "force", "channel recover-workspace option --force");
10456
10415
  if (args.outputRaw === true && source !== "rpc") {
10457
10416
  throw new Error("channel recover-workspace option --output-raw requires --source rpc.");
10458
10417
  }
10418
+ if (args.publishWorkspaceMirror === true) {
10419
+ requireArg(args.leaderAccount, "--leader-account");
10420
+ requireArg(args.output, "--output");
10421
+ } else {
10422
+ if (args.leaderAccount !== undefined) {
10423
+ throw new Error("channel recover-workspace option --leader-account requires --publish-workspace-mirror.");
10424
+ }
10425
+ if (args.output !== undefined) {
10426
+ throw new Error("channel recover-workspace option --output requires --publish-workspace-mirror.");
10427
+ }
10428
+ if (args.force !== undefined) {
10429
+ throw new Error("channel recover-workspace option --force requires --publish-workspace-mirror.");
10430
+ }
10431
+ }
10459
10432
  }
10460
10433
 
10461
10434
  function assertGetChannelArgs(args) {
@@ -10467,12 +10440,6 @@ function assertSetWorkspaceMirrorArgs(args) {
10467
10440
  requireWorkspaceMirrorUrl(args.url);
10468
10441
  }
10469
10442
 
10470
- function assertPublishWorkspaceMirrorArgs(args) {
10471
- assertAllowedCommandSchema(args, "channel-publish-workspace-mirror");
10472
- requireArg(args.output, "--output");
10473
- assertBooleanFlag(args, "force", "channel publish-workspace-mirror option --force");
10474
- }
10475
-
10476
10443
  function assertDepositBridgeArgs(args) {
10477
10444
  assertAllowedCommandSchema(args, "account-deposit-bridge");
10478
10445
  assertActionImpactArg(args, "account deposit-bridge");
@@ -11369,6 +11336,11 @@ function printGuideHumanResult(guide) {
11369
11336
  "Privacy Tip",
11370
11337
  formatHumanValue(guide.privacyTip),
11371
11338
  );
11339
+ lines.push(
11340
+ "",
11341
+ "Mirror Tip",
11342
+ formatHumanValue(guide.mirrorTip),
11343
+ );
11372
11344
  console.log(lines.join("\n"));
11373
11345
  }
11374
11346
 
@@ -11847,7 +11819,6 @@ export {
11847
11819
  assertRecoverWorkspaceArgs,
11848
11820
  assertGetChannelArgs,
11849
11821
  assertSetWorkspaceMirrorArgs,
11850
- assertPublishWorkspaceMirrorArgs,
11851
11822
  assertDepositBridgeArgs,
11852
11823
  assertWithdrawBridgeArgs,
11853
11824
  assertAccountGetBridgeFundArgs,
@@ -11881,7 +11852,6 @@ export {
11881
11852
  handleWorkspaceInit,
11882
11853
  handleGetChannel,
11883
11854
  handleSetChannelWorkspaceMirror,
11884
- handlePublishChannelWorkspaceMirror,
11885
11855
  handleDepositBridge,
11886
11856
  handleWithdrawBridge,
11887
11857
  handleAccountGetBridgeFund,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tokamak-private-dapps/private-state-cli",
3
- "version": "2.3.4",
3
+ "version": "2.4.0",
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",