@umbra-privacy/ceremony 0.1.4 → 0.2.5
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/dist/index.js +264 -156
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -5,7 +5,7 @@ import { render } from "ink";
|
|
|
5
5
|
|
|
6
6
|
// src/components/App.tsx
|
|
7
7
|
import { useEffect as useEffect4, useState as useState4 } from "react";
|
|
8
|
-
import { Box as
|
|
8
|
+
import { Box as Box7, Text as Text7, useApp, useInput as useInput2 } from "ink";
|
|
9
9
|
|
|
10
10
|
// src/cleanup.ts
|
|
11
11
|
var pendingLeaveQueue = null;
|
|
@@ -90,26 +90,20 @@ var api = {
|
|
|
90
90
|
},
|
|
91
91
|
// Slot polling
|
|
92
92
|
myTurn(ceremonyId2, trackId, token) {
|
|
93
|
-
return request(
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
);
|
|
93
|
+
return request(`/api/ceremonies/${ceremonyId2}/tracks/${trackId}/my-turn`, {
|
|
94
|
+
headers: bearer(token)
|
|
95
|
+
});
|
|
97
96
|
},
|
|
98
97
|
// Contribution
|
|
99
98
|
signalUploaded(ceremonyId2, trackId, contributionId, token) {
|
|
100
|
-
return request(
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
body: JSON.stringify({ contribution_id: contributionId })
|
|
106
|
-
}
|
|
107
|
-
);
|
|
99
|
+
return request(`/api/ceremonies/${ceremonyId2}/tracks/${trackId}/signal-uploaded`, {
|
|
100
|
+
method: "POST",
|
|
101
|
+
headers: bearer(token),
|
|
102
|
+
body: JSON.stringify({ contribution_id: contributionId })
|
|
103
|
+
});
|
|
108
104
|
},
|
|
109
105
|
getReceipt(ceremonyId2, contributionId) {
|
|
110
|
-
return request(
|
|
111
|
-
`/api/ceremonies/${ceremonyId2}/contributions/${contributionId}/receipt`
|
|
112
|
-
);
|
|
106
|
+
return request(`/api/ceremonies/${ceremonyId2}/contributions/${contributionId}/receipt`);
|
|
113
107
|
},
|
|
114
108
|
// Admin — signed-request flow. Caller supplies the 64-byte Solana keypair
|
|
115
109
|
// bytes (32 secret + 32 public). The helper fetches a one-time challenge,
|
|
@@ -252,6 +246,38 @@ async function recordContribution(trackId, contribution) {
|
|
|
252
246
|
|
|
253
247
|
// src/components/Header.tsx
|
|
254
248
|
import { Box, Text } from "ink";
|
|
249
|
+
|
|
250
|
+
// src/labels.ts
|
|
251
|
+
function ceremonyStatusLabel(status) {
|
|
252
|
+
switch (status) {
|
|
253
|
+
case "open":
|
|
254
|
+
return "open";
|
|
255
|
+
case "initialized":
|
|
256
|
+
return "not yet open";
|
|
257
|
+
case "finalizing":
|
|
258
|
+
return "closing";
|
|
259
|
+
case "completed":
|
|
260
|
+
return "complete";
|
|
261
|
+
default:
|
|
262
|
+
return status;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
function trackStatusLabel(status) {
|
|
266
|
+
switch (status) {
|
|
267
|
+
case "open":
|
|
268
|
+
return "open";
|
|
269
|
+
case "initializing":
|
|
270
|
+
return "preparing";
|
|
271
|
+
case "awaiting_beacon":
|
|
272
|
+
return "awaiting beacon";
|
|
273
|
+
case "finalized":
|
|
274
|
+
return "complete";
|
|
275
|
+
default:
|
|
276
|
+
return status;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
// src/components/Header.tsx
|
|
255
281
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
256
282
|
var STATUS_COLOR = {
|
|
257
283
|
open: "green",
|
|
@@ -262,15 +288,18 @@ var STATUS_COLOR = {
|
|
|
262
288
|
function Header({ ceremony, subtitle }) {
|
|
263
289
|
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [
|
|
264
290
|
/* @__PURE__ */ jsxs(Box, { children: [
|
|
265
|
-
/* @__PURE__ */ jsx(Text, { bold: true, color: "cyan", children: "\u25C6
|
|
291
|
+
/* @__PURE__ */ jsx(Text, { bold: true, color: "cyan", children: "\u25C6 Umbra Ceremony TUI" }),
|
|
266
292
|
ceremony && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
267
|
-
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "
|
|
293
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: " \xB7 " }),
|
|
268
294
|
/* @__PURE__ */ jsx(Text, { bold: true, children: ceremony.name }),
|
|
269
|
-
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "
|
|
270
|
-
/* @__PURE__ */ jsx(Text, { color: STATUS_COLOR[ceremony.status] ?? "white", children: ceremony.status }),
|
|
295
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: " [" }),
|
|
296
|
+
/* @__PURE__ */ jsx(Text, { color: STATUS_COLOR[ceremony.status] ?? "white", children: ceremonyStatusLabel(ceremony.status) }),
|
|
271
297
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "]" })
|
|
272
298
|
] })
|
|
273
299
|
] }),
|
|
300
|
+
/* @__PURE__ */ jsx(Text, { color: "cyan", children: "Phase 2 trusted-setup contribution \xB7 Groth16 / BN254" }),
|
|
301
|
+
/* @__PURE__ */ jsx(Text, { color: "gray", children: "You are adding fresh entropy to Umbra's circuit proving keys. The on-chain privacy of every deposit, claim and transfer holds as long as ONE contributor in this ceremony destroys their secret." }),
|
|
302
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "Press ? at any time for a full explanation of what is happening." }),
|
|
274
303
|
ceremony && /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
275
304
|
ceremony.total_tracks,
|
|
276
305
|
" circuit",
|
|
@@ -339,7 +368,10 @@ function QueueView({ ceremonyId: ceremonyId2, trackId, token, onReady, onError }
|
|
|
339
368
|
] });
|
|
340
369
|
}
|
|
341
370
|
const waitMins = Math.ceil((status.estimated_wait_secs ?? 0) / 60);
|
|
342
|
-
const expiresAt = status.slot_expires_at ? new Date(status.slot_expires_at).toLocaleTimeString([], {
|
|
371
|
+
const expiresAt = status.slot_expires_at ? new Date(status.slot_expires_at).toLocaleTimeString([], {
|
|
372
|
+
hour: "2-digit",
|
|
373
|
+
minute: "2-digit"
|
|
374
|
+
}) : null;
|
|
343
375
|
const fastPoll = status.queue_position <= 2;
|
|
344
376
|
return /* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", gap: 1, children: [
|
|
345
377
|
/* @__PURE__ */ jsxs2(Box2, { gap: 2, children: [
|
|
@@ -369,11 +401,7 @@ function QueueView({ ceremonyId: ceremonyId2, trackId, token, onReady, onError }
|
|
|
369
401
|
] }) }) : status.queue_position > 1 ? (
|
|
370
402
|
// Slot is idle but people are ahead — they joined and left without releasing.
|
|
371
403
|
// timeout_watchdog will clear each stale slot after contribution_timeout_secs.
|
|
372
|
-
/* @__PURE__ */
|
|
373
|
-
"Slot is idle \u2014 waiting for positions ahead to respond or time out",
|
|
374
|
-
" ",
|
|
375
|
-
"(up to ~5 min each)"
|
|
376
|
-
] })
|
|
404
|
+
/* @__PURE__ */ jsx2(Text2, { dimColor: true, children: "Slot is idle \u2014 waiting for positions ahead to respond or time out (up to ~5 min each)" })
|
|
377
405
|
) : (
|
|
378
406
|
// Position 1, slot idle — advance_queue should fire shortly.
|
|
379
407
|
/* @__PURE__ */ jsx2(Text2, { dimColor: true, children: "Slot is idle \u2014 your turn is being prepared..." })
|
|
@@ -457,7 +485,7 @@ function EntropyCollector({ onComplete, onError }) {
|
|
|
457
485
|
/* @__PURE__ */ jsx3(Text3, { bold: true, children: "Type anything to generate entropy:" }),
|
|
458
486
|
/* @__PURE__ */ jsx3(Text3, { dimColor: true, children: "Keystroke timing (nanosecond intervals) is the randomness source." }),
|
|
459
487
|
/* @__PURE__ */ jsxs3(Box3, { marginTop: 1, children: [
|
|
460
|
-
/* @__PURE__ */ jsx3(Text3, { dimColor: true, children: "
|
|
488
|
+
/* @__PURE__ */ jsx3(Text3, { dimColor: true, children: " > " }),
|
|
461
489
|
/* @__PURE__ */ jsx3(Text3, { color: "green", children: stars }),
|
|
462
490
|
/* @__PURE__ */ jsx3(Text3, { color: "yellow", children: "\u2588" })
|
|
463
491
|
] }),
|
|
@@ -472,7 +500,7 @@ function EntropyCollector({ onComplete, onError }) {
|
|
|
472
500
|
/* @__PURE__ */ jsxs3(Text3, { dimColor: true, children: [
|
|
473
501
|
"/",
|
|
474
502
|
TARGET,
|
|
475
|
-
" keystrokes
|
|
503
|
+
" keystrokes (",
|
|
476
504
|
pct,
|
|
477
505
|
"%)"
|
|
478
506
|
] })
|
|
@@ -569,9 +597,11 @@ function ContributeFlow(props) {
|
|
|
569
597
|
await api.signalUploaded(ceremonyId2, trackId, slotStatus.contribution_id, token);
|
|
570
598
|
if (cancelled) return;
|
|
571
599
|
setStep({ name: "verifying", attempt: 1 });
|
|
600
|
+
const TOTAL_POLLS = 80;
|
|
601
|
+
const FAST_POLLS = 20;
|
|
572
602
|
let receipt = null;
|
|
573
603
|
let lastErr = null;
|
|
574
|
-
for (let i = 0; i <
|
|
604
|
+
for (let i = 0; i < TOTAL_POLLS; i++) {
|
|
575
605
|
if (cancelled) return;
|
|
576
606
|
setStep({ name: "verifying", attempt: i + 1 });
|
|
577
607
|
try {
|
|
@@ -580,7 +610,8 @@ function ContributeFlow(props) {
|
|
|
580
610
|
break;
|
|
581
611
|
} catch (err) {
|
|
582
612
|
lastErr = err instanceof Error ? err : new Error(String(err));
|
|
583
|
-
|
|
613
|
+
const delay = i < FAST_POLLS ? 3e3 : 1e4;
|
|
614
|
+
await new Promise((r) => setTimeout(r, delay));
|
|
584
615
|
}
|
|
585
616
|
}
|
|
586
617
|
if (cancelled) return;
|
|
@@ -615,7 +646,8 @@ function ContributeFlow(props) {
|
|
|
615
646
|
const filled = Math.round(pct / 5);
|
|
616
647
|
const bar = "\u2588".repeat(filled) + "\u2591".repeat(20 - filled);
|
|
617
648
|
detail = /* @__PURE__ */ jsxs4(Text4, { dimColor: true, children: [
|
|
618
|
-
"
|
|
649
|
+
" ",
|
|
650
|
+
"[",
|
|
619
651
|
bar,
|
|
620
652
|
"] ",
|
|
621
653
|
pct,
|
|
@@ -623,10 +655,15 @@ function ContributeFlow(props) {
|
|
|
623
655
|
] });
|
|
624
656
|
}
|
|
625
657
|
if (isActive && step.name === "verifying") {
|
|
658
|
+
const elapsed = step.attempt <= 20 ? step.attempt * 3 : 20 * 3 + (step.attempt - 20) * 10;
|
|
659
|
+
const mins = Math.floor(elapsed / 60);
|
|
660
|
+
const secs = elapsed % 60;
|
|
661
|
+
const time = mins > 0 ? `${mins}m ${secs.toString().padStart(2, "0")}s` : `${secs}s`;
|
|
626
662
|
detail = /* @__PURE__ */ jsxs4(Text4, { dimColor: true, children: [
|
|
627
|
-
"
|
|
628
|
-
|
|
629
|
-
|
|
663
|
+
" ",
|
|
664
|
+
"worker verifying \u2014 large circuits can take a few minutes (",
|
|
665
|
+
time,
|
|
666
|
+
" elapsed)"
|
|
630
667
|
] });
|
|
631
668
|
}
|
|
632
669
|
return /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", children: [
|
|
@@ -659,25 +696,25 @@ function Attestation({ contribution }) {
|
|
|
659
696
|
const hashShort = contribution.contributionHash ? `${contribution.contributionHash.slice(0, 16)}...${contribution.contributionHash.slice(-8)}` : "(pending verification)";
|
|
660
697
|
const verifiedAt = contribution.verifiedAt ? new Date(contribution.verifiedAt).toLocaleString() : null;
|
|
661
698
|
return /* @__PURE__ */ jsxs5(Box5, { flexDirection: "column", gap: 1, children: [
|
|
662
|
-
/* @__PURE__ */ jsx5(Text5, { bold: true, color: "green", children: "\u2713
|
|
699
|
+
/* @__PURE__ */ jsx5(Text5, { bold: true, color: "green", children: "\u2713 Contribution verified!" }),
|
|
663
700
|
/* @__PURE__ */ jsxs5(Box5, { flexDirection: "column", gap: 0, children: [
|
|
664
701
|
/* @__PURE__ */ jsxs5(Box5, { gap: 2, children: [
|
|
665
702
|
/* @__PURE__ */ jsx5(Text5, { dimColor: true, children: "Circuit" }),
|
|
666
703
|
/* @__PURE__ */ jsx5(Text5, { bold: true, children: contribution.circuitName })
|
|
667
704
|
] }),
|
|
668
705
|
/* @__PURE__ */ jsxs5(Box5, { gap: 2, children: [
|
|
669
|
-
/* @__PURE__ */ jsx5(Text5, { dimColor: true, children: "Round
|
|
706
|
+
/* @__PURE__ */ jsx5(Text5, { dimColor: true, children: "Round " }),
|
|
670
707
|
/* @__PURE__ */ jsxs5(Text5, { bold: true, children: [
|
|
671
708
|
"#",
|
|
672
709
|
contribution.sequenceNumber
|
|
673
710
|
] })
|
|
674
711
|
] }),
|
|
675
712
|
/* @__PURE__ */ jsxs5(Box5, { gap: 2, children: [
|
|
676
|
-
/* @__PURE__ */ jsx5(Text5, { dimColor: true, children: "Hash
|
|
713
|
+
/* @__PURE__ */ jsx5(Text5, { dimColor: true, children: "Hash " }),
|
|
677
714
|
/* @__PURE__ */ jsx5(Text5, { color: "cyan", children: hashShort })
|
|
678
715
|
] }),
|
|
679
716
|
verifiedAt && /* @__PURE__ */ jsxs5(Box5, { gap: 2, children: [
|
|
680
|
-
/* @__PURE__ */ jsx5(Text5, { dimColor: true, children: "Time
|
|
717
|
+
/* @__PURE__ */ jsx5(Text5, { dimColor: true, children: "Time " }),
|
|
681
718
|
/* @__PURE__ */ jsx5(Text5, { dimColor: true, children: verifiedAt })
|
|
682
719
|
] })
|
|
683
720
|
] }),
|
|
@@ -688,8 +725,32 @@ function Attestation({ contribution }) {
|
|
|
688
725
|
] });
|
|
689
726
|
}
|
|
690
727
|
|
|
691
|
-
// src/components/
|
|
728
|
+
// src/components/InfoModal.tsx
|
|
729
|
+
import { Box as Box6, Text as Text6 } from "ink";
|
|
692
730
|
import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
731
|
+
function InfoModal() {
|
|
732
|
+
return /* @__PURE__ */ jsx6(Box6, { flexDirection: "column", paddingX: 2, paddingY: 1, children: /* @__PURE__ */ jsxs6(
|
|
733
|
+
Box6,
|
|
734
|
+
{
|
|
735
|
+
flexDirection: "column",
|
|
736
|
+
borderStyle: "round",
|
|
737
|
+
borderColor: "cyan",
|
|
738
|
+
paddingX: 2,
|
|
739
|
+
paddingY: 1,
|
|
740
|
+
width: 84,
|
|
741
|
+
gap: 1,
|
|
742
|
+
children: [
|
|
743
|
+
/* @__PURE__ */ jsx6(Text6, { bold: true, color: "cyan", children: "Umbra Phase 2 Trusted-Setup Ceremony" }),
|
|
744
|
+
/* @__PURE__ */ jsx6(Text6, { children: "Umbra uses Groth16 zero-knowledge proofs to give Solana users on-chain privacy. Every circuit needs a one-time multi-party ceremony to generate its proving key safely \u2014 that is Phase 2. Each contributor adds their own secret entropy and destroys it afterward. The setup stays secure as long as AT LEAST ONE contributor erased theirs, which is why your single contribution genuinely matters." }),
|
|
745
|
+
/* @__PURE__ */ jsx6(Text6, { children: "What you will do: tap 20 keys to seed your entropy, download the latest challenge file, run snarkjs locally to combine your secret with the parameters, and upload the response. Your secret never leaves your machine. Erase it when you are done." }),
|
|
746
|
+
/* @__PURE__ */ jsx6(Text6, { dimColor: true, children: "Press B, Esc or ? to close" })
|
|
747
|
+
]
|
|
748
|
+
}
|
|
749
|
+
) });
|
|
750
|
+
}
|
|
751
|
+
|
|
752
|
+
// src/components/App.tsx
|
|
753
|
+
import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
693
754
|
var NAME_MAX_LEN = 100;
|
|
694
755
|
var NAME_VALID_RE = /^[\p{L}\p{N} _.\-]*$/u;
|
|
695
756
|
function App({ ceremonyId: initialCeremonyId, displayName: initialDisplayName }) {
|
|
@@ -705,6 +766,7 @@ function App({ ceremonyId: initialCeremonyId, displayName: initialDisplayName })
|
|
|
705
766
|
const [contributed, setContributed] = useState4({});
|
|
706
767
|
const [selectedIdx, setSelectedIdx] = useState4(0);
|
|
707
768
|
const [tab, setTab] = useState4(0);
|
|
769
|
+
const [showInfo, setShowInfo] = useState4(false);
|
|
708
770
|
useEffect4(() => {
|
|
709
771
|
if (!nameSet) return;
|
|
710
772
|
if (!initialCeremonyId) {
|
|
@@ -719,7 +781,11 @@ function App({ ceremonyId: initialCeremonyId, displayName: initialDisplayName })
|
|
|
719
781
|
setScreen({ name: "ceremony-picker", ceremonies, loading: false });
|
|
720
782
|
setSelectedIdx(0);
|
|
721
783
|
} catch (e) {
|
|
722
|
-
setScreen({
|
|
784
|
+
setScreen({
|
|
785
|
+
name: "error",
|
|
786
|
+
message: e.message ?? "Failed to load ceremonies.",
|
|
787
|
+
recoverable: false
|
|
788
|
+
});
|
|
723
789
|
}
|
|
724
790
|
}
|
|
725
791
|
async function boot(cId) {
|
|
@@ -741,7 +807,11 @@ function App({ ceremonyId: initialCeremonyId, displayName: initialDisplayName })
|
|
|
741
807
|
try {
|
|
742
808
|
const { tracks } = await api.listTracks(cId, s.session_token);
|
|
743
809
|
if (tracks.length === 0) {
|
|
744
|
-
setScreen({
|
|
810
|
+
setScreen({
|
|
811
|
+
name: "error",
|
|
812
|
+
message: "No tracks found in this ceremony.",
|
|
813
|
+
recoverable: false
|
|
814
|
+
});
|
|
745
815
|
return;
|
|
746
816
|
}
|
|
747
817
|
setSelectedIdx(0);
|
|
@@ -754,17 +824,29 @@ function App({ ceremonyId: initialCeremonyId, displayName: initialDisplayName })
|
|
|
754
824
|
setSession(fresh);
|
|
755
825
|
const { tracks } = await api.listTracks(cId, fresh.session_token);
|
|
756
826
|
if (tracks.length === 0) {
|
|
757
|
-
setScreen({
|
|
827
|
+
setScreen({
|
|
828
|
+
name: "error",
|
|
829
|
+
message: "No tracks found in this ceremony.",
|
|
830
|
+
recoverable: false
|
|
831
|
+
});
|
|
758
832
|
return;
|
|
759
833
|
}
|
|
760
834
|
setSelectedIdx(0);
|
|
761
835
|
setScreen({ name: "tracks", tracks });
|
|
762
836
|
} catch (e2) {
|
|
763
|
-
setScreen({
|
|
837
|
+
setScreen({
|
|
838
|
+
name: "error",
|
|
839
|
+
message: e2.message ?? "Failed to load tracks.",
|
|
840
|
+
recoverable: false
|
|
841
|
+
});
|
|
764
842
|
}
|
|
765
843
|
return;
|
|
766
844
|
}
|
|
767
|
-
setScreen({
|
|
845
|
+
setScreen({
|
|
846
|
+
name: "error",
|
|
847
|
+
message: e.message ?? "Failed to load tracks.",
|
|
848
|
+
recoverable: false
|
|
849
|
+
});
|
|
768
850
|
}
|
|
769
851
|
}
|
|
770
852
|
function commitName(raw) {
|
|
@@ -777,10 +859,9 @@ function App({ ceremonyId: initialCeremonyId, displayName: initialDisplayName })
|
|
|
777
859
|
);
|
|
778
860
|
}
|
|
779
861
|
function randomAnonName() {
|
|
780
|
-
const hex = Array.from(
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
).join("");
|
|
862
|
+
const hex = Array.from({ length: 6 }, () => Math.floor(Math.random() * 16).toString(16)).join(
|
|
863
|
+
""
|
|
864
|
+
);
|
|
784
865
|
return `anon-${hex}`;
|
|
785
866
|
}
|
|
786
867
|
async function joinTrack(track) {
|
|
@@ -790,7 +871,11 @@ function App({ ceremonyId: initialCeremonyId, displayName: initialDisplayName })
|
|
|
790
871
|
await api.joinQueue(activeCeremonyId, track.id, session.session_token);
|
|
791
872
|
} catch (e) {
|
|
792
873
|
if (e.code !== "ALREADY_IN_QUEUE") {
|
|
793
|
-
setScreen({
|
|
874
|
+
setScreen({
|
|
875
|
+
name: "error",
|
|
876
|
+
message: e.message ?? "Failed to join queue.",
|
|
877
|
+
recoverable: true
|
|
878
|
+
});
|
|
794
879
|
return;
|
|
795
880
|
}
|
|
796
881
|
}
|
|
@@ -818,13 +903,28 @@ function App({ ceremonyId: initialCeremonyId, displayName: initialDisplayName })
|
|
|
818
903
|
}, [screen.name]);
|
|
819
904
|
useInput2((input, key) => {
|
|
820
905
|
const q = input.toLowerCase();
|
|
906
|
+
if (showInfo) {
|
|
907
|
+
if (key.escape || input === "?" || q === "b") {
|
|
908
|
+
setShowInfo(false);
|
|
909
|
+
return;
|
|
910
|
+
}
|
|
911
|
+
if (q === "q") {
|
|
912
|
+
exit();
|
|
913
|
+
return;
|
|
914
|
+
}
|
|
915
|
+
return;
|
|
916
|
+
}
|
|
917
|
+
if (input === "?" && screen.name !== "entropy") {
|
|
918
|
+
setShowInfo(true);
|
|
919
|
+
return;
|
|
920
|
+
}
|
|
821
921
|
if (screen.name === "name-input") {
|
|
822
922
|
if (key.escape) {
|
|
823
923
|
exit();
|
|
824
924
|
return;
|
|
825
925
|
}
|
|
826
926
|
if (key.tab) {
|
|
827
|
-
|
|
927
|
+
setScreen({ name: "name-input", value: randomAnonName() });
|
|
828
928
|
return;
|
|
829
929
|
}
|
|
830
930
|
if (key.return) {
|
|
@@ -912,49 +1012,53 @@ function App({ ceremonyId: initialCeremonyId, displayName: initialDisplayName })
|
|
|
912
1012
|
goHome();
|
|
913
1013
|
}
|
|
914
1014
|
});
|
|
1015
|
+
if (showInfo) {
|
|
1016
|
+
return /* @__PURE__ */ jsx7(InfoModal, {});
|
|
1017
|
+
}
|
|
915
1018
|
if (screen.name === "name-input") {
|
|
916
1019
|
const { value } = screen;
|
|
917
1020
|
const canSubmit = value.trim().length > 0;
|
|
918
|
-
return /* @__PURE__ */
|
|
919
|
-
/* @__PURE__ */
|
|
920
|
-
/* @__PURE__ */
|
|
921
|
-
/* @__PURE__ */
|
|
922
|
-
/* @__PURE__ */
|
|
923
|
-
/* @__PURE__ */
|
|
924
|
-
/* @__PURE__ */
|
|
925
|
-
/* @__PURE__ */
|
|
926
|
-
/* @__PURE__ */
|
|
1021
|
+
return /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", children: [
|
|
1022
|
+
/* @__PURE__ */ jsx7(Header, { ceremony: null }),
|
|
1023
|
+
/* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", marginTop: 1, gap: 1, children: [
|
|
1024
|
+
/* @__PURE__ */ jsx7(Text7, { bold: true, children: "Who are you contributing as?" }),
|
|
1025
|
+
/* @__PURE__ */ jsx7(Text7, { dimColor: true, children: "Your display name appears next to your contributions in the public transcript. Pick anything \u2014 your real name, a handle, or hit Tab for a random anonymous name." }),
|
|
1026
|
+
/* @__PURE__ */ jsxs7(Box7, { children: [
|
|
1027
|
+
/* @__PURE__ */ jsx7(Text7, { color: "cyan", children: " > " }),
|
|
1028
|
+
/* @__PURE__ */ jsx7(Text7, { children: value }),
|
|
1029
|
+
/* @__PURE__ */ jsx7(Text7, { color: "cyan", inverse: true, children: " " })
|
|
927
1030
|
] }),
|
|
928
|
-
/* @__PURE__ */
|
|
1031
|
+
/* @__PURE__ */ jsx7(Text7, { dimColor: true, children: canSubmit ? "Enter to continue \xB7 Tab rerolls random name \xB7 \u232B backspace \xB7 Esc to quit" : "Type a name, or press Tab to suggest a random anonymous one \xB7 Esc to quit" })
|
|
929
1032
|
] })
|
|
930
1033
|
] });
|
|
931
1034
|
}
|
|
932
1035
|
if (screen.name === "ceremony-picker") {
|
|
933
1036
|
const { ceremonies, loading } = screen;
|
|
934
|
-
return /* @__PURE__ */
|
|
935
|
-
/* @__PURE__ */
|
|
936
|
-
loading ? /* @__PURE__ */
|
|
937
|
-
/* @__PURE__ */
|
|
938
|
-
/* @__PURE__ */
|
|
939
|
-
/* @__PURE__ */
|
|
940
|
-
] }) : /* @__PURE__ */
|
|
941
|
-
/* @__PURE__ */
|
|
942
|
-
/* @__PURE__ */
|
|
1037
|
+
return /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", children: [
|
|
1038
|
+
/* @__PURE__ */ jsx7(Header, { ceremony: null }),
|
|
1039
|
+
loading ? /* @__PURE__ */ jsx7(Text7, { dimColor: true, children: "Loading ceremonies..." }) : ceremonies.length === 0 ? /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", gap: 1, children: [
|
|
1040
|
+
/* @__PURE__ */ jsx7(Text7, { color: "yellow", children: "No ceremonies found." }),
|
|
1041
|
+
/* @__PURE__ */ jsx7(Text7, { dimColor: true, children: "The server may not have any active ceremonies yet." }),
|
|
1042
|
+
/* @__PURE__ */ jsx7(Text7, { dimColor: true, children: "Q to quit" })
|
|
1043
|
+
] }) : /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", children: [
|
|
1044
|
+
/* @__PURE__ */ jsx7(Text7, { bold: true, children: "Select a ceremony:" }),
|
|
1045
|
+
/* @__PURE__ */ jsx7(Text7, { dimColor: true, children: " " + "\u2500".repeat(60) }),
|
|
943
1046
|
ceremonies.map((c, i) => {
|
|
944
1047
|
const isSelected = i === selectedIdx;
|
|
945
1048
|
const isOpen = c.status === "open";
|
|
946
1049
|
const statusColor = c.status === "open" ? "green" : c.status === "completed" ? "cyan" : "yellow";
|
|
947
|
-
|
|
948
|
-
|
|
1050
|
+
const statusLabel = ceremonyStatusLabel(c.status);
|
|
1051
|
+
return /* @__PURE__ */ jsxs7(Box7, { gap: 2, children: [
|
|
1052
|
+
/* @__PURE__ */ jsxs7(Text7, { color: isSelected ? "cyan" : isOpen ? void 0 : "gray", children: [
|
|
949
1053
|
isSelected ? "\u25B6 " : " ",
|
|
950
1054
|
c.name.padEnd(30)
|
|
951
1055
|
] }),
|
|
952
|
-
/* @__PURE__ */
|
|
1056
|
+
/* @__PURE__ */ jsxs7(Text7, { color: statusColor, children: [
|
|
953
1057
|
"[",
|
|
954
|
-
|
|
1058
|
+
statusLabel,
|
|
955
1059
|
"]"
|
|
956
1060
|
] }),
|
|
957
|
-
/* @__PURE__ */
|
|
1061
|
+
/* @__PURE__ */ jsxs7(Text7, { dimColor: true, children: [
|
|
958
1062
|
c.track_count,
|
|
959
1063
|
" track",
|
|
960
1064
|
c.track_count !== 1 ? "s" : "",
|
|
@@ -965,159 +1069,164 @@ function App({ ceremonyId: initialCeremonyId, displayName: initialDisplayName })
|
|
|
965
1069
|
] })
|
|
966
1070
|
] }, c.id);
|
|
967
1071
|
}),
|
|
968
|
-
/* @__PURE__ */
|
|
1072
|
+
/* @__PURE__ */ jsx7(Text7, { dimColor: true, children: " " + "\u2500".repeat(60) }),
|
|
969
1073
|
(() => {
|
|
970
1074
|
const c = ceremonies[selectedIdx];
|
|
971
1075
|
if (!c) return null;
|
|
972
1076
|
if (c.status === "initialized") {
|
|
973
|
-
return /* @__PURE__ */
|
|
974
|
-
"
|
|
975
|
-
"
|
|
976
|
-
" then open ",
|
|
977
|
-
"<id>",
|
|
978
|
-
" to start contributions."
|
|
1077
|
+
return /* @__PURE__ */ jsxs7(Text7, { color: "yellow", children: [
|
|
1078
|
+
" ",
|
|
1079
|
+
"This ceremony is not yet open for contributions. The Umbra team is still preparing the circuits \u2014 please check back shortly."
|
|
979
1080
|
] });
|
|
980
1081
|
}
|
|
981
1082
|
if (c.status === "finalizing") {
|
|
982
|
-
return /* @__PURE__ */
|
|
1083
|
+
return /* @__PURE__ */ jsxs7(Text7, { color: "yellow", children: [
|
|
1084
|
+
" ",
|
|
1085
|
+
"Contributions are closed. The ceremony is computing the final verification key \u2014 no further contributions can be added."
|
|
1086
|
+
] });
|
|
983
1087
|
}
|
|
984
1088
|
if (c.status === "completed") {
|
|
985
|
-
return /* @__PURE__ */
|
|
1089
|
+
return /* @__PURE__ */ jsxs7(Text7, { color: "cyan", children: [
|
|
1090
|
+
" ",
|
|
1091
|
+
"Ceremony complete. The verification keys are finalised \u2014 thank you to everyone who contributed."
|
|
1092
|
+
] });
|
|
986
1093
|
}
|
|
987
|
-
return /* @__PURE__ */
|
|
1094
|
+
return /* @__PURE__ */ jsx7(Text7, { dimColor: true, children: "\u2191/\u2193 select \xB7 Enter join \xB7 Q quit" });
|
|
988
1095
|
})()
|
|
989
1096
|
] })
|
|
990
1097
|
] });
|
|
991
1098
|
}
|
|
992
1099
|
if (screen.name === "loading") {
|
|
993
|
-
return /* @__PURE__ */
|
|
994
|
-
/* @__PURE__ */
|
|
995
|
-
/* @__PURE__ */
|
|
1100
|
+
return /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", children: [
|
|
1101
|
+
/* @__PURE__ */ jsx7(Header, { ceremony }),
|
|
1102
|
+
/* @__PURE__ */ jsx7(Text7, { dimColor: true, children: "Loading tracks..." })
|
|
996
1103
|
] });
|
|
997
1104
|
}
|
|
998
1105
|
if (screen.name === "error") {
|
|
999
1106
|
const backHint = !initialCeremonyId ? "\u232B Backspace \u2014 back to ceremony list \xB7 Q to quit" : screen.recoverable ? "\u232B Backspace / B to go back \xB7 Q to quit" : "Q to quit";
|
|
1000
|
-
return /* @__PURE__ */
|
|
1001
|
-
/* @__PURE__ */
|
|
1002
|
-
/* @__PURE__ */
|
|
1003
|
-
"\u2717
|
|
1107
|
+
return /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", children: [
|
|
1108
|
+
/* @__PURE__ */ jsx7(Header, { ceremony }),
|
|
1109
|
+
/* @__PURE__ */ jsxs7(Text7, { color: "red", bold: true, children: [
|
|
1110
|
+
"\u2717 ",
|
|
1004
1111
|
screen.message
|
|
1005
1112
|
] }),
|
|
1006
|
-
/* @__PURE__ */
|
|
1113
|
+
/* @__PURE__ */ jsx7(Text7, { dimColor: true, children: backHint })
|
|
1007
1114
|
] });
|
|
1008
1115
|
}
|
|
1009
1116
|
if (screen.name === "tracks") {
|
|
1010
1117
|
const { tracks } = screen;
|
|
1011
1118
|
const openTracks = tracks.filter((t) => t.status === "open");
|
|
1012
|
-
const myContributions = Object.values(contributed).filter(
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
/* @__PURE__ */
|
|
1017
|
-
/* @__PURE__ */
|
|
1119
|
+
const myContributions = Object.values(contributed).filter(
|
|
1120
|
+
(c) => c.ceremonyId === activeCeremonyId
|
|
1121
|
+
);
|
|
1122
|
+
const TabBar = () => /* @__PURE__ */ jsxs7(Box7, { gap: 1, marginBottom: 1, children: [
|
|
1123
|
+
/* @__PURE__ */ jsx7(Text7, { bold: tab === 0, color: tab === 0 ? "cyan" : void 0, dimColor: tab !== 0, children: tab === 0 ? "[ Dashboard ]" : " Dashboard " }),
|
|
1124
|
+
/* @__PURE__ */ jsx7(Text7, { dimColor: true, children: "|" }),
|
|
1125
|
+
/* @__PURE__ */ jsx7(Text7, { bold: tab === 1, color: tab === 1 ? "cyan" : void 0, dimColor: tab !== 1, children: tab === 1 ? `[ My Contributions (${myContributions.length}) ]` : ` My Contributions (${myContributions.length}) ` }),
|
|
1126
|
+
/* @__PURE__ */ jsx7(Text7, { dimColor: true, children: " Tab to switch" })
|
|
1018
1127
|
] });
|
|
1019
|
-
return /* @__PURE__ */
|
|
1020
|
-
/* @__PURE__ */
|
|
1021
|
-
/* @__PURE__ */
|
|
1128
|
+
return /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", children: [
|
|
1129
|
+
/* @__PURE__ */ jsx7(Header, { ceremony }),
|
|
1130
|
+
/* @__PURE__ */ jsx7(TabBar, {}),
|
|
1022
1131
|
tab === 0 ? (
|
|
1023
1132
|
// ── Dashboard tab ────────────────────────────────────────────────
|
|
1024
|
-
/* @__PURE__ */
|
|
1025
|
-
/* @__PURE__ */
|
|
1133
|
+
/* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", children: [
|
|
1134
|
+
/* @__PURE__ */ jsxs7(Text7, { dimColor: true, children: [
|
|
1026
1135
|
" CIRCUIT".padEnd(30),
|
|
1027
1136
|
"TOTAL".padEnd(10),
|
|
1028
1137
|
"QUEUE".padEnd(8),
|
|
1029
|
-
"STATUS".padEnd(
|
|
1138
|
+
"STATUS".padEnd(16),
|
|
1030
1139
|
"MY CONTRIBUTIONS"
|
|
1031
1140
|
] }),
|
|
1032
|
-
/* @__PURE__ */
|
|
1141
|
+
/* @__PURE__ */ jsx7(Text7, { dimColor: true, children: " " + "\u2500".repeat(70) }),
|
|
1033
1142
|
tracks.map((t, i) => {
|
|
1034
1143
|
const isSelected = i === selectedIdx;
|
|
1035
1144
|
const canContribute = t.status === "open";
|
|
1036
1145
|
const nameClipped = t.circuit_name.length > 26 ? t.circuit_name.slice(0, 24) + ".." : t.circuit_name;
|
|
1037
1146
|
const statusColor = t.status === "open" ? "green" : t.status === "finalized" ? "cyan" : "yellow";
|
|
1038
1147
|
const myContrib = contributed[t.id];
|
|
1039
|
-
return /* @__PURE__ */
|
|
1040
|
-
/* @__PURE__ */
|
|
1148
|
+
return /* @__PURE__ */ jsxs7(Box7, { children: [
|
|
1149
|
+
/* @__PURE__ */ jsxs7(Text7, { color: isSelected ? "cyan" : canContribute ? void 0 : "gray", children: [
|
|
1041
1150
|
isSelected ? "\u25B6 " : " ",
|
|
1042
1151
|
nameClipped.padEnd(28),
|
|
1043
1152
|
String(t.contribution_count).padEnd(10),
|
|
1044
1153
|
String(t.queue_depth).padEnd(8)
|
|
1045
1154
|
] }),
|
|
1046
|
-
/* @__PURE__ */
|
|
1047
|
-
myContrib ? isSelected ? /* @__PURE__ */
|
|
1155
|
+
/* @__PURE__ */ jsx7(Text7, { color: statusColor, children: trackStatusLabel(t.status).padEnd(16) }),
|
|
1156
|
+
myContrib ? isSelected ? /* @__PURE__ */ jsxs7(Text7, { color: "green", children: [
|
|
1048
1157
|
"\u2713 contributed (round #",
|
|
1049
1158
|
myContrib.sequenceNumber,
|
|
1050
|
-
")
|
|
1051
|
-
] }) : /* @__PURE__ */
|
|
1052
|
-
"\u2713 contributed
|
|
1159
|
+
") \u2014 already done"
|
|
1160
|
+
] }) : /* @__PURE__ */ jsxs7(Text7, { color: "green", children: [
|
|
1161
|
+
"\u2713 contributed (round #",
|
|
1053
1162
|
myContrib.sequenceNumber,
|
|
1054
1163
|
")"
|
|
1055
|
-
] }) : canContribute ? isSelected ? /* @__PURE__ */
|
|
1164
|
+
] }) : canContribute ? isSelected ? /* @__PURE__ */ jsx7(Text7, { color: "yellow", children: "\u2190 Enter to contribute" }) : /* @__PURE__ */ jsx7(Text7, { dimColor: true, children: "not contributed" }) : /* @__PURE__ */ jsx7(Text7, { dimColor: true, children: "\u2014" })
|
|
1056
1165
|
] }, t.id);
|
|
1057
1166
|
}),
|
|
1058
|
-
/* @__PURE__ */
|
|
1059
|
-
openTracks.length === 0 ? /* @__PURE__ */
|
|
1060
|
-
"\u2191/\u2193 select
|
|
1167
|
+
/* @__PURE__ */ jsx7(Text7, { dimColor: true, children: " " + "\u2500".repeat(70) }),
|
|
1168
|
+
openTracks.length === 0 ? /* @__PURE__ */ jsx7(Text7, { color: "yellow", children: "No circuits are open for contributions right now \u2014 the ceremony may be closing or already complete." }) : /* @__PURE__ */ jsxs7(Text7, { dimColor: true, children: [
|
|
1169
|
+
"\u2191/\u2193 select \xB7 Enter contribute \xB7 R refresh \xB7 Q quit",
|
|
1061
1170
|
!initialCeremonyId ? " \xB7 \u232B back to ceremony list" : ""
|
|
1062
1171
|
] })
|
|
1063
1172
|
] })
|
|
1064
1173
|
) : (
|
|
1065
1174
|
// ── My Contributions tab ─────────────────────────────────────────
|
|
1066
|
-
/* @__PURE__ */
|
|
1067
|
-
/* @__PURE__ */
|
|
1068
|
-
/* @__PURE__ */
|
|
1069
|
-
] }) : /* @__PURE__ */
|
|
1070
|
-
/* @__PURE__ */
|
|
1175
|
+
/* @__PURE__ */ jsx7(Box7, { flexDirection: "column", children: myContributions.length === 0 ? /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", gap: 1, children: [
|
|
1176
|
+
/* @__PURE__ */ jsx7(Text7, { dimColor: true, children: "No contributions yet." }),
|
|
1177
|
+
/* @__PURE__ */ jsx7(Text7, { dimColor: true, children: "Switch to Dashboard tab and press Enter on a circuit to contribute." })
|
|
1178
|
+
] }) : /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", children: [
|
|
1179
|
+
/* @__PURE__ */ jsxs7(Text7, { dimColor: true, children: [
|
|
1071
1180
|
" CIRCUIT".padEnd(28),
|
|
1072
1181
|
"ROUND".padEnd(8),
|
|
1073
1182
|
"HASH".padEnd(20),
|
|
1074
1183
|
"TIME"
|
|
1075
1184
|
] }),
|
|
1076
|
-
/* @__PURE__ */
|
|
1077
|
-
myContributions.map((c, i) => /* @__PURE__ */
|
|
1078
|
-
/* @__PURE__ */
|
|
1079
|
-
/* @__PURE__ */
|
|
1080
|
-
/* @__PURE__ */
|
|
1081
|
-
/* @__PURE__ */
|
|
1082
|
-
/* @__PURE__ */
|
|
1185
|
+
/* @__PURE__ */ jsx7(Text7, { dimColor: true, children: " " + "\u2500".repeat(68) }),
|
|
1186
|
+
myContributions.map((c, i) => /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", children: [
|
|
1187
|
+
/* @__PURE__ */ jsxs7(Box7, { children: [
|
|
1188
|
+
/* @__PURE__ */ jsx7(Text7, { color: "green", children: " \u2713 " }),
|
|
1189
|
+
/* @__PURE__ */ jsx7(Text7, { bold: true, children: c.circuitName.padEnd(24) }),
|
|
1190
|
+
/* @__PURE__ */ jsx7(Text7, { color: "yellow", children: "#" + c.sequenceNumber + " " }),
|
|
1191
|
+
/* @__PURE__ */ jsx7(Text7, { color: "cyan", children: c.contributionHash ? c.contributionHash.slice(0, 16) + "..." : "(pending)" })
|
|
1083
1192
|
] }),
|
|
1084
|
-
/* @__PURE__ */
|
|
1193
|
+
/* @__PURE__ */ jsxs7(Text7, { dimColor: true, children: [
|
|
1085
1194
|
" ",
|
|
1086
1195
|
c.verifiedAt ? new Date(c.verifiedAt).toLocaleString() : ""
|
|
1087
1196
|
] })
|
|
1088
1197
|
] }, i)),
|
|
1089
|
-
/* @__PURE__ */
|
|
1090
|
-
/* @__PURE__ */
|
|
1198
|
+
/* @__PURE__ */ jsx7(Text7, { dimColor: true, children: " " + "\u2500".repeat(68) }),
|
|
1199
|
+
/* @__PURE__ */ jsxs7(Text7, { dimColor: true, children: [
|
|
1091
1200
|
"Total: ",
|
|
1092
1201
|
myContributions.length,
|
|
1093
1202
|
" contribution",
|
|
1094
1203
|
myContributions.length !== 1 ? "s" : "",
|
|
1095
1204
|
" \xB7 ",
|
|
1096
|
-
"Tab to switch
|
|
1205
|
+
"Tab to switch \xB7 Q to quit"
|
|
1097
1206
|
] })
|
|
1098
1207
|
] }) })
|
|
1099
1208
|
)
|
|
1100
1209
|
] });
|
|
1101
1210
|
}
|
|
1102
1211
|
if (screen.name === "joining") {
|
|
1103
|
-
return /* @__PURE__ */
|
|
1104
|
-
/* @__PURE__ */
|
|
1105
|
-
/* @__PURE__ */
|
|
1212
|
+
return /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", children: [
|
|
1213
|
+
/* @__PURE__ */ jsx7(Header, { ceremony }),
|
|
1214
|
+
/* @__PURE__ */ jsx7(Text7, { dimColor: true, children: "Joining queue..." })
|
|
1106
1215
|
] });
|
|
1107
1216
|
}
|
|
1108
1217
|
if (screen.name === "queue") {
|
|
1109
1218
|
const { trackId, circuitName } = screen;
|
|
1110
1219
|
const priorContrib = contributed[trackId];
|
|
1111
|
-
return /* @__PURE__ */
|
|
1112
|
-
/* @__PURE__ */
|
|
1113
|
-
priorContrib && /* @__PURE__ */
|
|
1114
|
-
"\u26A0
|
|
1220
|
+
return /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", children: [
|
|
1221
|
+
/* @__PURE__ */ jsx7(Header, { ceremony, subtitle: `Circuit: ${circuitName}` }),
|
|
1222
|
+
priorContrib && /* @__PURE__ */ jsx7(Box7, { marginBottom: 1, paddingX: 1, children: /* @__PURE__ */ jsxs7(Text7, { color: "yellow", children: [
|
|
1223
|
+
"\u26A0 You already contributed to this circuit (round #",
|
|
1115
1224
|
priorContrib.sequenceNumber,
|
|
1116
1225
|
").",
|
|
1117
1226
|
" ",
|
|
1118
1227
|
"Contributing again is allowed and adds more entropy."
|
|
1119
1228
|
] }) }),
|
|
1120
|
-
/* @__PURE__ */
|
|
1229
|
+
/* @__PURE__ */ jsx7(
|
|
1121
1230
|
QueueView,
|
|
1122
1231
|
{
|
|
1123
1232
|
ceremonyId: activeCeremonyId,
|
|
@@ -1127,14 +1236,14 @@ function App({ ceremonyId: initialCeremonyId, displayName: initialDisplayName })
|
|
|
1127
1236
|
onError: (e) => setScreen({ name: "error", message: e.message, recoverable: true })
|
|
1128
1237
|
}
|
|
1129
1238
|
),
|
|
1130
|
-
/* @__PURE__ */
|
|
1239
|
+
/* @__PURE__ */ jsx7(Text7, { dimColor: true, children: "\u232B Backspace to go back \xB7 Q to quit" })
|
|
1131
1240
|
] });
|
|
1132
1241
|
}
|
|
1133
1242
|
if (screen.name === "entropy") {
|
|
1134
1243
|
const { trackId, circuitName, slotStatus } = screen;
|
|
1135
|
-
return /* @__PURE__ */
|
|
1136
|
-
/* @__PURE__ */
|
|
1137
|
-
/* @__PURE__ */
|
|
1244
|
+
return /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", children: [
|
|
1245
|
+
/* @__PURE__ */ jsx7(Header, { ceremony, subtitle: `Circuit: ${circuitName} \xB7 Your turn!` }),
|
|
1246
|
+
/* @__PURE__ */ jsx7(
|
|
1138
1247
|
EntropyCollector,
|
|
1139
1248
|
{
|
|
1140
1249
|
onComplete: (entropy) => setScreen({ name: "contribute", trackId, circuitName, slotStatus, entropy }),
|
|
@@ -1145,9 +1254,9 @@ function App({ ceremonyId: initialCeremonyId, displayName: initialDisplayName })
|
|
|
1145
1254
|
}
|
|
1146
1255
|
if (screen.name === "contribute") {
|
|
1147
1256
|
const { trackId, circuitName, slotStatus, entropy } = screen;
|
|
1148
|
-
return /* @__PURE__ */
|
|
1149
|
-
/* @__PURE__ */
|
|
1150
|
-
/* @__PURE__ */
|
|
1257
|
+
return /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", children: [
|
|
1258
|
+
/* @__PURE__ */ jsx7(Header, { ceremony, subtitle: `Circuit: ${circuitName} \xB7 Contributing` }),
|
|
1259
|
+
/* @__PURE__ */ jsx7(
|
|
1151
1260
|
ContributeFlow,
|
|
1152
1261
|
{
|
|
1153
1262
|
ceremonyId: activeCeremonyId,
|
|
@@ -1176,17 +1285,17 @@ function App({ ceremonyId: initialCeremonyId, displayName: initialDisplayName })
|
|
|
1176
1285
|
}
|
|
1177
1286
|
if (screen.name === "done") {
|
|
1178
1287
|
const { contribution } = screen;
|
|
1179
|
-
return /* @__PURE__ */
|
|
1180
|
-
/* @__PURE__ */
|
|
1181
|
-
/* @__PURE__ */
|
|
1182
|
-
/* @__PURE__ */
|
|
1288
|
+
return /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", children: [
|
|
1289
|
+
/* @__PURE__ */ jsx7(Header, { ceremony }),
|
|
1290
|
+
/* @__PURE__ */ jsx7(Attestation, { contribution }),
|
|
1291
|
+
/* @__PURE__ */ jsx7(Box7, { marginTop: 1, children: /* @__PURE__ */ jsx7(Text7, { dimColor: true, children: "\u232B Backspace / B = contribute to another circuit \xB7 Q to quit" }) })
|
|
1183
1292
|
] });
|
|
1184
1293
|
}
|
|
1185
1294
|
return null;
|
|
1186
1295
|
}
|
|
1187
1296
|
|
|
1188
1297
|
// src/index.tsx
|
|
1189
|
-
import { jsx as
|
|
1298
|
+
import { jsx as jsx8 } from "react/jsx-runtime";
|
|
1190
1299
|
var ceremonyId = process.env["CEREMONY_ID"] ?? "";
|
|
1191
1300
|
var displayName = process.env["CONTRIBUTOR_NAME"];
|
|
1192
1301
|
process.stdout.write("\x1B[?1049h\x1B[H");
|
|
@@ -1210,10 +1319,9 @@ process.on("SIGTERM", () => {
|
|
|
1210
1319
|
process.exit(0);
|
|
1211
1320
|
});
|
|
1212
1321
|
});
|
|
1213
|
-
var { waitUntilExit } = render(
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
);
|
|
1322
|
+
var { waitUntilExit } = render(/* @__PURE__ */ jsx8(App, { ceremonyId, displayName }), {
|
|
1323
|
+
exitOnCtrlC: false
|
|
1324
|
+
});
|
|
1217
1325
|
await waitUntilExit();
|
|
1218
1326
|
restoreScreen();
|
|
1219
1327
|
process.exit(0);
|