@tokamak-private-dapps/private-state-cli 1.0.2 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -414,31 +414,31 @@
414
414
  <div class="box">
415
415
  <ol class="guide-list">
416
416
  <li>
417
- <span class="guide-label">Join a channel:</span> <code>join-channel</code>
417
+ <span class="guide-label">Join a channel:</span> <code>channel join</code>
418
418
  <div class="guide-example">
419
- <code>join-channel --channel-name 'my-private-channel' --network 'sepolia' --account 'my-account' --wallet-secret-path '/path/to/wallet-secret' --rpc-url '__RPC_URL__'</code>
419
+ <code>channel join --channel-name 'my-private-channel' --network 'sepolia' --account 'my-account' --wallet-secret-path '/path/to/wallet-secret' --rpc-url '__RPC_URL__'</code>
420
420
  </div>
421
421
  </li>
422
422
  <li>
423
- <span class="guide-label">Create notes:</span> <code>deposit-bridge</code> -&gt; <code>deposit-channel</code> -&gt; <code>mint-notes</code>
423
+ <span class="guide-label">Create notes:</span> <code>account deposit-bridge</code> -&gt; <code>wallet deposit-channel</code> -&gt; <code>wallet mint-notes</code>
424
424
  <div class="guide-example">
425
- <code>deposit-bridge --amount '100' --network 'sepolia' --account 'my-account' --rpc-url '__RPC_URL__'</code><br />
426
- <code>deposit-channel --wallet 'my-private-channel-0xYourL1Address' --network 'sepolia' --amount '100'</code><br />
427
- <code>mint-notes --wallet 'my-private-channel-0xYourL1Address' --network 'sepolia' --amounts '[&quot;50&quot;,&quot;50&quot;,&quot;0&quot;]'</code>
425
+ <code>account deposit-bridge --amount '100' --network 'sepolia' --account 'my-account' --rpc-url '__RPC_URL__'</code><br />
426
+ <code>wallet deposit-channel --wallet 'my-private-channel-0xYourL1Address' --network 'sepolia' --amount '100'</code><br />
427
+ <code>wallet mint-notes --wallet 'my-private-channel-0xYourL1Address' --network 'sepolia' --amounts '[&quot;50&quot;,&quot;50&quot;,&quot;0&quot;]'</code>
428
428
  </div>
429
429
  </li>
430
430
  <li>
431
- <span class="guide-label">Split, merge, or transfer note ownership:</span> <code>transfer-notes</code>
431
+ <span class="guide-label">Split, merge, or transfer note ownership:</span> <code>wallet transfer-notes</code>
432
432
  <div class="guide-example">
433
- <code>transfer-notes --wallet 'my-private-channel-0xYourL1Address' --network 'sepolia' --note-ids '[&quot;0xNoteIdA&quot;]' --recipients '[&quot;0xRecipientL2AddressA&quot;,&quot;0xRecipientL2AddressB&quot;]' --amounts '[&quot;25&quot;,&quot;25&quot;]'</code>
433
+ <code>wallet transfer-notes --wallet 'my-private-channel-0xYourL1Address' --network 'sepolia' --note-ids '[&quot;0xNoteIdA&quot;]' --recipients '[&quot;0xRecipientL2AddressA&quot;,&quot;0xRecipientL2AddressB&quot;]' --amounts '[&quot;25&quot;,&quot;25&quot;]'</code>
434
434
  </div>
435
435
  </li>
436
436
  <li>
437
- <span class="guide-label">Redeem notes back to L1:</span> <code>redeem-notes</code> -&gt; <code>withdraw-channel</code> -&gt; <code>withdraw-bridge</code>
437
+ <span class="guide-label">Redeem notes back to L1:</span> <code>wallet redeem-notes</code> -&gt; <code>wallet withdraw-channel</code> -&gt; <code>account withdraw-bridge</code>
438
438
  <div class="guide-example">
439
- <code>redeem-notes --wallet 'my-private-channel-0xYourL1Address' --network 'sepolia' --note-ids '[&quot;0xNoteIdA&quot;]'</code><br />
440
- <code>withdraw-channel --wallet 'my-private-channel-0xYourL1Address' --network 'sepolia' --amount '25'</code><br />
441
- <code>withdraw-bridge --amount '25' --network 'sepolia' --account 'my-account' --rpc-url '__RPC_URL__'</code>
439
+ <code>wallet redeem-notes --wallet 'my-private-channel-0xYourL1Address' --network 'sepolia' --note-ids '[&quot;0xNoteIdA&quot;]'</code><br />
440
+ <code>wallet withdraw-channel --wallet 'my-private-channel-0xYourL1Address' --network 'sepolia' --amount '25'</code><br />
441
+ <code>account withdraw-bridge --amount '25' --network 'sepolia' --account 'my-account' --rpc-url '__RPC_URL__'</code>
442
442
  </div>
443
443
  </li>
444
444
  </ol>
@@ -466,7 +466,7 @@
466
466
  }));
467
467
 
468
468
  const defaultState = {
469
- commandId: "join-channel",
469
+ commandId: "channel-join",
470
470
  channelName: "",
471
471
  joinToll: "1",
472
472
  network: "sepolia",
@@ -612,13 +612,13 @@
612
612
  }
613
613
 
614
614
  function commandNeedsWalletNotes(command = currentCommand()) {
615
- return command.id === "transfer-notes" || command.id === "redeem-notes";
615
+ return command.id === "wallet-transfer-notes" || command.id === "wallet-redeem-notes";
616
616
  }
617
617
 
618
618
  function commandNeedsExistingChannel(command = currentCommand()) {
619
619
  return command.fields.includes("channelName")
620
- && command.id !== "create-channel"
621
- && command.id !== "recover-workspace";
620
+ && command.id !== "channel-create"
621
+ && command.id !== "channel-recover-workspace";
622
622
  }
623
623
 
624
624
  function currentWorkspaceOptions() {
@@ -695,7 +695,7 @@
695
695
  }
696
696
 
697
697
  function noteSelectionLimit() {
698
- return currentCommand().id === "redeem-notes" ? 1 : 2;
698
+ return currentCommand().id === "wallet-redeem-notes" ? 1 : 2;
699
699
  }
700
700
 
701
701
  function mintAmountsTotalLabel() {
@@ -814,7 +814,7 @@
814
814
  await refreshWalletNoteOptions();
815
815
  if (commandNeedsWalletNotes()) {
816
816
  rerenderCommandField("noteIds");
817
- if (currentCommand().id === "transfer-notes") {
817
+ if (currentCommand().id === "wallet-transfer-notes") {
818
818
  rerenderCommandField("recipients");
819
819
  }
820
820
  }
@@ -838,7 +838,7 @@
838
838
  }
839
839
 
840
840
  function missingFields(command) {
841
- const transferOutputs = command.id === "transfer-notes"
841
+ const transferOutputs = command.id === "wallet-transfer-notes"
842
842
  ? currentTransferOutputs()
843
843
  : null;
844
844
  const optionalFields = new Set(command.optionalFields ?? []);
@@ -846,10 +846,10 @@
846
846
  if (fieldCatalog[fieldKey]?.optional || optionalFields.has(fieldKey)) {
847
847
  return false;
848
848
  }
849
- if (fieldKey === "amounts" && command.id === "mint-notes") {
849
+ if (fieldKey === "amounts" && command.id === "wallet-mint-notes") {
850
850
  return currentMintAmounts().length === 0;
851
851
  }
852
- if ((fieldKey === "recipients" || fieldKey === "amounts") && command.id === "transfer-notes") {
852
+ if ((fieldKey === "recipients" || fieldKey === "amounts") && command.id === "wallet-transfer-notes") {
853
853
  if (fieldKey === "amounts") {
854
854
  return false;
855
855
  }
@@ -861,8 +861,8 @@
861
861
 
862
862
  function buildCommand({ maskSecrets }) {
863
863
  const command = currentCommand();
864
- const parts = [cliEntry, command.id];
865
- const transferOutputs = command.id === "transfer-notes"
864
+ const parts = [cliEntry, ...(command.display ?? command.id).split(" ")];
865
+ const transferOutputs = command.id === "wallet-transfer-notes"
866
866
  ? currentTransferOutputs()
867
867
  : null;
868
868
 
@@ -871,13 +871,13 @@
871
871
  continue;
872
872
  }
873
873
 
874
- const value = fieldKey === "amounts" && command.id === "mint-notes"
874
+ const value = fieldKey === "amounts" && command.id === "wallet-mint-notes"
875
875
  ? JSON.stringify(currentMintAmounts())
876
- : fieldKey === "amounts" && command.id === "transfer-notes"
876
+ : fieldKey === "amounts" && command.id === "wallet-transfer-notes"
877
877
  ? (!transferOutputs.hasPartialPair && transferOutputs.amounts.length > 0
878
878
  ? JSON.stringify(transferOutputs.amounts)
879
879
  : "")
880
- : fieldKey === "recipients" && command.id === "transfer-notes"
880
+ : fieldKey === "recipients" && command.id === "wallet-transfer-notes"
881
881
  ? (!transferOutputs.hasPartialPair && transferOutputs.recipients.length > 0
882
882
  ? JSON.stringify(transferOutputs.recipients)
883
883
  : "")
@@ -990,8 +990,8 @@
990
990
  const currentOptions = currentWorkspaceOptions();
991
991
  if (
992
992
  !currentOptions.channelOptions.includes(state.channelName)
993
- && currentCommand().id !== "create-channel"
994
- && currentCommand().id !== "recover-workspace"
993
+ && currentCommand().id !== "channel-create"
994
+ && currentCommand().id !== "channel-recover-workspace"
995
995
  ) {
996
996
  state.channelName = currentOptions.channelOptions[0] ?? "";
997
997
  }
@@ -1167,7 +1167,7 @@
1167
1167
  state.noteIds = nextSelection.length === 0 ? "" : JSON.stringify(nextSelection);
1168
1168
  persistState();
1169
1169
  rerenderCommandField("noteIds");
1170
- if (currentCommand().id === "transfer-notes") {
1170
+ if (currentCommand().id === "wallet-transfer-notes") {
1171
1171
  rerenderCommandField("recipients");
1172
1172
  }
1173
1173
  renderPreview();
@@ -1334,10 +1334,10 @@
1334
1334
  if (fieldKey === "wallet") {
1335
1335
  return createWalletField();
1336
1336
  }
1337
- if (fieldKey === "amounts" && currentCommand().id === "mint-notes") {
1337
+ if (fieldKey === "amounts" && currentCommand().id === "wallet-mint-notes") {
1338
1338
  return createMintAmountsField();
1339
1339
  }
1340
- if (fieldKey === "recipients" && currentCommand().id === "transfer-notes") {
1340
+ if (fieldKey === "recipients" && currentCommand().id === "wallet-transfer-notes") {
1341
1341
  return createTransferPairsField();
1342
1342
  }
1343
1343
  if (fieldKey === "noteIds" && commandNeedsWalletNotes()) {
@@ -1345,8 +1345,8 @@
1345
1345
  }
1346
1346
  if (
1347
1347
  fieldKey === "channelName"
1348
- && currentCommand().id !== "create-channel"
1349
- && currentCommand().id !== "recover-workspace"
1348
+ && currentCommand().id !== "channel-create"
1349
+ && currentCommand().id !== "channel-recover-workspace"
1350
1350
  ) {
1351
1351
  return createExistingChannelField();
1352
1352
  }
@@ -1423,7 +1423,7 @@
1423
1423
  for (const command of commands) {
1424
1424
  const option = document.createElement("option");
1425
1425
  option.value = command.id;
1426
- option.textContent = command.id;
1426
+ option.textContent = command.display ?? command.id;
1427
1427
  commandSelectEl.appendChild(option);
1428
1428
  }
1429
1429
  commandSelectEl.value = state.commandId;
@@ -1450,7 +1450,7 @@
1450
1450
  if (fieldKey === "rpcUrl" && !acceptsRpcUrl(command)) {
1451
1451
  continue;
1452
1452
  }
1453
- if (fieldKey === "amounts" && command.id === "transfer-notes") {
1453
+ if (fieldKey === "amounts" && command.id === "wallet-transfer-notes") {
1454
1454
  continue;
1455
1455
  }
1456
1456
  const fieldElement = createField(fieldKey);
@@ -68,6 +68,34 @@ export const PRIVATE_STATE_CLI_FIELD_CATALOG = Object.freeze({
68
68
  valueLabel: "<NAME>",
69
69
  option: "--wallet",
70
70
  },
71
+ output: {
72
+ label: "Output ZIP",
73
+ type: "text",
74
+ placeholder: "/path/to/wallet-export.zip",
75
+ valueLabel: "<ZIP>",
76
+ option: "--output",
77
+ },
78
+ input: {
79
+ label: "Input ZIP",
80
+ type: "text",
81
+ placeholder: "/path/to/wallet-export.zip",
82
+ valueLabel: "<ZIP>",
83
+ option: "--input",
84
+ },
85
+ all: {
86
+ label: "All Mainnet Wallets",
87
+ type: "checkbox",
88
+ hint: "Export every local mainnet wallet instead of one selected wallet.",
89
+ option: "--all",
90
+ optional: true,
91
+ },
92
+ includeNotes: {
93
+ label: "Include Immediate-Use Cache",
94
+ type: "checkbox",
95
+ hint: "Also export the channel workspace cache needed to use note and wallet commands without running recovery first.",
96
+ option: "--include-notes",
97
+ optional: true,
98
+ },
71
99
  amount: {
72
100
  label: "Amount",
73
101
  type: "text",
@@ -168,7 +196,15 @@ export const PRIVATE_STATE_CLI_COMMANDS = Object.freeze([
168
196
  usage: "no options",
169
197
  },
170
198
  {
171
- id: "update",
199
+ id: "help-commands",
200
+ display: "help commands",
201
+ description: "Show the private-state CLI command reference.",
202
+ fields: [],
203
+ usage: "no options",
204
+ },
205
+ {
206
+ id: "help-update",
207
+ display: "help update",
172
208
  description: "Check npm registry for the latest private-state CLI package and update global installs when possible.",
173
209
  fields: ["json"],
174
210
  usage: "optional --json",
@@ -178,7 +214,8 @@ export const PRIVATE_STATE_CLI_COMMANDS = Object.freeze([
178
214
  ],
179
215
  },
180
216
  {
181
- id: "doctor",
217
+ id: "help-doctor",
218
+ display: "help doctor",
182
219
  description: "Check private-state CLI package versions, runtime install state, Docker mode, CUDA mode, and deployment artifacts.",
183
220
  fields: ["gpu", "json"],
184
221
  usage: "optional --gpu and optional --json",
@@ -188,7 +225,8 @@ export const PRIVATE_STATE_CLI_COMMANDS = Object.freeze([
188
225
  ],
189
226
  },
190
227
  {
191
- id: "guide",
228
+ id: "help-guide",
229
+ display: "help guide",
192
230
  description: "Inspect local CLI state and available on-chain state, then print the next safe command.",
193
231
  fields: ["network", "channelName", "account", "wallet"],
194
232
  optionalFields: ["network", "channelName", "account", "wallet"],
@@ -196,7 +234,8 @@ export const PRIVATE_STATE_CLI_COMMANDS = Object.freeze([
196
234
  help: ["Does not accept --rpc-url and never writes RPC configuration"],
197
235
  },
198
236
  {
199
- id: "transaction-fees",
237
+ id: "help-transaction-fees",
238
+ display: "help transaction-fees",
200
239
  description: "Estimate ETH and USD fees for transaction-sending commands from packaged measured gas data and live network fee data.",
201
240
  fields: ["network", "rpcUrl", "json"],
202
241
  usage: "--network, optional --rpc-url, and optional --json",
@@ -213,7 +252,22 @@ export const PRIVATE_STATE_CLI_COMMANDS = Object.freeze([
213
252
  usage: "--account, --network, and --private-key-file",
214
253
  },
215
254
  {
216
- id: "create-channel",
255
+ id: "account-get-l1-address",
256
+ display: "account get-l1-address",
257
+ description: "Derive the L1 address for a local account.",
258
+ fields: ["account", "network"],
259
+ usage: "--network and --account",
260
+ },
261
+ {
262
+ id: "account-get-bridge-fund",
263
+ display: "account get-bridge-fund",
264
+ description: "Read the local account's current shared bridge vault balance.",
265
+ fields: ["network", "account", "rpcUrl"],
266
+ usage: "--network, --account, and optional --rpc-url",
267
+ },
268
+ {
269
+ id: "channel-create",
270
+ display: "channel create",
217
271
  description: "Create a bridge channel and initialize its workspace.",
218
272
  fields: ["channelName", "joinToll", "network", "account", "rpcUrl"],
219
273
  usage: "--channel-name, --join-toll, --network, --account, and optional --rpc-url",
@@ -223,7 +277,8 @@ export const PRIVATE_STATE_CLI_COMMANDS = Object.freeze([
223
277
  ],
224
278
  },
225
279
  {
226
- id: "recover-workspace",
280
+ id: "channel-recover-workspace",
281
+ display: "channel recover-workspace",
227
282
  description: "Rebuild the local channel workspace from bridge state.",
228
283
  fields: ["channelName", "network", "fromGenesis", "rpcUrl"],
229
284
  usage: "--channel-name, --network, optional --from-genesis, and optional --rpc-url",
@@ -235,36 +290,34 @@ export const PRIVATE_STATE_CLI_COMMANDS = Object.freeze([
235
290
  ],
236
291
  },
237
292
  {
238
- id: "get-channel",
293
+ id: "channel-get-meta",
294
+ display: "channel get-meta",
239
295
  description: "Read channel existence, manager, vault, toll, refund schedule, and immutable policy snapshot.",
240
296
  fields: ["channelName", "network", "rpcUrl"],
241
297
  usage: "--channel-name, --network, and optional --rpc-url",
242
298
  },
243
299
  {
244
- id: "deposit-bridge",
300
+ id: "account-deposit-bridge",
301
+ display: "account deposit-bridge",
245
302
  description: "Deposit canonical tokens into the shared bridge vault.",
246
303
  fields: ["amount", "network", "account", "rpcUrl"],
247
304
  usage: "--amount, --network, --account, and optional --rpc-url",
248
305
  },
249
306
  {
250
- id: "withdraw-bridge",
307
+ id: "account-withdraw-bridge",
308
+ display: "account withdraw-bridge",
251
309
  description: "Withdraw tokens from the shared bridge vault back to the wallet.",
252
310
  fields: ["amount", "network", "account", "rpcUrl"],
253
311
  usage: "--amount, --network, --account, and optional --rpc-url",
254
312
  },
255
313
  {
256
- id: "get-my-bridge-fund",
257
- description: "Read the current shared bridge vault balance.",
258
- fields: ["network", "account", "rpcUrl"],
259
- usage: "--network, --account, and optional --rpc-url",
260
- },
261
- {
262
- id: "recover-wallet",
314
+ id: "wallet-recover-workspace",
315
+ display: "wallet recover-workspace",
263
316
  description: "Rebuild a recoverable local wallet from on-chain channel state.",
264
317
  fields: ["channelName", "network", "account", "fromGenesis", "rpcUrl"],
265
318
  usage: "--channel-name, --network, --account, optional --from-genesis, and optional --rpc-url",
266
319
  help: [
267
- "Requires the protected wallet-local secret imported during join-channel to exist at the canonical secret path",
320
+ "Requires the protected wallet-local secret imported during channel join to exist at the canonical secret path",
268
321
  "Does not create or recover the wallet secret itself",
269
322
  "By default, resumes RPC log scanning from the workspace recovery index when available",
270
323
  "Fails instead of falling back to genesis when no usable recovery index exists",
@@ -273,7 +326,8 @@ export const PRIVATE_STATE_CLI_COMMANDS = Object.freeze([
273
326
  ],
274
327
  },
275
328
  {
276
- id: "join-channel",
329
+ id: "channel-join",
330
+ display: "channel join",
277
331
  description: "Pay the channel join toll and bind a wallet to a channel-specific L2 identity.",
278
332
  fields: ["channelName", "network", "account", "walletSecretPath", "rpcUrl"],
279
333
  usage: "--channel-name, --network, --account, --wallet-secret-path, and optional --rpc-url",
@@ -283,73 +337,101 @@ export const PRIVATE_STATE_CLI_COMMANDS = Object.freeze([
283
337
  ],
284
338
  },
285
339
  {
286
- id: "get-my-wallet-meta",
340
+ id: "wallet-get-meta",
341
+ display: "wallet get-meta",
287
342
  description: "Check whether a wallet matches the on-chain channel registration.",
288
343
  fields: ["wallet", "network"],
289
344
  usage: "--wallet and --network",
290
345
  help: ["Refreshes channel state through the workspace recovery index before reading registration metadata"],
291
346
  },
292
347
  {
293
- id: "get-my-l1-address",
294
- description: "Derive the L1 address for a private key.",
295
- fields: ["account", "network"],
296
- usage: "--network and --account",
297
- },
298
- {
299
- id: "list-local-wallets",
348
+ id: "wallet-list",
349
+ display: "wallet list",
300
350
  description: "List saved local wallet names that can be reused with --wallet.",
301
351
  fields: ["network", "channelName"],
302
352
  optionalFields: ["network", "channelName"],
303
353
  usage: "optional --network and --channel-name",
304
354
  },
305
355
  {
306
- id: "deposit-channel",
356
+ id: "wallet-export",
357
+ display: "wallet export",
358
+ description: "Export a local wallet backup ZIP that can be imported on another machine.",
359
+ fields: ["network", "wallet", "output", "all", "includeNotes"],
360
+ optionalFields: ["network", "wallet"],
361
+ usage: "--output, plus either --network and --wallet or --all; optional --include-notes",
362
+ help: [
363
+ "Default export includes the encrypted wallet, wallet metadata, and wallet-local secret; run channel recover-workspace after import",
364
+ "--include-notes also includes the channel workspace cache so wallet commands can run immediately when the cache is still chain-aligned",
365
+ "--all exports every local mainnet wallet and does not accept --network or --wallet",
366
+ ],
367
+ },
368
+ {
369
+ id: "wallet-import",
370
+ display: "wallet import",
371
+ description: "Import a ZIP created by wallet export into the canonical local wallet workspace.",
372
+ fields: ["input"],
373
+ usage: "--input",
374
+ help: [
375
+ "Refuses to overwrite existing wallet secrets or wallet files",
376
+ "Default exports require channel recover-workspace after import before wallet commands can use channel state",
377
+ ],
378
+ },
379
+ {
380
+ id: "wallet-deposit-channel",
381
+ display: "wallet deposit-channel",
307
382
  description: "Move bridged funds into the channel L2 accounting balance.",
308
383
  fields: ["wallet", "network", "amount"],
309
384
  usage: "--wallet, --network, and --amount",
310
385
  },
311
386
  {
312
- id: "withdraw-channel",
387
+ id: "wallet-withdraw-channel",
388
+ display: "wallet withdraw-channel",
313
389
  description: "Move channel L2 balance back into the shared bridge vault.",
314
390
  fields: ["wallet", "network", "amount"],
315
391
  usage: "--wallet, --network, and --amount",
316
392
  },
317
393
  {
318
- id: "get-my-channel-fund",
394
+ id: "wallet-get-channel-fund",
395
+ display: "wallet get-channel-fund",
319
396
  description: "Read the current channel L2 accounting balance.",
320
397
  fields: ["wallet", "network"],
321
398
  usage: "--wallet and --network",
322
399
  help: ["Refreshes channel state through the workspace recovery index before reading the L2 accounting balance"],
323
400
  },
324
401
  {
325
- id: "exit-channel",
402
+ id: "channel-exit",
403
+ display: "channel exit",
326
404
  description: "Exit a channel. Both the CLI and bridge contract require a zero channel balance.",
327
405
  fields: ["wallet", "network"],
328
406
  usage: "--wallet and --network",
329
407
  },
330
408
  {
331
- id: "mint-notes",
409
+ id: "wallet-mint-notes",
410
+ display: "wallet mint-notes",
332
411
  description: "Mint one or two private-state notes from the wallet's channel balance.",
333
412
  fields: ["wallet", "network", "amounts", "txSubmitter"],
334
413
  usage: "--wallet, --network, --amounts, and optional --tx-submitter",
335
414
  help: ["Use --tx-submitter <ACCOUNT> to let a separate local L1 account pay gas for stronger transaction privacy"],
336
415
  },
337
416
  {
338
- id: "transfer-notes",
417
+ id: "wallet-transfer-notes",
418
+ display: "wallet transfer-notes",
339
419
  description: "Spend input notes into the registered 1->1, 1->2, or 2->1 private transfer shapes.",
340
420
  fields: ["wallet", "network", "noteIds", "recipients", "amounts", "txSubmitter"],
341
421
  usage: "--wallet, --network, --note-ids, --recipients, --amounts, and optional --tx-submitter",
342
422
  help: ["Use --tx-submitter <ACCOUNT> to let a separate local L1 account pay gas for stronger transaction privacy"],
343
423
  },
344
424
  {
345
- id: "redeem-notes",
425
+ id: "wallet-redeem-notes",
426
+ display: "wallet redeem-notes",
346
427
  description: "Redeem one tracked note back into the wallet's channel balance.",
347
428
  fields: ["wallet", "network", "noteIds", "txSubmitter"],
348
429
  usage: "--wallet, --network, --note-ids, and optional --tx-submitter",
349
430
  help: ["Use --tx-submitter <ACCOUNT> to let a separate local L1 account pay gas for stronger transaction privacy"],
350
431
  },
351
432
  {
352
- id: "get-my-notes",
433
+ id: "wallet-get-notes",
434
+ display: "wallet get-notes",
353
435
  description: "Show the wallet's tracked note state and refresh received notes.",
354
436
  fields: ["wallet", "network"],
355
437
  usage: "--wallet and --network",
@@ -143,7 +143,7 @@ function printDoctorHumanReport(report) {
143
143
  "",
144
144
  formatDoctorTable(rows),
145
145
  "",
146
- "Run `doctor --json` for the full machine-readable report.",
146
+ "Run `help doctor --json` for the full machine-readable report.",
147
147
  ];
148
148
  console.log(lines.join("\n"));
149
149
  }
@@ -190,7 +190,7 @@ function buildDoctorHumanRows(report) {
190
190
  check: "docker gpu readiness",
191
191
  status: report.gpuDockerReadiness.skipped ? "SKIP" : doctorStatus(report.gpuDockerReadiness.ok),
192
192
  detail: report.gpuDockerReadiness.skipped
193
- ? "live GPU probe skipped; run `doctor --gpu` to check host NVIDIA and Docker GPU access"
193
+ ? "live GPU probe skipped; run `help doctor --gpu` to check host NVIDIA and Docker GPU access"
194
194
  : [
195
195
  `expectedUseGpus=${formatDoctorBool(report.gpuDockerReadiness.expectedUseGpus)}`,
196
196
  `liveUseGpus=${formatDoctorBool(report.gpuDockerReadiness.liveUseGpus)}`,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tokamak-private-dapps/private-state-cli",
3
- "version": "1.0.2",
3
+ "version": "1.1.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",
@@ -46,6 +46,7 @@
46
46
  "@tokamak-private-dapps/common-library": "^0.1.1",
47
47
  "@tokamak-private-dapps/groth16": "^0.2.0",
48
48
  "@tokamak-zk-evm/cli": "^2.1.0",
49
+ "adm-zip": "^0.5.17",
49
50
  "ethers": "^6.14.1",
50
51
  "tokamak-l2js": "^0.1.4"
51
52
  },