@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.
- package/CHANGELOG.md +53 -0
- package/README.md +194 -50
- package/cli-assistant.html +14 -9
- package/investigator/README.md +41 -0
- package/investigator/app.js +674 -0
- package/investigator/index.html +161 -0
- package/investigator/styles.css +249 -0
- package/lib/private-state-cli-command-registry.mjs +174 -54
- package/lib/private-state-cli-shared.mjs +0 -4
- package/package.json +2 -1
- package/private-state-bridge-cli.mjs +2205 -587
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,58 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## Unreleased
|
|
4
|
+
|
|
5
|
+
## 2.1.0 - 2026-05-14
|
|
6
|
+
|
|
7
|
+
- Required current epoch-aware wallet workspaces for wallet commands and backup imports. Local
|
|
8
|
+
wallet metadata must include the wallet index and epoch metadata; users with older local
|
|
9
|
+
workspaces should rebuild them with `wallet recover-workspace`.
|
|
10
|
+
- Required current epoch-aware evidence bundle note paths in the investigator and removed the
|
|
11
|
+
special-case legacy evidence layout branch.
|
|
12
|
+
- Consolidated the static evidence investigator into the CLI package under `cli/investigator/`
|
|
13
|
+
and removed the duplicate top-level investigator copy.
|
|
14
|
+
- Simplified wallet command argument validation by removing unused schema fallback wrappers.
|
|
15
|
+
|
|
16
|
+
## 2.0.0 - 2026-05-13
|
|
17
|
+
|
|
18
|
+
- Split wallet export/import into `wallet export backup`, `wallet export viewing-key`,
|
|
19
|
+
`wallet export spending-key`, `wallet import backup`, `wallet import viewing-key`, and
|
|
20
|
+
`wallet import spending-key`.
|
|
21
|
+
- Changed wallet backups so they exclude spending keys, viewing keys, key derivation material,
|
|
22
|
+
and plaintext note `owner`, `value`, and `salt` fields. Backups retain commitments,
|
|
23
|
+
nullifiers, encrypted note payloads, and channel workspace cache files.
|
|
24
|
+
- Replaced the previous full-control wallet workspace format with separate note-tracking,
|
|
25
|
+
spending-key metadata, and viewing-key metadata files. The CLI now loads only the current
|
|
26
|
+
wallet metadata format.
|
|
27
|
+
- Added action-impact acknowledgements for bridge-facing, channel, and note-mutating commands.
|
|
28
|
+
The warning output covers public event exposure, private note-state impact, note provenance
|
|
29
|
+
boundaries, illegal-use prohibition, CEX deposit-address warnings, secret-recovery limits, and
|
|
30
|
+
channel policy acceptance.
|
|
31
|
+
- Added full-note raw evidence export through `wallet get-notes --export-evidence` with an explicit
|
|
32
|
+
plaintext-export acknowledgement. Evidence bundles include note plaintext facts, derived
|
|
33
|
+
commitments and nullifiers, creation/spend transaction references, receipts, events, calldata, and
|
|
34
|
+
filtering indexes, while excluding viewing keys, spending keys, wallet secrets, account private
|
|
35
|
+
keys, and `.key` files.
|
|
36
|
+
- Made local wallet workspaces epoch-aware. `channel exit` now marks the active wallet epoch as
|
|
37
|
+
exited and retains its local note metadata instead of deleting the wallet workspace, while
|
|
38
|
+
`wallet recover-workspace` and `wallet get-notes --export-evidence` can still use retained exited
|
|
39
|
+
epochs for historical disclosure.
|
|
40
|
+
- Added a local static evidence investigator GUI and bundled it with the NPM package. The new
|
|
41
|
+
top-level `private-state-cli investigator` command prints the bundled HTML path, prints the file
|
|
42
|
+
URL, and opens the GUI in the default browser.
|
|
43
|
+
- Clarified wallet authority recovery in the NPM README: viewing-key rederivation needs the original
|
|
44
|
+
L1 private key and channel context, while spending-key rederivation additionally needs the same
|
|
45
|
+
wallet secret source used at `channel join`.
|
|
46
|
+
- Added a `channel join` success warning that losing both the spending-key file and wallet secret
|
|
47
|
+
source prevents spending-key rederivation.
|
|
48
|
+
- Aligned README terminology around `private-state DApp`, `private-state CLI`, `viewing key`,
|
|
49
|
+
`spending key`, `wallet secret source`, `user-controlled selective disclosure`, and
|
|
50
|
+
`privacy-preserving note semantics`.
|
|
51
|
+
- Added LLM-assistant guidance requiring strong user warnings and explicit confirmation before an
|
|
52
|
+
assistant runs commands that require `--acknowledge-*` options on a user's behalf.
|
|
53
|
+
- Simplified internal CLI code paths by removing a dead `loadWallet` parameter and redundant
|
|
54
|
+
`channel join` result aliases.
|
|
55
|
+
|
|
3
56
|
## 1.2.1 - 2026-05-11
|
|
4
57
|
|
|
5
58
|
- 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/`,
|
|
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
|
|
@@ -122,6 +176,16 @@ channel genesis and only runs when the recovery delta fits within the 7,200-bloc
|
|
|
122
176
|
is missing, unusable, or too far behind, the command stops and asks the user to run the appropriate recovery command
|
|
123
177
|
with `--from-genesis` explicitly when needed.
|
|
124
178
|
|
|
179
|
+
Local wallet workspaces are epoch-aware. Each successful channel registration creates a wallet epoch under the
|
|
180
|
+
canonical wallet directory. `channel exit` does not delete the local wallet workspace; it marks the active epoch as
|
|
181
|
+
exited with the exit transaction, block, and timestamp, then keeps that epoch read-only for historical note inspection
|
|
182
|
+
and evidence export. If the same account later joins the same channel again, the new registration is a separate active
|
|
183
|
+
epoch under the same canonical wallet name.
|
|
184
|
+
|
|
185
|
+
The current CLI only supports this epoch-aware wallet workspace layout. If a local wallet directory was created by an
|
|
186
|
+
older CLI and does not contain `wallet-index.metadata.json` plus `epochs/<epoch-id>/` metadata files, rebuild it with
|
|
187
|
+
`wallet recover-workspace` before using wallet commands.
|
|
188
|
+
|
|
125
189
|
Channel leaders can optionally register a workspace mirror server so users can bootstrap recovery
|
|
126
190
|
from a signed checkpoint and download only the local-to-checkpoint delta when a local recovery index
|
|
127
191
|
already exists. The channel leader can build the static mirror files with
|
|
@@ -134,33 +198,63 @@ https://github.com/tokamak-network/Tokamak-zk-EVM-contracts/blob/main/packages/a
|
|
|
134
198
|
Back up a local wallet with:
|
|
135
199
|
|
|
136
200
|
```bash
|
|
137
|
-
private-state-cli wallet export --network mainnet --wallet <WALLET> --output ./wallet-backup.zip
|
|
201
|
+
private-state-cli wallet export backup --network mainnet --wallet <WALLET> --output ./wallet-backup.zip
|
|
138
202
|
```
|
|
139
203
|
|
|
140
|
-
The
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
run `channel recover-workspace` before using wallet commands that need channel state:
|
|
204
|
+
The backup export stores note-tracking metadata and the channel workspace cache, but it does not include spending keys,
|
|
205
|
+
viewing keys, key derivation material, or plaintext note secrets. Note records in the backup keep commitments,
|
|
206
|
+
nullifiers, and encrypted note payloads only; `owner`, `value`, and `salt` are excluded.
|
|
207
|
+
Importing this backup restores encrypted tracking state and channel cache files, not wallet authority.
|
|
145
208
|
|
|
146
209
|
```bash
|
|
147
|
-
private-state-cli wallet import --input ./wallet-backup.zip
|
|
148
|
-
|
|
210
|
+
private-state-cli wallet import backup --input ./wallet-backup.zip
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
Export viewing and spending authority separately:
|
|
214
|
+
|
|
215
|
+
```bash
|
|
216
|
+
private-state-cli wallet export viewing-key --network mainnet --wallet <WALLET> --output ./wallet-viewing.key
|
|
217
|
+
private-state-cli wallet export spending-key --network mainnet --wallet <WALLET> --output ./wallet-spending.key
|
|
149
218
|
```
|
|
150
219
|
|
|
151
|
-
|
|
152
|
-
chain-aligned, add `--include-notes`:
|
|
220
|
+
Import those capabilities only when the target machine should receive them:
|
|
153
221
|
|
|
154
222
|
```bash
|
|
155
|
-
private-state-cli wallet
|
|
223
|
+
private-state-cli wallet import viewing-key --input ./wallet-viewing.key
|
|
224
|
+
private-state-cli wallet import spending-key --input ./wallet-spending.key
|
|
156
225
|
```
|
|
157
226
|
|
|
158
|
-
|
|
227
|
+
A backup plus a viewing key can reconstruct the wallet's readable note view from encrypted events, but it still cannot
|
|
228
|
+
spend notes. A backup plus a spending key is still missing event-log decryption authority. A normal operational restore
|
|
229
|
+
imports the backup, the viewing key, and the spending key, and still needs the relevant local L1 account secret for
|
|
230
|
+
commands that submit bridge or channel-registration transactions.
|
|
231
|
+
|
|
232
|
+
Export a local full-note evidence bundle with:
|
|
159
233
|
|
|
160
234
|
```bash
|
|
161
|
-
private-state-cli wallet
|
|
235
|
+
private-state-cli wallet get-notes --network mainnet --wallet <WALLET> --export-evidence ./wallet-evidence.zip --acknowledge-full-note-plaintext-export
|
|
162
236
|
```
|
|
163
237
|
|
|
238
|
+
This ZIP is an input for `private-state-cli investigator`. It contains plaintext for all locally known
|
|
239
|
+
notes, derived commitments and nullifiers, creation and spend transaction references, transaction calldata, receipts,
|
|
240
|
+
events, and indexes for filtering by note, nullifier, transaction, block range, or available counterparty metadata. It
|
|
241
|
+
includes all local epochs for the selected wallet, including exited epochs retained after `channel exit`. It does not
|
|
242
|
+
include viewing keys, spending keys, wallet secret material, account private keys, or `.key` files. Do not submit the
|
|
243
|
+
raw ZIP as an exchange or auditor package unless full wallet-history disclosure is intended.
|
|
244
|
+
|
|
245
|
+
Open the local evidence investigator with:
|
|
246
|
+
|
|
247
|
+
```bash
|
|
248
|
+
private-state-cli investigator
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
The command prints the bundled investigator HTML path and file URL, then opens the static browser GUI. Load the raw
|
|
252
|
+
evidence ZIP in that GUI, apply the requested filters, and export a narrower user-consent disclosure ZIP. The GUI runs
|
|
253
|
+
locally in the browser and does not send files over the network.
|
|
254
|
+
|
|
255
|
+
The investigator accepts current epoch-aware evidence bundles only. If a bundle was generated by an older CLI, rebuild
|
|
256
|
+
the wallet workspace with `wallet recover-workspace` and export a new bundle with `wallet get-notes --export-evidence`.
|
|
257
|
+
|
|
164
258
|
Estimate live transaction costs before sending commands with:
|
|
165
259
|
|
|
166
260
|
```bash
|
|
@@ -175,13 +269,13 @@ data.
|
|
|
175
269
|
Proof-backed note commands can use a separate L1 transaction submitter:
|
|
176
270
|
|
|
177
271
|
```bash
|
|
178
|
-
private-state-cli wallet mint-notes --wallet <WALLET> --network mainnet --amounts '[1]' --tx-submitter <ACCOUNT>
|
|
272
|
+
private-state-cli wallet mint-notes --wallet <WALLET> --network mainnet --amounts '[1]' --acknowledge-action-impact --tx-submitter <ACCOUNT>
|
|
179
273
|
```
|
|
180
274
|
|
|
181
275
|
`--tx-submitter <ACCOUNT>` is available on `wallet mint-notes`, `wallet transfer-notes`, and `wallet redeem-notes`. The wallet still proves
|
|
182
276
|
note ownership and builds the ZK proof, but the selected local account submits `executeChannelTransaction` and pays gas.
|
|
183
|
-
Use this option when
|
|
184
|
-
|
|
277
|
+
Use this option when a separate imported local account should submit the L1 transaction and pay gas for a proof-backed
|
|
278
|
+
note command.
|
|
185
279
|
|
|
186
280
|
Channel policy warning:
|
|
187
281
|
|
|
@@ -208,34 +302,67 @@ private-state-cli account import --account <ACCOUNT_NAME> --network sepolia --pr
|
|
|
208
302
|
private-state-cli account get-l1-address --account <ACCOUNT_NAME> --network sepolia
|
|
209
303
|
private-state-cli wallet list --network sepolia --channel-name cuda
|
|
210
304
|
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
|
|
305
|
+
private-state-cli wallet export backup --network sepolia --wallet <WALLET_NAME> --output ./wallet-backup.zip
|
|
306
|
+
private-state-cli wallet import backup --input ./wallet-backup.zip
|
|
213
307
|
```
|
|
214
308
|
|
|
215
309
|
`account import` is the only supported way to bring an L1 signing key into the CLI: it reads `--private-key-file` once
|
|
216
310
|
and stores a protected local account secret for later `--account` use. The source file does not need `0600` permissions.
|
|
217
|
-
`channel join`
|
|
218
|
-
|
|
311
|
+
`channel join` reads `--wallet-secret-path <PATH>` once while creating the channel-bound spending key and then stores
|
|
312
|
+
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
313
|
`--wallet`.
|
|
220
|
-
`wallet get-meta` opens
|
|
221
|
-
on-chain channel registration match state
|
|
222
|
-
|
|
314
|
+
`wallet get-meta` opens the wallet metadata and reports the stored L1/L2 identity metadata plus the current
|
|
315
|
+
on-chain channel registration match state, including the registered note-receive public key when present. On
|
|
316
|
+
epoch-aware wallet workspaces it also reports the selected wallet epoch and whether that epoch is active or exited.
|
|
317
|
+
`account get-l1-address` is a simple offline helper that derives the L1 address for a local account.
|
|
223
318
|
|
|
224
319
|
### Wallet Secret Source File
|
|
225
320
|
|
|
226
321
|
`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
|
|
228
|
-
wallet
|
|
322
|
+
line. The source file is arbitrary high-entropy secret text that the CLI reads once for channel-bound spending-key
|
|
323
|
+
derivation. It is not persisted in the wallet workspace.
|
|
229
324
|
|
|
230
325
|
Create one before joining a channel:
|
|
231
326
|
|
|
232
327
|
```bash
|
|
233
328
|
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
|
|
329
|
+
private-state-cli channel join --channel-name <CHANNEL> --network sepolia --account <ACCOUNT> --wallet-secret-path ./wallet-secret.txt --acknowledge-action-impact
|
|
235
330
|
```
|
|
236
331
|
|
|
237
|
-
The import source file does not need `0600` permissions. The
|
|
238
|
-
|
|
332
|
+
The import source file does not need `0600` permissions. The CLI does not persist a wallet-local secret:
|
|
333
|
+
it reads the source once for channel-bound L2 spending-key derivation. The join flow stores the viewing key and
|
|
334
|
+
spending key as separate protected key files under the CLI secret root; macOS/Linux uses `0600`, while Windows uses ACL
|
|
335
|
+
repair and inspection when possible.
|
|
336
|
+
|
|
337
|
+
Keep the wallet secret source separately backed up if you expect to rederive the spending key later. The viewing key can
|
|
338
|
+
be rederived from the same L1 private key and channel context because it comes from the note-receive typed-data signing
|
|
339
|
+
flow. The spending key needs the same L1 private key, the same channel context, and the same wallet secret source. If the
|
|
340
|
+
spending-key file is lost and the wallet secret source is also lost, the CLI cannot reconstruct the spending key and the
|
|
341
|
+
notes for that wallet cannot be spent, transferred, or redeemed through the normal note flow.
|
|
342
|
+
|
|
343
|
+
### Wallet Backup, Viewing, And Spending Authority
|
|
344
|
+
|
|
345
|
+
The wallet workspace is split so that a backup is not a full-control wallet export. Backup metadata stores the
|
|
346
|
+
recoverable local view of the channel: commitments, nullifiers, encrypted note-delivery payloads, scan checkpoints,
|
|
347
|
+
operation history, and the channel workspace cache. It deliberately omits plaintext note fields and key material.
|
|
348
|
+
|
|
349
|
+
The viewing key is the note-receive private key. It lets `wallet get-notes` decrypt bridge-propagated encrypted
|
|
350
|
+
note-delivery events and rebuild the user's readable note view. Sharing it gives read access to notes addressed to the
|
|
351
|
+
registered note-receive public key, but not spending authority.
|
|
352
|
+
|
|
353
|
+
The spending key is the channel-bound L2 private key. It authorizes proof-backed use of the wallet identity. Commands
|
|
354
|
+
that consume existing notes, such as `wallet transfer-notes` and `wallet redeem-notes`, need both the viewing key and
|
|
355
|
+
the spending key because the CLI must first reconstruct the plaintext notes and then prove authorized use of them.
|
|
356
|
+
|
|
357
|
+
Key recovery is intentionally split. Recreating the viewing key requires the original L1 private key and the same channel
|
|
358
|
+
context. Recreating the spending key requires the original L1 private key, the same channel context, and the same wallet
|
|
359
|
+
secret source used at `channel join`. Importing `wallet-viewing.key` or `wallet-spending.key` restores the corresponding
|
|
360
|
+
capability without rerunning derivation, but a backup ZIP alone never restores either capability.
|
|
361
|
+
|
|
362
|
+
`wallet get-notes --export-evidence <PATH> --acknowledge-full-note-plaintext-export` writes a local raw evidence ZIP.
|
|
363
|
+
The bundle is not a key export. It includes plaintext note facts for locally known notes so that
|
|
364
|
+
`private-state-cli investigator` can create narrower consent-disclosure packages without requiring viewing-key or
|
|
365
|
+
spending-key sharing.
|
|
239
366
|
|
|
240
367
|
## Workspace
|
|
241
368
|
|
|
@@ -245,8 +372,8 @@ The CLI stores user workspaces under:
|
|
|
245
372
|
~/tokamak-private-channels/workspace/<network>/<channel>/
|
|
246
373
|
```
|
|
247
374
|
|
|
248
|
-
Wallet
|
|
249
|
-
`~/tokamak-private-channels/secrets/<network>/wallets/<wallet
|
|
375
|
+
Wallet backup metadata lives under the channel workspace. Viewing and spending private keys live as separate protected
|
|
376
|
+
key files under `~/tokamak-private-channels/secrets/<network>/wallets/<wallet>/`.
|
|
250
377
|
|
|
251
378
|
Bridge-facing commands accept optional `--rpc-url <URL>`. When `--rpc-url` is provided, the CLI stores it in
|
|
252
379
|
`~/tokamak-private-channels/secrets/<network>/.env` as `RPC_URL=<URL>` with protected canonical secret permissions.
|
|
@@ -257,16 +384,19 @@ When `--rpc-url` is omitted, the CLI reads `RPC_URL` from that file. The `anvil`
|
|
|
257
384
|
## LLM Agent Guidance
|
|
258
385
|
|
|
259
386
|
You may act as an interactive guide for users who do not understand this CLI or the private-state DApp. Assume the
|
|
260
|
-
user
|
|
261
|
-
actions.
|
|
387
|
+
user wants to use confidential channel-local notes while keeping L1 bridge deposits and withdrawals transparent.
|
|
388
|
+
Translate the user's intent into safe, step-by-step CLI actions.
|
|
262
389
|
|
|
263
|
-
Primary goal: help the user
|
|
264
|
-
|
|
390
|
+
Primary goal: help the user safely use private-state note workflows: self-custody L1 funding, channel-local note
|
|
391
|
+
creation, note transfer, note recovery, and user-controlled disclosure where supported. Present this
|
|
392
|
+
as privacy-preserving note semantics for the current `private-state` DApp, not as invisible
|
|
393
|
+
activity or as a bridge-wide disclosure rule for every DApp.
|
|
265
394
|
|
|
266
395
|
Operating rules:
|
|
267
396
|
|
|
268
397
|
- 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
|
|
398
|
+
once, then use `--account` for L1 signing commands. Wallet viewing and spending authority is imported separately
|
|
399
|
+
with `wallet import viewing-key` and `wallet import spending-key`.
|
|
270
400
|
- Treat `private key file`, `account`, `wallet secret`, `wallet`, `network RPC URL`, and `channel policy` as
|
|
271
401
|
new concepts unless the user has already demonstrated that they understand them. Define each term before using it
|
|
272
402
|
in an instruction.
|
|
@@ -276,10 +406,14 @@ Operating rules:
|
|
|
276
406
|
- An account is the local nickname created by `account import`. After import, signing commands should use
|
|
277
407
|
`--account <NAME>` instead of asking for the raw key again.
|
|
278
408
|
- 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`
|
|
280
|
-
|
|
281
|
-
- A wallet is the
|
|
282
|
-
`<channelName>-<l1Address>`.
|
|
409
|
+
wallet. It is not the L1 private key. `channel join` reads it once for channel-bound spending-key derivation and
|
|
410
|
+
does not persist it in the wallet workspace.
|
|
411
|
+
- A wallet is the local private-state metadata set created during `channel join`. Its deterministic name is
|
|
412
|
+
`<channelName>-<l1Address>`. The wallet backup tracks encrypted note state, while viewing and spending authority
|
|
413
|
+
are stored in separate protected key files.
|
|
414
|
+
- A viewing key decrypts encrypted note-delivery events for the registered note-receive public key. A spending key is
|
|
415
|
+
the channel-bound L2 private key used to authorize note use. Do not describe either key as interchangeable with the
|
|
416
|
+
other.
|
|
283
417
|
- The network RPC URL is the endpoint used to read and write chain state. It can be supplied once with `--rpc-url`
|
|
284
418
|
on a bridge-facing command, after which the CLI saves it under the selected network.
|
|
285
419
|
- A workspace recovery index is the saved block pointer and state-root hash that lets the CLI resume log scanning
|
|
@@ -301,7 +435,13 @@ Operating rules:
|
|
|
301
435
|
8. inspect the channel with `channel get-meta` if it already exists, or create it with `channel create` if the user is
|
|
302
436
|
the channel creator
|
|
303
437
|
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
|
|
438
|
+
10. run `channel join --channel-name <CHANNEL> --network <NETWORK> --account <ACCOUNT> --wallet-secret-path <PATH> --acknowledge-action-impact`
|
|
439
|
+
- Before executing any command for a user that requires an `--acknowledge-*` option, strongly warn the user in plain
|
|
440
|
+
language about what that acknowledgement means and ask for explicit confirmation. Do not add
|
|
441
|
+
`--acknowledge-action-impact` or `--acknowledge-full-note-plaintext-export` on the user's behalf until they confirm.
|
|
442
|
+
For `--acknowledge-action-impact`, explain the command's public/private action-impact summary. For
|
|
443
|
+
`--acknowledge-full-note-plaintext-export`, explain that all locally known note plaintext will be written into the
|
|
444
|
+
exported ZIP.
|
|
305
445
|
- Before asking the user to create a file, explain what will be inside that file, who should be able to read it, and
|
|
306
446
|
whether losing it prevents wallet recovery.
|
|
307
447
|
- Prefer testnet examples unless the user explicitly asks for mainnet.
|
|
@@ -315,11 +455,11 @@ Operating rules:
|
|
|
315
455
|
local wallet metadata and on-chain channel registration state.
|
|
316
456
|
- Use `private-state-cli account get-bridge-fund` and `private-state-cli wallet get-channel-fund` to check balances before
|
|
317
457
|
telling the user to move funds.
|
|
318
|
-
- Explain that wallet names are local CLI identifiers, while
|
|
458
|
+
- Explain that wallet names are local CLI identifiers, while confidential note transfers use notes owned by L2 addresses
|
|
319
459
|
registered in the channel.
|
|
320
|
-
- Explain `--tx-submitter <ACCOUNT>` when the user wants
|
|
321
|
-
`wallet redeem-notes`: the wallet owner still proves note ownership, but another imported
|
|
322
|
-
on-chain `executeChannelTransaction` and pay gas.
|
|
460
|
+
- Explain `--tx-submitter <ACCOUNT>` when the user wants a separate L1 transaction submitter for `wallet mint-notes`,
|
|
461
|
+
`wallet transfer-notes`, or `wallet redeem-notes`: the wallet owner still proves note ownership, but another imported
|
|
462
|
+
local L1 account can submit the on-chain `executeChannelTransaction` and pay gas.
|
|
323
463
|
- Before guiding a user through `channel create` or `channel join`, explain that channel policy is immutable after
|
|
324
464
|
creation and that joining a channel means accepting its current verifier, DApp metadata, function layout, managed
|
|
325
465
|
storage vector, and refund policy.
|
|
@@ -339,7 +479,7 @@ Suggested interaction flow:
|
|
|
339
479
|
5. Run `wallet list` and relevant metadata or balance checks.
|
|
340
480
|
6. If needed, guide the user through `channel create`, `account deposit-bridge`, `channel join`, `wallet deposit-channel`, and
|
|
341
481
|
`wallet mint-notes`.
|
|
342
|
-
7. For a
|
|
482
|
+
7. For a confidential note transfer, select available note IDs from `wallet get-notes`, find the recipient L2 address from
|
|
343
483
|
`wallet get-meta`, then build `wallet transfer-notes`.
|
|
344
484
|
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
485
|
|
|
@@ -347,9 +487,10 @@ Example onboarding explanation for `channel join`:
|
|
|
347
487
|
|
|
348
488
|
> First we need two different local secrets. Your L1 private key proves which Ethereum account pays gas and signs
|
|
349
489
|
> 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
|
|
351
|
-
>
|
|
352
|
-
>
|
|
490
|
+
> instead of handling the raw key again. Separately, the wallet secret source derives the channel-bound spending key
|
|
491
|
+
> 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
|
|
492
|
+
> it in the wallet workspace. A wallet backup restores encrypted tracking state; the viewing key restores note
|
|
493
|
+
> readability; the spending key restores note spendability.
|
|
353
494
|
|
|
354
495
|
Example style: if the user says, "ADDR6 sends 10 tokens privately to ADDR8", do not assume the required note exists.
|
|
355
496
|
First ask or check which channel and network to use, whether ADDR6 and ADDR8 are already joined, what the local wallet
|
|
@@ -386,3 +527,6 @@ Run it once on a new machine, or after public bridge, DApp, Groth16, or Tokamak
|
|
|
386
527
|
|
|
387
528
|
No. User wallets and channel workspaces are created locally under `~/tokamak-private-channels/`.
|
|
388
529
|
Bridge-facing commands still submit public transactions and proof-backed state transitions to the selected network.
|
|
530
|
+
For the current `private-state` DApp, commitments, nullifiers, and encrypted note-delivery events are
|
|
531
|
+
part of the DApp-programmed public disclosure surface, while note plaintext, note ownership, and note
|
|
532
|
+
provenance remain controlled by user-held secrets and implemented wallet tooling.
|
package/cli-assistant.html
CHANGED
|
@@ -385,20 +385,20 @@
|
|
|
385
385
|
<div class="box">
|
|
386
386
|
<ul class="guide-list">
|
|
387
387
|
<li>
|
|
388
|
-
Your
|
|
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
|
-
|
|
393
|
-
|
|
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
|
-
|
|
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
|
|
400
|
-
|
|
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
|
|
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
|
-
|
|
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,41 @@
|
|
|
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
|
+
The investigator accepts current epoch-aware evidence bundles only. Supported note records live under
|
|
26
|
+
`wallets/<wallet>/epochs/<epoch-id>/notes/` inside the ZIP. If a bundle uses an older layout, rebuild the local wallet
|
|
27
|
+
workspace with `wallet recover-workspace` and export a new evidence ZIP with `wallet get-notes --export-evidence`.
|
|
28
|
+
|
|
29
|
+
## Supported Filtering
|
|
30
|
+
|
|
31
|
+
- note commitment or nullifier
|
|
32
|
+
- creation transaction or spend transaction
|
|
33
|
+
- creation or spend block range
|
|
34
|
+
- current note status
|
|
35
|
+
- relationship direction
|
|
36
|
+
- available counterparty L2 address metadata
|
|
37
|
+
- user-provided bridge deposit or withdraw transaction context
|
|
38
|
+
|
|
39
|
+
Counterparty filtering is only as complete as the relationship hints present in the raw evidence
|
|
40
|
+
bundle. The investigator does not create a keyless cryptographic decryption proof and does not
|
|
41
|
+
reconstruct private note provenance from public data alone.
|