@devtion/devcli 0.0.0-f3ea056 → 0.0.0-f7df5e1
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/.env +3 -3
- package/dist/index.js +34 -21
- package/dist/types/commands/finalize.d.ts +2 -1
- package/dist/types/lib/utils.d.ts +2 -1
- package/package.json +2 -2
- package/src/commands/auth.ts +5 -5
- package/src/commands/contribute.ts +7 -4
- package/src/commands/finalize.ts +12 -4
- package/src/commands/index.ts +1 -1
- package/src/commands/listCeremonies.ts +1 -2
- package/src/commands/observe.ts +1 -1
- package/src/commands/setup.ts +40 -19
- package/src/commands/validate.ts +1 -2
- package/src/index.ts +15 -8
- package/src/lib/services.ts +0 -2
- package/src/lib/utils.ts +22 -4
package/dist/.env
CHANGED
|
@@ -29,9 +29,9 @@ AUTH_GITHUB_CLIENT_ID=e9f8a5fabdfe0d95618c
|
|
|
29
29
|
### AWS S3 bucket used as storage for ceremony artifacts.
|
|
30
30
|
|
|
31
31
|
# The chunk size to be used when executing multi-part upload or downloads.
|
|
32
|
-
# default
|
|
33
|
-
# (e.g. a 200 MB file setting a stream chunk size of
|
|
34
|
-
CONFIG_STREAM_CHUNK_SIZE_IN_MB=
|
|
32
|
+
# default 25 MBs.
|
|
33
|
+
# (e.g. a 200 MB file setting a stream chunk size of 25 MB is going to be splitted and uploaded/downloaded in 4 chunks).
|
|
34
|
+
CONFIG_STREAM_CHUNK_SIZE_IN_MB=25
|
|
35
35
|
# The postfix string for each ceremony bucket.
|
|
36
36
|
# default -ph2-ceremony
|
|
37
37
|
CONFIG_CEREMONY_BUCKET_POSTFIX=-p0tion-development-environment
|
package/dist/index.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* @module @devtion/devcli
|
|
5
|
-
* @version 1.0.
|
|
5
|
+
* @version 1.0.8
|
|
6
6
|
* @file All-in-one interactive command-line for interfacing with zkSNARK Phase 2 Trusted Setup ceremonies
|
|
7
7
|
* @copyright Ethereum Foundation 2022
|
|
8
8
|
* @license MIT
|
|
@@ -585,8 +585,18 @@ const publishGist = async (token, content, ceremonyTitle, ceremonyPrefix) => {
|
|
|
585
585
|
* @returns <string> - the ready to share tweet url.
|
|
586
586
|
*/
|
|
587
587
|
const generateCustomUrlToTweetAboutParticipation = (ceremonyName, gistUrl, isFinalizing) => isFinalizing
|
|
588
|
-
? `https://twitter.com/intent/tweet?text=I%20have%20finalized%20the%20${ceremonyName}
|
|
589
|
-
|
|
588
|
+
? `https://twitter.com/intent/tweet?text=I%20have%20finalized%20the%20${ceremonyName}${ceremonyName.toLowerCase().includes("trusted") ||
|
|
589
|
+
ceremonyName.toLowerCase().includes("setup") ||
|
|
590
|
+
ceremonyName.toLowerCase().includes("phase2") ||
|
|
591
|
+
ceremonyName.toLowerCase().includes("ceremony")
|
|
592
|
+
? "!"
|
|
593
|
+
: "%20Phase%202%20Trusted%20Setup%20ceremony!"}%20You%20can%20view%20my%20final%20attestation%20here:%20${gistUrl}%20#Ethereum%20#ZKP%20#PSE`
|
|
594
|
+
: `https://twitter.com/intent/tweet?text=I%20contributed%20to%20the%20${ceremonyName}${ceremonyName.toLowerCase().includes("trusted") ||
|
|
595
|
+
ceremonyName.toLowerCase().includes("setup") ||
|
|
596
|
+
ceremonyName.toLowerCase().includes("phase2") ||
|
|
597
|
+
ceremonyName.toLowerCase().includes("ceremony")
|
|
598
|
+
? "!"
|
|
599
|
+
: "%20Phase%202%20Trusted%20Setup%20ceremony!"}%20You%20can%20view%20the%20steps%20to%20contribute%20here:%20https://ceremony.pse.dev%20You%20can%20view%20my%20attestation%20here:%20${gistUrl}%20#Ethereum%20#ZKP`;
|
|
590
600
|
/**
|
|
591
601
|
* Return a custom progress bar.
|
|
592
602
|
* @param type <ProgressBarType> - the type of the progress bar.
|
|
@@ -714,13 +724,14 @@ const getLatestUpdatesFromParticipant = async (firestoreDatabase, ceremonyId, pa
|
|
|
714
724
|
* @param entropyOrBeaconHash <string> - the entropy or beacon hash (only when finalizing) for the contribution.
|
|
715
725
|
* @param contributorOrCoordinatorIdentifier <string> - the identifier of the contributor or coordinator (only when finalizing).
|
|
716
726
|
* @param isFinalizing <boolean> - flag to discriminate between ceremony finalization (true) and contribution (false).
|
|
727
|
+
* @param circuitsLength <number> - the total number of circuits in the ceremony.
|
|
717
728
|
*/
|
|
718
|
-
const handleStartOrResumeContribution = async (cloudFunctions, firestoreDatabase, ceremony, circuit, participant, entropyOrBeaconHash, contributorOrCoordinatorIdentifier, isFinalizing) => {
|
|
729
|
+
const handleStartOrResumeContribution = async (cloudFunctions, firestoreDatabase, ceremony, circuit, participant, entropyOrBeaconHash, contributorOrCoordinatorIdentifier, isFinalizing, circuitsLength) => {
|
|
719
730
|
// Extract data.
|
|
720
731
|
const { prefix: ceremonyPrefix } = ceremony.data;
|
|
721
732
|
const { waitingQueue, avgTimings, prefix: circuitPrefix, sequencePosition } = circuit.data;
|
|
722
733
|
const { completedContributions } = waitingQueue; // = current progress.
|
|
723
|
-
console.log(`${theme.text.bold(`\n- Circuit # ${theme.colors.magenta(`${sequencePosition}`)}`)} (Contribution Steps)`);
|
|
734
|
+
console.log(`${theme.text.bold(`\n- Circuit # ${theme.colors.magenta(`${sequencePosition}/${circuitsLength}`)}`)} (Contribution Steps)`);
|
|
724
735
|
// Get most up-to-date data from the participant document.
|
|
725
736
|
let participantData = await getLatestUpdatesFromParticipant(firestoreDatabase, ceremony.id, participant.id);
|
|
726
737
|
const spinner = customSpinner(`${participantData.contributionStep === "DOWNLOADING" /* ParticipantContributionStep.DOWNLOADING */
|
|
@@ -1830,7 +1841,9 @@ const setup = async (cmd) => {
|
|
|
1830
1841
|
let ceremonyId = ""; // The unique identifier of the ceremony.
|
|
1831
1842
|
const { firebaseApp, firebaseFunctions, firestoreDatabase } = await bootstrapCommandExecutionAndServices();
|
|
1832
1843
|
// Check for authentication.
|
|
1833
|
-
const { user, providerUserId } = cmd.auth
|
|
1844
|
+
const { user, providerUserId } = cmd.auth
|
|
1845
|
+
? await authWithToken(firebaseApp, cmd.auth)
|
|
1846
|
+
: await checkAuth(firebaseApp);
|
|
1834
1847
|
// Preserve command execution only for coordinators.
|
|
1835
1848
|
if (!(await isCoordinator(user)))
|
|
1836
1849
|
showError(COMMAND_ERRORS.COMMAND_NOT_COORDINATOR, true);
|
|
@@ -1847,7 +1860,7 @@ const setup = async (cmd) => {
|
|
|
1847
1860
|
// if there is the file option, then set up the non interactively
|
|
1848
1861
|
if (cmd.template) {
|
|
1849
1862
|
// 1. parse the file
|
|
1850
|
-
// tmp data - do not cleanup files as we need them
|
|
1863
|
+
// tmp data - do not cleanup files as we need them
|
|
1851
1864
|
const spinner = customSpinner(`Parsing ${theme.text.bold(cmd.template)} setup configuration file...`, `clock`);
|
|
1852
1865
|
spinner.start();
|
|
1853
1866
|
const setupCeremonyData = await parseCeremonyFile(cmd.template);
|
|
@@ -2107,7 +2120,7 @@ const onVerification = async (verification) => {
|
|
|
2107
2120
|
clipboard.readSync();
|
|
2108
2121
|
// Display data.
|
|
2109
2122
|
console.log(`${theme.symbols.warning} Visit ${theme.text.bold(theme.text.underlined(verification.verification_uri))} on this device to generate a new token and authenticate\n`);
|
|
2110
|
-
console.log(theme.colors.magenta(figlet.textSync("Code is Below", { font: "ANSI Shadow" })),
|
|
2123
|
+
console.log(theme.colors.magenta(figlet.textSync("Code is Below", { font: "ANSI Shadow" })), "\n");
|
|
2111
2124
|
console.log(`${theme.symbols.info} Your auth code: ${theme.text.bold(verification.user_code)} has been copied to your clipboard (${theme.emojis.clipboard} ${theme.symbols.success})\n`);
|
|
2112
2125
|
const spinner = customSpinner(`Redirecting to Github...`, `clock`);
|
|
2113
2126
|
spinner.start();
|
|
@@ -2559,8 +2572,8 @@ const listenToParticipantDocumentChanges = async (firestoreDatabase, cloudFuncti
|
|
|
2559
2572
|
// Communicate resume / start of the contribution to participant.
|
|
2560
2573
|
await simpleLoader(`${changedContributionStep === "DOWNLOADING" /* ParticipantContributionStep.DOWNLOADING */ ? `Starting` : `Resuming`} your contribution...`, `clock`, 3000);
|
|
2561
2574
|
// Start / Resume the contribution for the participant.
|
|
2562
|
-
await handleStartOrResumeContribution(cloudFunctions, firestoreDatabase, ceremony, circuit, participant, entropy, providerUserId, false // not finalizing.
|
|
2563
|
-
);
|
|
2575
|
+
await handleStartOrResumeContribution(cloudFunctions, firestoreDatabase, ceremony, circuit, participant, entropy, providerUserId, false, // not finalizing.
|
|
2576
|
+
circuits.length);
|
|
2564
2577
|
}
|
|
2565
2578
|
// Scenario (3.A).
|
|
2566
2579
|
else if (isWaitingForContribution)
|
|
@@ -2609,7 +2622,9 @@ const listenToParticipantDocumentChanges = async (firestoreDatabase, cloudFuncti
|
|
|
2609
2622
|
// Get latest contribution verification result.
|
|
2610
2623
|
await getLatestVerificationResult(firestoreDatabase, ceremony.id, circuit.id, participant.id);
|
|
2611
2624
|
// Get next circuit for contribution.
|
|
2612
|
-
const nextCircuit = timeoutExpired
|
|
2625
|
+
const nextCircuit = timeoutExpired
|
|
2626
|
+
? getCircuitBySequencePosition(circuits, changedContributionProgress)
|
|
2627
|
+
: getCircuitBySequencePosition(circuits, changedContributionProgress + 1);
|
|
2613
2628
|
// Check disk space requirements for participant.
|
|
2614
2629
|
const wannaGenerateAttestation = await handleDiskSpaceRequirementForNextContribution(cloudFunctions, ceremony.id, nextCircuit.data.sequencePosition, nextCircuit.data.zKeySizeInBytes, timeoutExpired, providerUserId);
|
|
2615
2630
|
// Check if the participant would like to generate a new attestation.
|
|
@@ -2688,7 +2703,7 @@ const contribute = async (opt) => {
|
|
|
2688
2703
|
const userDoc = await getDocumentById(firestoreDatabase, commonTerms.collections.users.name, user.uid);
|
|
2689
2704
|
const userData = userDoc.data();
|
|
2690
2705
|
if (!userData) {
|
|
2691
|
-
spinner.fail(`Unfortunately we could not find a user document with your information. This likely means that you did not pass the GitHub reputation checks and therefore are not elegible to contribute to any ceremony. Please contact the coordinator if you believe this to be an error.`);
|
|
2706
|
+
spinner.fail(`Unfortunately we could not find a user document with your information. This likely means that you did not pass the GitHub reputation checks and therefore are not elegible to contribute to any ceremony. If you believe you pass the requirements, it might be possible that your profile is private and we were not able to fetch your real statistics, in this case please consider making your profile public for the duration of the contribution. Please contact the coordinator if you believe this to be an error.`);
|
|
2692
2707
|
process.exit(0);
|
|
2693
2708
|
}
|
|
2694
2709
|
// Check the user's current participant readiness for contribution status (eligible, already contributed, timed out).
|
|
@@ -2935,10 +2950,11 @@ const handleVerifierSmartContract = async (cloudFunctions, bucketName, finalZkey
|
|
|
2935
2950
|
* @param participant <FirebaseDocumentInfo> - the Firestore document of the participant (coordinator).
|
|
2936
2951
|
* @param beacon <string> - the value used to compute the final contribution while finalizing the ceremony.
|
|
2937
2952
|
* @param coordinatorIdentifier <string> - the identifier of the coordinator.
|
|
2953
|
+
* @param circuitsLength <number> - the number of circuits in the ceremony.
|
|
2938
2954
|
*/
|
|
2939
|
-
const handleCircuitFinalization = async (cloudFunctions, firestoreDatabase, ceremony, circuit, participant, beacon, coordinatorIdentifier) => {
|
|
2955
|
+
const handleCircuitFinalization = async (cloudFunctions, firestoreDatabase, ceremony, circuit, participant, beacon, coordinatorIdentifier, circuitsLength) => {
|
|
2940
2956
|
// Step (1).
|
|
2941
|
-
await handleStartOrResumeContribution(cloudFunctions, firestoreDatabase, ceremony, circuit, participant, computeSHA256ToHex(beacon), coordinatorIdentifier, true);
|
|
2957
|
+
await handleStartOrResumeContribution(cloudFunctions, firestoreDatabase, ceremony, circuit, participant, computeSHA256ToHex(beacon), coordinatorIdentifier, true, circuitsLength);
|
|
2942
2958
|
await sleep(2000); // workaound for descriptors.
|
|
2943
2959
|
// Extract data.
|
|
2944
2960
|
const { prefix: circuitPrefix } = circuit.data;
|
|
@@ -3012,7 +3028,7 @@ const finalize = async (opt) => {
|
|
|
3012
3028
|
const circuits = await getCeremonyCircuits(firestoreDatabase, selectedCeremony.id);
|
|
3013
3029
|
// Handle finalization for each ceremony circuit.
|
|
3014
3030
|
for await (const circuit of circuits)
|
|
3015
|
-
await handleCircuitFinalization(firebaseFunctions, firestoreDatabase, selectedCeremony, circuit, participant, beacon, providerUserId);
|
|
3031
|
+
await handleCircuitFinalization(firebaseFunctions, firestoreDatabase, selectedCeremony, circuit, participant, beacon, providerUserId, circuits.length);
|
|
3016
3032
|
process.stdout.write(`\n`);
|
|
3017
3033
|
const spinner = customSpinner(`Wrapping up the finalization of the ceremony...`, "clock");
|
|
3018
3034
|
spinner.start();
|
|
@@ -3169,10 +3185,7 @@ program
|
|
|
3169
3185
|
.command("clean")
|
|
3170
3186
|
.description("clean up output generated by commands from the current working directory")
|
|
3171
3187
|
.action(clean);
|
|
3172
|
-
program
|
|
3173
|
-
.command("list")
|
|
3174
|
-
.description("List all ceremonies prefixes")
|
|
3175
|
-
.action(listCeremonies);
|
|
3188
|
+
program.command("list").description("List all ceremonies prefixes").action(listCeremonies);
|
|
3176
3189
|
program
|
|
3177
3190
|
.command("logout")
|
|
3178
3191
|
.description("sign out from Firebae Auth service and delete Github OAuth 2.0 token from local storage")
|
|
@@ -3188,8 +3201,8 @@ const ceremony = program.command("coordinate").description("commands for coordin
|
|
|
3188
3201
|
ceremony
|
|
3189
3202
|
.command("setup")
|
|
3190
3203
|
.description("setup a Groth16 Phase 2 Trusted Setup ceremony for zk-SNARK circuits")
|
|
3191
|
-
.option(
|
|
3192
|
-
.option(
|
|
3204
|
+
.option("-t, --template <path>", "The path to the ceremony setup template", "")
|
|
3205
|
+
.option("-a, --auth <string>", "The Github OAuth 2.0 token", "")
|
|
3193
3206
|
.action(setup);
|
|
3194
3207
|
ceremony
|
|
3195
3208
|
.command("observe")
|
|
@@ -36,8 +36,9 @@ export declare const handleVerifierSmartContract: (cloudFunctions: Functions, bu
|
|
|
36
36
|
* @param participant <FirebaseDocumentInfo> - the Firestore document of the participant (coordinator).
|
|
37
37
|
* @param beacon <string> - the value used to compute the final contribution while finalizing the ceremony.
|
|
38
38
|
* @param coordinatorIdentifier <string> - the identifier of the coordinator.
|
|
39
|
+
* @param circuitsLength <number> - the number of circuits in the ceremony.
|
|
39
40
|
*/
|
|
40
|
-
export declare const handleCircuitFinalization: (cloudFunctions: Functions, firestoreDatabase: Firestore, ceremony: FirebaseDocumentInfo, circuit: FirebaseDocumentInfo, participant: FirebaseDocumentInfo, beacon: string, coordinatorIdentifier: string) => Promise<void>;
|
|
41
|
+
export declare const handleCircuitFinalization: (cloudFunctions: Functions, firestoreDatabase: Firestore, ceremony: FirebaseDocumentInfo, circuit: FirebaseDocumentInfo, participant: FirebaseDocumentInfo, beacon: string, coordinatorIdentifier: string, circuitsLength: number) => Promise<void>;
|
|
41
42
|
/**
|
|
42
43
|
* Finalize command.
|
|
43
44
|
* @notice The finalize command allows a coordinator to finalize a Trusted Setup Phase 2 ceremony by providing the final beacon,
|
|
@@ -154,5 +154,6 @@ export declare const getLatestUpdatesFromParticipant: (firestoreDatabase: Firest
|
|
|
154
154
|
* @param entropyOrBeaconHash <string> - the entropy or beacon hash (only when finalizing) for the contribution.
|
|
155
155
|
* @param contributorOrCoordinatorIdentifier <string> - the identifier of the contributor or coordinator (only when finalizing).
|
|
156
156
|
* @param isFinalizing <boolean> - flag to discriminate between ceremony finalization (true) and contribution (false).
|
|
157
|
+
* @param circuitsLength <number> - the total number of circuits in the ceremony.
|
|
157
158
|
*/
|
|
158
|
-
export declare const handleStartOrResumeContribution: (cloudFunctions: Functions, firestoreDatabase: Firestore, ceremony: FirebaseDocumentInfo, circuit: FirebaseDocumentInfo, participant: FirebaseDocumentInfo, entropyOrBeaconHash: any, contributorOrCoordinatorIdentifier: string, isFinalizing: boolean) => Promise<void>;
|
|
159
|
+
export declare const handleStartOrResumeContribution: (cloudFunctions: Functions, firestoreDatabase: Firestore, ceremony: FirebaseDocumentInfo, circuit: FirebaseDocumentInfo, participant: FirebaseDocumentInfo, entropyOrBeaconHash: any, contributorOrCoordinatorIdentifier: string, isFinalizing: boolean, circuitsLength: number) => Promise<void>;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@devtion/devcli",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0.0-
|
|
4
|
+
"version": "0.0.0-f7df5e1",
|
|
5
5
|
"description": "All-in-one interactive command-line for interfacing with zkSNARK Phase 2 Trusted Setup ceremonies",
|
|
6
6
|
"repository": "git@github.com:privacy-scaling-explorations/p0tion.git",
|
|
7
7
|
"homepage": "https://github.com/privacy-scaling-explorations/p0tion",
|
|
@@ -97,5 +97,5 @@
|
|
|
97
97
|
"publishConfig": {
|
|
98
98
|
"access": "public"
|
|
99
99
|
},
|
|
100
|
-
"gitHead": "
|
|
100
|
+
"gitHead": "b5e67b5aab3948e7dae6eec480d727db8e6de80f"
|
|
101
101
|
}
|
package/src/commands/auth.ts
CHANGED
|
@@ -73,12 +73,12 @@ export const onVerification = async (verification: Verification): Promise<void>
|
|
|
73
73
|
)} on this device to generate a new token and authenticate\n`
|
|
74
74
|
)
|
|
75
75
|
|
|
76
|
-
console.log(theme.colors.magenta(figlet.textSync("Code is Below", { font: "ANSI Shadow" })),
|
|
77
|
-
|
|
76
|
+
console.log(theme.colors.magenta(figlet.textSync("Code is Below", { font: "ANSI Shadow" })), "\n")
|
|
77
|
+
|
|
78
78
|
console.log(
|
|
79
|
-
`${theme.symbols.info} Your auth code: ${theme.text.bold(
|
|
80
|
-
|
|
81
|
-
})\n`
|
|
79
|
+
`${theme.symbols.info} Your auth code: ${theme.text.bold(
|
|
80
|
+
verification.user_code
|
|
81
|
+
)} has been copied to your clipboard (${theme.emojis.clipboard} ${theme.symbols.success})\n`
|
|
82
82
|
)
|
|
83
83
|
|
|
84
84
|
const spinner = customSpinner(`Redirecting to Github...`, `clock`)
|
|
@@ -724,7 +724,8 @@ export const listenToParticipantDocumentChanges = async (
|
|
|
724
724
|
participant,
|
|
725
725
|
entropy,
|
|
726
726
|
providerUserId,
|
|
727
|
-
false // not finalizing.
|
|
727
|
+
false, // not finalizing.
|
|
728
|
+
circuits.length
|
|
728
729
|
)
|
|
729
730
|
}
|
|
730
731
|
// Scenario (3.A).
|
|
@@ -810,7 +811,9 @@ export const listenToParticipantDocumentChanges = async (
|
|
|
810
811
|
await getLatestVerificationResult(firestoreDatabase, ceremony.id, circuit.id, participant.id)
|
|
811
812
|
|
|
812
813
|
// Get next circuit for contribution.
|
|
813
|
-
const nextCircuit = timeoutExpired
|
|
814
|
+
const nextCircuit = timeoutExpired
|
|
815
|
+
? getCircuitBySequencePosition(circuits, changedContributionProgress)
|
|
816
|
+
: getCircuitBySequencePosition(circuits, changedContributionProgress + 1)
|
|
814
817
|
|
|
815
818
|
// Check disk space requirements for participant.
|
|
816
819
|
const wannaGenerateAttestation = await handleDiskSpaceRequirementForNextContribution(
|
|
@@ -894,7 +897,7 @@ const contribute = async (opt: any) => {
|
|
|
894
897
|
// Get options.
|
|
895
898
|
const ceremonyOpt = opt.ceremony
|
|
896
899
|
const entropyOpt = opt.entropy
|
|
897
|
-
const auth = opt.auth
|
|
900
|
+
const auth = opt.auth
|
|
898
901
|
|
|
899
902
|
// Check for authentication.
|
|
900
903
|
const { user, providerUserId, token } = auth ? await authWithToken(firebaseApp, auth) : await checkAuth(firebaseApp)
|
|
@@ -949,7 +952,7 @@ const contribute = async (opt: any) => {
|
|
|
949
952
|
const userData = userDoc.data()
|
|
950
953
|
if (!userData) {
|
|
951
954
|
spinner.fail(
|
|
952
|
-
`Unfortunately we could not find a user document with your information. This likely means that you did not pass the GitHub reputation checks and therefore are not elegible to contribute to any ceremony. Please contact the coordinator if you believe this to be an error.`
|
|
955
|
+
`Unfortunately we could not find a user document with your information. This likely means that you did not pass the GitHub reputation checks and therefore are not elegible to contribute to any ceremony. If you believe you pass the requirements, it might be possible that your profile is private and we were not able to fetch your real statistics, in this case please consider making your profile public for the duration of the contribution. Please contact the coordinator if you believe this to be an error.`
|
|
953
956
|
)
|
|
954
957
|
process.exit(0)
|
|
955
958
|
}
|
package/src/commands/finalize.ts
CHANGED
|
@@ -152,6 +152,7 @@ export const handleVerifierSmartContract = async (
|
|
|
152
152
|
* @param participant <FirebaseDocumentInfo> - the Firestore document of the participant (coordinator).
|
|
153
153
|
* @param beacon <string> - the value used to compute the final contribution while finalizing the ceremony.
|
|
154
154
|
* @param coordinatorIdentifier <string> - the identifier of the coordinator.
|
|
155
|
+
* @param circuitsLength <number> - the number of circuits in the ceremony.
|
|
155
156
|
*/
|
|
156
157
|
export const handleCircuitFinalization = async (
|
|
157
158
|
cloudFunctions: Functions,
|
|
@@ -160,7 +161,8 @@ export const handleCircuitFinalization = async (
|
|
|
160
161
|
circuit: FirebaseDocumentInfo,
|
|
161
162
|
participant: FirebaseDocumentInfo,
|
|
162
163
|
beacon: string,
|
|
163
|
-
coordinatorIdentifier: string
|
|
164
|
+
coordinatorIdentifier: string,
|
|
165
|
+
circuitsLength: number
|
|
164
166
|
) => {
|
|
165
167
|
// Step (1).
|
|
166
168
|
await handleStartOrResumeContribution(
|
|
@@ -171,7 +173,8 @@ export const handleCircuitFinalization = async (
|
|
|
171
173
|
participant,
|
|
172
174
|
computeSHA256ToHex(beacon),
|
|
173
175
|
coordinatorIdentifier,
|
|
174
|
-
true
|
|
176
|
+
true,
|
|
177
|
+
circuitsLength
|
|
175
178
|
)
|
|
176
179
|
|
|
177
180
|
await sleep(2000) // workaound for descriptors.
|
|
@@ -246,7 +249,11 @@ const finalize = async (opt: any) => {
|
|
|
246
249
|
|
|
247
250
|
// Check for authentication.
|
|
248
251
|
const auth = opt.auth
|
|
249
|
-
const {
|
|
252
|
+
const {
|
|
253
|
+
user,
|
|
254
|
+
providerUserId,
|
|
255
|
+
token: coordinatorAccessToken
|
|
256
|
+
} = auth ? await authWithToken(firebaseApp, auth) : await checkAuth(firebaseApp)
|
|
250
257
|
|
|
251
258
|
// Preserve command execution only for coordinators.
|
|
252
259
|
if (!(await isCoordinator(user))) showError(COMMAND_ERRORS.COMMAND_NOT_COORDINATOR, true)
|
|
@@ -307,7 +314,8 @@ const finalize = async (opt: any) => {
|
|
|
307
314
|
circuit,
|
|
308
315
|
participant,
|
|
309
316
|
beacon,
|
|
310
|
-
providerUserId
|
|
317
|
+
providerUserId,
|
|
318
|
+
circuits.length
|
|
311
319
|
)
|
|
312
320
|
|
|
313
321
|
process.stdout.write(`\n`)
|
package/src/commands/index.ts
CHANGED
|
@@ -6,4 +6,4 @@ export { default as finalize } from "./finalize.js"
|
|
|
6
6
|
export { default as clean } from "./clean.js"
|
|
7
7
|
export { default as logout } from "./logout.js"
|
|
8
8
|
export { default as validate } from "./validate.js"
|
|
9
|
-
export { default as listCeremonies} from "./listCeremonies.js"
|
|
9
|
+
export { default as listCeremonies } from "./listCeremonies.js"
|
|
@@ -17,11 +17,10 @@ const listCeremonies = async () => {
|
|
|
17
17
|
|
|
18
18
|
// loop through all ceremonies
|
|
19
19
|
for (const ceremony of ceremonies) names.push(ceremony.data().prefix)
|
|
20
|
-
|
|
20
|
+
|
|
21
21
|
// print them to the console
|
|
22
22
|
console.log(names.join(", "))
|
|
23
23
|
process.exit(0)
|
|
24
|
-
|
|
25
24
|
} catch (err: any) {
|
|
26
25
|
showError(`${err.toString()}`, false)
|
|
27
26
|
// we want to exit with a non-zero exit code
|
package/src/commands/observe.ts
CHANGED
|
@@ -15,7 +15,7 @@ import { COMMAND_ERRORS, GENERIC_ERRORS, showError } from "../lib/errors.js"
|
|
|
15
15
|
import { promptForCeremonySelection } from "../lib/prompts.js"
|
|
16
16
|
import { bootstrapCommandExecutionAndServices, checkAuth } from "../lib/services.js"
|
|
17
17
|
import theme from "../lib/theme.js"
|
|
18
|
-
import {customSpinner, getSecondsMinutesHoursFromMillis, sleep } from "../lib/utils.js"
|
|
18
|
+
import { customSpinner, getSecondsMinutesHoursFromMillis, sleep } from "../lib/utils.js"
|
|
19
19
|
|
|
20
20
|
/**
|
|
21
21
|
* Clean cursor lines from current position back to root (default: zero).
|
package/src/commands/setup.ts
CHANGED
|
@@ -466,7 +466,7 @@ export const handleCircuitArtifactUploadToStorage = async (
|
|
|
466
466
|
* from Hermez's ceremony Phase 1 Reliable Setup Ceremony.
|
|
467
467
|
* @param cmd? <any> - the path to the ceremony setup file.
|
|
468
468
|
*/
|
|
469
|
-
const setup = async (cmd: { template?: string
|
|
469
|
+
const setup = async (cmd: { template?: string; auth?: string }) => {
|
|
470
470
|
// Setup command state.
|
|
471
471
|
const circuits: Array<CircuitDocument> = [] // Circuits.
|
|
472
472
|
let ceremonyId: string = "" // The unique identifier of the ceremony.
|
|
@@ -474,8 +474,10 @@ const setup = async (cmd: { template?: string, auth?: string}) => {
|
|
|
474
474
|
const { firebaseApp, firebaseFunctions, firestoreDatabase } = await bootstrapCommandExecutionAndServices()
|
|
475
475
|
|
|
476
476
|
// Check for authentication.
|
|
477
|
-
const { user, providerUserId } = cmd.auth
|
|
478
|
-
|
|
477
|
+
const { user, providerUserId } = cmd.auth
|
|
478
|
+
? await authWithToken(firebaseApp, cmd.auth)
|
|
479
|
+
: await checkAuth(firebaseApp)
|
|
480
|
+
|
|
479
481
|
// Preserve command execution only for coordinators.
|
|
480
482
|
if (!(await isCoordinator(user))) showError(COMMAND_ERRORS.COMMAND_NOT_COORDINATOR, true)
|
|
481
483
|
|
|
@@ -501,7 +503,7 @@ const setup = async (cmd: { template?: string, auth?: string}) => {
|
|
|
501
503
|
// if there is the file option, then set up the non interactively
|
|
502
504
|
if (cmd.template) {
|
|
503
505
|
// 1. parse the file
|
|
504
|
-
// tmp data - do not cleanup files as we need them
|
|
506
|
+
// tmp data - do not cleanup files as we need them
|
|
505
507
|
const spinner = customSpinner(`Parsing ${theme.text.bold(cmd.template!)} setup configuration file...`, `clock`)
|
|
506
508
|
spinner.start()
|
|
507
509
|
const setupCeremonyData = await parseCeremonyFile(cmd.template!)
|
|
@@ -524,13 +526,26 @@ const setup = async (cmd: { template?: string, auth?: string}) => {
|
|
|
524
526
|
const zkeyLocalPathAndFileName = getZkeyLocalFilePath(circuit.files.initialZkeyFilename)
|
|
525
527
|
|
|
526
528
|
// 2. download the pot and wasm files
|
|
527
|
-
await checkAndDownloadSmallestPowersOfTau(
|
|
528
|
-
|
|
529
|
+
await checkAndDownloadSmallestPowersOfTau(
|
|
530
|
+
convertToDoubleDigits(circuit.metadata?.pot!),
|
|
531
|
+
circuit.files.potFilename
|
|
532
|
+
)
|
|
533
|
+
|
|
529
534
|
// 3. generate the zKey
|
|
530
|
-
const spinner = customSpinner(
|
|
535
|
+
const spinner = customSpinner(
|
|
536
|
+
`Generating genesis zKey for circuit ${theme.text.bold(circuit.name)}...`,
|
|
537
|
+
`clock`
|
|
538
|
+
)
|
|
531
539
|
spinner.start()
|
|
532
|
-
await zKey.newZKey(
|
|
533
|
-
|
|
540
|
+
await zKey.newZKey(
|
|
541
|
+
r1csLocalPathAndFileName,
|
|
542
|
+
getPotLocalFilePath(circuit.files.potFilename),
|
|
543
|
+
zkeyLocalPathAndFileName,
|
|
544
|
+
undefined
|
|
545
|
+
)
|
|
546
|
+
spinner.succeed(
|
|
547
|
+
`Generation of the genesis zKey for citcui ${theme.text.bold(circuit.name)} completed successfully`
|
|
548
|
+
)
|
|
534
549
|
|
|
535
550
|
// 4. calculate the hashes
|
|
536
551
|
const wasmBlake2bHash = await blake512FromPath(wasmLocalPathAndFileName)
|
|
@@ -547,7 +562,7 @@ const setup = async (cmd: { template?: string, auth?: string}) => {
|
|
|
547
562
|
zkeyLocalPathAndFileName,
|
|
548
563
|
circuit.files.initialZkeyFilename
|
|
549
564
|
)
|
|
550
|
-
|
|
565
|
+
|
|
551
566
|
// Check if PoT file has been already uploaded to storage.
|
|
552
567
|
const alreadyUploadedPot = await checkIfObjectExist(
|
|
553
568
|
firebaseFunctions,
|
|
@@ -595,18 +610,24 @@ const setup = async (cmd: { template?: string, auth?: string}) => {
|
|
|
595
610
|
|
|
596
611
|
ceremonySetupData.circuits[index].zKeySizeInBytes = getFileStats(zkeyLocalPathAndFileName).size
|
|
597
612
|
}
|
|
598
|
-
|
|
599
613
|
|
|
600
614
|
// 7. setup the ceremony
|
|
601
|
-
const ceremonyId = await setupCeremony(
|
|
602
|
-
|
|
603
|
-
ceremonySetupData.ceremonyInputData
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
615
|
+
const ceremonyId = await setupCeremony(
|
|
616
|
+
firebaseFunctions,
|
|
617
|
+
ceremonySetupData.ceremonyInputData,
|
|
618
|
+
ceremonySetupData.ceremonyPrefix,
|
|
619
|
+
ceremonySetupData.circuits
|
|
620
|
+
)
|
|
621
|
+
console.log(
|
|
622
|
+
`Congratulations, the setup of ceremony ${theme.text.bold(
|
|
623
|
+
ceremonySetupData.ceremonyInputData.title
|
|
624
|
+
)} (${`UID: ${theme.text.bold(ceremonyId)}`}) has been successfully completed ${
|
|
625
|
+
theme.emojis.tada
|
|
626
|
+
}. You will be able to find all the files and info respectively in the ceremony bucket and database document.`
|
|
627
|
+
)
|
|
628
|
+
|
|
608
629
|
terminate(providerUserId)
|
|
609
|
-
}
|
|
630
|
+
}
|
|
610
631
|
|
|
611
632
|
// Look for R1CS files.
|
|
612
633
|
const r1csFilePaths = await filterDirectoryFilesByExtension(cwd, `.r1cs`)
|
package/src/commands/validate.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { showError } from "../lib/errors.js"
|
|
|
4
4
|
/**
|
|
5
5
|
* Validate ceremony setup command.
|
|
6
6
|
*/
|
|
7
|
-
const validate = async (cmd: { template: string
|
|
7
|
+
const validate = async (cmd: { template: string; constraints?: number }) => {
|
|
8
8
|
try {
|
|
9
9
|
// parse the file and cleanup after
|
|
10
10
|
const parsedFile = await parseCeremonyFile(cmd.template, true)
|
|
@@ -18,7 +18,6 @@ const validate = async (cmd: { template: string, constraints?: number }) => {
|
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
console.log(true)
|
|
21
|
-
|
|
22
21
|
} catch (err: any) {
|
|
23
22
|
showError(`${err.toString()}`, false)
|
|
24
23
|
// we want to exit with a non-zero exit code
|
package/src/index.ts
CHANGED
|
@@ -4,7 +4,17 @@ import { createCommand } from "commander"
|
|
|
4
4
|
import { readFileSync } from "fs"
|
|
5
5
|
import { dirname } from "path"
|
|
6
6
|
import { fileURLToPath } from "url"
|
|
7
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
setup,
|
|
9
|
+
auth,
|
|
10
|
+
contribute,
|
|
11
|
+
observe,
|
|
12
|
+
finalize,
|
|
13
|
+
clean,
|
|
14
|
+
logout,
|
|
15
|
+
validate,
|
|
16
|
+
listCeremonies
|
|
17
|
+
} from "./commands/index.js"
|
|
8
18
|
|
|
9
19
|
// Get pkg info (e.g., name, version).
|
|
10
20
|
const packagePath = `${dirname(fileURLToPath(import.meta.url))}/..`
|
|
@@ -27,10 +37,7 @@ program
|
|
|
27
37
|
.command("clean")
|
|
28
38
|
.description("clean up output generated by commands from the current working directory")
|
|
29
39
|
.action(clean)
|
|
30
|
-
program
|
|
31
|
-
.command("list")
|
|
32
|
-
.description("List all ceremonies prefixes")
|
|
33
|
-
.action(listCeremonies)
|
|
40
|
+
program.command("list").description("List all ceremonies prefixes").action(listCeremonies)
|
|
34
41
|
program
|
|
35
42
|
.command("logout")
|
|
36
43
|
.description("sign out from Firebae Auth service and delete Github OAuth 2.0 token from local storage")
|
|
@@ -48,10 +55,10 @@ const ceremony = program.command("coordinate").description("commands for coordin
|
|
|
48
55
|
ceremony
|
|
49
56
|
.command("setup")
|
|
50
57
|
.description("setup a Groth16 Phase 2 Trusted Setup ceremony for zk-SNARK circuits")
|
|
51
|
-
.option(
|
|
52
|
-
.option(
|
|
58
|
+
.option("-t, --template <path>", "The path to the ceremony setup template", "")
|
|
59
|
+
.option("-a, --auth <string>", "The Github OAuth 2.0 token", "")
|
|
53
60
|
.action(setup)
|
|
54
|
-
|
|
61
|
+
|
|
55
62
|
ceremony
|
|
56
63
|
.command("observe")
|
|
57
64
|
.description("observe in real-time the waiting queue of each ceremony circuit")
|
package/src/lib/services.ts
CHANGED
package/src/lib/utils.ts
CHANGED
|
@@ -311,8 +311,22 @@ export const generateCustomUrlToTweetAboutParticipation = (
|
|
|
311
311
|
isFinalizing: boolean
|
|
312
312
|
) =>
|
|
313
313
|
isFinalizing
|
|
314
|
-
? `https://twitter.com/intent/tweet?text=I%20have%20finalized%20the%20${ceremonyName}
|
|
315
|
-
|
|
314
|
+
? `https://twitter.com/intent/tweet?text=I%20have%20finalized%20the%20${ceremonyName}${
|
|
315
|
+
ceremonyName.toLowerCase().includes("trusted") ||
|
|
316
|
+
ceremonyName.toLowerCase().includes("setup") ||
|
|
317
|
+
ceremonyName.toLowerCase().includes("phase2") ||
|
|
318
|
+
ceremonyName.toLowerCase().includes("ceremony")
|
|
319
|
+
? "!"
|
|
320
|
+
: "%20Phase%202%20Trusted%20Setup%20ceremony!"
|
|
321
|
+
}%20You%20can%20view%20my%20final%20attestation%20here:%20${gistUrl}%20#Ethereum%20#ZKP%20#PSE`
|
|
322
|
+
: `https://twitter.com/intent/tweet?text=I%20contributed%20to%20the%20${ceremonyName}${
|
|
323
|
+
ceremonyName.toLowerCase().includes("trusted") ||
|
|
324
|
+
ceremonyName.toLowerCase().includes("setup") ||
|
|
325
|
+
ceremonyName.toLowerCase().includes("phase2") ||
|
|
326
|
+
ceremonyName.toLowerCase().includes("ceremony")
|
|
327
|
+
? "!"
|
|
328
|
+
: "%20Phase%202%20Trusted%20Setup%20ceremony!"
|
|
329
|
+
}%20You%20can%20view%20the%20steps%20to%20contribute%20here:%20https://ceremony.pse.dev%20You%20can%20view%20my%20attestation%20here:%20${gistUrl}%20#Ethereum%20#ZKP`
|
|
316
330
|
|
|
317
331
|
/**
|
|
318
332
|
* Return a custom progress bar.
|
|
@@ -521,6 +535,7 @@ export const getLatestUpdatesFromParticipant = async (
|
|
|
521
535
|
* @param entropyOrBeaconHash <string> - the entropy or beacon hash (only when finalizing) for the contribution.
|
|
522
536
|
* @param contributorOrCoordinatorIdentifier <string> - the identifier of the contributor or coordinator (only when finalizing).
|
|
523
537
|
* @param isFinalizing <boolean> - flag to discriminate between ceremony finalization (true) and contribution (false).
|
|
538
|
+
* @param circuitsLength <number> - the total number of circuits in the ceremony.
|
|
524
539
|
*/
|
|
525
540
|
export const handleStartOrResumeContribution = async (
|
|
526
541
|
cloudFunctions: Functions,
|
|
@@ -530,7 +545,8 @@ export const handleStartOrResumeContribution = async (
|
|
|
530
545
|
participant: FirebaseDocumentInfo,
|
|
531
546
|
entropyOrBeaconHash: any,
|
|
532
547
|
contributorOrCoordinatorIdentifier: string,
|
|
533
|
-
isFinalizing: boolean
|
|
548
|
+
isFinalizing: boolean,
|
|
549
|
+
circuitsLength: number
|
|
534
550
|
): Promise<void> => {
|
|
535
551
|
// Extract data.
|
|
536
552
|
const { prefix: ceremonyPrefix } = ceremony.data
|
|
@@ -538,7 +554,9 @@ export const handleStartOrResumeContribution = async (
|
|
|
538
554
|
const { completedContributions } = waitingQueue // = current progress.
|
|
539
555
|
|
|
540
556
|
console.log(
|
|
541
|
-
`${theme.text.bold(
|
|
557
|
+
`${theme.text.bold(
|
|
558
|
+
`\n- Circuit # ${theme.colors.magenta(`${sequencePosition}/${circuitsLength}`)}`
|
|
559
|
+
)} (Contribution Steps)`
|
|
542
560
|
)
|
|
543
561
|
|
|
544
562
|
// Get most up-to-date data from the participant document.
|