@devtion/actions 0.0.0-270e9e0 → 0.0.0-4f2b2be
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.mjs +84 -92
- package/dist/index.node.js +83 -91
- package/dist/types/src/helpers/constants.d.ts +6 -0
- package/dist/types/src/helpers/constants.d.ts.map +1 -1
- package/dist/types/src/helpers/security.d.ts +2 -2
- package/dist/types/src/helpers/security.d.ts.map +1 -1
- package/dist/types/src/helpers/utils.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/helpers/constants.ts +6 -0
- package/src/helpers/security.ts +29 -49
- package/src/helpers/utils.ts +17 -22
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @module @
|
|
3
|
-
* @version 1.0.
|
|
2
|
+
* @module @devtion/actions
|
|
3
|
+
* @version 1.0.6
|
|
4
4
|
* @file A set of actions and helpers for CLI commands
|
|
5
5
|
* @copyright Ethereum Foundation 2022
|
|
6
6
|
* @license MIT
|
|
@@ -17,7 +17,7 @@ import crypto from 'crypto';
|
|
|
17
17
|
import blake from 'blakejs';
|
|
18
18
|
import { utils } from 'ffjavascript';
|
|
19
19
|
import winston from 'winston';
|
|
20
|
-
import { S3Client,
|
|
20
|
+
import { S3Client, GetObjectCommand } from '@aws-sdk/client-s3';
|
|
21
21
|
import { pipeline, Readable } from 'stream';
|
|
22
22
|
import { promisify } from 'util';
|
|
23
23
|
import { initializeApp } from 'firebase/app';
|
|
@@ -244,6 +244,12 @@ const commonTerms = {
|
|
|
244
244
|
verificationStartedAt: "verificationStartedAt"
|
|
245
245
|
}
|
|
246
246
|
},
|
|
247
|
+
avatars: {
|
|
248
|
+
name: "avatars",
|
|
249
|
+
fields: {
|
|
250
|
+
avatarUrl: "avatarUrl"
|
|
251
|
+
}
|
|
252
|
+
},
|
|
247
253
|
ceremonies: {
|
|
248
254
|
name: "ceremonies",
|
|
249
255
|
fields: {
|
|
@@ -1085,42 +1091,34 @@ const parseCeremonyFile = async (path, cleanup = false) => {
|
|
|
1085
1091
|
circuitArtifacts.push({
|
|
1086
1092
|
artifacts: artifacts
|
|
1087
1093
|
});
|
|
1088
|
-
const r1csPath = artifacts.r1csStoragePath;
|
|
1089
|
-
const wasmPath = artifacts.wasmStoragePath;
|
|
1090
1094
|
// where we storing the r1cs downloaded
|
|
1091
1095
|
const localR1csPath = `./${circuitData.name}.r1cs`;
|
|
1096
|
+
// where we storing the wasm downloaded
|
|
1097
|
+
const localWasmPath = `./${circuitData.name}.wasm`;
|
|
1092
1098
|
// check that the artifacts exist in S3
|
|
1093
1099
|
// we don't need any privileges to download this
|
|
1094
1100
|
// just the correct region
|
|
1095
|
-
const s3 = new S3Client({
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
Key: r1csPath
|
|
1100
|
-
}));
|
|
1101
|
-
}
|
|
1102
|
-
catch (error) {
|
|
1103
|
-
throw new Error(`The r1cs file (${r1csPath}) seems to not exist. Please ensure this is correct and that the object is publicly available.`);
|
|
1104
|
-
}
|
|
1105
|
-
try {
|
|
1106
|
-
await s3.send(new HeadObjectCommand({
|
|
1107
|
-
Bucket: artifacts.bucket,
|
|
1108
|
-
Key: wasmPath
|
|
1109
|
-
}));
|
|
1110
|
-
}
|
|
1111
|
-
catch (error) {
|
|
1112
|
-
throw new Error(`The wasm file (${wasmPath}) seems to not exist. Please ensure this is correct and that the object is publicly available.`);
|
|
1113
|
-
}
|
|
1101
|
+
const s3 = new S3Client({
|
|
1102
|
+
region: artifacts.region,
|
|
1103
|
+
credentials: undefined
|
|
1104
|
+
});
|
|
1114
1105
|
// download the r1cs to extract the metadata
|
|
1115
1106
|
const command = new GetObjectCommand({ Bucket: artifacts.bucket, Key: artifacts.r1csStoragePath });
|
|
1116
1107
|
const response = await s3.send(command);
|
|
1117
1108
|
const streamPipeline = promisify(pipeline);
|
|
1118
1109
|
if (response.$metadata.httpStatusCode !== 200)
|
|
1119
|
-
throw new Error(
|
|
1110
|
+
throw new Error(`There was an error while trying to download the r1cs file for circuit ${circuitData.name}. Please check that the file has the correct permissions (public) set.`);
|
|
1120
1111
|
if (response.Body instanceof Readable)
|
|
1121
1112
|
await streamPipeline(response.Body, fs.createWriteStream(localR1csPath));
|
|
1122
1113
|
// extract the metadata from the r1cs
|
|
1123
1114
|
const metadata = getR1CSInfo(localR1csPath);
|
|
1115
|
+
// download wasm too to ensure it's available
|
|
1116
|
+
const wasmCommand = new GetObjectCommand({ Bucket: artifacts.bucket, Key: artifacts.wasmStoragePath });
|
|
1117
|
+
const wasmResponse = await s3.send(wasmCommand);
|
|
1118
|
+
if (wasmResponse.$metadata.httpStatusCode !== 200)
|
|
1119
|
+
throw new Error(`There was an error while trying to download the wasm file for circuit ${circuitData.name}. Please check that the file has the correct permissions (public) set.`);
|
|
1120
|
+
if (wasmResponse.Body instanceof Readable)
|
|
1121
|
+
await streamPipeline(wasmResponse.Body, fs.createWriteStream(localWasmPath));
|
|
1124
1122
|
// validate that the circuit hash and template links are valid
|
|
1125
1123
|
const template = circuitData.template;
|
|
1126
1124
|
const URLMatch = template.source.match(urlPattern);
|
|
@@ -1168,35 +1166,53 @@ const parseCeremonyFile = async (path, cleanup = false) => {
|
|
|
1168
1166
|
// check that the timeout is provided for the correct configuration
|
|
1169
1167
|
let dynamicThreshold;
|
|
1170
1168
|
let fixedTimeWindow;
|
|
1169
|
+
let circuit = {};
|
|
1171
1170
|
if (data.timeoutMechanismType === "DYNAMIC" /* CeremonyTimeoutType.DYNAMIC */) {
|
|
1172
1171
|
if (circuitData.dynamicThreshold <= 0)
|
|
1173
1172
|
throw new Error("The dynamic threshold should be > 0.");
|
|
1174
1173
|
dynamicThreshold = circuitData.dynamicThreshold;
|
|
1174
|
+
// the Circuit data for the ceremony setup
|
|
1175
|
+
circuit = {
|
|
1176
|
+
name: circuitData.name,
|
|
1177
|
+
description: circuitData.description,
|
|
1178
|
+
prefix: circuitPrefix,
|
|
1179
|
+
sequencePosition: i + 1,
|
|
1180
|
+
metadata: metadata,
|
|
1181
|
+
files: files,
|
|
1182
|
+
template: template,
|
|
1183
|
+
compiler: compiler,
|
|
1184
|
+
verification: verification,
|
|
1185
|
+
dynamicThreshold: dynamicThreshold,
|
|
1186
|
+
avgTimings: {
|
|
1187
|
+
contributionComputation: 0,
|
|
1188
|
+
fullContribution: 0,
|
|
1189
|
+
verifyCloudFunction: 0
|
|
1190
|
+
},
|
|
1191
|
+
};
|
|
1175
1192
|
}
|
|
1176
1193
|
if (data.timeoutMechanismType === "FIXED" /* CeremonyTimeoutType.FIXED */) {
|
|
1177
1194
|
if (circuitData.fixedTimeWindow <= 0)
|
|
1178
1195
|
throw new Error("The fixed time window threshold should be > 0.");
|
|
1179
1196
|
fixedTimeWindow = circuitData.fixedTimeWindow;
|
|
1197
|
+
// the Circuit data for the ceremony setup
|
|
1198
|
+
circuit = {
|
|
1199
|
+
name: circuitData.name,
|
|
1200
|
+
description: circuitData.description,
|
|
1201
|
+
prefix: circuitPrefix,
|
|
1202
|
+
sequencePosition: i + 1,
|
|
1203
|
+
metadata: metadata,
|
|
1204
|
+
files: files,
|
|
1205
|
+
template: template,
|
|
1206
|
+
compiler: compiler,
|
|
1207
|
+
verification: verification,
|
|
1208
|
+
fixedTimeWindow: fixedTimeWindow,
|
|
1209
|
+
avgTimings: {
|
|
1210
|
+
contributionComputation: 0,
|
|
1211
|
+
fullContribution: 0,
|
|
1212
|
+
verifyCloudFunction: 0
|
|
1213
|
+
},
|
|
1214
|
+
};
|
|
1180
1215
|
}
|
|
1181
|
-
// the Circuit data for the ceremony setup
|
|
1182
|
-
const circuit = {
|
|
1183
|
-
name: circuitData.name,
|
|
1184
|
-
description: circuitData.description,
|
|
1185
|
-
prefix: circuitPrefix,
|
|
1186
|
-
sequencePosition: i + 1,
|
|
1187
|
-
metadata: metadata,
|
|
1188
|
-
files: files,
|
|
1189
|
-
template: template,
|
|
1190
|
-
compiler: compiler,
|
|
1191
|
-
verification: verification,
|
|
1192
|
-
fixedTimeWindow: fixedTimeWindow,
|
|
1193
|
-
// dynamicThreshold: dynamicThreshold,
|
|
1194
|
-
avgTimings: {
|
|
1195
|
-
contributionComputation: 0,
|
|
1196
|
-
fullContribution: 0,
|
|
1197
|
-
verifyCloudFunction: 0
|
|
1198
|
-
},
|
|
1199
|
-
};
|
|
1200
1216
|
circuits.push(circuit);
|
|
1201
1217
|
// remove the local r1cs download (if used for verifying the config only vs setup)
|
|
1202
1218
|
if (cleanup)
|
|
@@ -2061,55 +2077,27 @@ const verifyCeremony = async (functions, firestore, ceremonyPrefix, outputDirect
|
|
|
2061
2077
|
};
|
|
2062
2078
|
|
|
2063
2079
|
/**
|
|
2064
|
-
* This function
|
|
2065
|
-
* @param user
|
|
2066
|
-
* @returns
|
|
2080
|
+
* This function queries the GitHub API to fetch users statistics
|
|
2081
|
+
* @param user {string} the user uid
|
|
2082
|
+
* @returns {any} the stats from the GitHub API
|
|
2067
2083
|
*/
|
|
2068
|
-
const
|
|
2069
|
-
const response = await fetch(`https://api.github.com/user/${user}
|
|
2084
|
+
const getGitHubStats = async (user) => {
|
|
2085
|
+
const response = await fetch(`https://api.github.com/user/${user}`, {
|
|
2070
2086
|
method: "GET",
|
|
2071
2087
|
headers: {
|
|
2072
2088
|
Authorization: `token ${process.env.GITHUB_ACCESS_TOKEN}`
|
|
2073
2089
|
}
|
|
2074
2090
|
});
|
|
2075
2091
|
if (response.status !== 200)
|
|
2076
|
-
throw new Error("It was not possible to retrieve the
|
|
2092
|
+
throw new Error("It was not possible to retrieve the user's statistic. Please try again.");
|
|
2077
2093
|
const jsonData = await response.json();
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
const getNumberOfFollowersGitHub = async (user) => {
|
|
2086
|
-
const response = await fetch(`https://api.github.com/user/${user}/followers`, {
|
|
2087
|
-
method: "GET",
|
|
2088
|
-
headers: {
|
|
2089
|
-
Authorization: `token ${process.env.GITHUB_ACCESS_TOKEN}`
|
|
2090
|
-
}
|
|
2091
|
-
});
|
|
2092
|
-
if (response.status !== 200)
|
|
2093
|
-
throw new Error("It was not possible to retrieve the number of followers. Please try again.");
|
|
2094
|
-
const jsonData = await response.json();
|
|
2095
|
-
return jsonData.length;
|
|
2096
|
-
};
|
|
2097
|
-
/**
|
|
2098
|
-
* This function will return the number of following of a user
|
|
2099
|
-
* @param user <string> The username of the user
|
|
2100
|
-
* @returns <number> The number of following users
|
|
2101
|
-
*/
|
|
2102
|
-
const getNumberOfFollowingGitHub = async (user) => {
|
|
2103
|
-
const response = await fetch(`https://api.github.com/user/${user}/following`, {
|
|
2104
|
-
method: "GET",
|
|
2105
|
-
headers: {
|
|
2106
|
-
Authorization: `token ${process.env.GITHUB_ACCESS_TOKEN}`
|
|
2107
|
-
}
|
|
2108
|
-
});
|
|
2109
|
-
if (response.status !== 200)
|
|
2110
|
-
throw new Error("It was not possible to retrieve the number of following. Please try again.");
|
|
2111
|
-
const jsonData = await response.json();
|
|
2112
|
-
return jsonData.length;
|
|
2094
|
+
const data = {
|
|
2095
|
+
following: jsonData.following,
|
|
2096
|
+
followers: jsonData.followers,
|
|
2097
|
+
publicRepos: jsonData.public_repos,
|
|
2098
|
+
avatarUrl: jsonData.avatar_url
|
|
2099
|
+
};
|
|
2100
|
+
return data;
|
|
2113
2101
|
};
|
|
2114
2102
|
/**
|
|
2115
2103
|
* This function will check if the user is reputable enough to be able to use the app
|
|
@@ -2117,19 +2105,23 @@ const getNumberOfFollowingGitHub = async (user) => {
|
|
|
2117
2105
|
* @param minimumAmountOfFollowing <number> The minimum amount of following the user should have
|
|
2118
2106
|
* @param minimumAmountOfFollowers <number> The minimum amount of followers the user should have
|
|
2119
2107
|
* @param minimumAmountOfPublicRepos <number> The minimum amount of public repos the user should have
|
|
2120
|
-
* @returns <
|
|
2108
|
+
* @returns <any> Return the avatar URL of the user if the user is reputable, false otherwise
|
|
2121
2109
|
*/
|
|
2122
2110
|
const githubReputation = async (userLogin, minimumAmountOfFollowing, minimumAmountOfFollowers, minimumAmountOfPublicRepos) => {
|
|
2123
2111
|
if (!process.env.GITHUB_ACCESS_TOKEN)
|
|
2124
2112
|
throw new Error("The GitHub access token is missing. Please insert a valid token to be used for anti-sybil checks on user registation, and then try again.");
|
|
2125
|
-
const following = await
|
|
2126
|
-
const repos = await getNumberOfPublicReposGitHub(userLogin);
|
|
2127
|
-
const followers = await getNumberOfFollowersGitHub(userLogin);
|
|
2113
|
+
const { following, followers, publicRepos, avatarUrl } = await getGitHubStats(userLogin);
|
|
2128
2114
|
if (following < minimumAmountOfFollowing ||
|
|
2129
|
-
|
|
2115
|
+
publicRepos < minimumAmountOfPublicRepos ||
|
|
2130
2116
|
followers < minimumAmountOfFollowers)
|
|
2131
|
-
return
|
|
2132
|
-
|
|
2117
|
+
return {
|
|
2118
|
+
reputable: false,
|
|
2119
|
+
avatarUrl: ""
|
|
2120
|
+
};
|
|
2121
|
+
return {
|
|
2122
|
+
reputable: true,
|
|
2123
|
+
avatarUrl: avatarUrl
|
|
2124
|
+
};
|
|
2133
2125
|
};
|
|
2134
2126
|
|
|
2135
2127
|
/**
|
package/dist/index.node.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @module @
|
|
3
|
-
* @version 1.0.
|
|
2
|
+
* @module @devtion/actions
|
|
3
|
+
* @version 1.0.6
|
|
4
4
|
* @file A set of actions and helpers for CLI commands
|
|
5
5
|
* @copyright Ethereum Foundation 2022
|
|
6
6
|
* @license MIT
|
|
@@ -246,6 +246,12 @@ const commonTerms = {
|
|
|
246
246
|
verificationStartedAt: "verificationStartedAt"
|
|
247
247
|
}
|
|
248
248
|
},
|
|
249
|
+
avatars: {
|
|
250
|
+
name: "avatars",
|
|
251
|
+
fields: {
|
|
252
|
+
avatarUrl: "avatarUrl"
|
|
253
|
+
}
|
|
254
|
+
},
|
|
249
255
|
ceremonies: {
|
|
250
256
|
name: "ceremonies",
|
|
251
257
|
fields: {
|
|
@@ -1087,42 +1093,34 @@ const parseCeremonyFile = async (path, cleanup = false) => {
|
|
|
1087
1093
|
circuitArtifacts.push({
|
|
1088
1094
|
artifacts: artifacts
|
|
1089
1095
|
});
|
|
1090
|
-
const r1csPath = artifacts.r1csStoragePath;
|
|
1091
|
-
const wasmPath = artifacts.wasmStoragePath;
|
|
1092
1096
|
// where we storing the r1cs downloaded
|
|
1093
1097
|
const localR1csPath = `./${circuitData.name}.r1cs`;
|
|
1098
|
+
// where we storing the wasm downloaded
|
|
1099
|
+
const localWasmPath = `./${circuitData.name}.wasm`;
|
|
1094
1100
|
// check that the artifacts exist in S3
|
|
1095
1101
|
// we don't need any privileges to download this
|
|
1096
1102
|
// just the correct region
|
|
1097
|
-
const s3 = new clientS3.S3Client({
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
Key: r1csPath
|
|
1102
|
-
}));
|
|
1103
|
-
}
|
|
1104
|
-
catch (error) {
|
|
1105
|
-
throw new Error(`The r1cs file (${r1csPath}) seems to not exist. Please ensure this is correct and that the object is publicly available.`);
|
|
1106
|
-
}
|
|
1107
|
-
try {
|
|
1108
|
-
await s3.send(new clientS3.HeadObjectCommand({
|
|
1109
|
-
Bucket: artifacts.bucket,
|
|
1110
|
-
Key: wasmPath
|
|
1111
|
-
}));
|
|
1112
|
-
}
|
|
1113
|
-
catch (error) {
|
|
1114
|
-
throw new Error(`The wasm file (${wasmPath}) seems to not exist. Please ensure this is correct and that the object is publicly available.`);
|
|
1115
|
-
}
|
|
1103
|
+
const s3 = new clientS3.S3Client({
|
|
1104
|
+
region: artifacts.region,
|
|
1105
|
+
credentials: undefined
|
|
1106
|
+
});
|
|
1116
1107
|
// download the r1cs to extract the metadata
|
|
1117
1108
|
const command = new clientS3.GetObjectCommand({ Bucket: artifacts.bucket, Key: artifacts.r1csStoragePath });
|
|
1118
1109
|
const response = await s3.send(command);
|
|
1119
1110
|
const streamPipeline = util.promisify(stream.pipeline);
|
|
1120
1111
|
if (response.$metadata.httpStatusCode !== 200)
|
|
1121
|
-
throw new Error(
|
|
1112
|
+
throw new Error(`There was an error while trying to download the r1cs file for circuit ${circuitData.name}. Please check that the file has the correct permissions (public) set.`);
|
|
1122
1113
|
if (response.Body instanceof stream.Readable)
|
|
1123
1114
|
await streamPipeline(response.Body, fs.createWriteStream(localR1csPath));
|
|
1124
1115
|
// extract the metadata from the r1cs
|
|
1125
1116
|
const metadata = getR1CSInfo(localR1csPath);
|
|
1117
|
+
// download wasm too to ensure it's available
|
|
1118
|
+
const wasmCommand = new clientS3.GetObjectCommand({ Bucket: artifacts.bucket, Key: artifacts.wasmStoragePath });
|
|
1119
|
+
const wasmResponse = await s3.send(wasmCommand);
|
|
1120
|
+
if (wasmResponse.$metadata.httpStatusCode !== 200)
|
|
1121
|
+
throw new Error(`There was an error while trying to download the wasm file for circuit ${circuitData.name}. Please check that the file has the correct permissions (public) set.`);
|
|
1122
|
+
if (wasmResponse.Body instanceof stream.Readable)
|
|
1123
|
+
await streamPipeline(wasmResponse.Body, fs.createWriteStream(localWasmPath));
|
|
1126
1124
|
// validate that the circuit hash and template links are valid
|
|
1127
1125
|
const template = circuitData.template;
|
|
1128
1126
|
const URLMatch = template.source.match(urlPattern);
|
|
@@ -1170,35 +1168,53 @@ const parseCeremonyFile = async (path, cleanup = false) => {
|
|
|
1170
1168
|
// check that the timeout is provided for the correct configuration
|
|
1171
1169
|
let dynamicThreshold;
|
|
1172
1170
|
let fixedTimeWindow;
|
|
1171
|
+
let circuit = {};
|
|
1173
1172
|
if (data.timeoutMechanismType === "DYNAMIC" /* CeremonyTimeoutType.DYNAMIC */) {
|
|
1174
1173
|
if (circuitData.dynamicThreshold <= 0)
|
|
1175
1174
|
throw new Error("The dynamic threshold should be > 0.");
|
|
1176
1175
|
dynamicThreshold = circuitData.dynamicThreshold;
|
|
1176
|
+
// the Circuit data for the ceremony setup
|
|
1177
|
+
circuit = {
|
|
1178
|
+
name: circuitData.name,
|
|
1179
|
+
description: circuitData.description,
|
|
1180
|
+
prefix: circuitPrefix,
|
|
1181
|
+
sequencePosition: i + 1,
|
|
1182
|
+
metadata: metadata,
|
|
1183
|
+
files: files,
|
|
1184
|
+
template: template,
|
|
1185
|
+
compiler: compiler,
|
|
1186
|
+
verification: verification,
|
|
1187
|
+
dynamicThreshold: dynamicThreshold,
|
|
1188
|
+
avgTimings: {
|
|
1189
|
+
contributionComputation: 0,
|
|
1190
|
+
fullContribution: 0,
|
|
1191
|
+
verifyCloudFunction: 0
|
|
1192
|
+
},
|
|
1193
|
+
};
|
|
1177
1194
|
}
|
|
1178
1195
|
if (data.timeoutMechanismType === "FIXED" /* CeremonyTimeoutType.FIXED */) {
|
|
1179
1196
|
if (circuitData.fixedTimeWindow <= 0)
|
|
1180
1197
|
throw new Error("The fixed time window threshold should be > 0.");
|
|
1181
1198
|
fixedTimeWindow = circuitData.fixedTimeWindow;
|
|
1199
|
+
// the Circuit data for the ceremony setup
|
|
1200
|
+
circuit = {
|
|
1201
|
+
name: circuitData.name,
|
|
1202
|
+
description: circuitData.description,
|
|
1203
|
+
prefix: circuitPrefix,
|
|
1204
|
+
sequencePosition: i + 1,
|
|
1205
|
+
metadata: metadata,
|
|
1206
|
+
files: files,
|
|
1207
|
+
template: template,
|
|
1208
|
+
compiler: compiler,
|
|
1209
|
+
verification: verification,
|
|
1210
|
+
fixedTimeWindow: fixedTimeWindow,
|
|
1211
|
+
avgTimings: {
|
|
1212
|
+
contributionComputation: 0,
|
|
1213
|
+
fullContribution: 0,
|
|
1214
|
+
verifyCloudFunction: 0
|
|
1215
|
+
},
|
|
1216
|
+
};
|
|
1182
1217
|
}
|
|
1183
|
-
// the Circuit data for the ceremony setup
|
|
1184
|
-
const circuit = {
|
|
1185
|
-
name: circuitData.name,
|
|
1186
|
-
description: circuitData.description,
|
|
1187
|
-
prefix: circuitPrefix,
|
|
1188
|
-
sequencePosition: i + 1,
|
|
1189
|
-
metadata: metadata,
|
|
1190
|
-
files: files,
|
|
1191
|
-
template: template,
|
|
1192
|
-
compiler: compiler,
|
|
1193
|
-
verification: verification,
|
|
1194
|
-
fixedTimeWindow: fixedTimeWindow,
|
|
1195
|
-
// dynamicThreshold: dynamicThreshold,
|
|
1196
|
-
avgTimings: {
|
|
1197
|
-
contributionComputation: 0,
|
|
1198
|
-
fullContribution: 0,
|
|
1199
|
-
verifyCloudFunction: 0
|
|
1200
|
-
},
|
|
1201
|
-
};
|
|
1202
1218
|
circuits.push(circuit);
|
|
1203
1219
|
// remove the local r1cs download (if used for verifying the config only vs setup)
|
|
1204
1220
|
if (cleanup)
|
|
@@ -2063,55 +2079,27 @@ const verifyCeremony = async (functions, firestore$1, ceremonyPrefix, outputDire
|
|
|
2063
2079
|
};
|
|
2064
2080
|
|
|
2065
2081
|
/**
|
|
2066
|
-
* This function
|
|
2067
|
-
* @param user
|
|
2068
|
-
* @returns
|
|
2082
|
+
* This function queries the GitHub API to fetch users statistics
|
|
2083
|
+
* @param user {string} the user uid
|
|
2084
|
+
* @returns {any} the stats from the GitHub API
|
|
2069
2085
|
*/
|
|
2070
|
-
const
|
|
2071
|
-
const response = await fetch(`https://api.github.com/user/${user}
|
|
2086
|
+
const getGitHubStats = async (user) => {
|
|
2087
|
+
const response = await fetch(`https://api.github.com/user/${user}`, {
|
|
2072
2088
|
method: "GET",
|
|
2073
2089
|
headers: {
|
|
2074
2090
|
Authorization: `token ${process.env.GITHUB_ACCESS_TOKEN}`
|
|
2075
2091
|
}
|
|
2076
2092
|
});
|
|
2077
2093
|
if (response.status !== 200)
|
|
2078
|
-
throw new Error("It was not possible to retrieve the
|
|
2094
|
+
throw new Error("It was not possible to retrieve the user's statistic. Please try again.");
|
|
2079
2095
|
const jsonData = await response.json();
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
const getNumberOfFollowersGitHub = async (user) => {
|
|
2088
|
-
const response = await fetch(`https://api.github.com/user/${user}/followers`, {
|
|
2089
|
-
method: "GET",
|
|
2090
|
-
headers: {
|
|
2091
|
-
Authorization: `token ${process.env.GITHUB_ACCESS_TOKEN}`
|
|
2092
|
-
}
|
|
2093
|
-
});
|
|
2094
|
-
if (response.status !== 200)
|
|
2095
|
-
throw new Error("It was not possible to retrieve the number of followers. Please try again.");
|
|
2096
|
-
const jsonData = await response.json();
|
|
2097
|
-
return jsonData.length;
|
|
2098
|
-
};
|
|
2099
|
-
/**
|
|
2100
|
-
* This function will return the number of following of a user
|
|
2101
|
-
* @param user <string> The username of the user
|
|
2102
|
-
* @returns <number> The number of following users
|
|
2103
|
-
*/
|
|
2104
|
-
const getNumberOfFollowingGitHub = async (user) => {
|
|
2105
|
-
const response = await fetch(`https://api.github.com/user/${user}/following`, {
|
|
2106
|
-
method: "GET",
|
|
2107
|
-
headers: {
|
|
2108
|
-
Authorization: `token ${process.env.GITHUB_ACCESS_TOKEN}`
|
|
2109
|
-
}
|
|
2110
|
-
});
|
|
2111
|
-
if (response.status !== 200)
|
|
2112
|
-
throw new Error("It was not possible to retrieve the number of following. Please try again.");
|
|
2113
|
-
const jsonData = await response.json();
|
|
2114
|
-
return jsonData.length;
|
|
2096
|
+
const data = {
|
|
2097
|
+
following: jsonData.following,
|
|
2098
|
+
followers: jsonData.followers,
|
|
2099
|
+
publicRepos: jsonData.public_repos,
|
|
2100
|
+
avatarUrl: jsonData.avatar_url
|
|
2101
|
+
};
|
|
2102
|
+
return data;
|
|
2115
2103
|
};
|
|
2116
2104
|
/**
|
|
2117
2105
|
* This function will check if the user is reputable enough to be able to use the app
|
|
@@ -2119,19 +2107,23 @@ const getNumberOfFollowingGitHub = async (user) => {
|
|
|
2119
2107
|
* @param minimumAmountOfFollowing <number> The minimum amount of following the user should have
|
|
2120
2108
|
* @param minimumAmountOfFollowers <number> The minimum amount of followers the user should have
|
|
2121
2109
|
* @param minimumAmountOfPublicRepos <number> The minimum amount of public repos the user should have
|
|
2122
|
-
* @returns <
|
|
2110
|
+
* @returns <any> Return the avatar URL of the user if the user is reputable, false otherwise
|
|
2123
2111
|
*/
|
|
2124
2112
|
const githubReputation = async (userLogin, minimumAmountOfFollowing, minimumAmountOfFollowers, minimumAmountOfPublicRepos) => {
|
|
2125
2113
|
if (!process.env.GITHUB_ACCESS_TOKEN)
|
|
2126
2114
|
throw new Error("The GitHub access token is missing. Please insert a valid token to be used for anti-sybil checks on user registation, and then try again.");
|
|
2127
|
-
const following = await
|
|
2128
|
-
const repos = await getNumberOfPublicReposGitHub(userLogin);
|
|
2129
|
-
const followers = await getNumberOfFollowersGitHub(userLogin);
|
|
2115
|
+
const { following, followers, publicRepos, avatarUrl } = await getGitHubStats(userLogin);
|
|
2130
2116
|
if (following < minimumAmountOfFollowing ||
|
|
2131
|
-
|
|
2117
|
+
publicRepos < minimumAmountOfPublicRepos ||
|
|
2132
2118
|
followers < minimumAmountOfFollowers)
|
|
2133
|
-
return
|
|
2134
|
-
|
|
2119
|
+
return {
|
|
2120
|
+
reputable: false,
|
|
2121
|
+
avatarUrl: ""
|
|
2122
|
+
};
|
|
2123
|
+
return {
|
|
2124
|
+
reputable: true,
|
|
2125
|
+
avatarUrl: avatarUrl
|
|
2126
|
+
};
|
|
2135
2127
|
};
|
|
2136
2128
|
|
|
2137
2129
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../../src/helpers/constants.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,sBAAsB,+CAA+C,CAAA;AAElF,eAAO,MAAM,mBAAmB,6BAA6B,CAAA;AAE7D,eAAO,MAAM,gBAAgB,UAAU,CAAA;AAEvC,eAAO,MAAM,gBAAgB,KAAK,CAAA;AAElC,eAAO,MAAM,eAAe,UAAU,CAAA;AAEtC,eAAO,MAAM,sBAAsB,UAAU,CAAA;AAE7C,eAAO,MAAM,sBAAsB,SAAS,CAAA;AAE5C,eAAO,MAAM,4BAA4B,aAAa,CAAA;AAEtD,eAAO,MAAM,cAAc,sBAAsB,CAAA;AAEjD,eAAO,MAAM,yBAAyB,iBAAiB,CAAA;AAEvD;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2ChC,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,gBAAgB;;;GA6G5B,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,WAAW
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../../src/helpers/constants.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,sBAAsB,+CAA+C,CAAA;AAElF,eAAO,MAAM,mBAAmB,6BAA6B,CAAA;AAE7D,eAAO,MAAM,gBAAgB,UAAU,CAAA;AAEvC,eAAO,MAAM,gBAAgB,KAAK,CAAA;AAElC,eAAO,MAAM,eAAe,UAAU,CAAA;AAEtC,eAAO,MAAM,sBAAsB,UAAU,CAAA;AAE7C,eAAO,MAAM,sBAAsB,SAAS,CAAA;AAE5C,eAAO,MAAM,4BAA4B,aAAa,CAAA;AAEtD,eAAO,MAAM,cAAc,sBAAsB,CAAA;AAEjD,eAAO,MAAM,yBAAyB,iBAAiB,CAAA;AAEvD;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2ChC,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,gBAAgB;;;GA6G5B,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6HvB,CAAA"}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* @param minimumAmountOfFollowing <number> The minimum amount of following the user should have
|
|
5
5
|
* @param minimumAmountOfFollowers <number> The minimum amount of followers the user should have
|
|
6
6
|
* @param minimumAmountOfPublicRepos <number> The minimum amount of public repos the user should have
|
|
7
|
-
* @returns <
|
|
7
|
+
* @returns <any> Return the avatar URL of the user if the user is reputable, false otherwise
|
|
8
8
|
*/
|
|
9
|
-
export declare const githubReputation: (userLogin: string, minimumAmountOfFollowing: number, minimumAmountOfFollowers: number, minimumAmountOfPublicRepos: number) => Promise<
|
|
9
|
+
export declare const githubReputation: (userLogin: string, minimumAmountOfFollowing: number, minimumAmountOfFollowers: number, minimumAmountOfPublicRepos: number) => Promise<any>;
|
|
10
10
|
//# sourceMappingURL=security.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"security.d.ts","sourceRoot":"","sources":["../../../../src/helpers/security.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"security.d.ts","sourceRoot":"","sources":["../../../../src/helpers/security.ts"],"names":[],"mappings":"AA8BA;;;;;;;GAOG;AACH,eAAO,MAAM,gBAAgB,cACd,MAAM,4BACS,MAAM,4BACN,MAAM,8BACJ,MAAM,KACnC,QAAQ,GAAG,CAsBb,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../../src/helpers/utils.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAA;AAC9C,OAAW,EAAE,YAAY,EAAE,MAAM,IAAI,CAAA;AAErC,OAAO,OAAO,EAAE,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AAEzC,OAAO,EACH,eAAe,EACf,YAAY,EAGZ,oBAAoB,EACpB,oBAAoB,EACpB,iBAAiB,EAGpB,MAAM,gBAAgB,CAAA;AAmBvB;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,SAAgB,MAAM,YAAW,OAAO,KAAW,QAAQ,iBAAiB,
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../../src/helpers/utils.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAA;AAC9C,OAAW,EAAE,YAAY,EAAE,MAAM,IAAI,CAAA;AAErC,OAAO,OAAO,EAAE,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AAEzC,OAAO,EACH,eAAe,EACf,YAAY,EAGZ,oBAAoB,EACpB,oBAAoB,EACpB,iBAAiB,EAGpB,MAAM,gBAAgB,CAAA;AAmBvB;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,SAAgB,MAAM,YAAW,OAAO,KAAW,QAAQ,iBAAiB,CA+NzG,CAAA;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,+BAA+B,iBAAkB,MAAM,UAAU,MAAM,KAAG,MAgBtF,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,oCAAoC,gBAAiB,MAAM,WAAW,MAAM,WAUxF,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,eAAe,aAAc,MAAM,KAAG,MASlD,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,wBAAyB,MAAM,KAAG,MACH,CAAA;AAElE;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa,QAAS,MAAM,KAAG,MAEsC,CAAA;AAElF;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,cAAsE,CAAA;AAEtG;;;;;;;GAOG;AACH,eAAO,MAAM,4BAA4B,aAC3B,MAAM,oBAAoB,CAAC,oBACnB,MAAM,KACzB,oBAYF,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,cAAe,MAAM,WAAW,OAAO,KAAG,MAC1B,CAAA;AAEjD;;;;;;;;GAQG;AACH,eAAO,MAAM,sCAAsC,sBAC5B,SAAS,YAClB,MAAM,oBAAoB,CAAC,cACzB,MAAM,iBACH,MAAM,gBACP,OAAO,KACtB,QAAQ,MAAM,oBAAoB,CAAC,CAmCrC,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,0CAA0C,0BAC5B,MAAM,gBACf,MAAM,gBACN,OAAO,WAImF,CAAA;AAE5G;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,qCAAqC,sBAC3B,SAAS,YAClB,MAAM,oBAAoB,CAAC,cACzB,MAAM,iBACH,MAAM,4BACK,MAAM,YAAY,CAAC,yBACtB,MAAM,gBACf,MAAM,gBACN,OAAO,KACtB,QAAQ,MAAM,CA2DhB,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,yBAAyB,aAAc,MAAM,UAAS,QAAQ,aAAa,CAAC,OAAO,CAAC,KAAY,MAQvG,CAAA;AAEN;;;;;;;GAOG;AACH,eAAO,MAAM,iBAAiB,kBACX,MAAM,UACb,MAAM,UACN,MAAM,YACJ,YAAY,KACvB,MAYF,CAAA;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,WAAW,sBAAuB,MAAM,KAAG,eA0IvD,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,WAAY,MAAM,KAAG,MAA0D,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@devtion/actions",
|
|
3
|
-
"version": "0.0.0-
|
|
3
|
+
"version": "0.0.0-4f2b2be",
|
|
4
4
|
"description": "A set of actions and helpers for CLI commands",
|
|
5
5
|
"repository": "git@github.com:privacy-scaling-explorations/p0tion.git",
|
|
6
6
|
"homepage": "https://github.com/privacy-scaling-explorations/p0tion",
|
|
@@ -83,5 +83,5 @@
|
|
|
83
83
|
"publishConfig": {
|
|
84
84
|
"access": "public"
|
|
85
85
|
},
|
|
86
|
-
"gitHead": "
|
|
86
|
+
"gitHead": "816ae7bedeb8c579e91cc2444d8c9d58ca77dc77"
|
|
87
87
|
}
|
package/src/helpers/constants.ts
CHANGED
package/src/helpers/security.ts
CHANGED
|
@@ -1,45 +1,12 @@
|
|
|
1
1
|
import fetch from "@adobe/node-fetch-retry"
|
|
2
|
+
|
|
2
3
|
/**
|
|
3
|
-
* This function
|
|
4
|
-
* @param user
|
|
5
|
-
* @returns
|
|
6
|
-
*/
|
|
7
|
-
const getNumberOfPublicReposGitHub = async (user: string): Promise<number> => {
|
|
8
|
-
const response = await fetch(`https://api.github.com/user/${user}/repos`, {
|
|
9
|
-
method: "GET",
|
|
10
|
-
headers: {
|
|
11
|
-
Authorization: `token ${process.env.GITHUB_ACCESS_TOKEN!}`
|
|
12
|
-
}
|
|
13
|
-
})
|
|
14
|
-
if (response.status !== 200)
|
|
15
|
-
throw new Error("It was not possible to retrieve the number of public repositories. Please try again.")
|
|
16
|
-
const jsonData: any = await response.json()
|
|
17
|
-
return jsonData.length
|
|
18
|
-
}
|
|
19
|
-
/**
|
|
20
|
-
* This function will return the number of followers of a user
|
|
21
|
-
* @param user <string> The username of the user
|
|
22
|
-
* @returns <number> The number of followers
|
|
23
|
-
*/
|
|
24
|
-
const getNumberOfFollowersGitHub = async (user: string): Promise<number> => {
|
|
25
|
-
const response = await fetch(`https://api.github.com/user/${user}/followers`, {
|
|
26
|
-
method: "GET",
|
|
27
|
-
headers: {
|
|
28
|
-
Authorization: `token ${process.env.GITHUB_ACCESS_TOKEN!}`
|
|
29
|
-
}
|
|
30
|
-
})
|
|
31
|
-
if (response.status !== 200)
|
|
32
|
-
throw new Error("It was not possible to retrieve the number of followers. Please try again.")
|
|
33
|
-
const jsonData: any = await response.json()
|
|
34
|
-
return jsonData.length
|
|
35
|
-
}
|
|
36
|
-
/**
|
|
37
|
-
* This function will return the number of following of a user
|
|
38
|
-
* @param user <string> The username of the user
|
|
39
|
-
* @returns <number> The number of following users
|
|
4
|
+
* This function queries the GitHub API to fetch users statistics
|
|
5
|
+
* @param user {string} the user uid
|
|
6
|
+
* @returns {any} the stats from the GitHub API
|
|
40
7
|
*/
|
|
41
|
-
const
|
|
42
|
-
const response = await fetch(`https://api.github.com/user/${user}
|
|
8
|
+
const getGitHubStats = async (user: string): Promise<any> => {
|
|
9
|
+
const response = await fetch(`https://api.github.com/user/${user}`, {
|
|
43
10
|
method: "GET",
|
|
44
11
|
headers: {
|
|
45
12
|
Authorization: `token ${process.env.GITHUB_ACCESS_TOKEN!}`
|
|
@@ -47,11 +14,18 @@ const getNumberOfFollowingGitHub = async (user: string): Promise<number> => {
|
|
|
47
14
|
})
|
|
48
15
|
|
|
49
16
|
if (response.status !== 200)
|
|
50
|
-
throw new Error("It was not possible to retrieve the
|
|
17
|
+
throw new Error("It was not possible to retrieve the user's statistic. Please try again.")
|
|
51
18
|
|
|
52
19
|
const jsonData: any = await response.json()
|
|
53
20
|
|
|
54
|
-
|
|
21
|
+
const data = {
|
|
22
|
+
following: jsonData.following,
|
|
23
|
+
followers: jsonData.followers,
|
|
24
|
+
publicRepos: jsonData.public_repos,
|
|
25
|
+
avatarUrl: jsonData.avatar_url
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return data
|
|
55
29
|
}
|
|
56
30
|
|
|
57
31
|
/**
|
|
@@ -60,27 +34,33 @@ const getNumberOfFollowingGitHub = async (user: string): Promise<number> => {
|
|
|
60
34
|
* @param minimumAmountOfFollowing <number> The minimum amount of following the user should have
|
|
61
35
|
* @param minimumAmountOfFollowers <number> The minimum amount of followers the user should have
|
|
62
36
|
* @param minimumAmountOfPublicRepos <number> The minimum amount of public repos the user should have
|
|
63
|
-
* @returns <
|
|
37
|
+
* @returns <any> Return the avatar URL of the user if the user is reputable, false otherwise
|
|
64
38
|
*/
|
|
65
39
|
export const githubReputation = async (
|
|
66
40
|
userLogin: string,
|
|
67
41
|
minimumAmountOfFollowing: number,
|
|
68
42
|
minimumAmountOfFollowers: number,
|
|
69
43
|
minimumAmountOfPublicRepos: number
|
|
70
|
-
): Promise<
|
|
44
|
+
): Promise<any> => {
|
|
71
45
|
if (!process.env.GITHUB_ACCESS_TOKEN)
|
|
72
46
|
throw new Error(
|
|
73
47
|
"The GitHub access token is missing. Please insert a valid token to be used for anti-sybil checks on user registation, and then try again."
|
|
74
48
|
)
|
|
75
|
-
|
|
76
|
-
const
|
|
77
|
-
const followers = await getNumberOfFollowersGitHub(userLogin)
|
|
49
|
+
|
|
50
|
+
const { following, followers, publicRepos, avatarUrl } = await getGitHubStats(userLogin)
|
|
78
51
|
|
|
79
52
|
if (
|
|
80
53
|
following < minimumAmountOfFollowing ||
|
|
81
|
-
|
|
54
|
+
publicRepos < minimumAmountOfPublicRepos ||
|
|
82
55
|
followers < minimumAmountOfFollowers
|
|
83
56
|
)
|
|
84
|
-
return
|
|
85
|
-
|
|
57
|
+
return {
|
|
58
|
+
reputable: false,
|
|
59
|
+
avatarUrl: ""
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return {
|
|
63
|
+
reputable: true,
|
|
64
|
+
avatarUrl: avatarUrl
|
|
65
|
+
}
|
|
86
66
|
}
|
package/src/helpers/utils.ts
CHANGED
|
@@ -87,34 +87,19 @@ export const parseCeremonyFile = async (path: string, cleanup: boolean = false):
|
|
|
87
87
|
circuitArtifacts.push({
|
|
88
88
|
artifacts: artifacts
|
|
89
89
|
})
|
|
90
|
-
const r1csPath = artifacts.r1csStoragePath
|
|
91
|
-
const wasmPath = artifacts.wasmStoragePath
|
|
92
90
|
|
|
93
91
|
// where we storing the r1cs downloaded
|
|
94
92
|
const localR1csPath = `./${circuitData.name}.r1cs`
|
|
93
|
+
// where we storing the wasm downloaded
|
|
94
|
+
const localWasmPath = `./${circuitData.name}.wasm`
|
|
95
95
|
|
|
96
96
|
// check that the artifacts exist in S3
|
|
97
97
|
// we don't need any privileges to download this
|
|
98
98
|
// just the correct region
|
|
99
|
-
const s3 = new S3Client({
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
Bucket: artifacts.bucket,
|
|
104
|
-
Key: r1csPath
|
|
105
|
-
}))
|
|
106
|
-
} catch (error: any) {
|
|
107
|
-
throw new Error(`The r1cs file (${r1csPath}) seems to not exist. Please ensure this is correct and that the object is publicly available.`)
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
try {
|
|
111
|
-
await s3.send(new HeadObjectCommand({
|
|
112
|
-
Bucket: artifacts.bucket,
|
|
113
|
-
Key: wasmPath
|
|
114
|
-
}))
|
|
115
|
-
} catch (error: any) {
|
|
116
|
-
throw new Error(`The wasm file (${wasmPath}) seems to not exist. Please ensure this is correct and that the object is publicly available.`)
|
|
117
|
-
}
|
|
99
|
+
const s3 = new S3Client({
|
|
100
|
+
region: artifacts.region,
|
|
101
|
+
credentials: undefined
|
|
102
|
+
})
|
|
118
103
|
|
|
119
104
|
// download the r1cs to extract the metadata
|
|
120
105
|
const command = new GetObjectCommand({ Bucket: artifacts.bucket, Key: artifacts.r1csStoragePath })
|
|
@@ -122,7 +107,7 @@ export const parseCeremonyFile = async (path: string, cleanup: boolean = false):
|
|
|
122
107
|
const streamPipeline = promisify(pipeline)
|
|
123
108
|
|
|
124
109
|
if (response.$metadata.httpStatusCode !== 200)
|
|
125
|
-
throw new Error(
|
|
110
|
+
throw new Error(`There was an error while trying to download the r1cs file for circuit ${circuitData.name}. Please check that the file has the correct permissions (public) set.`)
|
|
126
111
|
|
|
127
112
|
if (response.Body instanceof Readable)
|
|
128
113
|
await streamPipeline(response.Body, fs.createWriteStream(localR1csPath))
|
|
@@ -130,6 +115,16 @@ export const parseCeremonyFile = async (path: string, cleanup: boolean = false):
|
|
|
130
115
|
// extract the metadata from the r1cs
|
|
131
116
|
const metadata = getR1CSInfo(localR1csPath)
|
|
132
117
|
|
|
118
|
+
// download wasm too to ensure it's available
|
|
119
|
+
const wasmCommand = new GetObjectCommand({ Bucket: artifacts.bucket, Key: artifacts.wasmStoragePath })
|
|
120
|
+
const wasmResponse = await s3.send(wasmCommand)
|
|
121
|
+
|
|
122
|
+
if (wasmResponse.$metadata.httpStatusCode !== 200)
|
|
123
|
+
throw new Error(`There was an error while trying to download the wasm file for circuit ${circuitData.name}. Please check that the file has the correct permissions (public) set.`)
|
|
124
|
+
|
|
125
|
+
if (wasmResponse.Body instanceof Readable)
|
|
126
|
+
await streamPipeline(wasmResponse.Body, fs.createWriteStream(localWasmPath))
|
|
127
|
+
|
|
133
128
|
// validate that the circuit hash and template links are valid
|
|
134
129
|
const template = circuitData.template
|
|
135
130
|
|