@tokamak-private-dapps/private-state-cli 1.2.1 → 2.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.
@@ -58,7 +58,7 @@ export const PRIVATE_STATE_CLI_FIELD_CATALOG = Object.freeze({
58
58
  type: "text",
59
59
  placeholder: "/path/to/wallet-secret",
60
60
  valueLabel: "<PATH>",
61
- hint: "Source file permissions are not enforced; the imported wallet-local secret is protected.",
61
+ hint: "Source file permissions are not enforced; the secret is read once for channel-bound spending-key derivation and is not stored in the wallet workspace.",
62
62
  option: "--wallet-secret-path",
63
63
  },
64
64
  wallet: {
@@ -75,26 +75,34 @@ export const PRIVATE_STATE_CLI_FIELD_CATALOG = Object.freeze({
75
75
  valueLabel: "<PATH>",
76
76
  option: "--output",
77
77
  },
78
- input: {
79
- label: "Input ZIP",
78
+ exportEvidence: {
79
+ label: "Evidence ZIP",
80
80
  type: "text",
81
- placeholder: "/path/to/wallet-export.zip",
82
- valueLabel: "<ZIP>",
83
- option: "--input",
81
+ placeholder: "/path/to/evidence.zip",
82
+ valueLabel: "<PATH>",
83
+ hint: "Optional. Export a local full-note evidence bundle as a ZIP for later selective filtering.",
84
+ option: "--export-evidence",
85
+ optional: true,
84
86
  },
85
- all: {
86
- label: "All Mainnet Wallets",
87
+ acknowledgeFullNotePlaintextExport: {
88
+ label: "Acknowledge Note Plaintext Export",
87
89
  type: "checkbox",
88
- hint: "Export every local mainnet wallet instead of one selected wallet.",
89
- option: "--all",
90
+ hint: "Required with --export-evidence. Confirms that all locally known note plaintext will be written to the ZIP.",
91
+ option: "--acknowledge-full-note-plaintext-export",
90
92
  optional: true,
91
93
  },
92
- includeNotes: {
93
- label: "Include Immediate-Use Cache",
94
+ acknowledgeActionImpact: {
95
+ label: "Acknowledge Action Impact",
94
96
  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,
97
+ hint: "Required for transaction-sending bridge, channel, and note commands. Confirms that the user reviewed the public/private action-impact warning.",
98
+ option: "--acknowledge-action-impact",
99
+ },
100
+ input: {
101
+ label: "Input File",
102
+ type: "text",
103
+ placeholder: "/path/to/wallet-backup.zip",
104
+ valueLabel: "<PATH>",
105
+ option: "--input",
98
106
  },
99
107
  amount: {
100
108
  label: "Amount",
@@ -201,6 +209,15 @@ export const PRIVATE_STATE_CLI_FIELD_CATALOG = Object.freeze({
201
209
  },
202
210
  });
203
211
 
212
+ const ACTION_IMPACT_HELP = Object.freeze({
213
+ acknowledgement: "Requires --acknowledge-action-impact after the user reviews the action-impact warning.",
214
+ illegalUse: "The command must not be used for money laundering, sanctions evasion, terrorist financing, illegal gambling, criminal-proceeds concealment, or regulatory evasion.",
215
+ secretRecovery: "Losing wallet secrets, viewing keys, or spending keys can prevent note discovery or note use; the CLI cannot recover lost secrets.",
216
+ cexAddress: "Do not use a centralized-exchange controlled address as a self-custody bridge source or direct bridge withdrawal target.",
217
+ policy: "The user must review the channel policy snapshot before accepting channel-bound actions.",
218
+ provenance: "Public observers cannot reconstruct private note counterparty relationships or note provenance from public contract state alone.",
219
+ });
220
+
204
221
  export const PRIVATE_STATE_CLI_COMMANDS = Object.freeze([
205
222
  {
206
223
  id: "install",
@@ -268,6 +285,17 @@ export const PRIVATE_STATE_CLI_COMMANDS = Object.freeze([
268
285
  "Reads live fee data from the selected network RPC and live ETH/USD from CoinGecko",
269
286
  ],
270
287
  },
288
+ {
289
+ id: "investigator",
290
+ description: "Open the local evidence investigator GUI in the default browser.",
291
+ fields: [],
292
+ usage: "no options",
293
+ help: [
294
+ "Prints the local investigator HTML path and opens it in the default browser",
295
+ "Use wallet get-notes --export-evidence first, then load the raw ZIP in the investigator GUI",
296
+ "The raw evidence ZIP contains full locally known note plaintext and should not be submitted as-is unless full wallet-history disclosure is intended",
297
+ ],
298
+ },
271
299
  {
272
300
  id: "account-import",
273
301
  display: "account import",
@@ -349,15 +377,29 @@ export const PRIVATE_STATE_CLI_COMMANDS = Object.freeze([
349
377
  id: "account-deposit-bridge",
350
378
  display: "account deposit-bridge",
351
379
  description: "Deposit canonical tokens into the shared bridge vault.",
352
- fields: ["amount", "network", "account", "rpcUrl"],
353
- usage: "--amount, --network, --account, and optional --rpc-url",
380
+ fields: ["amount", "network", "account", "acknowledgeActionImpact", "rpcUrl"],
381
+ usage: "--amount, --network, --account, --acknowledge-action-impact, and optional --rpc-url",
382
+ help: [
383
+ "Action impact: emits public L1 approval and bridge funding events that expose the local L1 account, bridge vault, amount, and transaction hashes.",
384
+ "Private note state is not changed by this command.",
385
+ ACTION_IMPACT_HELP.cexAddress,
386
+ ACTION_IMPACT_HELP.illegalUse,
387
+ ACTION_IMPACT_HELP.acknowledgement,
388
+ ],
354
389
  },
355
390
  {
356
391
  id: "account-withdraw-bridge",
357
392
  display: "account withdraw-bridge",
358
393
  description: "Withdraw tokens from the shared bridge vault back to the wallet.",
359
- fields: ["amount", "network", "account", "rpcUrl"],
360
- usage: "--amount, --network, --account, and optional --rpc-url",
394
+ fields: ["amount", "network", "account", "acknowledgeActionImpact", "rpcUrl"],
395
+ usage: "--amount, --network, --account, --acknowledge-action-impact, and optional --rpc-url",
396
+ help: [
397
+ "Action impact: emits a public L1 bridge withdrawal event that exposes the local L1 recipient, bridge vault, amount, and transaction hash.",
398
+ "Private note state is not changed by this command; prior note provenance is not public by default.",
399
+ ACTION_IMPACT_HELP.cexAddress,
400
+ ACTION_IMPACT_HELP.illegalUse,
401
+ ACTION_IMPACT_HELP.acknowledgement,
402
+ ],
361
403
  },
362
404
  {
363
405
  id: "wallet-recover-workspace",
@@ -366,8 +408,8 @@ export const PRIVATE_STATE_CLI_COMMANDS = Object.freeze([
366
408
  fields: ["channelName", "network", "account", "fromGenesis", "rpcUrl"],
367
409
  usage: "--channel-name, --network, --account, optional --from-genesis, and optional --rpc-url",
368
410
  help: [
369
- "Requires the protected wallet-local secret imported during channel join to exist at the canonical secret path",
370
- "Does not create or recover the wallet secret itself",
411
+ "Rebuilds backup metadata from channel state without recreating the spending key",
412
+ "Derives and stores the viewing key when the local account signer can reproduce the registered viewing public key",
371
413
  "By default, resumes RPC log scanning from the workspace recovery index when available",
372
414
  "Fails instead of falling back to genesis when no usable recovery index exists",
373
415
  "Use --from-genesis to ignore the recovery index and replay channel logs from channel genesis",
@@ -378,13 +420,19 @@ export const PRIVATE_STATE_CLI_COMMANDS = Object.freeze([
378
420
  id: "channel-join",
379
421
  display: "channel join",
380
422
  description: "Pay the channel join toll and bind a wallet to a channel-specific L2 identity.",
381
- fields: ["channelName", "network", "account", "walletSecretPath", "rpcUrl"],
382
- usage: "--channel-name, --network, --account, --wallet-secret-path, and optional --rpc-url",
423
+ fields: ["channelName", "network", "account", "walletSecretPath", "acknowledgeActionImpact", "rpcUrl"],
424
+ usage: "--channel-name, --network, --account, --wallet-secret-path, --acknowledge-action-impact, and optional --rpc-url",
383
425
  help: [
384
426
  "Refreshes the local channel workspace through the saved recovery index before joining when the scan fits the 10 second pre-command budget",
385
427
  "Fails instead of replaying from genesis; run channel recover-workspace --source rpc --from-genesis when a genesis rebuild is required",
386
- "--wallet-secret-path imports an existing source secret file into the protected wallet-local secret file",
428
+ "--wallet-secret-path is read once for channel-bound L2 spending-key derivation and is not stored in the wallet workspace",
387
429
  "Prints the immutable policy snapshot before first registration",
430
+ "Action impact: emits public channel join and token-vault registration events exposing the L1 account, L2 address pair, note-receive public key, join toll, and channel id.",
431
+ "Private note state is not changed by this command.",
432
+ ACTION_IMPACT_HELP.policy,
433
+ ACTION_IMPACT_HELP.secretRecovery,
434
+ ACTION_IMPACT_HELP.illegalUse,
435
+ ACTION_IMPACT_HELP.acknowledgement,
388
436
  ],
389
437
  },
390
438
  {
@@ -393,7 +441,10 @@ export const PRIVATE_STATE_CLI_COMMANDS = Object.freeze([
393
441
  description: "Check whether a wallet matches the on-chain channel registration.",
394
442
  fields: ["wallet", "network"],
395
443
  usage: "--wallet and --network",
396
- help: ["Refreshes the local channel workspace through the saved recovery index before reading registration metadata when the scan fits the 10 second pre-command budget"],
444
+ help: [
445
+ "Refreshes the local channel workspace through the saved recovery index before reading registration metadata when the scan fits the 10 second pre-command budget",
446
+ "Reports the selected local wallet epoch and lifecycle status when the workspace uses the epoch-aware wallet format",
447
+ ],
397
448
  },
398
449
  {
399
450
  id: "wallet-list",
@@ -404,44 +455,87 @@ export const PRIVATE_STATE_CLI_COMMANDS = Object.freeze([
404
455
  usage: "optional --network and --channel-name",
405
456
  },
406
457
  {
407
- id: "wallet-export",
408
- display: "wallet export",
409
- description: "Export a local wallet backup ZIP that can be imported on another machine.",
410
- fields: ["network", "wallet", "output", "all", "includeNotes"],
411
- optionalFields: ["network", "wallet"],
412
- usage: "--output, plus either --network and --wallet or --all; optional --include-notes",
458
+ id: "wallet-export-backup",
459
+ display: "wallet export backup",
460
+ description: "Export a wallet backup ZIP without spending keys, viewing keys, derivation material, or plaintext note secrets.",
461
+ fields: ["network", "wallet", "output"],
462
+ usage: "--network, --wallet, and --output",
413
463
  help: [
414
- "Default export includes the encrypted wallet, wallet metadata, and wallet-local secret; run channel recover-workspace after import",
415
- "--include-notes also includes the channel workspace cache so wallet commands can run immediately when the cache is still chain-aligned",
416
- "--all exports every local mainnet wallet and does not accept --network or --wallet",
464
+ "Includes wallet note-tracking metadata, public key metadata, and channel workspace cache",
465
+ "Excludes L1 private keys, L2 spending keys, viewing private keys, wallet secrets, owner, value, and salt",
417
466
  ],
418
467
  },
419
468
  {
420
- id: "wallet-import",
421
- display: "wallet import",
422
- description: "Import a ZIP created by wallet export into the canonical local wallet workspace.",
469
+ id: "wallet-export-viewing-key",
470
+ display: "wallet export viewing-key",
471
+ description: "Export a secret .key file containing the wallet viewing private key and public viewing-key metadata.",
472
+ fields: ["network", "wallet", "output"],
473
+ usage: "--network, --wallet, and --output",
474
+ },
475
+ {
476
+ id: "wallet-export-spending-key",
477
+ display: "wallet export spending-key",
478
+ description: "Export a secret .key file containing the wallet L2 spending private key and public spending-key metadata.",
479
+ fields: ["network", "wallet", "output"],
480
+ usage: "--network, --wallet, and --output",
481
+ },
482
+ {
483
+ id: "wallet-import-backup",
484
+ display: "wallet import backup",
485
+ description: "Import a backup ZIP created by wallet export backup.",
423
486
  fields: ["input"],
424
487
  usage: "--input",
425
488
  help: [
426
- "Refuses to overwrite existing wallet secrets or wallet files",
427
- "Default exports require channel recover-workspace after import before wallet commands can use channel state",
489
+ "Refuses to overwrite existing wallet metadata or workspace cache files",
490
+ "Does not grant viewing or spending authority; import the corresponding key files separately when needed",
428
491
  ],
429
492
  },
493
+ {
494
+ id: "wallet-import-viewing-key",
495
+ display: "wallet import viewing-key",
496
+ description: "Import a secret .key file created by wallet export viewing-key.",
497
+ fields: ["input"],
498
+ usage: "--input",
499
+ },
500
+ {
501
+ id: "wallet-import-spending-key",
502
+ display: "wallet import spending-key",
503
+ description: "Import a secret .key file created by wallet export spending-key.",
504
+ fields: ["input"],
505
+ usage: "--input",
506
+ },
430
507
  {
431
508
  id: "wallet-deposit-channel",
432
509
  display: "wallet deposit-channel",
433
510
  description: "Move bridged funds into the channel L2 accounting balance.",
434
- fields: ["wallet", "network", "amount"],
435
- usage: "--wallet, --network, and --amount",
436
- help: ["Refreshes the local channel workspace through the saved recovery index before proving the deposit when the scan fits the 10 second pre-command budget"],
511
+ fields: ["wallet", "network", "amount", "acknowledgeActionImpact"],
512
+ usage: "--wallet, --network, --amount, and --acknowledge-action-impact",
513
+ help: [
514
+ "Refreshes the local channel workspace through the saved recovery index before proving the deposit when the scan fits the 10 second pre-command budget",
515
+ "Action impact: emits public proof-backed bridge/channel accounting events exposing the L1 submitter, registered L2 address, amount, channel id, and transaction hash.",
516
+ "Private note state is not changed by this command.",
517
+ ACTION_IMPACT_HELP.policy,
518
+ ACTION_IMPACT_HELP.secretRecovery,
519
+ ACTION_IMPACT_HELP.illegalUse,
520
+ ACTION_IMPACT_HELP.acknowledgement,
521
+ ],
437
522
  },
438
523
  {
439
524
  id: "wallet-withdraw-channel",
440
525
  display: "wallet withdraw-channel",
441
526
  description: "Move channel L2 balance back into the shared bridge vault.",
442
- fields: ["wallet", "network", "amount"],
443
- usage: "--wallet, --network, and --amount",
444
- help: ["Refreshes the local channel workspace through the saved recovery index before proving the withdrawal when the scan fits the 10 second pre-command budget"],
527
+ fields: ["wallet", "network", "amount", "acknowledgeActionImpact"],
528
+ usage: "--wallet, --network, --amount, and --acknowledge-action-impact",
529
+ help: [
530
+ "Refreshes the local channel workspace through the saved recovery index before proving the withdrawal when the scan fits the 10 second pre-command budget",
531
+ "Action impact: emits public proof-backed bridge/channel accounting events exposing the L1 submitter, registered L2 address, amount, channel id, and transaction hash.",
532
+ "Private note state is not changed by this command; prior note provenance is not public by default.",
533
+ ACTION_IMPACT_HELP.provenance,
534
+ ACTION_IMPACT_HELP.policy,
535
+ ACTION_IMPACT_HELP.secretRecovery,
536
+ ACTION_IMPACT_HELP.illegalUse,
537
+ ACTION_IMPACT_HELP.acknowledgement,
538
+ ],
445
539
  },
446
540
  {
447
541
  id: "wallet-get-channel-fund",
@@ -457,51 +551,77 @@ export const PRIVATE_STATE_CLI_COMMANDS = Object.freeze([
457
551
  description: "Exit a channel. Both the CLI and bridge contract require a zero channel balance.",
458
552
  fields: ["wallet", "network"],
459
553
  usage: "--wallet and --network",
460
- help: ["Refreshes the local channel workspace through the saved recovery index before checking the channel balance when the scan fits the 10 second pre-command budget"],
554
+ help: [
555
+ "Refreshes the local channel workspace through the saved recovery index before checking the channel balance when the scan fits the 10 second pre-command budget",
556
+ "Marks the current local wallet epoch as exited and keeps its note metadata available for historical evidence export",
557
+ ],
461
558
  },
462
559
  {
463
560
  id: "wallet-mint-notes",
464
561
  display: "wallet mint-notes",
465
562
  description: "Mint one or two private-state notes from the wallet's channel balance.",
466
- fields: ["wallet", "network", "amounts", "txSubmitter"],
467
- usage: "--wallet, --network, --amounts, and optional --tx-submitter",
563
+ fields: ["wallet", "network", "amounts", "acknowledgeActionImpact", "txSubmitter"],
564
+ usage: "--wallet, --network, --amounts, --acknowledge-action-impact, and optional --tx-submitter",
468
565
  help: [
469
566
  "Refreshes the local channel workspace through the saved recovery index before proving the mint when the scan fits the 10 second pre-command budget",
470
567
  "Use --tx-submitter <ACCOUNT> to let a separate local L1 account pay gas for stronger transaction privacy",
568
+ "Action impact: emits public accepted-transition, commitment, encrypted note-delivery, root update, and transaction events.",
569
+ "Private note state changes by creating local note plaintext and public commitments; note owner/value/salt are not public by default.",
570
+ ACTION_IMPACT_HELP.provenance,
571
+ ACTION_IMPACT_HELP.policy,
572
+ ACTION_IMPACT_HELP.secretRecovery,
573
+ ACTION_IMPACT_HELP.illegalUse,
574
+ ACTION_IMPACT_HELP.acknowledgement,
471
575
  ],
472
576
  },
473
577
  {
474
578
  id: "wallet-transfer-notes",
475
579
  display: "wallet transfer-notes",
476
580
  description: "Spend input notes into the registered 1->1, 1->2, or 2->1 private transfer shapes.",
477
- fields: ["wallet", "network", "noteIds", "recipients", "amounts", "txSubmitter"],
478
- usage: "--wallet, --network, --note-ids, --recipients, --amounts, and optional --tx-submitter",
581
+ fields: ["wallet", "network", "noteIds", "recipients", "amounts", "acknowledgeActionImpact", "txSubmitter"],
582
+ usage: "--wallet, --network, --note-ids, --recipients, --amounts, --acknowledge-action-impact, and optional --tx-submitter",
479
583
  help: [
480
584
  "Refreshes the local channel workspace and received-note logs through saved recovery indexes before proving the transfer when scans fit the 10 second pre-command budget",
481
585
  "Use --tx-submitter <ACCOUNT> to let a separate local L1 account pay gas for stronger transaction privacy",
586
+ "Action impact: emits public accepted-transition, input nullifier, output commitment, encrypted note-delivery, root update, and transaction events.",
587
+ "Private note state changes by consuming selected input notes and creating output notes; sender-recipient relationship, note plaintext, and note provenance are not public by default.",
588
+ ACTION_IMPACT_HELP.provenance,
589
+ ACTION_IMPACT_HELP.policy,
590
+ ACTION_IMPACT_HELP.secretRecovery,
591
+ ACTION_IMPACT_HELP.illegalUse,
592
+ ACTION_IMPACT_HELP.acknowledgement,
482
593
  ],
483
594
  },
484
595
  {
485
596
  id: "wallet-redeem-notes",
486
597
  display: "wallet redeem-notes",
487
598
  description: "Redeem one tracked note back into the wallet's channel balance.",
488
- fields: ["wallet", "network", "noteIds", "txSubmitter"],
489
- usage: "--wallet, --network, --note-ids, and optional --tx-submitter",
599
+ fields: ["wallet", "network", "noteIds", "acknowledgeActionImpact", "txSubmitter"],
600
+ usage: "--wallet, --network, --note-ids, --acknowledge-action-impact, and optional --tx-submitter",
490
601
  help: [
491
602
  "Refreshes the local channel workspace and received-note logs through saved recovery indexes before proving the redeem when scans fit the 10 second pre-command budget",
492
603
  "Use --tx-submitter <ACCOUNT> to let a separate local L1 account pay gas for stronger transaction privacy",
604
+ "Action impact: emits public accepted-transition, note nullifier, accounting update, root update, and transaction events.",
605
+ "Private note state changes by consuming selected notes; prior note provenance is not public by default.",
606
+ ACTION_IMPACT_HELP.provenance,
607
+ ACTION_IMPACT_HELP.policy,
608
+ ACTION_IMPACT_HELP.secretRecovery,
609
+ ACTION_IMPACT_HELP.illegalUse,
610
+ ACTION_IMPACT_HELP.acknowledgement,
493
611
  ],
494
612
  },
495
613
  {
496
614
  id: "wallet-get-notes",
497
615
  display: "wallet get-notes",
498
616
  description: "Refresh received notes when the saved recovery index is recent, then show tracked note state.",
499
- fields: ["wallet", "network"],
500
- usage: "--wallet and --network",
617
+ fields: ["wallet", "network", "exportEvidence", "acknowledgeFullNotePlaintextExport"],
618
+ usage: "--wallet, --network, optional --export-evidence, and optional --acknowledge-full-note-plaintext-export",
501
619
  help: [
502
620
  "Refreshes the local channel workspace through the saved recovery index before reading notes when the scan fits the 10 second pre-command budget",
503
621
  "Refreshes received-note logs through the saved wallet note recovery index when the scan fits the 10 second pre-command budget",
504
622
  "Fails instead of replaying from genesis; run wallet recover-workspace --from-genesis when a genesis rebuild is required",
623
+ "Use --export-evidence <PATH> with --acknowledge-full-note-plaintext-export to write a local full-note evidence ZIP for private-state-cli investigator",
624
+ "Evidence export includes all local epochs for the selected wallet, including exited epochs retained for dispute evidence",
505
625
  ],
506
626
  },
507
627
  ]);
@@ -88,7 +88,3 @@ export function workspaceWalletsDir(workspaceDir) {
88
88
  export function walletDirForName(walletsRoot, walletName) {
89
89
  return path.join(walletsRoot, slugifyPathComponent(walletName));
90
90
  }
91
-
92
- export function walletMetadataPathForDir(walletDir) {
93
- return path.join(walletDir, "wallet.metadata.json");
94
- }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tokamak-private-dapps/private-state-cli",
3
- "version": "1.2.1",
3
+ "version": "2.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",
@@ -30,6 +30,7 @@
30
30
  "LICENSE",
31
31
  "private-state-bridge-cli.mjs",
32
32
  "cli-assistant.html",
33
+ "investigator",
33
34
  "assets",
34
35
  "lib"
35
36
  ],