@tokamak-private-dapps/private-state-cli 1.2.0 → 2.0.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
  {
@@ -404,44 +452,87 @@ export const PRIVATE_STATE_CLI_COMMANDS = Object.freeze([
404
452
  usage: "optional --network and --channel-name",
405
453
  },
406
454
  {
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",
455
+ id: "wallet-export-backup",
456
+ display: "wallet export backup",
457
+ description: "Export a wallet backup ZIP without spending keys, viewing keys, derivation material, or plaintext note secrets.",
458
+ fields: ["network", "wallet", "output"],
459
+ usage: "--network, --wallet, and --output",
413
460
  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",
461
+ "Includes wallet note-tracking metadata, public key metadata, and channel workspace cache",
462
+ "Excludes L1 private keys, L2 spending keys, viewing private keys, wallet secrets, owner, value, and salt",
417
463
  ],
418
464
  },
419
465
  {
420
- id: "wallet-import",
421
- display: "wallet import",
422
- description: "Import a ZIP created by wallet export into the canonical local wallet workspace.",
466
+ id: "wallet-export-viewing-key",
467
+ display: "wallet export viewing-key",
468
+ description: "Export a secret .key file containing the wallet viewing private key and public viewing-key metadata.",
469
+ fields: ["network", "wallet", "output"],
470
+ usage: "--network, --wallet, and --output",
471
+ },
472
+ {
473
+ id: "wallet-export-spending-key",
474
+ display: "wallet export spending-key",
475
+ description: "Export a secret .key file containing the wallet L2 spending private key and public spending-key metadata.",
476
+ fields: ["network", "wallet", "output"],
477
+ usage: "--network, --wallet, and --output",
478
+ },
479
+ {
480
+ id: "wallet-import-backup",
481
+ display: "wallet import backup",
482
+ description: "Import a backup ZIP created by wallet export backup.",
423
483
  fields: ["input"],
424
484
  usage: "--input",
425
485
  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",
486
+ "Refuses to overwrite existing wallet metadata or workspace cache files",
487
+ "Does not grant viewing or spending authority; import the corresponding key files separately when needed",
428
488
  ],
429
489
  },
490
+ {
491
+ id: "wallet-import-viewing-key",
492
+ display: "wallet import viewing-key",
493
+ description: "Import a secret .key file created by wallet export viewing-key.",
494
+ fields: ["input"],
495
+ usage: "--input",
496
+ },
497
+ {
498
+ id: "wallet-import-spending-key",
499
+ display: "wallet import spending-key",
500
+ description: "Import a secret .key file created by wallet export spending-key.",
501
+ fields: ["input"],
502
+ usage: "--input",
503
+ },
430
504
  {
431
505
  id: "wallet-deposit-channel",
432
506
  display: "wallet deposit-channel",
433
507
  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"],
508
+ fields: ["wallet", "network", "amount", "acknowledgeActionImpact"],
509
+ usage: "--wallet, --network, --amount, and --acknowledge-action-impact",
510
+ help: [
511
+ "Refreshes the local channel workspace through the saved recovery index before proving the deposit when the scan fits the 10 second pre-command budget",
512
+ "Action impact: emits public proof-backed bridge/channel accounting events exposing the L1 submitter, registered L2 address, amount, channel id, and transaction hash.",
513
+ "Private note state is not changed by this command.",
514
+ ACTION_IMPACT_HELP.policy,
515
+ ACTION_IMPACT_HELP.secretRecovery,
516
+ ACTION_IMPACT_HELP.illegalUse,
517
+ ACTION_IMPACT_HELP.acknowledgement,
518
+ ],
437
519
  },
438
520
  {
439
521
  id: "wallet-withdraw-channel",
440
522
  display: "wallet withdraw-channel",
441
523
  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"],
524
+ fields: ["wallet", "network", "amount", "acknowledgeActionImpact"],
525
+ usage: "--wallet, --network, --amount, and --acknowledge-action-impact",
526
+ help: [
527
+ "Refreshes the local channel workspace through the saved recovery index before proving the withdrawal when the scan fits the 10 second pre-command budget",
528
+ "Action impact: emits public proof-backed bridge/channel accounting events exposing the L1 submitter, registered L2 address, amount, channel id, and transaction hash.",
529
+ "Private note state is not changed by this command; prior note provenance is not public by default.",
530
+ ACTION_IMPACT_HELP.provenance,
531
+ ACTION_IMPACT_HELP.policy,
532
+ ACTION_IMPACT_HELP.secretRecovery,
533
+ ACTION_IMPACT_HELP.illegalUse,
534
+ ACTION_IMPACT_HELP.acknowledgement,
535
+ ],
445
536
  },
446
537
  {
447
538
  id: "wallet-get-channel-fund",
@@ -463,45 +554,67 @@ export const PRIVATE_STATE_CLI_COMMANDS = Object.freeze([
463
554
  id: "wallet-mint-notes",
464
555
  display: "wallet mint-notes",
465
556
  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",
557
+ fields: ["wallet", "network", "amounts", "acknowledgeActionImpact", "txSubmitter"],
558
+ usage: "--wallet, --network, --amounts, --acknowledge-action-impact, and optional --tx-submitter",
468
559
  help: [
469
560
  "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
561
  "Use --tx-submitter <ACCOUNT> to let a separate local L1 account pay gas for stronger transaction privacy",
562
+ "Action impact: emits public accepted-transition, commitment, encrypted note-delivery, root update, and transaction events.",
563
+ "Private note state changes by creating local note plaintext and public commitments; note owner/value/salt are not public by default.",
564
+ ACTION_IMPACT_HELP.provenance,
565
+ ACTION_IMPACT_HELP.policy,
566
+ ACTION_IMPACT_HELP.secretRecovery,
567
+ ACTION_IMPACT_HELP.illegalUse,
568
+ ACTION_IMPACT_HELP.acknowledgement,
471
569
  ],
472
570
  },
473
571
  {
474
572
  id: "wallet-transfer-notes",
475
573
  display: "wallet transfer-notes",
476
574
  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",
575
+ fields: ["wallet", "network", "noteIds", "recipients", "amounts", "acknowledgeActionImpact", "txSubmitter"],
576
+ usage: "--wallet, --network, --note-ids, --recipients, --amounts, --acknowledge-action-impact, and optional --tx-submitter",
479
577
  help: [
480
578
  "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
579
  "Use --tx-submitter <ACCOUNT> to let a separate local L1 account pay gas for stronger transaction privacy",
580
+ "Action impact: emits public accepted-transition, input nullifier, output commitment, encrypted note-delivery, root update, and transaction events.",
581
+ "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.",
582
+ ACTION_IMPACT_HELP.provenance,
583
+ ACTION_IMPACT_HELP.policy,
584
+ ACTION_IMPACT_HELP.secretRecovery,
585
+ ACTION_IMPACT_HELP.illegalUse,
586
+ ACTION_IMPACT_HELP.acknowledgement,
482
587
  ],
483
588
  },
484
589
  {
485
590
  id: "wallet-redeem-notes",
486
591
  display: "wallet redeem-notes",
487
592
  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",
593
+ fields: ["wallet", "network", "noteIds", "acknowledgeActionImpact", "txSubmitter"],
594
+ usage: "--wallet, --network, --note-ids, --acknowledge-action-impact, and optional --tx-submitter",
490
595
  help: [
491
596
  "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
597
  "Use --tx-submitter <ACCOUNT> to let a separate local L1 account pay gas for stronger transaction privacy",
598
+ "Action impact: emits public accepted-transition, note nullifier, accounting update, root update, and transaction events.",
599
+ "Private note state changes by consuming selected notes; prior note provenance is not public by default.",
600
+ ACTION_IMPACT_HELP.provenance,
601
+ ACTION_IMPACT_HELP.policy,
602
+ ACTION_IMPACT_HELP.secretRecovery,
603
+ ACTION_IMPACT_HELP.illegalUse,
604
+ ACTION_IMPACT_HELP.acknowledgement,
493
605
  ],
494
606
  },
495
607
  {
496
608
  id: "wallet-get-notes",
497
609
  display: "wallet get-notes",
498
610
  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",
611
+ fields: ["wallet", "network", "exportEvidence", "acknowledgeFullNotePlaintextExport"],
612
+ usage: "--wallet, --network, optional --export-evidence, and optional --acknowledge-full-note-plaintext-export",
501
613
  help: [
502
614
  "Refreshes the local channel workspace through the saved recovery index before reading notes when the scan fits the 10 second pre-command budget",
503
615
  "Refreshes received-note logs through the saved wallet note recovery index when the scan fits the 10 second pre-command budget",
504
616
  "Fails instead of replaying from genesis; run wallet recover-workspace --from-genesis when a genesis rebuild is required",
617
+ "Use --export-evidence <PATH> with --acknowledge-full-note-plaintext-export to write a local full-note evidence ZIP for private-state-cli investigator",
505
618
  ],
506
619
  },
507
620
  ]);
@@ -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.0",
3
+ "version": "2.0.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
  ],