@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.
- package/CHANGELOG.md +43 -2
- package/README.md +183 -54
- package/cli-assistant.html +14 -9
- package/investigator/README.md +37 -0
- package/investigator/app.js +657 -0
- package/investigator/index.html +161 -0
- package/investigator/styles.css +249 -0
- package/lib/private-state-cli-command-registry.mjs +165 -52
- package/lib/private-state-cli-shared.mjs +0 -4
- package/package.json +2 -1
- package/private-state-bridge-cli.mjs +1629 -514
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,48 @@
|
|
|
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
|
+
|
|
41
|
+
## 1.2.1 - 2026-05-11
|
|
42
|
+
|
|
43
|
+
- Changed pre-command automatic recovery from an RPC log request time estimate to a fixed
|
|
44
|
+
7,200-block recovery delta budget.
|
|
45
|
+
|
|
3
46
|
## 1.2.0 - 2026-05-08
|
|
4
47
|
|
|
5
48
|
- Added optional channel workspace mirror recovery. `channel recover-workspace` now accepts
|
|
@@ -20,8 +63,6 @@
|
|
|
20
63
|
when a genesis rebuild is required.
|
|
21
64
|
- Restored received-note event-log refresh for `wallet get-notes`, `wallet transfer-notes`, and
|
|
22
65
|
`wallet redeem-notes`, limited to the saved wallet note recovery index.
|
|
23
|
-
- Limited pre-command automatic recovery to a 10 second RPC log scan budget based on the CLI's
|
|
24
|
-
paced log query rate.
|
|
25
66
|
- Reworked workspace mirror recovery around leader-signed checkpoint manifests and
|
|
26
67
|
delta bundles. When a local recovery index exists, the CLI prechecks the mirror checkpoint and
|
|
27
68
|
downloads only the matching delta bundle instead of a full workspace bundle.
|
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
|
|
@@ -118,9 +172,9 @@ saved index instead of silently replaying from genesis.
|
|
|
118
172
|
Wallet getter commands that need channel state, including `wallet get-meta`, `wallet get-channel-fund`, and
|
|
119
173
|
`wallet get-notes`, refresh stale local workspaces through saved recovery indexes before reading state. `wallet get-notes`
|
|
120
174
|
also refreshes received-note logs through the saved wallet note recovery index. Automatic refresh never replays from
|
|
121
|
-
channel genesis and only runs when the
|
|
122
|
-
|
|
123
|
-
|
|
175
|
+
channel genesis and only runs when the recovery delta fits within the 7,200-block pre-command budget. If a saved index
|
|
176
|
+
is missing, unusable, or too far behind, the command stops and asks the user to run the appropriate recovery command
|
|
177
|
+
with `--from-genesis` explicitly when needed.
|
|
124
178
|
|
|
125
179
|
Channel leaders can optionally register a workspace mirror server so users can bootstrap recovery
|
|
126
180
|
from a signed checkpoint and download only the local-to-checkpoint delta when a local recovery index
|
|
@@ -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
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
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
|
-
|
|
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-
|
|
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
|
-
|
|
210
|
+
Import those capabilities only when the target machine should receive them:
|
|
159
211
|
|
|
160
212
|
```bash
|
|
161
|
-
private-state-cli wallet
|
|
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
|
|
184
|
-
|
|
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`
|
|
218
|
-
|
|
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
|
|
221
|
-
on-chain channel registration match state
|
|
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
|
|
228
|
-
wallet
|
|
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
|
|
238
|
-
|
|
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
|
|
249
|
-
`~/tokamak-private-channels/secrets/<network>/wallets/<wallet
|
|
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
|
|
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
|
|
264
|
-
|
|
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
|
|
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`
|
|
280
|
-
|
|
281
|
-
- A wallet is the
|
|
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
|
|
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
|
|
321
|
-
`wallet redeem-notes`: the wallet owner still proves note ownership, but another imported
|
|
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,17 +464,18 @@ 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
|
|
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
|
-
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
|
|
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
|
|
|
346
471
|
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
|
|
351
|
-
>
|
|
352
|
-
>
|
|
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.
|
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,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.
|