@tokamak-private-dapps/private-state-cli 2.1.0 → 2.1.2

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.
@@ -27,90 +27,136 @@
27
27
  spending keys, wallet secrets, or account private keys.
28
28
  </section>
29
29
 
30
- <section class="grid">
31
- <form id="filters" class="panel">
32
- <h2>Filter Scope</h2>
33
- <label>
34
- Commitment contains
35
- <input name="commitment" autocomplete="off" placeholder="0x...">
36
- </label>
37
- <label>
38
- Nullifier contains
39
- <input name="nullifier" autocomplete="off" placeholder="0x...">
40
- </label>
41
- <label>
42
- Creation tx
43
- <input name="creationTx" autocomplete="off" placeholder="0x...">
44
- </label>
45
- <label>
46
- Spend tx
47
- <input name="spendTx" autocomplete="off" placeholder="0x...">
48
- </label>
49
- <div class="two-col">
50
- <label>
51
- Created from block
52
- <input name="createdFrom" inputmode="numeric" autocomplete="off">
30
+ <section id="summaryCards" class="summary-grid" aria-live="polite"></section>
31
+
32
+ <section class="workspace">
33
+ <form id="filters" class="panel scope-panel">
34
+ <div class="panel-head">
35
+ <h2>Disclosure Request</h2>
36
+ <button id="applyFilters" type="button">Apply</button>
37
+ </div>
38
+
39
+ <div class="purpose-grid" role="radiogroup" aria-label="Disclosure request type">
40
+ <label class="purpose-card">
41
+ <input name="purpose" type="radio" value="overview" checked>
42
+ <span>Full graph view</span>
53
43
  </label>
54
- <label>
55
- Created to block
56
- <input name="createdTo" inputmode="numeric" autocomplete="off">
44
+ <label class="purpose-card">
45
+ <input name="purpose" type="radio" value="receipt">
46
+ <span>Specific note receipt</span>
47
+ </label>
48
+ <label class="purpose-card">
49
+ <input name="purpose" type="radio" value="spend">
50
+ <span>Specific note use</span>
51
+ </label>
52
+ <label class="purpose-card">
53
+ <input name="purpose" type="radio" value="transaction">
54
+ <span>Transaction linkage</span>
55
+ </label>
56
+ <label class="purpose-card">
57
+ <input name="purpose" type="radio" value="range">
58
+ <span>Period receipts</span>
59
+ </label>
60
+ <label class="purpose-card">
61
+ <input name="purpose" type="radio" value="counterparty">
62
+ <span>Counterparty subset</span>
63
+ </label>
64
+ </div>
65
+
66
+ <div class="form-section">
67
+ <h3>Request Inputs</h3>
68
+ <label data-purpose-field="receipt spend">
69
+ Commitment contains
70
+ <input name="commitment" autocomplete="off" placeholder="0x...">
71
+ </label>
72
+ <label data-purpose-field="spend">
73
+ Nullifier contains
74
+ <input name="nullifier" autocomplete="off" placeholder="0x...">
75
+ </label>
76
+ <label data-purpose-field="receipt transaction">
77
+ Creation tx
78
+ <input name="creationTx" autocomplete="off" placeholder="0x...">
79
+ </label>
80
+ <label data-purpose-field="spend transaction">
81
+ Spend tx
82
+ <input name="spendTx" autocomplete="off" placeholder="0x...">
83
+ </label>
84
+ <div class="two-col" data-purpose-field="range">
85
+ <label>
86
+ Created from block
87
+ <input name="createdFrom" inputmode="numeric" autocomplete="off">
88
+ </label>
89
+ <label>
90
+ Created to block
91
+ <input name="createdTo" inputmode="numeric" autocomplete="off">
92
+ </label>
93
+ </div>
94
+ <div class="two-col" data-purpose-field="range spend">
95
+ <label>
96
+ Spent from block
97
+ <input name="spentFrom" inputmode="numeric" autocomplete="off">
98
+ </label>
99
+ <label>
100
+ Spent to block
101
+ <input name="spentTo" inputmode="numeric" autocomplete="off">
102
+ </label>
103
+ </div>
104
+ <label data-purpose-field="counterparty">
105
+ Counterparty L2 address
106
+ <input name="counterparty" autocomplete="off" placeholder="0x...">
57
107
  </label>
58
108
  </div>
109
+
110
+ <details class="advanced-filters">
111
+ <summary>Advanced filters</summary>
112
+ <div class="two-col">
113
+ <label>
114
+ Status
115
+ <select name="status">
116
+ <option value="">Any</option>
117
+ <option value="unused">Unused</option>
118
+ <option value="spent">Spent</option>
119
+ </select>
120
+ </label>
121
+ <label>
122
+ Direction
123
+ <select name="direction">
124
+ <option value="">Any</option>
125
+ <option value="self-mint">Self mint</option>
126
+ <option value="sent">Sent</option>
127
+ <option value="received">Received</option>
128
+ <option value="unknown">Unknown</option>
129
+ </select>
130
+ </label>
131
+ </div>
132
+ </details>
133
+ </form>
134
+
135
+ <form id="packageForm" class="panel package-panel">
136
+ <div class="panel-head">
137
+ <h2>Export Package</h2>
138
+ <button id="buildPackage" type="button" disabled>Build disclosure ZIP</button>
139
+ </div>
59
140
  <div class="two-col">
60
141
  <label>
61
- Spent from block
62
- <input name="spentFrom" inputmode="numeric" autocomplete="off">
142
+ Case ID
143
+ <input name="caseId" autocomplete="off" placeholder="exchange-case-001">
63
144
  </label>
64
145
  <label>
65
- Spent to block
66
- <input name="spentTo" inputmode="numeric" autocomplete="off">
146
+ Requesting party
147
+ <input name="requestingParty" autocomplete="off" placeholder="Exchange or investigator name">
67
148
  </label>
68
149
  </div>
69
150
  <div class="two-col">
70
151
  <label>
71
- Status
72
- <select name="status">
73
- <option value="">Any</option>
74
- <option value="unused">Unused</option>
75
- <option value="spent">Spent</option>
76
- </select>
152
+ Bridge deposit tx
153
+ <input name="bridgeDepositTx" autocomplete="off" placeholder="0x...">
77
154
  </label>
78
155
  <label>
79
- Direction
80
- <select name="direction">
81
- <option value="">Any</option>
82
- <option value="self-mint">Self mint</option>
83
- <option value="sent">Sent</option>
84
- <option value="received">Received</option>
85
- <option value="unknown">Unknown</option>
86
- </select>
156
+ Withdraw or claim tx
157
+ <input name="withdrawTx" autocomplete="off" placeholder="0x...">
87
158
  </label>
88
159
  </div>
89
- <label>
90
- Counterparty L2 address
91
- <input name="counterparty" autocomplete="off" placeholder="0x...">
92
- </label>
93
- <button id="applyFilters" type="button">Apply filters</button>
94
- </form>
95
-
96
- <form id="packageForm" class="panel">
97
- <h2>Package Metadata</h2>
98
- <label>
99
- Case ID
100
- <input name="caseId" autocomplete="off" placeholder="exchange-case-001">
101
- </label>
102
- <label>
103
- Requesting party
104
- <input name="requestingParty" autocomplete="off" placeholder="Exchange or investigator name">
105
- </label>
106
- <label>
107
- Bridge deposit tx
108
- <input name="bridgeDepositTx" autocomplete="off" placeholder="0x...">
109
- </label>
110
- <label>
111
- Withdraw or claim tx
112
- <input name="withdrawTx" autocomplete="off" placeholder="0x...">
113
- </label>
114
160
  <fieldset>
115
161
  <legend>Disclosure intents</legend>
116
162
  <label><input name="intent" type="checkbox" value="note-receipt" checked> Note receipt</label>
@@ -122,37 +168,54 @@
122
168
  </fieldset>
123
169
  <label>
124
170
  User statement
125
- <textarea name="statement" rows="5" placeholder="Optional explanation included in the disclosure package."></textarea>
171
+ <textarea name="statement" rows="4" placeholder="Optional explanation included in the disclosure package."></textarea>
126
172
  </label>
127
- <button id="buildPackage" type="button" disabled>Build disclosure ZIP</button>
128
173
  </form>
129
174
  </section>
130
175
 
131
176
  <section class="panel">
132
- <div class="table-header">
133
- <h2>Matched Notes</h2>
177
+ <div class="result-header">
178
+ <div>
179
+ <h2>Results</h2>
180
+ <div id="status" class="status">Load a raw evidence ZIP to begin.</div>
181
+ </div>
134
182
  <div class="actions">
183
+ <button id="exportAscii" type="button" disabled>Export ASCII-art</button>
135
184
  <button id="selectAll" type="button" disabled>Select all</button>
136
185
  <button id="selectNone" type="button" disabled>Select none</button>
137
186
  </div>
138
187
  </div>
139
- <div id="status" class="status">Load a raw evidence ZIP to begin.</div>
140
- <div class="table-wrap">
141
- <table>
142
- <thead>
143
- <tr>
144
- <th>Use</th>
145
- <th>Commitment</th>
146
- <th>Value</th>
147
- <th>Status</th>
148
- <th>Created</th>
149
- <th>Spent</th>
150
- <th>Direction</th>
151
- <th>Counterparty</th>
152
- </tr>
153
- </thead>
154
- <tbody id="noteRows"></tbody>
155
- </table>
188
+
189
+ <div class="tabs" role="tablist" aria-label="Result views">
190
+ <button id="graphTab" class="tab is-active" type="button" data-result-tab="graph">Graph</button>
191
+ <button id="notesTab" class="tab" type="button" data-result-tab="notes">Notes</button>
192
+ </div>
193
+
194
+ <div id="graphPanel" class="result-panel is-active">
195
+ <div id="graphViewport" class="graph-viewport">
196
+ <svg id="graphSvg" class="graph-svg" role="img" aria-label="Note linkage graph"></svg>
197
+ <div id="nodeDetail" class="node-detail is-hidden"></div>
198
+ </div>
199
+ </div>
200
+
201
+ <div id="notesPanel" class="result-panel">
202
+ <div class="table-wrap">
203
+ <table>
204
+ <thead>
205
+ <tr>
206
+ <th>Use</th>
207
+ <th>Commitment</th>
208
+ <th>Value</th>
209
+ <th>Status</th>
210
+ <th>Created</th>
211
+ <th>Spent</th>
212
+ <th>Direction</th>
213
+ <th>Counterparty</th>
214
+ </tr>
215
+ </thead>
216
+ <tbody id="noteRows"></tbody>
217
+ </table>
218
+ </div>
156
219
  </div>
157
220
  </section>
158
221
  </main>
@@ -1,14 +1,19 @@
1
1
  :root {
2
2
  color-scheme: light;
3
- --bg: #f6f7f9;
3
+ --bg: #f4f6f8;
4
4
  --panel: #ffffff;
5
- --text: #18202a;
6
- --muted: #647183;
7
- --line: #d7dde6;
8
- --accent: #0d6efd;
9
- --accent-dark: #084fb2;
10
- --warn-bg: #fff6dc;
11
- --warn-line: #ebc35a;
5
+ --text: #17202a;
6
+ --muted: #647184;
7
+ --line: #d5dce6;
8
+ --soft-line: #e7ebf0;
9
+ --accent: #0b6f8f;
10
+ --accent-dark: #084f66;
11
+ --accent-soft: #e5f4f8;
12
+ --green: #2f855a;
13
+ --orange: #b26a00;
14
+ --warn-bg: #fff7dd;
15
+ --warn-line: #dfbd52;
16
+ --shadow: 0 12px 28px rgba(23, 32, 42, 0.12);
12
17
  font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
13
18
  }
14
19
 
@@ -23,21 +28,33 @@ body {
23
28
  }
24
29
 
25
30
  .app {
26
- max-width: 1240px;
31
+ max-width: 1360px;
27
32
  margin: 0 auto;
28
33
  padding: 24px;
29
34
  }
30
35
 
31
- .toolbar {
36
+ .toolbar,
37
+ .result-header,
38
+ .panel-head,
39
+ .actions {
32
40
  display: flex;
33
41
  align-items: center;
42
+ gap: 14px;
43
+ }
44
+
45
+ .toolbar,
46
+ .result-header,
47
+ .panel-head {
34
48
  justify-content: space-between;
35
- gap: 24px;
49
+ }
50
+
51
+ .toolbar {
36
52
  margin-bottom: 16px;
37
53
  }
38
54
 
39
55
  h1,
40
- h2 {
56
+ h2,
57
+ h3 {
41
58
  margin: 0;
42
59
  letter-spacing: 0;
43
60
  }
@@ -52,6 +69,14 @@ h2 {
52
69
  line-height: 1.3;
53
70
  }
54
71
 
72
+ h3 {
73
+ color: var(--muted);
74
+ font-size: 13px;
75
+ font-weight: 700;
76
+ line-height: 1.3;
77
+ text-transform: uppercase;
78
+ }
79
+
55
80
  p {
56
81
  margin: 8px 0 0;
57
82
  color: var(--muted);
@@ -65,7 +90,7 @@ button {
65
90
  border-radius: 6px;
66
91
  padding: 10px 14px;
67
92
  font-size: 14px;
68
- font-weight: 600;
93
+ font-weight: 700;
69
94
  cursor: pointer;
70
95
  white-space: nowrap;
71
96
  }
@@ -85,18 +110,51 @@ button:hover:not(:disabled),
85
110
  background: var(--accent-dark);
86
111
  }
87
112
 
113
+ button.secondary {
114
+ border-color: var(--line);
115
+ background: #fff;
116
+ color: var(--text);
117
+ }
118
+
88
119
  .warning {
89
120
  border: 1px solid var(--warn-line);
90
121
  background: var(--warn-bg);
91
122
  border-radius: 8px;
92
123
  padding: 14px 16px;
93
- margin-bottom: 18px;
124
+ margin-bottom: 16px;
94
125
  line-height: 1.5;
95
126
  }
96
127
 
97
- .grid {
128
+ .summary-grid {
129
+ display: grid;
130
+ grid-template-columns: repeat(5, minmax(0, 1fr));
131
+ gap: 10px;
132
+ margin-bottom: 16px;
133
+ }
134
+
135
+ .summary-card {
136
+ border: 1px solid var(--line);
137
+ background: var(--panel);
138
+ border-radius: 8px;
139
+ padding: 12px;
140
+ min-width: 0;
141
+ }
142
+
143
+ .summary-card span {
144
+ display: block;
145
+ color: var(--muted);
146
+ font-size: 12px;
147
+ }
148
+
149
+ .summary-card strong {
150
+ display: block;
151
+ margin-top: 4px;
152
+ overflow-wrap: anywhere;
153
+ }
154
+
155
+ .workspace {
98
156
  display: grid;
99
- grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
157
+ grid-template-columns: minmax(320px, 0.8fr) minmax(420px, 1.2fr);
100
158
  gap: 16px;
101
159
  margin-bottom: 16px;
102
160
  }
@@ -108,7 +166,9 @@ button:hover:not(:disabled),
108
166
  padding: 16px;
109
167
  }
110
168
 
111
- form {
169
+ form,
170
+ .form-section,
171
+ .package-panel {
112
172
  display: grid;
113
173
  gap: 12px;
114
174
  }
@@ -170,30 +230,210 @@ legend {
170
230
  gap: 10px;
171
231
  }
172
232
 
173
- .table-header {
233
+ .purpose-grid {
234
+ display: grid;
235
+ grid-template-columns: repeat(2, minmax(0, 1fr));
236
+ gap: 8px;
237
+ }
238
+
239
+ .purpose-card {
174
240
  display: flex;
175
- justify-content: space-between;
176
241
  align-items: center;
177
- gap: 16px;
242
+ gap: 8px;
243
+ min-height: 42px;
244
+ border: 1px solid var(--line);
245
+ border-radius: 8px;
246
+ padding: 9px 10px;
247
+ color: var(--text);
248
+ cursor: pointer;
249
+ }
250
+
251
+ .purpose-card:has(input:checked) {
252
+ border-color: var(--accent);
253
+ background: var(--accent-soft);
254
+ }
255
+
256
+ .purpose-card input {
257
+ width: auto;
258
+ }
259
+
260
+ .advanced-filters {
261
+ border-top: 1px solid var(--soft-line);
262
+ padding-top: 10px;
263
+ }
264
+
265
+ .advanced-filters summary {
266
+ color: var(--muted);
267
+ cursor: pointer;
268
+ font-weight: 700;
269
+ }
270
+
271
+ .advanced-filters[open] summary {
178
272
  margin-bottom: 10px;
179
273
  }
180
274
 
181
- .actions {
275
+ .status {
276
+ min-height: 22px;
277
+ margin-top: 4px;
278
+ color: var(--muted);
279
+ font-size: 14px;
280
+ }
281
+
282
+ .tabs {
182
283
  display: flex;
183
284
  gap: 8px;
285
+ border-bottom: 1px solid var(--line);
286
+ margin-top: 12px;
184
287
  }
185
288
 
186
- .status {
187
- min-height: 22px;
188
- margin-bottom: 10px;
289
+ .tab {
290
+ border: 0;
291
+ border-bottom: 3px solid transparent;
292
+ background: transparent;
189
293
  color: var(--muted);
294
+ border-radius: 0;
295
+ padding: 10px 4px 9px;
296
+ }
297
+
298
+ .tab:hover,
299
+ .tab.is-active {
300
+ background: transparent;
301
+ color: var(--text);
302
+ border-bottom-color: var(--accent);
303
+ }
304
+
305
+ .result-panel {
306
+ display: none;
307
+ }
308
+
309
+ .result-panel.is-active {
310
+ display: block;
311
+ }
312
+
313
+ .graph-viewport {
314
+ position: relative;
315
+ min-height: 520px;
316
+ margin-top: 14px;
317
+ border: 1px solid var(--line);
318
+ border-radius: 8px;
319
+ overflow: auto;
320
+ background:
321
+ linear-gradient(#eef2f6 1px, transparent 1px),
322
+ linear-gradient(90deg, #eef2f6 1px, transparent 1px),
323
+ #fbfcfe;
324
+ background-size: 28px 28px;
325
+ }
326
+
327
+ .graph-svg {
328
+ display: block;
329
+ min-width: 100%;
330
+ min-height: 520px;
331
+ }
332
+
333
+ .graph-edge {
334
+ fill: none;
335
+ stroke: #7c8794;
336
+ stroke-width: 1.8;
337
+ }
338
+
339
+ .graph-edge.local {
340
+ stroke: var(--accent);
341
+ stroke-width: 2.2;
342
+ }
343
+
344
+ .graph-edge.external-in {
345
+ stroke: var(--green);
346
+ }
347
+
348
+ .graph-edge.external-out {
349
+ stroke: var(--orange);
350
+ }
351
+
352
+ .edge-arrow {
353
+ fill: currentColor;
354
+ color: #7c8794;
355
+ }
356
+
357
+ .edge-label,
358
+ .graph-empty {
359
+ fill: var(--muted);
360
+ font-size: 12px;
361
+ }
362
+
363
+ .graph-node {
364
+ cursor: pointer;
365
+ outline: none;
366
+ }
367
+
368
+ .graph-node rect {
369
+ fill: #fff;
370
+ stroke: var(--line);
371
+ stroke-width: 1.5;
372
+ }
373
+
374
+ .graph-node:hover rect,
375
+ .graph-node:focus rect {
376
+ stroke: var(--accent);
377
+ }
378
+
379
+ .graph-node.is-selected rect {
380
+ fill: var(--accent-soft);
381
+ stroke: var(--accent);
382
+ }
383
+
384
+ .node-label {
385
+ fill: var(--text);
190
386
  font-size: 14px;
387
+ font-weight: 800;
388
+ }
389
+
390
+ .node-value {
391
+ fill: var(--muted);
392
+ font-size: 12px;
393
+ }
394
+
395
+ .node-detail {
396
+ position: absolute;
397
+ z-index: 3;
398
+ width: min(360px, calc(100% - 32px));
399
+ border: 1px solid var(--line);
400
+ border-radius: 8px;
401
+ background: #fff;
402
+ box-shadow: var(--shadow);
403
+ padding: 12px;
404
+ }
405
+
406
+ .node-detail.is-hidden {
407
+ display: none;
408
+ }
409
+
410
+ .detail-title {
411
+ margin-bottom: 8px;
412
+ font-weight: 800;
413
+ }
414
+
415
+ .detail-rows {
416
+ display: grid;
417
+ grid-template-columns: 86px minmax(0, 1fr);
418
+ gap: 6px 10px;
419
+ margin: 0 0 12px;
420
+ font-size: 12px;
421
+ }
422
+
423
+ .detail-rows dt {
424
+ color: var(--muted);
425
+ }
426
+
427
+ .detail-rows dd {
428
+ margin: 0;
429
+ overflow-wrap: anywhere;
191
430
  }
192
431
 
193
432
  .table-wrap {
194
433
  overflow: auto;
195
434
  border: 1px solid var(--line);
196
435
  border-radius: 8px;
436
+ margin-top: 14px;
197
437
  }
198
438
 
199
439
  table {
@@ -231,19 +471,28 @@ tr:last-child td {
231
471
  color: var(--muted);
232
472
  }
233
473
 
234
- @media (max-width: 900px) {
474
+ @media (max-width: 980px) {
235
475
  .app {
236
476
  padding: 16px;
237
477
  }
238
478
 
239
479
  .toolbar,
240
- .grid {
241
- grid-template-columns: 1fr;
480
+ .result-header,
481
+ .panel-head,
482
+ .workspace {
242
483
  display: grid;
484
+ grid-template-columns: 1fr;
243
485
  }
244
486
 
487
+ .summary-grid,
488
+ .workspace,
245
489
  fieldset,
246
- .two-col {
490
+ .two-col,
491
+ .purpose-grid {
247
492
  grid-template-columns: 1fr;
248
493
  }
494
+
495
+ .actions {
496
+ flex-wrap: wrap;
497
+ }
249
498
  }