@devtion/devcli 0.0.0-004e6ad
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/LICENSE +21 -0
- package/README.md +120 -0
- package/dist/.env +55 -0
- package/dist/index.js +3635 -0
- package/dist/public/mini-semaphore.wasm +0 -0
- package/dist/public/mini-semaphore.zkey +0 -0
- package/dist/types/commands/auth.d.ts +25 -0
- package/dist/types/commands/authBandada.d.ts +2 -0
- package/dist/types/commands/authSIWE.d.ts +7 -0
- package/dist/types/commands/ceremony/index.d.ts +3 -0
- package/dist/types/commands/ceremony/listParticipants.d.ts +2 -0
- package/dist/types/commands/clean.d.ts +6 -0
- package/dist/types/commands/contribute.d.ts +139 -0
- package/dist/types/commands/finalize.d.ts +52 -0
- package/dist/types/commands/index.d.ts +11 -0
- package/dist/types/commands/listCeremonies.d.ts +5 -0
- package/dist/types/commands/logout.d.ts +6 -0
- package/dist/types/commands/observe.d.ts +22 -0
- package/dist/types/commands/setup.d.ts +86 -0
- package/dist/types/commands/validate.d.ts +8 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/lib/bandada.d.ts +6 -0
- package/dist/types/lib/errors.d.ts +60 -0
- package/dist/types/lib/files.d.ts +65 -0
- package/dist/types/lib/localConfigs.d.ts +148 -0
- package/dist/types/lib/prompts.d.ts +104 -0
- package/dist/types/lib/services.d.ts +31 -0
- package/dist/types/lib/theme.d.ts +42 -0
- package/dist/types/lib/utils.d.ts +159 -0
- package/dist/types/types/index.d.ts +134 -0
- package/package.json +108 -0
- package/src/commands/auth.ts +214 -0
- package/src/commands/authBandada.ts +120 -0
- package/src/commands/authSIWE.ts +185 -0
- package/src/commands/ceremony/index.ts +20 -0
- package/src/commands/ceremony/listParticipants.ts +56 -0
- package/src/commands/clean.ts +49 -0
- package/src/commands/contribute.ts +1116 -0
- package/src/commands/finalize.ts +395 -0
- package/src/commands/index.ts +11 -0
- package/src/commands/listCeremonies.ts +31 -0
- package/src/commands/logout.ts +69 -0
- package/src/commands/observe.ts +197 -0
- package/src/commands/setup.ts +912 -0
- package/src/commands/validate.ts +28 -0
- package/src/index.ts +88 -0
- package/src/lib/bandada.ts +51 -0
- package/src/lib/errors.ts +77 -0
- package/src/lib/files.ts +102 -0
- package/src/lib/localConfigs.ts +240 -0
- package/src/lib/prompts.ts +745 -0
- package/src/lib/services.ts +214 -0
- package/src/lib/theme.ts +45 -0
- package/src/lib/utils.ts +813 -0
- package/src/types/conf.d.ts +16 -0
- package/src/types/index.ts +145 -0
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
FirebaseDocumentInfo,
|
|
5
|
+
getCeremonyCircuits,
|
|
6
|
+
getCircuitContributionsFromContributor,
|
|
7
|
+
getOpenedCeremonies,
|
|
8
|
+
isCoordinator,
|
|
9
|
+
convertToDoubleDigits
|
|
10
|
+
} from "@devtion/actions"
|
|
11
|
+
import { Firestore } from "firebase/firestore"
|
|
12
|
+
import logSymbols from "log-symbols"
|
|
13
|
+
import readline from "readline"
|
|
14
|
+
import { COMMAND_ERRORS, GENERIC_ERRORS, showError } from "../lib/errors.js"
|
|
15
|
+
import { promptForCeremonySelection } from "../lib/prompts.js"
|
|
16
|
+
import { bootstrapCommandExecutionAndServices, checkAuth } from "../lib/services.js"
|
|
17
|
+
import theme from "../lib/theme.js"
|
|
18
|
+
import { customSpinner, getSecondsMinutesHoursFromMillis, sleep } from "../lib/utils.js"
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Clean cursor lines from current position back to root (default: zero).
|
|
22
|
+
* @param currentCursorPos - the current position of the cursor.
|
|
23
|
+
* @returns <number>
|
|
24
|
+
*/
|
|
25
|
+
export const cleanCursorPosBackToRoot = (currentCursorPos: number) => {
|
|
26
|
+
while (currentCursorPos < 0) {
|
|
27
|
+
// Get back and clean line by line.
|
|
28
|
+
readline.cursorTo(process.stdout, 0)
|
|
29
|
+
readline.clearLine(process.stdout, 0)
|
|
30
|
+
readline.moveCursor(process.stdout, -1, -1)
|
|
31
|
+
|
|
32
|
+
currentCursorPos += 1
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return currentCursorPos
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Show the latest updates for the given circuit.
|
|
40
|
+
* @param firestoreDatabase <Firestore> - the Firestore database to query from.
|
|
41
|
+
* @param ceremony <FirebaseDocumentInfo> - the Firebase document containing info about the ceremony.
|
|
42
|
+
* @param circuit <FirebaseDocumentInfo> - the Firebase document containing info about the circuit.
|
|
43
|
+
* @returns Promise<number> return the current position of the cursor (i.e., number of lines displayed).
|
|
44
|
+
*/
|
|
45
|
+
export const displayLatestCircuitUpdates = async (
|
|
46
|
+
firestoreDatabase: Firestore,
|
|
47
|
+
ceremony: FirebaseDocumentInfo,
|
|
48
|
+
circuit: FirebaseDocumentInfo
|
|
49
|
+
): Promise<number> => {
|
|
50
|
+
let observation = theme.text.bold(`- Circuit # ${theme.colors.magenta(circuit.data.sequencePosition)}`) // Observation output.
|
|
51
|
+
let cursorPos = -1 // Current cursor position (nb. decrease every time there's a new line!).
|
|
52
|
+
|
|
53
|
+
const { waitingQueue } = circuit.data
|
|
54
|
+
|
|
55
|
+
// Get info from circuit.
|
|
56
|
+
const { currentContributor } = waitingQueue
|
|
57
|
+
const { completedContributions } = waitingQueue
|
|
58
|
+
|
|
59
|
+
if (!currentContributor) {
|
|
60
|
+
observation += `\n> Nobody's currently waiting to contribute ${theme.emojis.eyes}`
|
|
61
|
+
cursorPos -= 1
|
|
62
|
+
} else {
|
|
63
|
+
// Search for currentContributor' contribution.
|
|
64
|
+
const contributions = await getCircuitContributionsFromContributor(
|
|
65
|
+
firestoreDatabase,
|
|
66
|
+
ceremony.id,
|
|
67
|
+
circuit.id,
|
|
68
|
+
currentContributor
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
if (!contributions.length) {
|
|
72
|
+
// The contributor is currently contributing.
|
|
73
|
+
observation += `\n> Participant ${theme.text.bold(`#${completedContributions + 1}`)} (${theme.text.bold(
|
|
74
|
+
currentContributor
|
|
75
|
+
)}) is currently contributing ${theme.emojis.fire}`
|
|
76
|
+
|
|
77
|
+
cursorPos -= 1
|
|
78
|
+
} else {
|
|
79
|
+
// The contributor has contributed.
|
|
80
|
+
observation += `\n> Participant ${theme.text.bold(`#${completedContributions}`)} (${theme.text.bold(
|
|
81
|
+
currentContributor
|
|
82
|
+
)}) has completed the contribution ${theme.emojis.tada}`
|
|
83
|
+
|
|
84
|
+
cursorPos -= 1
|
|
85
|
+
|
|
86
|
+
// The contributor has finished the contribution.
|
|
87
|
+
const contributionData = contributions.at(0)?.data
|
|
88
|
+
|
|
89
|
+
if (!contributionData) showError(GENERIC_ERRORS.GENERIC_ERROR_RETRIEVING_DATA, true)
|
|
90
|
+
|
|
91
|
+
// Convert times to seconds.
|
|
92
|
+
const {
|
|
93
|
+
seconds: contributionTimeSeconds,
|
|
94
|
+
minutes: contributionTimeMinutes,
|
|
95
|
+
hours: contributionTimeHours
|
|
96
|
+
} = getSecondsMinutesHoursFromMillis(contributionData?.contributionComputationTime)
|
|
97
|
+
const {
|
|
98
|
+
seconds: verificationTimeSeconds,
|
|
99
|
+
minutes: verificationTimeMinutes,
|
|
100
|
+
hours: verificationTimeHours
|
|
101
|
+
} = getSecondsMinutesHoursFromMillis(contributionData?.verificationComputationTime)
|
|
102
|
+
|
|
103
|
+
observation += `\n> The ${theme.text.bold("computation")} took ${theme.text.bold(
|
|
104
|
+
`${convertToDoubleDigits(contributionTimeHours)}:${convertToDoubleDigits(
|
|
105
|
+
contributionTimeMinutes
|
|
106
|
+
)}:${convertToDoubleDigits(contributionTimeSeconds)}`
|
|
107
|
+
)}`
|
|
108
|
+
observation += `\n> The ${theme.text.bold("verification")} took ${theme.text.bold(
|
|
109
|
+
`${convertToDoubleDigits(verificationTimeHours)}:${convertToDoubleDigits(
|
|
110
|
+
verificationTimeMinutes
|
|
111
|
+
)}:${convertToDoubleDigits(verificationTimeSeconds)}`
|
|
112
|
+
)}`
|
|
113
|
+
observation += `\n> Contribution ${
|
|
114
|
+
contributionData?.valid
|
|
115
|
+
? `${theme.text.bold("VALID")} ${theme.symbols.success}`
|
|
116
|
+
: `${theme.text.bold("INVALID")} ${theme.symbols.error}`
|
|
117
|
+
}`
|
|
118
|
+
|
|
119
|
+
cursorPos -= 3
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Show observation for circuit.
|
|
124
|
+
process.stdout.write(`${observation}\n\n`)
|
|
125
|
+
cursorPos -= 1
|
|
126
|
+
|
|
127
|
+
return cursorPos
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Observe command.
|
|
132
|
+
*/
|
|
133
|
+
const observe = async () => {
|
|
134
|
+
// @todo to be moved as command configuration parameter.
|
|
135
|
+
const observationWaitingTimeInMillis = 3000
|
|
136
|
+
try {
|
|
137
|
+
// Initialize services.
|
|
138
|
+
const { firebaseApp, firestoreDatabase } = await bootstrapCommandExecutionAndServices()
|
|
139
|
+
|
|
140
|
+
// Handle current authenticated user sign in.
|
|
141
|
+
const { user } = await checkAuth(firebaseApp)
|
|
142
|
+
|
|
143
|
+
// Preserve command execution only for coordinators].
|
|
144
|
+
if (!(await isCoordinator(user))) showError(COMMAND_ERRORS.COMMAND_NOT_COORDINATOR, true)
|
|
145
|
+
|
|
146
|
+
// Get running ceremonies info (if any).
|
|
147
|
+
const runningCeremoniesDocs = await getOpenedCeremonies(firestoreDatabase)
|
|
148
|
+
|
|
149
|
+
// Ask to select a ceremony.
|
|
150
|
+
const ceremony = await promptForCeremonySelection(
|
|
151
|
+
runningCeremoniesDocs,
|
|
152
|
+
false,
|
|
153
|
+
"Which ceremony would you like to observe?"
|
|
154
|
+
)
|
|
155
|
+
|
|
156
|
+
console.log(`${logSymbols.info} Refresh rate set to ~3 seconds for waiting queue updates\n`)
|
|
157
|
+
|
|
158
|
+
let cursorPos = 0 // Keep track of current cursor position.
|
|
159
|
+
|
|
160
|
+
const spinner = customSpinner(`Getting ready...`, "clock")
|
|
161
|
+
spinner.start()
|
|
162
|
+
|
|
163
|
+
// Get circuit updates every 3 seconds.
|
|
164
|
+
setInterval(async () => {
|
|
165
|
+
// Clean cursor position back to root.
|
|
166
|
+
cursorPos = cleanCursorPosBackToRoot(cursorPos)
|
|
167
|
+
|
|
168
|
+
spinner.stop()
|
|
169
|
+
|
|
170
|
+
spinner.text = `Updating...`
|
|
171
|
+
spinner.start()
|
|
172
|
+
|
|
173
|
+
// Get updates from circuits.
|
|
174
|
+
const circuits = await getCeremonyCircuits(firestoreDatabase, ceremony.id)
|
|
175
|
+
|
|
176
|
+
await sleep(observationWaitingTimeInMillis / 10) // Just for a smoother UX/UI experience.
|
|
177
|
+
|
|
178
|
+
spinner.stop()
|
|
179
|
+
|
|
180
|
+
// Observe changes for each circuit
|
|
181
|
+
for await (const circuit of circuits)
|
|
182
|
+
cursorPos += await displayLatestCircuitUpdates(firestoreDatabase, ceremony, circuit)
|
|
183
|
+
|
|
184
|
+
process.stdout.write(`Press CTRL+C to exit`)
|
|
185
|
+
|
|
186
|
+
await sleep(1000) // Just for a smoother UX/UI experience.
|
|
187
|
+
}, observationWaitingTimeInMillis)
|
|
188
|
+
|
|
189
|
+
await sleep(observationWaitingTimeInMillis) // Wait until the first update.
|
|
190
|
+
|
|
191
|
+
spinner.stop()
|
|
192
|
+
} catch (err: any) {
|
|
193
|
+
showError(`Something went wrong: ${err.toString()}`, true)
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
export default observe
|