@devtion/backend 0.0.0-b499eaf → 0.0.0-bbc217a

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.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/types/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAA;AAExF;;;;;;GAMG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC5B,iBAAiB,EAAE,iBAAiB,CAAA;IACpC,cAAc,EAAE,MAAM,CAAA;IACtB,QAAQ,EAAE,KAAK,CAAC,eAAe,CAAC,CAAA;CACnC,CAAA;AAED;;;;GAIG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC3B,UAAU,EAAE,MAAM,CAAA;CACrB,CAAA;AAED;;;;;GAKG;AACH,MAAM,MAAM,sBAAsB,GAAG;IACjC,UAAU,EAAE,MAAM,CAAA;IAClB,SAAS,EAAE,MAAM,CAAA;CACpB,CAAA;AAED;;;;;;GAMG;AACH,MAAM,MAAM,wBAAwB,GAAG,sBAAsB,GAAG;IAC5D,UAAU,CAAC,EAAE,MAAM,CAAA;CACtB,CAAA;AAED;;;;;;;;GAQG;AACH,MAAM,MAAM,8BAA8B,GAAG,sBAAsB,GAAG;IAClE,QAAQ,EAAE,MAAM,CAAA;IAChB,aAAa,EAAE,MAAM,CAAA;IACrB,UAAU,CAAC,EAAE,MAAM,CAAA;CACtB,CAAA;AAED;;;;;;;;GAQG;AACH,MAAM,MAAM,2BAA2B,GAAG,sBAAsB,GAAG;IAC/D,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,EAAE,KAAK,CAAC,kBAAkB,CAAC,CAAA;IAChC,UAAU,CAAC,EAAE,MAAM,CAAA;CACtB,CAAA;AAED;;;;;;GAMG;AACH,MAAM,MAAM,8CAA8C,GAAG;IACzD,UAAU,EAAE,MAAM,CAAA;IAClB,2BAA2B,EAAE,MAAM,CAAA;IACnC,gBAAgB,EAAE,MAAM,CAAA;CAC3B,CAAA;AAED;;;;;GAKG;AACH,MAAM,MAAM,kDAAkD,GAAG;IAC7D,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;CACnB,CAAA;AAED;;;;;GAKG;AACH,MAAM,MAAM,kDAAkD,GAAG;IAC7D,UAAU,EAAE,MAAM,CAAA;IAClB,KAAK,EAAE,kBAAkB,CAAA;CAC5B,CAAA;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,sBAAsB,GAAG;IACjC,UAAU,EAAE,MAAM,CAAA;IAClB,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,EAAE,MAAM,CAAA;IAClB,kCAAkC,EAAE,MAAM,CAAA;CAC7C,CAAA;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,mBAAmB,GAAG;IAC9B,UAAU,EAAE,MAAM,CAAA;IAClB,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,EAAE,MAAM,CAAA;IAClB,MAAM,EAAE,MAAM,CAAA;CACjB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/types/index.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@devtion/backend",
3
- "version": "0.0.0-b499eaf",
3
+ "version": "0.0.0-bbc217a",
4
4
  "description": "MPC Phase 2 backend for Firebase services management",
5
5
  "repository": "git@github.com:privacy-scaling-explorations/p0tion.git",
6
6
  "homepage": "https://github.com/privacy-scaling-explorations/p0tion",
@@ -67,6 +67,7 @@
67
67
  "@aws-sdk/client-ssm": "^3.357.0",
68
68
  "@aws-sdk/middleware-endpoint": "^3.329.0",
69
69
  "@aws-sdk/s3-request-presigner": "^3.329.0",
70
+ "@bandada/api-sdk": "^1.0.0-beta.1",
70
71
  "@devtion/actions": "latest",
71
72
  "blakejs": "^1.2.1",
72
73
  "dotenv": "^16.0.3",
@@ -76,7 +77,7 @@
76
77
  "html-entities": "^2.3.3",
77
78
  "rimraf": "^5.0.0",
78
79
  "rollup": "^3.21.6",
79
- "snarkjs": "^0.6.11",
80
+ "snarkjs": "0.7.3",
80
81
  "solc": "^0.8.19",
81
82
  "timer-node": "^5.0.7",
82
83
  "uuid": "^9.0.0",
@@ -85,5 +86,5 @@
85
86
  "publishConfig": {
86
87
  "access": "public"
87
88
  },
88
- "gitHead": "253890f0a88d586c4d023c6ace7a5fd3d5085568"
89
+ "gitHead": "41d13d724d628f5901ece1ef659d1a554c0db8d9"
89
90
  }
@@ -0,0 +1,155 @@
1
+ import dotenv from "dotenv"
2
+ import * as functions from "firebase-functions"
3
+ import { ApiSdk } from "@bandada/api-sdk"
4
+ import { groth16 } from "snarkjs"
5
+ import { getAuth } from "firebase-admin/auth"
6
+ import admin from "firebase-admin"
7
+ import { BandadaValidateProof, VerifiedBandadaResponse } from "../types/index"
8
+
9
+ const VKEY_DATA = {
10
+ protocol: "groth16",
11
+ curve: "bn128",
12
+ nPublic: 3,
13
+ vk_alpha_1: [
14
+ "20491192805390485299153009773594534940189261866228447918068658471970481763042",
15
+ "9383485363053290200918347156157836566562967994039712273449902621266178545958",
16
+ "1"
17
+ ],
18
+ vk_beta_2: [
19
+ [
20
+ "6375614351688725206403948262868962793625744043794305715222011528459656738731",
21
+ "4252822878758300859123897981450591353533073413197771768651442665752259397132"
22
+ ],
23
+ [
24
+ "10505242626370262277552901082094356697409835680220590971873171140371331206856",
25
+ "21847035105528745403288232691147584728191162732299865338377159692350059136679"
26
+ ],
27
+ ["1", "0"]
28
+ ],
29
+ vk_gamma_2: [
30
+ [
31
+ "10857046999023057135944570762232829481370756359578518086990519993285655852781",
32
+ "11559732032986387107991004021392285783925812861821192530917403151452391805634"
33
+ ],
34
+ [
35
+ "8495653923123431417604973247489272438418190587263600148770280649306958101930",
36
+ "4082367875863433681332203403145435568316851327593401208105741076214120093531"
37
+ ],
38
+ ["1", "0"]
39
+ ],
40
+ vk_delta_2: [
41
+ [
42
+ "3697618915467790705869942236922063775466274665053173890632463796679068973252",
43
+ "14948341351907992175709156460547989243732741534604949238422596319735704165658"
44
+ ],
45
+ [
46
+ "3028459181652799888716942141752307629938889957960373621898607910203491239368",
47
+ "11380736494786911280692284374675752681598754560757720296073023058533044108340"
48
+ ],
49
+ ["1", "0"]
50
+ ],
51
+ vk_alphabeta_12: [
52
+ [
53
+ [
54
+ "2029413683389138792403550203267699914886160938906632433982220835551125967885",
55
+ "21072700047562757817161031222997517981543347628379360635925549008442030252106"
56
+ ],
57
+ [
58
+ "5940354580057074848093997050200682056184807770593307860589430076672439820312",
59
+ "12156638873931618554171829126792193045421052652279363021382169897324752428276"
60
+ ],
61
+ [
62
+ "7898200236362823042373859371574133993780991612861777490112507062703164551277",
63
+ "7074218545237549455313236346927434013100842096812539264420499035217050630853"
64
+ ]
65
+ ],
66
+ [
67
+ [
68
+ "7077479683546002997211712695946002074877511277312570035766170199895071832130",
69
+ "10093483419865920389913245021038182291233451549023025229112148274109565435465"
70
+ ],
71
+ [
72
+ "4595479056700221319381530156280926371456704509942304414423590385166031118820",
73
+ "19831328484489333784475432780421641293929726139240675179672856274388269393268"
74
+ ],
75
+ [
76
+ "11934129596455521040620786944827826205713621633706285934057045369193958244500",
77
+ "8037395052364110730298837004334506829870972346962140206007064471173334027475"
78
+ ]
79
+ ]
80
+ ],
81
+ IC: [
82
+ [
83
+ "12951059800758687233303204819298121944551181861362200875212570257618182506154",
84
+ "5751958719396509176593242305268064754837298673622815112953832050159760501392",
85
+ "1"
86
+ ],
87
+ [
88
+ "9561588427935871983444704959674198910445823619407211599507208879011862515257",
89
+ "14576201570478094842467636169770180675293504492823217349086195663150934064643",
90
+ "1"
91
+ ],
92
+ [
93
+ "4811967233483727873912563574622036989372099129165459921963463310078093941559",
94
+ "1874883809855039536107616044787862082553628089593740724610117059083415551067",
95
+ "1"
96
+ ],
97
+ [
98
+ "12252730267779308452229639835051322390696643456253768618882001876621526827161",
99
+ "7899194018737016222260328309937800777948677569409898603827268776967707173231",
100
+ "1"
101
+ ]
102
+ ]
103
+ }
104
+
105
+ dotenv.config()
106
+
107
+ const { BANDADA_API_URL, BANDADA_GROUP_ID } = process.env
108
+
109
+ const bandadaApi = new ApiSdk(BANDADA_API_URL)
110
+
111
+ export const bandadaValidateProof = functions
112
+ .region("europe-west1")
113
+ .runWith({
114
+ memory: "512MB"
115
+ })
116
+ .https.onCall(async (data: BandadaValidateProof): Promise<VerifiedBandadaResponse> => {
117
+ if (!BANDADA_GROUP_ID) throw new Error("BANDADA_GROUP_ID is not defined in .env")
118
+
119
+ const { proof, publicSignals } = data
120
+ const isCorrect = groth16.verify(VKEY_DATA, publicSignals, proof)
121
+ if (!isCorrect)
122
+ return {
123
+ valid: false,
124
+ message: "Invalid proof",
125
+ token: ""
126
+ }
127
+
128
+ const commitment = data.publicSignals[1]
129
+ const isMember = await bandadaApi.isGroupMember(BANDADA_GROUP_ID, commitment)
130
+ if (!isMember)
131
+ return {
132
+ valid: false,
133
+ message: "Not a member of the group",
134
+ token: ""
135
+ }
136
+ const auth = getAuth()
137
+ try {
138
+ await admin.auth().createUser({
139
+ uid: commitment
140
+ })
141
+ } catch (error: any) {
142
+ // if user already exist then just pass
143
+ if (error.code !== "auth/uid-already-exists") {
144
+ throw new Error(error)
145
+ }
146
+ }
147
+ const token = await auth.createCustomToken(commitment)
148
+ return {
149
+ valid: true,
150
+ message: "Valid proof and group member",
151
+ token
152
+ }
153
+ })
154
+
155
+ export default bandadaValidateProof
@@ -46,7 +46,7 @@ dotenv.config()
46
46
  export const startCeremony = functions
47
47
  .region("europe-west1")
48
48
  .runWith({
49
- memory: "512MB"
49
+ memory: "1GB"
50
50
  })
51
51
  .pubsub.schedule(`every 30 minutes`)
52
52
  .onRun(async () => {
@@ -71,7 +71,7 @@ export const startCeremony = functions
71
71
  export const stopCeremony = functions
72
72
  .region("europe-west1")
73
73
  .runWith({
74
- memory: "512MB"
74
+ memory: "1GB"
75
75
  })
76
76
  .pubsub.schedule(`every 30 minutes`)
77
77
  .onRun(async () => {
@@ -96,7 +96,7 @@ export const stopCeremony = functions
96
96
  export const setupCeremony = functions
97
97
  .region("europe-west1")
98
98
  .runWith({
99
- memory: "512MB"
99
+ memory: "1GB"
100
100
  })
101
101
  .https.onCall(async (data: SetupCeremonyData, context: functions.https.CallableContext): Promise<any> => {
102
102
  // Check if the user has the coordinator claim.
@@ -273,7 +273,7 @@ export const initEmptyWaitingQueueForCircuit = functions
273
273
  export const finalizeCeremony = functions
274
274
  .region("europe-west1")
275
275
  .runWith({
276
- memory: "512MB"
276
+ memory: "1GB"
277
277
  })
278
278
  .https.onCall(async (data: { ceremonyId: string }, context: functions.https.CallableContext): Promise<any> => {
279
279
  if (!context.auth || !context.auth.token.coordinator) logAndThrowError(COMMON_ERRORS.CM_NOT_COORDINATOR_ROLE)
@@ -312,7 +312,7 @@ const waitForVMCommandExecution = (ssm: SSMClient, vmInstanceId: string, command
312
312
  export const coordinateCeremonyParticipant = functionsV1
313
313
  .region("europe-west1")
314
314
  .runWith({
315
- memory: "512MB"
315
+ memory: "1GB"
316
316
  })
317
317
  .firestore.document(
318
318
  `${commonTerms.collections.ceremonies.name}/{ceremonyId}/${commonTerms.collections.participants.name}/{participantId}`
@@ -883,7 +883,7 @@ export const verifycontribution = functionsV2.https.onCall(
883
883
  export const refreshParticipantAfterContributionVerification = functionsV1
884
884
  .region("europe-west1")
885
885
  .runWith({
886
- memory: "512MB"
886
+ memory: "1GB"
887
887
  })
888
888
  .firestore.document(
889
889
  `/${commonTerms.collections.ceremonies.name}/{ceremony}/${commonTerms.collections.circuits.name}/{circuit}/${commonTerms.collections.contributions.name}/{contributions}`
@@ -966,7 +966,7 @@ export const refreshParticipantAfterContributionVerification = functionsV1
966
966
  export const finalizeCircuit = functionsV1
967
967
  .region("europe-west1")
968
968
  .runWith({
969
- memory: "512MB"
969
+ memory: "1GB"
970
970
  })
971
971
  .https.onCall(async (data: FinalizeCircuitData, context: functionsV1.https.CallableContext) => {
972
972
  if (!context.auth || !context.auth.token.coordinator) logAndThrowError(COMMON_ERRORS.CM_NOT_COORDINATOR_ROLE)
@@ -31,6 +31,8 @@ export {
31
31
  generatePreSignedUrlsParts,
32
32
  completeMultiPartUpload
33
33
  } from "./storage"
34
+ export { bandadaValidateProof } from "./bandada"
35
+ export { checkNonceOfSIWEAddress } from "./siwe"
34
36
  export { checkAndRemoveBlockingContributor, resumeContributionAfterTimeoutExpiration } from "./timeout"
35
37
 
36
38
  admin.initializeApp()
@@ -46,7 +46,7 @@ dotenv.config()
46
46
  export const checkParticipantForCeremony = functions
47
47
  .region("europe-west1")
48
48
  .runWith({
49
- memory: "512MB"
49
+ memory: "1GB"
50
50
  })
51
51
  .https.onCall(async (data: { ceremonyId: string }, context: functions.https.CallableContext) => {
52
52
  if (!context.auth || (!context.auth.token.participant && !context.auth.token.coordinator))
@@ -177,7 +177,7 @@ export const checkParticipantForCeremony = functions
177
177
  export const progressToNextCircuitForContribution = functions
178
178
  .region("europe-west1")
179
179
  .runWith({
180
- memory: "512MB"
180
+ memory: "1GB"
181
181
  })
182
182
  .https.onCall(async (data: { ceremonyId: string }, context: functions.https.CallableContext): Promise<void> => {
183
183
  if (!context.auth || (!context.auth.token.participant && !context.auth.token.coordinator))
@@ -235,7 +235,7 @@ export const progressToNextCircuitForContribution = functions
235
235
  export const progressToNextContributionStep = functions
236
236
  .region("europe-west1")
237
237
  .runWith({
238
- memory: "512MB"
238
+ memory: "1GB"
239
239
  })
240
240
  .https.onCall(async (data: { ceremonyId: string }, context: functions.https.CallableContext) => {
241
241
  if (!context.auth || (!context.auth.token.participant && !context.auth.token.coordinator))
@@ -298,7 +298,7 @@ export const progressToNextContributionStep = functions
298
298
  export const permanentlyStoreCurrentContributionTimeAndHash = functions
299
299
  .region("europe-west1")
300
300
  .runWith({
301
- memory: "512MB"
301
+ memory: "1GB"
302
302
  })
303
303
  .https.onCall(
304
304
  async (data: PermanentlyStoreCurrentContributionTimeAndHash, context: functions.https.CallableContext) => {
@@ -357,7 +357,7 @@ export const permanentlyStoreCurrentContributionTimeAndHash = functions
357
357
  export const temporaryStoreCurrentContributionMultiPartUploadId = functions
358
358
  .region("europe-west1")
359
359
  .runWith({
360
- memory: "512MB"
360
+ memory: "1GB"
361
361
  })
362
362
  .https.onCall(
363
363
  async (data: TemporaryStoreCurrentContributionMultiPartUploadId, context: functions.https.CallableContext) => {
@@ -411,7 +411,7 @@ export const temporaryStoreCurrentContributionMultiPartUploadId = functions
411
411
  export const temporaryStoreCurrentContributionUploadedChunkData = functions
412
412
  .region("europe-west1")
413
413
  .runWith({
414
- memory: "512MB"
414
+ memory: "1GB"
415
415
  })
416
416
  .https.onCall(
417
417
  async (data: TemporaryStoreCurrentContributionUploadedChunkData, context: functions.https.CallableContext) => {
@@ -471,7 +471,7 @@ export const temporaryStoreCurrentContributionUploadedChunkData = functions
471
471
  export const checkAndPrepareCoordinatorForFinalization = functions
472
472
  .region("europe-west1")
473
473
  .runWith({
474
- memory: "512MB"
474
+ memory: "1GB"
475
475
  })
476
476
  .https.onCall(async (data: { ceremonyId: string }, context: functions.https.CallableContext): Promise<boolean> => {
477
477
  if (!context.auth || !context.auth.token.coordinator) logAndThrowError(COMMON_ERRORS.CM_NOT_COORDINATOR_ROLE)
@@ -0,0 +1,77 @@
1
+ import dotenv from "dotenv"
2
+ import fetch from "@adobe/node-fetch-retry"
3
+ import * as functions from "firebase-functions"
4
+ import { getAuth } from "firebase-admin/auth"
5
+ import admin from "firebase-admin"
6
+ import { Auth0UserInfo, CheckNonceOfSIWEAddressRequest, CheckNonceOfSIWEAddressResponse } from "../types"
7
+ import { setEthProvider } from "../lib/services"
8
+
9
+ dotenv.config()
10
+
11
+ export const checkNonceOfSIWEAddress = functions
12
+ .region("europe-west1")
13
+ .runWith({ memory: "1GB" })
14
+ .https.onCall(async (data: CheckNonceOfSIWEAddressRequest): Promise<CheckNonceOfSIWEAddressResponse> => {
15
+ try {
16
+ const { auth0Token } = data
17
+ const result = (await fetch(`${process.env.AUTH0_APPLICATION_URL}/userinfo`, {
18
+ method: "GET",
19
+ headers: {
20
+ "content-type": "application/json",
21
+ authorization: `Bearer ${auth0Token}`
22
+ }
23
+ }).then((_res) => _res.json())) as Auth0UserInfo
24
+ if (!result.sub) {
25
+ return {
26
+ valid: false,
27
+ message: "No user detected. Please check device flow token"
28
+ }
29
+ }
30
+ const auth = getAuth()
31
+ // check nonce
32
+ const parts = result.sub.split("|")
33
+ const address = decodeURIComponent(parts[2]).split(":")[2]
34
+
35
+ const minimumNonce = Number(process.env.ETH_MINIMUM_NONCE)
36
+ const nonceBlockHeight = "latest" // process.env.ETH_NONCE_BLOCK_HEIGHT
37
+ // look up nonce for address @block
38
+ let nonceOk = true
39
+ if (minimumNonce > 0) {
40
+ const provider = setEthProvider()
41
+ console.log(`got provider - block # ${await provider.getBlockNumber()}`)
42
+ const nonce = await provider.getTransactionCount(address, nonceBlockHeight)
43
+ console.log(`nonce ${nonce}`)
44
+ nonceOk = nonce >= minimumNonce
45
+ }
46
+ console.log(`checking nonce ${nonceOk}`)
47
+ if (!nonceOk) {
48
+ return {
49
+ valid: false,
50
+ message: "Eth address does not meet the nonce requirements"
51
+ }
52
+ }
53
+ try {
54
+ await admin.auth().createUser({
55
+ displayName: address,
56
+ uid: address
57
+ })
58
+ } catch (error: any) {
59
+ // if user already exist then just pass
60
+ if (error.code !== "auth/uid-already-exists") {
61
+ throw new Error(error)
62
+ }
63
+ }
64
+ const token = await auth.createCustomToken(address)
65
+ return {
66
+ valid: true,
67
+ token
68
+ }
69
+ } catch (error) {
70
+ return {
71
+ valid: false,
72
+ message: `Something went wrong ${error}`
73
+ }
74
+ }
75
+ })
76
+
77
+ export default checkNonceOfSIWEAddress
@@ -134,7 +134,7 @@ const checkIfBucketIsDedicatedToCeremony = async (bucketName: string) => {
134
134
  export const createBucket = functions
135
135
  .region("europe-west1")
136
136
  .runWith({
137
- memory: "512MB"
137
+ memory: "1GB"
138
138
  })
139
139
  .https.onCall(async (data: CreateBucketData, context: functions.https.CallableContext) => {
140
140
  // Check if the user has the coordinator claim.
@@ -238,7 +238,7 @@ export const createBucket = functions
238
238
  export const checkIfObjectExist = functions
239
239
  .region("europe-west1")
240
240
  .runWith({
241
- memory: "512MB"
241
+ memory: "1GB"
242
242
  })
243
243
  .https.onCall(async (data: BucketAndObjectKeyData, context: functions.https.CallableContext): Promise<boolean> => {
244
244
  // Check if the user has the coordinator claim.
@@ -294,7 +294,7 @@ export const checkIfObjectExist = functions
294
294
  export const generateGetObjectPreSignedUrl = functions
295
295
  .region("europe-west1")
296
296
  .runWith({
297
- memory: "512MB"
297
+ memory: "1GB"
298
298
  })
299
299
  .https.onCall(async (data: BucketAndObjectKeyData, context: functions.https.CallableContext): Promise<any> => {
300
300
  if (!context.auth) logAndThrowError(COMMON_ERRORS.CM_NOT_AUTHENTICATED)
@@ -341,7 +341,7 @@ export const generateGetObjectPreSignedUrl = functions
341
341
  export const startMultiPartUpload = functions
342
342
  .region("europe-west1")
343
343
  .runWith({
344
- memory: "512MB"
344
+ memory: "2GB"
345
345
  })
346
346
  .https.onCall(async (data: StartMultiPartUploadData, context: functions.https.CallableContext): Promise<any> => {
347
347
  if (!context.auth || (!context.auth.token.participant && !context.auth.token.coordinator))
@@ -409,7 +409,7 @@ export const startMultiPartUpload = functions
409
409
  export const generatePreSignedUrlsParts = functions
410
410
  .region("europe-west1")
411
411
  .runWith({
412
- memory: "512MB",
412
+ memory: "1GB",
413
413
  timeoutSeconds: 300
414
414
  })
415
415
  .https.onCall(
@@ -487,7 +487,7 @@ export const generatePreSignedUrlsParts = functions
487
487
  export const completeMultiPartUpload = functions
488
488
  .region("europe-west1")
489
489
  .runWith({
490
- memory: "512MB"
490
+ memory: "2GB"
491
491
  })
492
492
  .https.onCall(async (data: CompleteMultiPartUploadData, context: functions.https.CallableContext): Promise<any> => {
493
493
  if (!context.auth || (!context.auth.token.participant && !context.auth.token.coordinator))
@@ -42,7 +42,7 @@ dotenv.config()
42
42
  export const checkAndRemoveBlockingContributor = functions
43
43
  .region("europe-west1")
44
44
  .runWith({
45
- memory: "512MB"
45
+ memory: "1GB"
46
46
  })
47
47
  .pubsub.schedule("every 1 minutes")
48
48
  .onRun(async () => {
@@ -144,7 +144,8 @@ export const checkAndRemoveBlockingContributor = functions
144
144
  timeoutExpirationDateInMsForBlockingContributor < currentServerTimestamp &&
145
145
  (contributionStep === ParticipantContributionStep.DOWNLOADING ||
146
146
  contributionStep === ParticipantContributionStep.COMPUTING ||
147
- contributionStep === ParticipantContributionStep.UPLOADING)
147
+ contributionStep === ParticipantContributionStep.UPLOADING ||
148
+ contributionStep === ParticipantContributionStep.COMPLETED)
148
149
  )
149
150
  timeoutType = TimeoutType.BLOCKING_CONTRIBUTION
150
151
 
@@ -253,7 +254,7 @@ export const checkAndRemoveBlockingContributor = functions
253
254
  export const resumeContributionAfterTimeoutExpiration = functions
254
255
  .region("europe-west1")
255
256
  .runWith({
256
- memory: "512MB"
257
+ memory: "1GB"
257
258
  })
258
259
  .https.onCall(async (data: { ceremonyId: string }, context: functions.https.CallableContext): Promise<void> => {
259
260
  if (!context.auth || (!context.auth.token.participant && !context.auth.token.coordinator))
@@ -18,7 +18,7 @@ dotenv.config()
18
18
  export const registerAuthUser = functions
19
19
  .region("europe-west1")
20
20
  .runWith({
21
- memory: "512MB"
21
+ memory: "1GB"
22
22
  })
23
23
  .auth.user()
24
24
  .onCreate(async (user: UserRecord) => {
@@ -55,7 +55,7 @@ export const registerAuthUser = functions
55
55
  ) {
56
56
  const auth = admin.auth()
57
57
  // if provider == github.com let's use our functions to check the user's reputation
58
- if (user.providerData[0].providerId === "github.com") {
58
+ if (user.providerData.length > 0 && user.providerData[0].providerId === "github.com") {
59
59
  const vars = getGitHubVariables()
60
60
 
61
61
  // this return true or false
@@ -112,7 +112,7 @@ export const registerAuthUser = functions
112
112
  encodedDisplayName,
113
113
  // Metadata.
114
114
  creationTime,
115
- lastSignInTime,
115
+ lastSignInTime: lastSignInTime || creationTime,
116
116
  // Optional.
117
117
  email: email || "",
118
118
  emailVerified: emailVerified || false,
@@ -136,7 +136,7 @@ export const registerAuthUser = functions
136
136
  export const processSignUpWithCustomClaims = functions
137
137
  .region("europe-west1")
138
138
  .runWith({
139
- memory: "512MB"
139
+ memory: "1GB"
140
140
  })
141
141
  .auth.user()
142
142
  .onCreate(async (user: UserRecord) => {
package/src/lib/errors.ts CHANGED
@@ -7,7 +7,7 @@ import { LogLevel } from "../types/enums"
7
7
  * @notice the set of Firebase Functions status codes. The codes are the same at the
8
8
  * ones exposed by {@link https://github.com/grpc/grpc/blob/master/doc/statuscodes.md | gRPC}.
9
9
  * @param errorCode <FunctionsErrorCode> - the set of possible error codes.
10
- * @param message <string> - the error messge.
10
+ * @param message <string> - the error message.
11
11
  * @param [details] <string> - the details of the error (optional).
12
12
  * @returns <HttpsError>
13
13
  */
@@ -1,6 +1,11 @@
1
+ import dotenv from "dotenv"
2
+ import ethers from "ethers"
1
3
  import { S3Client } from "@aws-sdk/client-s3"
2
4
  import { COMMON_ERRORS, logAndThrowError } from "./errors"
3
5
 
6
+ dotenv.config()
7
+ let provider: ethers.providers.Provider
8
+
4
9
  /**
5
10
  * Return a configured and connected instance of the AWS S3 client.
6
11
  * @dev this method check and utilize the environment variables to configure the connection
@@ -26,3 +31,34 @@ export const getS3Client = async (): Promise<S3Client> => {
26
31
  region: process.env.AWS_REGION!
27
32
  })
28
33
  }
34
+
35
+ /**
36
+ * Returns a Prvider, connected via a configured JSON URL or else
37
+ * the ethers.js default provider, using configured API keys.
38
+ * @returns <ethers.providers.Provider> An Eth node provider
39
+ */
40
+ export const setEthProvider = (): ethers.providers.Provider => {
41
+ if (provider) return provider
42
+ console.log(`setting new provider`)
43
+
44
+ // Use JSON URL if defined
45
+ // if ((hardhat as any).ethers) {
46
+ // console.log(`using hardhat.ethers provider`)
47
+ // provider = (hardhat as any).ethers.provider
48
+ // } else
49
+ if (process.env.ETH_PROVIDER_JSON_URL) {
50
+ console.log(`JSON URL provider at ${process.env.ETH_PROVIDER_JSON_URL}`)
51
+ provider = new ethers.providers.JsonRpcProvider({
52
+ url: process.env.ETH_PROVIDER_JSON_URL,
53
+ skipFetchSetup: true
54
+ })
55
+ } else {
56
+ // Otherwise, connect the default provider with ALchemy, Infura, or both
57
+ provider = ethers.providers.getDefaultProvider("homestead", {
58
+ alchemy: process.env.ETH_PROVIDER_ALCHEMY_API_KEY!,
59
+ infura: process.env.ETH_PROVIDER_INFURA_API_KEY!
60
+ })
61
+ }
62
+
63
+ return provider
64
+ }
@@ -0,0 +1 @@
1
+ declare module "@bandada/api-sdk"
@@ -1,4 +1,5 @@
1
1
  import { CeremonyInputData, CircuitDocument, ETagWithPartNumber } from "@devtion/actions"
2
+ import type { Groth16Proof, PublicSignals } from "snarkjs"
2
3
 
3
4
  /**
4
5
  * Group all the necessary data needed for running the `setupCeremony` cloud function.
@@ -138,3 +139,62 @@ export type FinalizeCircuitData = {
138
139
  bucketName: string
139
140
  beacon: string
140
141
  }
142
+
143
+ /**
144
+ * Group all the necessary data needed for running the `bandadaValidateProof` cloud function.
145
+ * @typedef {Object} BandadaValidateProof
146
+ * @property {string} merkleTreeRoot - the merkle tree root of the group.
147
+ * @property {string} nullifierHash - the nullifier hash of the member.
148
+ * @property {string} externalNullifier - the external nullifier of the member.
149
+ * @property {PackedProof} proof - the packed proof generated on the client.
150
+ */
151
+ export type BandadaValidateProof = {
152
+ proof: Groth16Proof
153
+ publicSignals: PublicSignals
154
+ }
155
+
156
+ /**
157
+ * Define the return object of the function that verifies the Bandada membership and proof.
158
+ * @typedef {Object} VerifiedBandadaResponse
159
+ * @property {boolean} valid - true if the proof is valid and the user is a member of the group; otherwise false.
160
+ * @property {string} message - a message describing the result of the verification.
161
+ * @property {string} token - the custom access token.
162
+ */
163
+ export type VerifiedBandadaResponse = {
164
+ valid: boolean
165
+ message: string
166
+ token: string
167
+ }
168
+
169
+ /**
170
+ * Define the check nonce object for the cloud function
171
+ * @typedef {Object} CheckNonceOfSIWEAddressRequest
172
+ * @property {string} auth0Token - token from the device flow authentication
173
+ */
174
+ export type CheckNonceOfSIWEAddressRequest = {
175
+ auth0Token: string
176
+ }
177
+
178
+ /**
179
+ * Define the check nonce response object of the cloud function
180
+ * @typedef {Object} CheckNonceOfSIWEAddressResponse
181
+ * @property {boolean} valid - if the checking result was valid or not
182
+ * @property {string} message - informative message
183
+ * @property {string} token - token to sign in
184
+ */
185
+ export type CheckNonceOfSIWEAddressResponse = {
186
+ valid: boolean
187
+ message?: string
188
+ token?: string
189
+ }
190
+ /**
191
+ * Define the response from auth0 /userinfo endpoint
192
+ *
193
+ */
194
+ export type Auth0UserInfo = {
195
+ sub: string
196
+ nickname: string
197
+ name: string
198
+ picture: string
199
+ updated_at: string
200
+ }