@tokamak-private-dapps/private-state-cli 1.0.1 → 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,26 @@ export const PRIVATE_STATE_CLI_COMMANDS = Object.freeze([
168
196
  usage: "no options",
169
197
  },
170
198
  {
171
- id: "doctor",
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",
208
+ description: "Check npm registry for the latest private-state CLI package and update global installs when possible.",
209
+ fields: ["json"],
210
+ usage: "optional --json",
211
+ help: [
212
+ "Global npm installs are updated with npm install -g when a newer registry version exists",
213
+ "Repository checkouts and non-global installs print the required update command instead of modifying source files",
214
+ ],
215
+ },
216
+ {
217
+ id: "help-doctor",
218
+ display: "help doctor",
172
219
  description: "Check private-state CLI package versions, runtime install state, Docker mode, CUDA mode, and deployment artifacts.",
173
220
  fields: ["gpu", "json"],
174
221
  usage: "optional --gpu and optional --json",
@@ -178,7 +225,8 @@ export const PRIVATE_STATE_CLI_COMMANDS = Object.freeze([
178
225
  ],
179
226
  },
180
227
  {
181
- id: "guide",
228
+ id: "help-guide",
229
+ display: "help guide",
182
230
  description: "Inspect local CLI state and available on-chain state, then print the next safe command.",
183
231
  fields: ["network", "channelName", "account", "wallet"],
184
232
  optionalFields: ["network", "channelName", "account", "wallet"],
@@ -186,7 +234,8 @@ export const PRIVATE_STATE_CLI_COMMANDS = Object.freeze([
186
234
  help: ["Does not accept --rpc-url and never writes RPC configuration"],
187
235
  },
188
236
  {
189
- id: "transaction-fees",
237
+ id: "help-transaction-fees",
238
+ display: "help transaction-fees",
190
239
  description: "Estimate ETH and USD fees for transaction-sending commands from packaged measured gas data and live network fee data.",
191
240
  fields: ["network", "rpcUrl", "json"],
192
241
  usage: "--network, optional --rpc-url, and optional --json",
@@ -203,60 +252,82 @@ export const PRIVATE_STATE_CLI_COMMANDS = Object.freeze([
203
252
  usage: "--account, --network, and --private-key-file",
204
253
  },
205
254
  {
206
- 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",
207
271
  description: "Create a bridge channel and initialize its workspace.",
208
272
  fields: ["channelName", "joinToll", "network", "account", "rpcUrl"],
209
273
  usage: "--channel-name, --join-toll, --network, --account, and optional --rpc-url",
210
- help: ["Prints the immutable policy snapshot before sending the transaction"],
274
+ help: [
275
+ "Prints the immutable policy snapshot before sending the transaction",
276
+ "Initializes the local channel workspace by replaying channel logs from channel genesis",
277
+ ],
211
278
  },
212
279
  {
213
- id: "recover-workspace",
280
+ id: "channel-recover-workspace",
281
+ display: "channel recover-workspace",
214
282
  description: "Rebuild the local channel workspace from bridge state.",
215
283
  fields: ["channelName", "network", "fromGenesis", "rpcUrl"],
216
284
  usage: "--channel-name, --network, optional --from-genesis, and optional --rpc-url",
217
285
  help: [
218
286
  "By default, resumes RPC log scanning from the workspace recovery index when available",
287
+ "Fails instead of falling back to genesis when no usable recovery index exists",
219
288
  "Use --from-genesis to ignore the recovery index and replay logs from channel genesis",
220
289
  "Prints RPC log scan progress while rebuilding the workspace",
221
290
  ],
222
291
  },
223
292
  {
224
- id: "get-channel",
293
+ id: "channel-get-meta",
294
+ display: "channel get-meta",
225
295
  description: "Read channel existence, manager, vault, toll, refund schedule, and immutable policy snapshot.",
226
296
  fields: ["channelName", "network", "rpcUrl"],
227
297
  usage: "--channel-name, --network, and optional --rpc-url",
228
298
  },
229
299
  {
230
- id: "deposit-bridge",
300
+ id: "account-deposit-bridge",
301
+ display: "account deposit-bridge",
231
302
  description: "Deposit canonical tokens into the shared bridge vault.",
232
303
  fields: ["amount", "network", "account", "rpcUrl"],
233
304
  usage: "--amount, --network, --account, and optional --rpc-url",
234
305
  },
235
306
  {
236
- id: "withdraw-bridge",
307
+ id: "account-withdraw-bridge",
308
+ display: "account withdraw-bridge",
237
309
  description: "Withdraw tokens from the shared bridge vault back to the wallet.",
238
310
  fields: ["amount", "network", "account", "rpcUrl"],
239
311
  usage: "--amount, --network, --account, and optional --rpc-url",
240
312
  },
241
313
  {
242
- id: "get-my-bridge-fund",
243
- description: "Read the current shared bridge vault balance.",
244
- fields: ["network", "account", "rpcUrl"],
245
- usage: "--network, --account, and optional --rpc-url",
246
- },
247
- {
248
- id: "recover-wallet",
314
+ id: "wallet-recover-workspace",
315
+ display: "wallet recover-workspace",
249
316
  description: "Rebuild a recoverable local wallet from on-chain channel state.",
250
- fields: ["channelName", "network", "account", "rpcUrl"],
251
- usage: "--channel-name, --network, --account, and optional --rpc-url",
317
+ fields: ["channelName", "network", "account", "fromGenesis", "rpcUrl"],
318
+ usage: "--channel-name, --network, --account, optional --from-genesis, and optional --rpc-url",
252
319
  help: [
253
- "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",
254
321
  "Does not create or recover the wallet secret itself",
322
+ "By default, resumes RPC log scanning from the workspace recovery index when available",
323
+ "Fails instead of falling back to genesis when no usable recovery index exists",
324
+ "Use --from-genesis to ignore the recovery index and replay channel logs from channel genesis",
255
325
  "Prints RPC log scan progress while rebuilding channel state and received-note state",
256
326
  ],
257
327
  },
258
328
  {
259
- id: "join-channel",
329
+ id: "channel-join",
330
+ display: "channel join",
260
331
  description: "Pay the channel join toll and bind a wallet to a channel-specific L2 identity.",
261
332
  fields: ["channelName", "network", "account", "walletSecretPath", "rpcUrl"],
262
333
  usage: "--channel-name, --network, --account, --wallet-secret-path, and optional --rpc-url",
@@ -266,74 +337,108 @@ export const PRIVATE_STATE_CLI_COMMANDS = Object.freeze([
266
337
  ],
267
338
  },
268
339
  {
269
- id: "get-my-wallet-meta",
340
+ id: "wallet-get-meta",
341
+ display: "wallet get-meta",
270
342
  description: "Check whether a wallet matches the on-chain channel registration.",
271
343
  fields: ["wallet", "network"],
272
344
  usage: "--wallet and --network",
345
+ help: ["Refreshes channel state through the workspace recovery index before reading registration metadata"],
273
346
  },
274
347
  {
275
- id: "get-my-l1-address",
276
- description: "Derive the L1 address for a private key.",
277
- fields: ["account", "network"],
278
- usage: "--network and --account",
279
- },
280
- {
281
- id: "list-local-wallets",
348
+ id: "wallet-list",
349
+ display: "wallet list",
282
350
  description: "List saved local wallet names that can be reused with --wallet.",
283
351
  fields: ["network", "channelName"],
284
352
  optionalFields: ["network", "channelName"],
285
353
  usage: "optional --network and --channel-name",
286
354
  },
287
355
  {
288
- 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",
289
382
  description: "Move bridged funds into the channel L2 accounting balance.",
290
383
  fields: ["wallet", "network", "amount"],
291
384
  usage: "--wallet, --network, and --amount",
292
385
  },
293
386
  {
294
- id: "withdraw-channel",
387
+ id: "wallet-withdraw-channel",
388
+ display: "wallet withdraw-channel",
295
389
  description: "Move channel L2 balance back into the shared bridge vault.",
296
390
  fields: ["wallet", "network", "amount"],
297
391
  usage: "--wallet, --network, and --amount",
298
392
  },
299
393
  {
300
- id: "get-my-channel-fund",
394
+ id: "wallet-get-channel-fund",
395
+ display: "wallet get-channel-fund",
301
396
  description: "Read the current channel L2 accounting balance.",
302
397
  fields: ["wallet", "network"],
303
398
  usage: "--wallet and --network",
399
+ help: ["Refreshes channel state through the workspace recovery index before reading the L2 accounting balance"],
304
400
  },
305
401
  {
306
- id: "exit-channel",
402
+ id: "channel-exit",
403
+ display: "channel exit",
307
404
  description: "Exit a channel. Both the CLI and bridge contract require a zero channel balance.",
308
405
  fields: ["wallet", "network"],
309
406
  usage: "--wallet and --network",
310
407
  },
311
408
  {
312
- id: "mint-notes",
409
+ id: "wallet-mint-notes",
410
+ display: "wallet mint-notes",
313
411
  description: "Mint one or two private-state notes from the wallet's channel balance.",
314
412
  fields: ["wallet", "network", "amounts", "txSubmitter"],
315
413
  usage: "--wallet, --network, --amounts, and optional --tx-submitter",
316
414
  help: ["Use --tx-submitter <ACCOUNT> to let a separate local L1 account pay gas for stronger transaction privacy"],
317
415
  },
318
416
  {
319
- id: "transfer-notes",
417
+ id: "wallet-transfer-notes",
418
+ display: "wallet transfer-notes",
320
419
  description: "Spend input notes into the registered 1->1, 1->2, or 2->1 private transfer shapes.",
321
420
  fields: ["wallet", "network", "noteIds", "recipients", "amounts", "txSubmitter"],
322
421
  usage: "--wallet, --network, --note-ids, --recipients, --amounts, and optional --tx-submitter",
323
422
  help: ["Use --tx-submitter <ACCOUNT> to let a separate local L1 account pay gas for stronger transaction privacy"],
324
423
  },
325
424
  {
326
- id: "redeem-notes",
425
+ id: "wallet-redeem-notes",
426
+ display: "wallet redeem-notes",
327
427
  description: "Redeem one tracked note back into the wallet's channel balance.",
328
428
  fields: ["wallet", "network", "noteIds", "txSubmitter"],
329
429
  usage: "--wallet, --network, --note-ids, and optional --tx-submitter",
330
430
  help: ["Use --tx-submitter <ACCOUNT> to let a separate local L1 account pay gas for stronger transaction privacy"],
331
431
  },
332
432
  {
333
- id: "get-my-notes",
433
+ id: "wallet-get-notes",
434
+ display: "wallet get-notes",
334
435
  description: "Show the wallet's tracked note state and refresh received notes.",
335
436
  fields: ["wallet", "network"],
336
437
  usage: "--wallet and --network",
438
+ help: [
439
+ "Refreshes channel state through the workspace recovery index before reading notes",
440
+ "Refreshes received-note logs through the wallet note recovery index",
441
+ ],
337
442
  },
338
443
  ]);
339
444
 
@@ -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)}`,
@@ -1300,9 +1300,11 @@ export {
1300
1300
  installGroth16RuntimeForPrivateState,
1301
1301
  installPrivateStateCliArtifacts,
1302
1302
  writePrivateStateCliInstallManifest,
1303
+ parseJsonReport,
1303
1304
  resolveArtifactCacheBaseRoot,
1304
1305
  privateStateCliArtifactPaths,
1305
1306
  inspectGroth16Runtime,
1307
+ stripAnsi,
1306
1308
  resolveActiveGroth16ProverRuntime,
1307
1309
  resolveActiveTokamakCliInvocation,
1308
1310
  readTokamakCliPackageReport,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tokamak-private-dapps/private-state-cli",
3
- "version": "1.0.1",
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
  },