@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 +5 -0
- package/README.md +7 -4
- package/commands/channel.mjs +0 -7
- package/lib/private-state-cli-command-registry.mjs +28 -17
- package/lib/runtime.mjs +72 -102
- package/package.json +1 -1
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
|
|
240
|
-
|
|
241
|
-
|
|
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
|
package/commands/channel.mjs
CHANGED
|
@@ -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: [
|
|
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
|
-
|
|
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
|
|
879
|
-
|
|
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 =
|
|
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
|
-
`
|
|
949
|
+
`Recovered workspace index ${local.recoveryLastScannedBlock} is not ahead of the registered mirror`,
|
|
931
950
|
`checkpoint ${remote.exists ? remote.recoveryLastScannedBlock : "<missing>"}.`,
|
|
932
|
-
"
|
|
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
|
-
|
|
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