@tokamak-private-dapps/private-state-cli 1.2.1 → 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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,43 @@
1
1
  # Changelog
2
2
 
3
+ ## Unreleased
4
+
5
+ ## 2.0.0 - 2026-05-13
6
+
7
+ - Split wallet export/import into `wallet export backup`, `wallet export viewing-key`,
8
+ `wallet export spending-key`, `wallet import backup`, `wallet import viewing-key`, and
9
+ `wallet import spending-key`.
10
+ - Changed wallet backups so they exclude spending keys, viewing keys, key derivation material,
11
+ and plaintext note `owner`, `value`, and `salt` fields. Backups retain commitments,
12
+ nullifiers, encrypted note payloads, and channel workspace cache files.
13
+ - Replaced the previous full-control wallet workspace format with separate note-tracking,
14
+ spending-key metadata, and viewing-key metadata files. The CLI now loads only the current
15
+ wallet metadata format.
16
+ - Added action-impact acknowledgements for bridge-facing, channel, and note-mutating commands.
17
+ The warning output covers public event exposure, private note-state impact, note provenance
18
+ boundaries, illegal-use prohibition, CEX deposit-address warnings, secret-recovery limits, and
19
+ channel policy acceptance.
20
+ - Added full-note raw evidence export through `wallet get-notes --export-evidence` with an explicit
21
+ plaintext-export acknowledgement. Evidence bundles include note plaintext facts, derived
22
+ commitments and nullifiers, creation/spend transaction references, receipts, events, calldata, and
23
+ filtering indexes, while excluding viewing keys, spending keys, wallet secrets, account private
24
+ keys, and `.key` files.
25
+ - Added a local static evidence investigator GUI and bundled it with the NPM package. The new
26
+ top-level `private-state-cli investigator` command prints the bundled HTML path, prints the file
27
+ URL, and opens the GUI in the default browser.
28
+ - Clarified wallet authority recovery in the NPM README: viewing-key rederivation needs the original
29
+ L1 private key and channel context, while spending-key rederivation additionally needs the same
30
+ wallet secret source used at `channel join`.
31
+ - Added a `channel join` success warning that losing both the spending-key file and wallet secret
32
+ source prevents spending-key rederivation.
33
+ - Aligned README terminology around `private-state DApp`, `private-state CLI`, `viewing key`,
34
+ `spending key`, `wallet secret source`, `user-controlled selective disclosure`, and
35
+ `privacy-preserving note semantics`.
36
+ - Added LLM-assistant guidance requiring strong user warnings and explicit confirmation before an
37
+ assistant runs commands that require `--acknowledge-*` options on a user's behalf.
38
+ - Simplified internal CLI code paths by removing a dead `loadWallet` parameter and redundant
39
+ `channel join` result aliases.
40
+
3
41
  ## 1.2.1 - 2026-05-11
4
42
 
5
43
  - Changed pre-command automatic recovery from an RPC log request time estimate to a fixed
package/README.md CHANGED
@@ -6,6 +6,35 @@ The full private-state DApp documentation is published with the repository:
6
6
 
7
7
  - https://github.com/tokamak-network/Tokamak-zk-EVM-contracts/tree/main/packages/apps/private-state/docs
8
8
 
9
+ ## Terminology And CEX Boundary
10
+
11
+ This npm README uses the same terminology as the repository README:
12
+
13
+ - `Tokamak Private App Channels`: Ethereum-settled, validity-proven execution domains for bridge-coupled DApps.
14
+ - `private-state DApp`: the current reference DApp that programs confidential application state inside a channel.
15
+ - `canonical Tokamak Network Token`: the L1 asset whose custody remains anchored on Ethereum.
16
+ - `self-custody L1 wallet`: a user-controlled L1 account, not a centralized-exchange deposit address.
17
+ - `L1-transparent bridge edge`: public bridge deposit and withdrawal transactions involving the canonical token.
18
+ - `channel-local accounting balance`: liquid application balance inside a channel before or after note use.
19
+ - `private-state note`: a channel-local application note, not an exchange-supported token or deposit asset.
20
+ - `proof-backed confidential application state`: DApp state advanced by accepted proof-backed channel transitions.
21
+ - `user-controlled selective disclosure`: optional user disclosure from local wallet state; Tokamak does not hold a master viewing key.
22
+ - `viewing key`: the note-receive private key used to decrypt note-delivery events for the registered note-receive public key.
23
+ - `spending key`: the channel-bound L2 private key used to authorize proof-backed note use.
24
+
25
+ Tokamak Private App Channels are not a centralized-exchange deposit network. CEX-facing token transfers and bridge
26
+ entry or exit remain public L1 activity. Internal private-state note counterparty relationships and note provenance are
27
+ not public by default and are not reconstructed by Tokamak on a user's behalf.
28
+
29
+ ## Tokamak-Operated Mainnet Channels
30
+
31
+ The table below lists private-state mainnet channels directly opened by Tokamak Network. Dates are
32
+ UTC.
33
+
34
+ | Channel name | Channel creator / leader | Created at | Genesis block | Channel manager |
35
+ | --- | --- | --- | ---: | --- |
36
+ | `the-great-first-channel` | [`0x32e6EE3d9820F0843E3e596132368747d36425F0`](https://etherscan.io/address/0x32e6EE3d9820F0843E3e596132368747d36425F0) | 2026-05-04 01:30:59 UTC | `25018368` | [`0x3108d92A38bFb4B3396DE7ad4D92318a8fbE61D7`](https://etherscan.io/address/0x3108d92A38bFb4B3396DE7ad4D92318a8fbE61D7) |
37
+
9
38
  ## Install
10
39
 
11
40
  ```bash
@@ -75,8 +104,8 @@ private-state-cli uninstall
75
104
 
76
105
  `uninstall` is intentionally interactive. It requires typing
77
106
  `I understand that the wallet secrets deleted due to this decision cannot be recovered` before deleting
78
- `~/tokamak-private-channels/`, the Tokamak zk-EVM runtime cache, and the global CLI npm package when npm reports that it
79
- is globally installed.
107
+ `~/tokamak-private-channels/`, including local account secrets and wallet key files, the Tokamak zk-EVM runtime cache,
108
+ and the global CLI npm package when npm reports that it is globally installed.
80
109
 
81
110
  ## Commands
82
111
 
@@ -97,6 +126,31 @@ A common private-state flow is:
97
126
  Use `private-state-cli help commands` for the full command list and required options. `private-state-cli --help`
98
127
  continues to print the same command list for shell compatibility.
99
128
 
129
+ ### Action-impact acknowledgement
130
+
131
+ Transaction-sending bridge, channel, and note commands require `--acknowledge-action-impact`. Before submitting any
132
+ transaction, the CLI prints a static action-impact summary covering whether the command emits public L1 events, whether
133
+ it changes private-state note state, which addresses or amounts become public, which note facts are not public by default,
134
+ illegal-use prohibition, secret-recovery limits, and channel policy acceptance. In non-interactive contexts, such as
135
+ scripts and LLM-assisted execution, the command fails unless the flag is present.
136
+
137
+ Static warning scope:
138
+
139
+ | Command | Public surface | Private-state note state | Not public by default |
140
+ |---|---|---|---|
141
+ | `account deposit-bridge` | L1 account, bridge vault, amount, approval/funding txs | No note change | No note plaintext or provenance is created |
142
+ | `account withdraw-bridge` | L1 recipient/account, bridge vault, amount, withdrawal tx | No note change | Prior private-state note path is not reconstructed |
143
+ | `channel join` | L1 account, L2 address, note-receive public key, join toll, channel id | No note change | Wallet secret, spending key, viewing key, and note plaintext |
144
+ | `wallet deposit-channel` | L1 submitter, registered L2 address, amount, channel id, accounting update | No note change | No note provenance is created |
145
+ | `wallet mint-notes` | L1 submitter, registered L2 address, commitments, encrypted note events, root update | Creates notes | Note owner, value, salt, and later provenance |
146
+ | `wallet transfer-notes` | L1 submitter, input nullifiers, output commitments, encrypted note events, root update | Spends and creates notes | Sender-recipient relationship, note plaintext, and provenance |
147
+ | `wallet redeem-notes` | L1 submitter, input nullifier, accounting update, root update | Consumes notes | Prior path by which the note was received |
148
+ | `wallet withdraw-channel` | L1 submitter, registered L2 address, amount, channel id, accounting update | No direct note spend | Prior private-state note path behind the liquid balance |
149
+
150
+ `account deposit-bridge` and `account withdraw-bridge` also print a centralized-exchange address warning. Do not use a
151
+ centralized-exchange controlled address as a self-custody bridge source or as the direct bridge withdrawal target
152
+ unless the user explicitly understands the compliance implications. Prefer a self-custody L1 wallet.
153
+
100
154
  Workspace recovery commands use the saved recovery index by default. If the local workspace is missing, corrupted, or
101
155
  does not contain a usable index, `channel recover-workspace` and `wallet recover-workspace` stop with an explicit error instead of
102
156
  silently replaying logs from channel genesis. Use `--source rpc --from-genesis` only when you intentionally want to
@@ -134,33 +188,59 @@ https://github.com/tokamak-network/Tokamak-zk-EVM-contracts/blob/main/packages/a
134
188
  Back up a local wallet with:
135
189
 
136
190
  ```bash
137
- private-state-cli wallet export --network mainnet --wallet <WALLET> --output ./wallet-backup.zip
191
+ private-state-cli wallet export backup --network mainnet --wallet <WALLET> --output ./wallet-backup.zip
138
192
  ```
139
193
 
140
- The default export stores the encrypted wallet, wallet metadata, and wallet-local secret. The encrypted `wallet.json`
141
- contains the wallet's current key material and tracked note state. The export intentionally excludes account secrets
142
- because wallet commands restore the L1 signer from the encrypted `wallet.json`; account secrets are only needed for
143
- account-level bridge-vault commands and optional `--tx-submitter` use. After importing a default export on a new machine,
144
- run `channel recover-workspace` before using wallet commands that need channel state:
194
+ The backup export stores note-tracking metadata and the channel workspace cache, but it does not include spending keys,
195
+ viewing keys, key derivation material, or plaintext note secrets. Note records in the backup keep commitments,
196
+ nullifiers, and encrypted note payloads only; `owner`, `value`, and `salt` are excluded.
197
+ Importing this backup restores encrypted tracking state and channel cache files, not wallet authority.
145
198
 
146
199
  ```bash
147
- private-state-cli wallet import --input ./wallet-backup.zip
148
- private-state-cli channel recover-workspace --channel-name <CHANNEL> --network mainnet --source rpc --from-genesis
200
+ private-state-cli wallet import backup --input ./wallet-backup.zip
149
201
  ```
150
202
 
151
- For a wider backup that can run wallet commands immediately when the imported channel workspace cache is still
152
- chain-aligned, add `--include-notes`:
203
+ Export viewing and spending authority separately:
153
204
 
154
205
  ```bash
155
- private-state-cli wallet export --network mainnet --wallet <WALLET> --output ./wallet-backup.zip --include-notes
206
+ private-state-cli wallet export viewing-key --network mainnet --wallet <WALLET> --output ./wallet-viewing.key
207
+ private-state-cli wallet export spending-key --network mainnet --wallet <WALLET> --output ./wallet-spending.key
156
208
  ```
157
209
 
158
- Use `--all` to export every local mainnet wallet into one ZIP:
210
+ Import those capabilities only when the target machine should receive them:
159
211
 
160
212
  ```bash
161
- private-state-cli wallet export --all --output ./mainnet-wallets.zip
213
+ private-state-cli wallet import viewing-key --input ./wallet-viewing.key
214
+ private-state-cli wallet import spending-key --input ./wallet-spending.key
162
215
  ```
163
216
 
217
+ A backup plus a viewing key can reconstruct the wallet's readable note view from encrypted events, but it still cannot
218
+ spend notes. A backup plus a spending key is still missing event-log decryption authority. A normal operational restore
219
+ imports the backup, the viewing key, and the spending key, and still needs the relevant local L1 account secret for
220
+ commands that submit bridge or channel-registration transactions.
221
+
222
+ Export a local full-note evidence bundle with:
223
+
224
+ ```bash
225
+ private-state-cli wallet get-notes --network mainnet --wallet <WALLET> --export-evidence ./wallet-evidence.zip --acknowledge-full-note-plaintext-export
226
+ ```
227
+
228
+ This ZIP is an input for `private-state-cli investigator`. It contains plaintext for all locally known
229
+ notes, derived commitments and nullifiers, creation and spend transaction references, transaction calldata, receipts,
230
+ events, and indexes for filtering by note, nullifier, transaction, block range, or available counterparty metadata. It
231
+ does not include viewing keys, spending keys, wallet secret material, account private keys, or `.key` files. Do not
232
+ submit the raw ZIP as an exchange or auditor package unless full wallet-history disclosure is intended.
233
+
234
+ Open the local evidence investigator with:
235
+
236
+ ```bash
237
+ private-state-cli investigator
238
+ ```
239
+
240
+ The command prints the bundled investigator HTML path and file URL, then opens the static browser GUI. Load the raw
241
+ evidence ZIP in that GUI, apply the requested filters, and export a narrower user-consent disclosure ZIP. The GUI runs
242
+ locally in the browser and does not send files over the network.
243
+
164
244
  Estimate live transaction costs before sending commands with:
165
245
 
166
246
  ```bash
@@ -175,13 +255,13 @@ data.
175
255
  Proof-backed note commands can use a separate L1 transaction submitter:
176
256
 
177
257
  ```bash
178
- private-state-cli wallet mint-notes --wallet <WALLET> --network mainnet --amounts '[1]' --tx-submitter <ACCOUNT>
258
+ private-state-cli wallet mint-notes --wallet <WALLET> --network mainnet --amounts '[1]' --acknowledge-action-impact --tx-submitter <ACCOUNT>
179
259
  ```
180
260
 
181
261
  `--tx-submitter <ACCOUNT>` is available on `wallet mint-notes`, `wallet transfer-notes`, and `wallet redeem-notes`. The wallet still proves
182
262
  note ownership and builds the ZK proof, but the selected local account submits `executeChannelTransaction` and pays gas.
183
- Use this option when you want stronger privacy by avoiding a direct on-chain link between the note owner's wallet L1
184
- account and the proof-submission transaction.
263
+ Use this option when a separate imported local account should submit the L1 transaction and pay gas for a proof-backed
264
+ note command.
185
265
 
186
266
  Channel policy warning:
187
267
 
@@ -208,34 +288,66 @@ private-state-cli account import --account <ACCOUNT_NAME> --network sepolia --pr
208
288
  private-state-cli account get-l1-address --account <ACCOUNT_NAME> --network sepolia
209
289
  private-state-cli wallet list --network sepolia --channel-name cuda
210
290
  private-state-cli wallet get-meta --wallet <WALLET_NAME> --network sepolia
211
- private-state-cli wallet export --network sepolia --wallet <WALLET_NAME> --output ./wallet-backup.zip
212
- private-state-cli wallet import --input ./wallet-backup.zip
291
+ private-state-cli wallet export backup --network sepolia --wallet <WALLET_NAME> --output ./wallet-backup.zip
292
+ private-state-cli wallet import backup --input ./wallet-backup.zip
213
293
  ```
214
294
 
215
295
  `account import` is the only supported way to bring an L1 signing key into the CLI: it reads `--private-key-file` once
216
296
  and stores a protected local account secret for later `--account` use. The source file does not need `0600` permissions.
217
- `channel join` imports `--wallet-secret-path <PATH>` into the protected wallet-local default secret while creating the
218
- encrypted local wallet. `wallet list` reads only the local workspace and prints saved wallet names that can be reused with
297
+ `channel join` reads `--wallet-secret-path <PATH>` once while creating the channel-bound spending key and then stores
298
+ wallet backup metadata, viewing-key metadata, and spending-key metadata as separate files. `wallet list` reads only the local workspace and prints saved wallet names that can be reused with
219
299
  `--wallet`.
220
- `wallet get-meta` opens an encrypted local wallet and reports the stored L1/L2 identity metadata plus the current
221
- on-chain channel registration match state. `account get-l1-address` is a simple offline helper that derives the L1
222
- address for a local account.
300
+ `wallet get-meta` opens the wallet metadata and reports the stored L1/L2 identity metadata plus the current
301
+ on-chain channel registration match state, including the registered note-receive public key when present.
302
+ `account get-l1-address` is a simple offline helper that derives the L1 address for a local account.
223
303
 
224
304
  ### Wallet Secret Source File
225
305
 
226
306
  `channel join` needs a wallet secret source file because the CLI no longer accepts raw wallet secrets on the command
227
- line. The source file is arbitrary high-entropy secret text that the CLI reads once and imports into the protected
228
- wallet-local canonical secret.
307
+ line. The source file is arbitrary high-entropy secret text that the CLI reads once for channel-bound spending-key
308
+ derivation. It is not persisted in the wallet workspace.
229
309
 
230
310
  Create one before joining a channel:
231
311
 
232
312
  ```bash
233
313
  openssl rand -hex 32 > ./wallet-secret.txt
234
- private-state-cli channel join --channel-name <CHANNEL> --network sepolia --account <ACCOUNT> --wallet-secret-path ./wallet-secret.txt
314
+ private-state-cli channel join --channel-name <CHANNEL> --network sepolia --account <ACCOUNT> --wallet-secret-path ./wallet-secret.txt --acknowledge-action-impact
235
315
  ```
236
316
 
237
- The import source file does not need `0600` permissions. The canonical wallet-local secret written by the CLI remains
238
- protected: macOS/Linux uses `0600`, while Windows uses ACL repair and inspection when possible.
317
+ The import source file does not need `0600` permissions. The CLI does not persist a wallet-local secret:
318
+ it reads the source once for channel-bound L2 spending-key derivation. The join flow stores the viewing key and
319
+ spending key as separate protected key files under the CLI secret root; macOS/Linux uses `0600`, while Windows uses ACL
320
+ repair and inspection when possible.
321
+
322
+ Keep the wallet secret source separately backed up if you expect to rederive the spending key later. The viewing key can
323
+ be rederived from the same L1 private key and channel context because it comes from the note-receive typed-data signing
324
+ flow. The spending key needs the same L1 private key, the same channel context, and the same wallet secret source. If the
325
+ spending-key file is lost and the wallet secret source is also lost, the CLI cannot reconstruct the spending key and the
326
+ notes for that wallet cannot be spent, transferred, or redeemed through the normal note flow.
327
+
328
+ ### Wallet Backup, Viewing, And Spending Authority
329
+
330
+ The wallet workspace is split so that a backup is not a full-control wallet export. Backup metadata stores the
331
+ recoverable local view of the channel: commitments, nullifiers, encrypted note-delivery payloads, scan checkpoints,
332
+ operation history, and the channel workspace cache. It deliberately omits plaintext note fields and key material.
333
+
334
+ The viewing key is the note-receive private key. It lets `wallet get-notes` decrypt bridge-propagated encrypted
335
+ note-delivery events and rebuild the user's readable note view. Sharing it gives read access to notes addressed to the
336
+ registered note-receive public key, but not spending authority.
337
+
338
+ The spending key is the channel-bound L2 private key. It authorizes proof-backed use of the wallet identity. Commands
339
+ that consume existing notes, such as `wallet transfer-notes` and `wallet redeem-notes`, need both the viewing key and
340
+ the spending key because the CLI must first reconstruct the plaintext notes and then prove authorized use of them.
341
+
342
+ Key recovery is intentionally split. Recreating the viewing key requires the original L1 private key and the same channel
343
+ context. Recreating the spending key requires the original L1 private key, the same channel context, and the same wallet
344
+ secret source used at `channel join`. Importing `wallet-viewing.key` or `wallet-spending.key` restores the corresponding
345
+ capability without rerunning derivation, but a backup ZIP alone never restores either capability.
346
+
347
+ `wallet get-notes --export-evidence <PATH> --acknowledge-full-note-plaintext-export` writes a local raw evidence ZIP.
348
+ The bundle is not a key export. It includes plaintext note facts for locally known notes so that
349
+ `private-state-cli investigator` can create narrower consent-disclosure packages without requiring viewing-key or
350
+ spending-key sharing.
239
351
 
240
352
  ## Workspace
241
353
 
@@ -245,8 +357,8 @@ The CLI stores user workspaces under:
245
357
  ~/tokamak-private-channels/workspace/<network>/<channel>/
246
358
  ```
247
359
 
248
- Wallet data is encrypted with the wallet-local default secret file under
249
- `~/tokamak-private-channels/secrets/<network>/wallets/<wallet>/secret`.
360
+ Wallet backup metadata lives under the channel workspace. Viewing and spending private keys live as separate protected
361
+ key files under `~/tokamak-private-channels/secrets/<network>/wallets/<wallet>/`.
250
362
 
251
363
  Bridge-facing commands accept optional `--rpc-url <URL>`. When `--rpc-url` is provided, the CLI stores it in
252
364
  `~/tokamak-private-channels/secrets/<network>/.env` as `RPC_URL=<URL>` with protected canonical secret permissions.
@@ -257,16 +369,19 @@ When `--rpc-url` is omitted, the CLI reads `RPC_URL` from that file. The `anvil`
257
369
  ## LLM Agent Guidance
258
370
 
259
371
  You may act as an interactive guide for users who do not understand this CLI or the private-state DApp. Assume the
260
- user only knows that the DApp is a way to send funds privately. Translate the user's intent into safe, step-by-step CLI
261
- actions.
372
+ user wants to use confidential channel-local notes while keeping L1 bridge deposits and withdrawals transparent.
373
+ Translate the user's intent into safe, step-by-step CLI actions.
262
374
 
263
- Primary goal: help the user privately send funds by guiding them through the required private-state CLI commands,
264
- explaining each step only as much as needed to proceed safely.
375
+ Primary goal: help the user safely use private-state note workflows: self-custody L1 funding, channel-local note
376
+ creation, note transfer, note recovery, and user-controlled disclosure where supported. Present this
377
+ as privacy-preserving note semantics for the current `private-state` DApp, not as invisible
378
+ activity or as a bridge-wide disclosure rule for every DApp.
265
379
 
266
380
  Operating rules:
267
381
 
268
382
  - Do not ask the user to reveal raw private keys or wallet secrets in chat. Use `account import --private-key-file`
269
- once, then use `--account` for L1 signing commands. Wallet commands use wallet-local default secret files.
383
+ once, then use `--account` for L1 signing commands. Wallet viewing and spending authority is imported separately
384
+ with `wallet import viewing-key` and `wallet import spending-key`.
270
385
  - Treat `private key file`, `account`, `wallet secret`, `wallet`, `network RPC URL`, and `channel policy` as
271
386
  new concepts unless the user has already demonstrated that they understand them. Define each term before using it
272
387
  in an instruction.
@@ -276,10 +391,14 @@ Operating rules:
276
391
  - An account is the local nickname created by `account import`. After import, signing commands should use
277
392
  `--account <NAME>` instead of asking for the raw key again.
278
393
  - A wallet secret source file is a separate high-entropy local secret chosen by the user for this private-state
279
- wallet. It is not the L1 private key. `channel join` imports it once and uses it to protect and recover the
280
- channel-local wallet.
281
- - A wallet is the encrypted local private-state wallet created during `channel join`. Its deterministic name is
282
- `<channelName>-<l1Address>`.
394
+ wallet. It is not the L1 private key. `channel join` reads it once for channel-bound spending-key derivation and
395
+ does not persist it in the wallet workspace.
396
+ - A wallet is the local private-state metadata set created during `channel join`. Its deterministic name is
397
+ `<channelName>-<l1Address>`. The wallet backup tracks encrypted note state, while viewing and spending authority
398
+ are stored in separate protected key files.
399
+ - A viewing key decrypts encrypted note-delivery events for the registered note-receive public key. A spending key is
400
+ the channel-bound L2 private key used to authorize note use. Do not describe either key as interchangeable with the
401
+ other.
283
402
  - The network RPC URL is the endpoint used to read and write chain state. It can be supplied once with `--rpc-url`
284
403
  on a bridge-facing command, after which the CLI saves it under the selected network.
285
404
  - A workspace recovery index is the saved block pointer and state-root hash that lets the CLI resume log scanning
@@ -301,7 +420,13 @@ Operating rules:
301
420
  8. inspect the channel with `channel get-meta` if it already exists, or create it with `channel create` if the user is
302
421
  the channel creator
303
422
  9. explain the immutable policy warning printed by the CLI
304
- 10. run `channel join --channel-name <CHANNEL> --network <NETWORK> --account <ACCOUNT> --wallet-secret-path <PATH>`
423
+ 10. run `channel join --channel-name <CHANNEL> --network <NETWORK> --account <ACCOUNT> --wallet-secret-path <PATH> --acknowledge-action-impact`
424
+ - Before executing any command for a user that requires an `--acknowledge-*` option, strongly warn the user in plain
425
+ language about what that acknowledgement means and ask for explicit confirmation. Do not add
426
+ `--acknowledge-action-impact` or `--acknowledge-full-note-plaintext-export` on the user's behalf until they confirm.
427
+ For `--acknowledge-action-impact`, explain the command's public/private action-impact summary. For
428
+ `--acknowledge-full-note-plaintext-export`, explain that all locally known note plaintext will be written into the
429
+ exported ZIP.
305
430
  - Before asking the user to create a file, explain what will be inside that file, who should be able to read it, and
306
431
  whether losing it prevents wallet recovery.
307
432
  - Prefer testnet examples unless the user explicitly asks for mainnet.
@@ -315,11 +440,11 @@ Operating rules:
315
440
  local wallet metadata and on-chain channel registration state.
316
441
  - Use `private-state-cli account get-bridge-fund` and `private-state-cli wallet get-channel-fund` to check balances before
317
442
  telling the user to move funds.
318
- - Explain that wallet names are local CLI identifiers, while private transfers use notes owned by L2 addresses
443
+ - Explain that wallet names are local CLI identifiers, while confidential note transfers use notes owned by L2 addresses
319
444
  registered in the channel.
320
- - Explain `--tx-submitter <ACCOUNT>` when the user wants stronger privacy for `wallet mint-notes`, `wallet transfer-notes`, or
321
- `wallet redeem-notes`: the wallet owner still proves note ownership, but another imported local L1 account can submit the
322
- on-chain `executeChannelTransaction` and pay gas.
445
+ - Explain `--tx-submitter <ACCOUNT>` when the user wants a separate L1 transaction submitter for `wallet mint-notes`,
446
+ `wallet transfer-notes`, or `wallet redeem-notes`: the wallet owner still proves note ownership, but another imported
447
+ local L1 account can submit the on-chain `executeChannelTransaction` and pay gas.
323
448
  - Before guiding a user through `channel create` or `channel join`, explain that channel policy is immutable after
324
449
  creation and that joining a channel means accepting its current verifier, DApp metadata, function layout, managed
325
450
  storage vector, and refund policy.
@@ -339,7 +464,7 @@ Suggested interaction flow:
339
464
  5. Run `wallet list` and relevant metadata or balance checks.
340
465
  6. If needed, guide the user through `channel create`, `account deposit-bridge`, `channel join`, `wallet deposit-channel`, and
341
466
  `wallet mint-notes`.
342
- 7. For a private transfer, select available note IDs from `wallet get-notes`, find the recipient L2 address from
467
+ 7. For a confidential note transfer, select available note IDs from `wallet get-notes`, find the recipient L2 address from
343
468
  `wallet get-meta`, then build `wallet transfer-notes`.
344
469
  8. After transfer, guide the recipient to run `wallet get-notes`; it refreshes received notes from the saved recovery index when the delta fits the 7,200-block pre-command budget. If the index is missing or too far behind, explain `wallet recover-workspace --from-genesis`.
345
470
 
@@ -347,9 +472,10 @@ Example onboarding explanation for `channel join`:
347
472
 
348
473
  > First we need two different local secrets. Your L1 private key proves which Ethereum account pays gas and signs
349
474
  > bridge transactions. We import it once into a local account nickname, so later commands can say `--account alice`
350
- > instead of handling the raw key again. Separately, the wallet secret protects the encrypted private-state wallet for
351
- > this channel. It is not sent on-chain and it is not the same as your L1 private key. If you lose the wallet secret,
352
- > recovering this channel wallet can become impossible.
475
+ > instead of handling the raw key again. Separately, the wallet secret source derives the channel-bound spending key
476
+ > during `channel join`. It is not sent on-chain, it is not the same as your L1 private key, and the CLI does not store
477
+ > it in the wallet workspace. A wallet backup restores encrypted tracking state; the viewing key restores note
478
+ > readability; the spending key restores note spendability.
353
479
 
354
480
  Example style: if the user says, "ADDR6 sends 10 tokens privately to ADDR8", do not assume the required note exists.
355
481
  First ask or check which channel and network to use, whether ADDR6 and ADDR8 are already joined, what the local wallet
@@ -386,3 +512,6 @@ Run it once on a new machine, or after public bridge, DApp, Groth16, or Tokamak
386
512
 
387
513
  No. User wallets and channel workspaces are created locally under `~/tokamak-private-channels/`.
388
514
  Bridge-facing commands still submit public transactions and proof-backed state transitions to the selected network.
515
+ For the current `private-state` DApp, commitments, nullifiers, and encrypted note-delivery events are
516
+ part of the DApp-programmed public disclosure surface, while note plaintext, note ownership, and note
517
+ provenance remain controlled by user-held secrets and implemented wallet tooling.
@@ -385,20 +385,20 @@
385
385
  <div class="box">
386
386
  <ul class="guide-list">
387
387
  <li>
388
- Your channel wallet is stored in your local workspace at
388
+ Your wallet backup metadata is stored in your local workspace at
389
389
  <code id="workspace-path-label"></code>.
390
390
  </li>
391
391
  <li>
392
- Even if you lose the channel wallet file, only your Ethereum private key, together with the correct
393
- channel context, can recover your channel wallet as long as you still know the wallet secret.
392
+ A wallet backup does not include viewing keys, spending keys, key derivation material, or plaintext
393
+ note owner, value, and salt fields.
394
394
  </li>
395
395
  <li>
396
- If your channel wallet file and wallet secret are both stolen, your channel funds can be stolen.
396
+ The viewing key decrypts encrypted note-delivery events. The spending key authorizes note use. Export
397
+ and import those keys only when that authority should move to the target machine.
397
398
  </li>
398
399
  <li>
399
- If you lose your wallet secret, you lose the ability to derive your channel L2 private key. In that
400
- case, you lose ownership of all notes because you can no longer use them, and that ownership cannot be
401
- recovered.
400
+ If you lose the spending key and cannot recreate it from the original account, channel context, and
401
+ wallet secret source, you lose the ability to spend, transfer, or redeem notes.
402
402
  </li>
403
403
  <li>
404
404
  Channel policy is immutable after creation. Joining a channel means accepting its verifier bindings,
@@ -485,6 +485,7 @@
485
485
  transferAmount1: "",
486
486
  transferRecipient2: "",
487
487
  transferAmount2: "",
488
+ acknowledgeActionImpact: false,
488
489
  docker: false,
489
490
  includeLocalArtifacts: false,
490
491
  groth16CliVersion: "",
@@ -826,7 +827,7 @@
826
827
  if (!commandNeedsWalletNotes()) {
827
828
  return;
828
829
  }
829
- clearWalletNoteState("Enter note IDs manually. The CLI uses the wallet-local default secret file and the assistant does not request wallet secrets.");
830
+ clearWalletNoteState("Enter note IDs manually. The CLI uses local wallet metadata plus protected viewing/spending key files when commands require them.");
830
831
  }
831
832
 
832
833
  function acceptsRpcUrl(command) {
@@ -843,9 +844,13 @@
843
844
  : null;
844
845
  const optionalFields = new Set(command.optionalFields ?? []);
845
846
  return command.fields.filter((fieldKey) => {
846
- if (fieldCatalog[fieldKey]?.optional || optionalFields.has(fieldKey)) {
847
+ const fieldConfig = fieldCatalog[fieldKey];
848
+ if (fieldConfig?.optional || optionalFields.has(fieldKey)) {
847
849
  return false;
848
850
  }
851
+ if (fieldConfig?.type === "checkbox") {
852
+ return state[fieldKey] !== true;
853
+ }
849
854
  if (fieldKey === "amounts" && command.id === "wallet-mint-notes") {
850
855
  return currentMintAmounts().length === 0;
851
856
  }
@@ -0,0 +1,37 @@
1
+ # Private-State Evidence Investigator
2
+
3
+ This directory contains a static browser tool for filtering a local raw evidence bundle produced by:
4
+
5
+ ```bash
6
+ private-state-cli wallet get-notes \
7
+ --network <NETWORK> \
8
+ --wallet <WALLET> \
9
+ --export-evidence ./wallet-evidence.zip \
10
+ --acknowledge-full-note-plaintext-export
11
+ ```
12
+
13
+ Open `index.html` in a modern browser, load the raw ZIP, select a filter scope, and build a narrower
14
+ user-consent disclosure ZIP. From an installed CLI package, `private-state-cli investigator` prints the bundled
15
+ HTML path and opens it in the default browser.
16
+
17
+ The tool does not run a server and does not send files over the network. It reads the selected ZIP in
18
+ the browser and writes a new ZIP with selected note records plus directly referenced transaction,
19
+ receipt, and event files.
20
+
21
+ The raw evidence bundle contains plaintext for all locally known notes. Do not submit the raw bundle
22
+ as an exchange or auditor package unless full wallet-history disclosure is intended. Use the
23
+ investigator output package for scoped disclosure.
24
+
25
+ ## Supported Filtering
26
+
27
+ - note commitment or nullifier
28
+ - creation transaction or spend transaction
29
+ - creation or spend block range
30
+ - current note status
31
+ - relationship direction
32
+ - available counterparty L2 address metadata
33
+ - user-provided bridge deposit or withdraw transaction context
34
+
35
+ Counterparty filtering is only as complete as the relationship hints present in the raw evidence
36
+ bundle. The investigator does not create a keyless cryptographic decryption proof and does not
37
+ reconstruct private note provenance from public data alone.