@zkpassport/sdk 0.2.7 → 0.2.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/dist/cjs/index.d.ts +36 -2
- package/dist/cjs/index.js +332 -82
- package/dist/esm/index.d.ts +36 -2
- package/dist/esm/index.js +332 -82
- package/package.json +1 -1
- package/src/index.ts +393 -85
package/dist/esm/index.js
CHANGED
|
@@ -62,6 +62,7 @@ export class ZKPassport {
|
|
|
62
62
|
//private wasmVerifierInit: boolean = false
|
|
63
63
|
constructor(_domain) {
|
|
64
64
|
this.topicToConfig = {};
|
|
65
|
+
this.topicToLocalConfig = {};
|
|
65
66
|
this.topicToKeyPair = {};
|
|
66
67
|
this.topicToWebSocketClient = {};
|
|
67
68
|
this.topicToSharedSecret = {};
|
|
@@ -69,6 +70,7 @@ export class ZKPassport {
|
|
|
69
70
|
this.topicToService = {};
|
|
70
71
|
this.topicToProofs = {};
|
|
71
72
|
this.topicToExpectedProofCount = {};
|
|
73
|
+
this.topicToFailedProofCount = {};
|
|
72
74
|
this.topicToResults = {};
|
|
73
75
|
this.onRequestReceivedCallbacks = {};
|
|
74
76
|
this.onGeneratingProofCallbacks = {};
|
|
@@ -93,14 +95,19 @@ export class ZKPassport {
|
|
|
93
95
|
// Clear the results straight away to avoid concurrency issues
|
|
94
96
|
delete this.topicToResults[topic];
|
|
95
97
|
// Verify the proofs and extract the unique identifier (aka nullifier) and the verification result
|
|
96
|
-
const { uniqueIdentifier, verified } = await this.verify(topic, this.topicToProofs[topic], result);
|
|
98
|
+
const { uniqueIdentifier, verified, queryResultErrors } = await this.verify(topic, this.topicToProofs[topic], result);
|
|
99
|
+
const hasFailedProofs = this.topicToFailedProofCount[topic] > 0;
|
|
97
100
|
await Promise.all(this.onResultCallbacks[topic].map((callback) => callback({
|
|
98
|
-
|
|
99
|
-
verified
|
|
101
|
+
// If there are failed proofs, we don't return the unique identifier
|
|
102
|
+
// and we set the verified result to false
|
|
103
|
+
uniqueIdentifier: hasFailedProofs ? undefined : uniqueIdentifier,
|
|
104
|
+
verified: hasFailedProofs ? false : verified,
|
|
100
105
|
result,
|
|
106
|
+
queryResultErrors,
|
|
101
107
|
})));
|
|
102
|
-
// Clear the expected proof count
|
|
108
|
+
// Clear the expected proof count and failed proof count
|
|
103
109
|
delete this.topicToExpectedProofCount[topic];
|
|
110
|
+
delete this.topicToFailedProofCount[topic];
|
|
104
111
|
}
|
|
105
112
|
setExpectedProofCount(topic) {
|
|
106
113
|
const fields = Object.keys(this.topicToConfig[topic]).filter((key) => hasRequestedAccessToField(this.topicToConfig[topic], key));
|
|
@@ -151,6 +158,7 @@ export class ZKPassport {
|
|
|
151
158
|
// Each separate needed circuit adds 1 disclosure proof
|
|
152
159
|
this.topicToExpectedProofCount[topic] =
|
|
153
160
|
neededCircuits.length === 0 ? 4 : 3 + neededCircuits.length;
|
|
161
|
+
this.topicToFailedProofCount[topic] = 0;
|
|
154
162
|
}
|
|
155
163
|
/**
|
|
156
164
|
* @notice Handle an encrypted message.
|
|
@@ -206,6 +214,7 @@ export class ZKPassport {
|
|
|
206
214
|
// This means the user has an ID that is not supported yet
|
|
207
215
|
// So we won't receive any proofs and we can handle the result now
|
|
208
216
|
this.topicToExpectedProofCount[topic] = 0;
|
|
217
|
+
this.topicToFailedProofCount[topic] += this.topicToExpectedProofCount[topic];
|
|
209
218
|
if (this.topicToResults[topic]) {
|
|
210
219
|
await this.handleResult(topic);
|
|
211
220
|
}
|
|
@@ -214,6 +223,7 @@ export class ZKPassport {
|
|
|
214
223
|
// This means one of the disclosure proofs failed to be generated
|
|
215
224
|
// So we need to remove one from the expected proof count
|
|
216
225
|
this.topicToExpectedProofCount[topic] -= 1;
|
|
226
|
+
this.topicToFailedProofCount[topic] += 1;
|
|
217
227
|
// If the expected proof count is now equal to the number of proofs received
|
|
218
228
|
// and the results were received, we can handle the result now
|
|
219
229
|
if (this.topicToResults[topic] &&
|
|
@@ -270,9 +280,6 @@ export class ZKPassport {
|
|
|
270
280
|
};
|
|
271
281
|
return this.getZkPassportRequest(topic);
|
|
272
282
|
},
|
|
273
|
-
/*checkAML: (country?: CountryName | Alpha2Code | Alpha3Code) => {
|
|
274
|
-
return this.getZkPassportRequest(topic)
|
|
275
|
-
},*/
|
|
276
283
|
done: () => {
|
|
277
284
|
const base64Config = Buffer.from(JSON.stringify(this.topicToConfig[topic])).toString("base64");
|
|
278
285
|
const base64Service = Buffer.from(JSON.stringify(this.topicToService[topic])).toString("base64");
|
|
@@ -295,10 +302,15 @@ export class ZKPassport {
|
|
|
295
302
|
};
|
|
296
303
|
}
|
|
297
304
|
/**
|
|
298
|
-
* @notice Create a new request
|
|
305
|
+
* @notice Create a new request
|
|
306
|
+
* @param name Your service name
|
|
307
|
+
* @param logo The logo of your service
|
|
308
|
+
* @param purpose To explain what you want to do with the user's data
|
|
309
|
+
* @param scope Scope this request to a specific use case
|
|
310
|
+
* @param validity How many days ago should have the ID been last scanned by the user?
|
|
299
311
|
* @returns The query builder object.
|
|
300
312
|
*/
|
|
301
|
-
async request({ name, logo, purpose, scope, topicOverride, keyPairOverride, }) {
|
|
313
|
+
async request({ name, logo, purpose, scope, validity, topicOverride, keyPairOverride, }) {
|
|
302
314
|
const topic = topicOverride || randomBytes(16).toString("hex");
|
|
303
315
|
const keyPair = keyPairOverride || (await generateECDHKeyPair());
|
|
304
316
|
this.topicToKeyPair[topic] = {
|
|
@@ -309,6 +321,10 @@ export class ZKPassport {
|
|
|
309
321
|
this.topicToService[topic] = { name, logo, purpose, scope };
|
|
310
322
|
this.topicToProofs[topic] = [];
|
|
311
323
|
this.topicToExpectedProofCount[topic] = 0;
|
|
324
|
+
this.topicToLocalConfig[topic] = {
|
|
325
|
+
// Default to 6 months
|
|
326
|
+
validity: validity || 6 * 30,
|
|
327
|
+
};
|
|
312
328
|
this.onRequestReceivedCallbacks[topic] = [];
|
|
313
329
|
this.onGeneratingProofCallbacks[topic] = [];
|
|
314
330
|
this.onBridgeConnectCallbacks[topic] = [];
|
|
@@ -365,7 +381,7 @@ export class ZKPassport {
|
|
|
365
381
|
};
|
|
366
382
|
return this.getZkPassportRequest(topic);
|
|
367
383
|
}
|
|
368
|
-
async checkPublicInputs(proofs, queryResult) {
|
|
384
|
+
async checkPublicInputs(proofs, queryResult, topic) {
|
|
369
385
|
let commitmentIn;
|
|
370
386
|
let commitmentOut;
|
|
371
387
|
let isCorrect = true;
|
|
@@ -374,6 +390,23 @@ export class ZKPassport {
|
|
|
374
390
|
const defaultDateValue = new Date(1111, 10, 11);
|
|
375
391
|
const currentTime = new Date();
|
|
376
392
|
const today = new Date(currentTime.getFullYear(), currentTime.getMonth(), currentTime.getDate(), 0, 0, 0, 0);
|
|
393
|
+
const queryResultErrors = {
|
|
394
|
+
sig_check_dsc: {},
|
|
395
|
+
sig_check_id_data: {},
|
|
396
|
+
data_check_integrity: {},
|
|
397
|
+
disclose: {},
|
|
398
|
+
age: {},
|
|
399
|
+
birthdate: {},
|
|
400
|
+
expiry_date: {},
|
|
401
|
+
document_type: {},
|
|
402
|
+
issuing_country: {},
|
|
403
|
+
gender: {},
|
|
404
|
+
nationality: {},
|
|
405
|
+
firstname: {},
|
|
406
|
+
lastname: {},
|
|
407
|
+
fullname: {},
|
|
408
|
+
document_number: {},
|
|
409
|
+
};
|
|
377
410
|
// Since the order is important for the commitments, we need to sort the proofs
|
|
378
411
|
// by their expected order: root signature check -> ID signature check -> integrity check -> disclosure
|
|
379
412
|
const sortedProofs = proofs.sort((a, b) => {
|
|
@@ -402,7 +435,11 @@ export class ZKPassport {
|
|
|
402
435
|
if (merkleRoot !== expectedMerkleRoot) {
|
|
403
436
|
console.warn("The ID was signed by an unrecognized root certificate");
|
|
404
437
|
isCorrect = false;
|
|
405
|
-
|
|
438
|
+
queryResultErrors.sig_check_dsc.certificate = {
|
|
439
|
+
expected: `Certificate registry root: ${expectedMerkleRoot.toString()}`,
|
|
440
|
+
received: `Certificate registry root: ${merkleRoot.toString()}`,
|
|
441
|
+
message: "The ID was signed by an unrecognized root certificate",
|
|
442
|
+
};
|
|
406
443
|
}
|
|
407
444
|
}
|
|
408
445
|
else if (proof.name?.startsWith("sig_check_id_data")) {
|
|
@@ -410,7 +447,11 @@ export class ZKPassport {
|
|
|
410
447
|
if (commitmentIn !== commitmentOut) {
|
|
411
448
|
console.warn("Failed to check the link between the certificate signature and ID signature");
|
|
412
449
|
isCorrect = false;
|
|
413
|
-
|
|
450
|
+
queryResultErrors.sig_check_id_data.commitment = {
|
|
451
|
+
expected: `Commitment: ${commitmentOut?.toString() || "undefined"}`,
|
|
452
|
+
received: `Commitment: ${commitmentIn?.toString() || "undefined"}`,
|
|
453
|
+
message: "Failed to check the link between the certificate signature and ID signature",
|
|
454
|
+
};
|
|
414
455
|
}
|
|
415
456
|
commitmentOut = getCommitmentOutFromIDDataProof(proofData);
|
|
416
457
|
}
|
|
@@ -419,17 +460,26 @@ export class ZKPassport {
|
|
|
419
460
|
if (commitmentIn !== commitmentOut) {
|
|
420
461
|
console.warn("Failed to check the link between the ID signature and the data signed");
|
|
421
462
|
isCorrect = false;
|
|
422
|
-
|
|
463
|
+
queryResultErrors.data_check_integrity.commitment = {
|
|
464
|
+
expected: `Commitment: ${commitmentOut?.toString() || "undefined"}`,
|
|
465
|
+
received: `Commitment: ${commitmentIn?.toString() || "undefined"}`,
|
|
466
|
+
message: "Failed to check the link between the ID signature and the data signed",
|
|
467
|
+
};
|
|
423
468
|
}
|
|
424
469
|
commitmentOut = getCommitmentOutFromIntegrityProof(proofData);
|
|
425
470
|
const currentDate = getCurrentDateFromIntegrityProof(proofData);
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
471
|
+
const todayToCurrentDate = today.getTime() - currentDate.getTime();
|
|
472
|
+
const expectedDifference = this.topicToLocalConfig[topic]?.validity * 86400000;
|
|
473
|
+
const actualDifference = today.getTime() - (today.getTime() - expectedDifference);
|
|
474
|
+
// The ID should not expire within the next 6 months (or whatever the custom value is)
|
|
475
|
+
if (todayToCurrentDate >= actualDifference) {
|
|
476
|
+
console.warn(`The date used to check the validity of the ID is older than ${this.topicToLocalConfig[topic]?.validity} days. You can ask the user to rescan their ID or ask them to disclose their expiry date`);
|
|
431
477
|
isCorrect = false;
|
|
432
|
-
|
|
478
|
+
queryResultErrors.data_check_integrity.date = {
|
|
479
|
+
expected: `Difference: ${this.topicToLocalConfig[topic]?.validity} days`,
|
|
480
|
+
received: `Difference: ${Math.round(todayToCurrentDate / 86400000)} days`,
|
|
481
|
+
message: "The date used to check the validity of the ID is older than the validity period",
|
|
482
|
+
};
|
|
433
483
|
}
|
|
434
484
|
}
|
|
435
485
|
else if (proof.name === "disclose_bytes") {
|
|
@@ -437,7 +487,11 @@ export class ZKPassport {
|
|
|
437
487
|
if (commitmentIn !== commitmentOut) {
|
|
438
488
|
console.warn("Failed to check the link between the validity of the ID and the data to disclose");
|
|
439
489
|
isCorrect = false;
|
|
440
|
-
|
|
490
|
+
queryResultErrors.disclose.commitment = {
|
|
491
|
+
expected: `Commitment: ${commitmentOut?.toString() || "undefined"}`,
|
|
492
|
+
received: `Commitment: ${commitmentIn?.toString() || "undefined"}`,
|
|
493
|
+
message: "Failed to check the link between the validity of the ID and the data to disclose",
|
|
494
|
+
};
|
|
441
495
|
}
|
|
442
496
|
// We can't be certain that the disclosed data is for a passport or an ID card
|
|
443
497
|
// so we need to check both (unless the document type is revealed)
|
|
@@ -450,12 +504,20 @@ export class ZKPassport {
|
|
|
450
504
|
queryResult.document_type.eq.expected !== disclosedDataPassport.documentType) {
|
|
451
505
|
console.warn("Document type does not match the expected document type");
|
|
452
506
|
isCorrect = false;
|
|
453
|
-
|
|
507
|
+
queryResultErrors.document_type.eq = {
|
|
508
|
+
expected: `${queryResult.document_type.eq.expected}`,
|
|
509
|
+
received: `${disclosedDataPassport.documentType}`,
|
|
510
|
+
message: "Document type does not match the expected document type",
|
|
511
|
+
};
|
|
454
512
|
}
|
|
455
513
|
if (queryResult.document_type.disclose?.result !== disclosedDataIDCard.documentType) {
|
|
456
514
|
console.warn("Document type does not match the disclosed document type in query result");
|
|
457
515
|
isCorrect = false;
|
|
458
|
-
|
|
516
|
+
queryResultErrors.document_type.disclose = {
|
|
517
|
+
expected: `${queryResult.document_type.disclose?.result}`,
|
|
518
|
+
received: `${disclosedDataIDCard.documentType}`,
|
|
519
|
+
message: "Document type does not match the disclosed document type in query result",
|
|
520
|
+
};
|
|
459
521
|
}
|
|
460
522
|
}
|
|
461
523
|
if (queryResult.birthdate) {
|
|
@@ -467,14 +529,22 @@ export class ZKPassport {
|
|
|
467
529
|
queryResult.birthdate.eq.expected.getTime() !== birthdateIDCard.getTime()) {
|
|
468
530
|
console.warn("Birthdate does not match the expected birthdate");
|
|
469
531
|
isCorrect = false;
|
|
470
|
-
|
|
532
|
+
queryResultErrors.birthdate.eq = {
|
|
533
|
+
expected: `${queryResult.birthdate.eq.expected.toISOString()}`,
|
|
534
|
+
received: `${birthdatePassport.toISOString()}`,
|
|
535
|
+
message: "Birthdate does not match the expected birthdate",
|
|
536
|
+
};
|
|
471
537
|
}
|
|
472
538
|
if (queryResult.birthdate.disclose &&
|
|
473
539
|
queryResult.birthdate.disclose.result.getTime() !== birthdatePassport.getTime() &&
|
|
474
540
|
queryResult.birthdate.disclose.result.getTime() !== birthdateIDCard.getTime()) {
|
|
475
541
|
console.warn("Birthdate does not match the disclosed birthdate in query result");
|
|
476
542
|
isCorrect = false;
|
|
477
|
-
|
|
543
|
+
queryResultErrors.birthdate.disclose = {
|
|
544
|
+
expected: `${queryResult.birthdate.disclose.result.toISOString()}`,
|
|
545
|
+
received: `${birthdatePassport.toISOString()}`,
|
|
546
|
+
message: "Birthdate does not match the disclosed birthdate in query result",
|
|
547
|
+
};
|
|
478
548
|
}
|
|
479
549
|
}
|
|
480
550
|
if (queryResult.expiry_date) {
|
|
@@ -486,14 +556,22 @@ export class ZKPassport {
|
|
|
486
556
|
queryResult.expiry_date.eq.expected.getTime() !== expiryDateIDCard.getTime()) {
|
|
487
557
|
console.warn("Expiry date does not match the expected expiry date");
|
|
488
558
|
isCorrect = false;
|
|
489
|
-
|
|
559
|
+
queryResultErrors.expiry_date.eq = {
|
|
560
|
+
expected: `${queryResult.expiry_date.eq.expected.toISOString()}`,
|
|
561
|
+
received: `${expiryDatePassport.toISOString()}`,
|
|
562
|
+
message: "Expiry date does not match the expected expiry date",
|
|
563
|
+
};
|
|
490
564
|
}
|
|
491
565
|
if (queryResult.expiry_date.disclose &&
|
|
492
566
|
queryResult.expiry_date.disclose.result.getTime() !== expiryDatePassport.getTime() &&
|
|
493
567
|
queryResult.expiry_date.disclose.result.getTime() !== expiryDateIDCard.getTime()) {
|
|
494
568
|
console.warn("Expiry date does not match the disclosed expiry date in query result");
|
|
495
569
|
isCorrect = false;
|
|
496
|
-
|
|
570
|
+
queryResultErrors.expiry_date.disclose = {
|
|
571
|
+
expected: `${queryResult.expiry_date.disclose.result.toISOString()}`,
|
|
572
|
+
received: `${expiryDatePassport.toISOString()}`,
|
|
573
|
+
message: "Expiry date does not match the disclosed expiry date in query result",
|
|
574
|
+
};
|
|
497
575
|
}
|
|
498
576
|
}
|
|
499
577
|
if (queryResult.nationality) {
|
|
@@ -505,14 +583,22 @@ export class ZKPassport {
|
|
|
505
583
|
queryResult.nationality.eq.expected !== nationalityIDCard) {
|
|
506
584
|
console.warn("Nationality does not match the expected nationality");
|
|
507
585
|
isCorrect = false;
|
|
508
|
-
|
|
586
|
+
queryResultErrors.nationality.eq = {
|
|
587
|
+
expected: `${queryResult.nationality.eq.expected}`,
|
|
588
|
+
received: `${nationalityPassport}`,
|
|
589
|
+
message: "Nationality does not match the expected nationality",
|
|
590
|
+
};
|
|
509
591
|
}
|
|
510
592
|
if (queryResult.nationality.disclose &&
|
|
511
593
|
queryResult.nationality.disclose.result !== nationalityPassport &&
|
|
512
594
|
queryResult.nationality.disclose.result !== nationalityIDCard) {
|
|
513
595
|
console.warn("Nationality does not match the disclosed nationality in query result");
|
|
514
596
|
isCorrect = false;
|
|
515
|
-
|
|
597
|
+
queryResultErrors.nationality.disclose = {
|
|
598
|
+
expected: `${queryResult.nationality.disclose.result}`,
|
|
599
|
+
received: `${nationalityPassport}`,
|
|
600
|
+
message: "Nationality does not match the disclosed nationality in query result",
|
|
601
|
+
};
|
|
516
602
|
}
|
|
517
603
|
}
|
|
518
604
|
if (queryResult.document_number) {
|
|
@@ -524,14 +610,22 @@ export class ZKPassport {
|
|
|
524
610
|
queryResult.document_number.eq.expected !== documentNumberIDCard) {
|
|
525
611
|
console.warn("Document number does not match the expected document number");
|
|
526
612
|
isCorrect = false;
|
|
527
|
-
|
|
613
|
+
queryResultErrors.document_number.eq = {
|
|
614
|
+
expected: `${queryResult.document_number.eq.expected}`,
|
|
615
|
+
received: `${documentNumberPassport}`,
|
|
616
|
+
message: "Document number does not match the expected document number",
|
|
617
|
+
};
|
|
528
618
|
}
|
|
529
619
|
if (queryResult.document_number.disclose &&
|
|
530
620
|
queryResult.document_number.disclose.result !== documentNumberPassport &&
|
|
531
621
|
queryResult.document_number.disclose.result !== documentNumberIDCard) {
|
|
532
622
|
console.warn("Document number does not match the disclosed document number in query result");
|
|
533
623
|
isCorrect = false;
|
|
534
|
-
|
|
624
|
+
queryResultErrors.document_number.disclose = {
|
|
625
|
+
expected: `${queryResult.document_number.disclose.result}`,
|
|
626
|
+
received: `${documentNumberPassport}`,
|
|
627
|
+
message: "Document number does not match the disclosed document number in query result",
|
|
628
|
+
};
|
|
535
629
|
}
|
|
536
630
|
}
|
|
537
631
|
if (queryResult.gender) {
|
|
@@ -543,14 +637,22 @@ export class ZKPassport {
|
|
|
543
637
|
queryResult.gender.eq.expected !== genderIDCard) {
|
|
544
638
|
console.warn("Gender does not match the expected gender");
|
|
545
639
|
isCorrect = false;
|
|
546
|
-
|
|
640
|
+
queryResultErrors.gender.eq = {
|
|
641
|
+
expected: `${queryResult.gender.eq.expected}`,
|
|
642
|
+
received: `${genderPassport}`,
|
|
643
|
+
message: "Gender does not match the expected gender",
|
|
644
|
+
};
|
|
547
645
|
}
|
|
548
646
|
if (queryResult.gender.disclose &&
|
|
549
647
|
queryResult.gender.disclose.result !== genderPassport &&
|
|
550
648
|
queryResult.gender.disclose.result !== genderIDCard) {
|
|
551
649
|
console.warn("Gender does not match the disclosed gender in query result");
|
|
552
650
|
isCorrect = false;
|
|
553
|
-
|
|
651
|
+
queryResultErrors.gender.disclose = {
|
|
652
|
+
expected: `${queryResult.gender.disclose.result}`,
|
|
653
|
+
received: `${genderPassport}`,
|
|
654
|
+
message: "Gender does not match the disclosed gender in query result",
|
|
655
|
+
};
|
|
554
656
|
}
|
|
555
657
|
}
|
|
556
658
|
if (queryResult.issuing_country) {
|
|
@@ -562,14 +664,22 @@ export class ZKPassport {
|
|
|
562
664
|
queryResult.issuing_country.eq.expected !== issuingCountryIDCard) {
|
|
563
665
|
console.warn("Issuing country does not match the expected issuing country");
|
|
564
666
|
isCorrect = false;
|
|
565
|
-
|
|
667
|
+
queryResultErrors.issuing_country.eq = {
|
|
668
|
+
expected: `${queryResult.issuing_country.eq.expected}`,
|
|
669
|
+
received: `${issuingCountryPassport}`,
|
|
670
|
+
message: "Issuing country does not match the expected issuing country",
|
|
671
|
+
};
|
|
566
672
|
}
|
|
567
673
|
if (queryResult.issuing_country.disclose &&
|
|
568
674
|
queryResult.issuing_country.disclose.result !== issuingCountryPassport &&
|
|
569
675
|
queryResult.issuing_country.disclose.result !== issuingCountryIDCard) {
|
|
570
676
|
console.warn("Issuing country does not match the disclosed issuing country in query result");
|
|
571
677
|
isCorrect = false;
|
|
572
|
-
|
|
678
|
+
queryResultErrors.issuing_country.disclose = {
|
|
679
|
+
expected: `${queryResult.issuing_country.disclose.result}`,
|
|
680
|
+
received: `${issuingCountryPassport}`,
|
|
681
|
+
message: "Issuing country does not match the disclosed issuing country in query result",
|
|
682
|
+
};
|
|
573
683
|
}
|
|
574
684
|
}
|
|
575
685
|
if (queryResult.fullname) {
|
|
@@ -583,7 +693,11 @@ export class ZKPassport {
|
|
|
583
693
|
fullnameIDCard.toLowerCase()) {
|
|
584
694
|
console.warn("Fullname does not match the expected fullname");
|
|
585
695
|
isCorrect = false;
|
|
586
|
-
|
|
696
|
+
queryResultErrors.fullname.eq = {
|
|
697
|
+
expected: `${queryResult.fullname.eq.expected}`,
|
|
698
|
+
received: `${fullnamePassport}`,
|
|
699
|
+
message: "Fullname does not match the expected fullname",
|
|
700
|
+
};
|
|
587
701
|
}
|
|
588
702
|
if (queryResult.fullname.disclose &&
|
|
589
703
|
formatName(queryResult.fullname.disclose.result).toLowerCase() !==
|
|
@@ -592,7 +706,11 @@ export class ZKPassport {
|
|
|
592
706
|
fullnameIDCard.toLowerCase()) {
|
|
593
707
|
console.warn("Fullname does not match the disclosed fullname in query result");
|
|
594
708
|
isCorrect = false;
|
|
595
|
-
|
|
709
|
+
queryResultErrors.fullname.disclose = {
|
|
710
|
+
expected: `${queryResult.fullname.disclose.result}`,
|
|
711
|
+
received: `${fullnamePassport}`,
|
|
712
|
+
message: "Fullname does not match the disclosed fullname in query result",
|
|
713
|
+
};
|
|
596
714
|
}
|
|
597
715
|
}
|
|
598
716
|
if (queryResult.firstname) {
|
|
@@ -611,7 +729,11 @@ export class ZKPassport {
|
|
|
611
729
|
firstnameIDCard.toLowerCase()) {
|
|
612
730
|
console.warn("Firstname does not match the expected firstname");
|
|
613
731
|
isCorrect = false;
|
|
614
|
-
|
|
732
|
+
queryResultErrors.firstname.eq = {
|
|
733
|
+
expected: `${queryResult.firstname.eq.expected}`,
|
|
734
|
+
received: `${firstnamePassport}`,
|
|
735
|
+
message: "Firstname does not match the expected firstname",
|
|
736
|
+
};
|
|
615
737
|
}
|
|
616
738
|
if (queryResult.firstname.disclose &&
|
|
617
739
|
formatName(queryResult.firstname.disclose.result).toLowerCase() !==
|
|
@@ -620,7 +742,11 @@ export class ZKPassport {
|
|
|
620
742
|
firstnameIDCard.toLowerCase()) {
|
|
621
743
|
console.warn("Firstname does not match the disclosed firstname in query result");
|
|
622
744
|
isCorrect = false;
|
|
623
|
-
|
|
745
|
+
queryResultErrors.firstname.disclose = {
|
|
746
|
+
expected: `${queryResult.firstname.disclose.result}`,
|
|
747
|
+
received: `${firstnamePassport}`,
|
|
748
|
+
message: "Firstname does not match the disclosed firstname in query result",
|
|
749
|
+
};
|
|
624
750
|
}
|
|
625
751
|
}
|
|
626
752
|
if (queryResult.lastname) {
|
|
@@ -639,7 +765,11 @@ export class ZKPassport {
|
|
|
639
765
|
lastnameIDCard.toLowerCase()) {
|
|
640
766
|
console.warn("Lastname does not match the expected lastname");
|
|
641
767
|
isCorrect = false;
|
|
642
|
-
|
|
768
|
+
queryResultErrors.lastname.eq = {
|
|
769
|
+
expected: `${queryResult.lastname.eq.expected}`,
|
|
770
|
+
received: `${lastnamePassport}`,
|
|
771
|
+
message: "Lastname does not match the expected lastname",
|
|
772
|
+
};
|
|
643
773
|
}
|
|
644
774
|
if (queryResult.lastname.disclose &&
|
|
645
775
|
formatName(queryResult.lastname.disclose.result).toLowerCase() !==
|
|
@@ -648,7 +778,11 @@ export class ZKPassport {
|
|
|
648
778
|
lastnameIDCard.toLowerCase()) {
|
|
649
779
|
console.warn("Lastname does not match the disclosed lastname in query result");
|
|
650
780
|
isCorrect = false;
|
|
651
|
-
|
|
781
|
+
queryResultErrors.lastname.disclose = {
|
|
782
|
+
expected: `${queryResult.lastname.disclose.result}`,
|
|
783
|
+
received: `${lastnamePassport}`,
|
|
784
|
+
message: "Lastname does not match the disclosed lastname in query result",
|
|
785
|
+
};
|
|
652
786
|
}
|
|
653
787
|
}
|
|
654
788
|
uniqueIdentifier = getNullifierFromDisclosureProof(proofData).toString(10);
|
|
@@ -658,7 +792,11 @@ export class ZKPassport {
|
|
|
658
792
|
if (commitmentIn !== commitmentOut) {
|
|
659
793
|
console.warn("Failed to check the link between the validity of the ID and the age derived from it");
|
|
660
794
|
isCorrect = false;
|
|
661
|
-
|
|
795
|
+
queryResultErrors.age.commitment = {
|
|
796
|
+
expected: `Commitment: ${commitmentOut}`,
|
|
797
|
+
received: `Commitment: ${commitmentIn}`,
|
|
798
|
+
message: "Failed to check the link between the validity of the ID and the age derived from it",
|
|
799
|
+
};
|
|
662
800
|
}
|
|
663
801
|
const minAge = getMinAgeFromProof(proofData);
|
|
664
802
|
const maxAge = getMaxAgeFromProof(proofData);
|
|
@@ -668,14 +806,22 @@ export class ZKPassport {
|
|
|
668
806
|
minAge < queryResult.age.gte.expected) {
|
|
669
807
|
console.warn("Age is not greater than or equal to the expected age");
|
|
670
808
|
isCorrect = false;
|
|
671
|
-
|
|
809
|
+
queryResultErrors.age.gte = {
|
|
810
|
+
expected: queryResult.age.gte.expected,
|
|
811
|
+
received: minAge,
|
|
812
|
+
message: "Age is not greater than or equal to the expected age",
|
|
813
|
+
};
|
|
672
814
|
}
|
|
673
815
|
if (queryResult.age.lt &&
|
|
674
816
|
queryResult.age.lt.result &&
|
|
675
817
|
maxAge >= queryResult.age.lt.expected) {
|
|
676
818
|
console.warn("Age is not less than the expected age");
|
|
677
819
|
isCorrect = false;
|
|
678
|
-
|
|
820
|
+
queryResultErrors.age.lt = {
|
|
821
|
+
expected: queryResult.age.lt.expected,
|
|
822
|
+
received: maxAge,
|
|
823
|
+
message: "Age is not less than the expected age",
|
|
824
|
+
};
|
|
679
825
|
}
|
|
680
826
|
if (queryResult.age.range) {
|
|
681
827
|
if (queryResult.age.range.result &&
|
|
@@ -683,38 +829,60 @@ export class ZKPassport {
|
|
|
683
829
|
maxAge >= queryResult.age.range.expected[1])) {
|
|
684
830
|
console.warn("Age is not in the expected range");
|
|
685
831
|
isCorrect = false;
|
|
686
|
-
|
|
832
|
+
queryResultErrors.age.range = {
|
|
833
|
+
expected: queryResult.age.range.expected,
|
|
834
|
+
received: [minAge, maxAge],
|
|
835
|
+
message: "Age is not in the expected range",
|
|
836
|
+
};
|
|
687
837
|
}
|
|
688
838
|
}
|
|
689
839
|
if (!queryResult.age.lt && !queryResult.age.range && maxAge != 0) {
|
|
690
840
|
console.warn("Maximum age should be equal to 0");
|
|
691
841
|
isCorrect = false;
|
|
692
|
-
|
|
842
|
+
queryResultErrors.age.disclose = {
|
|
843
|
+
expected: 0,
|
|
844
|
+
received: maxAge,
|
|
845
|
+
message: "Maximum age should be equal to 0",
|
|
846
|
+
};
|
|
693
847
|
}
|
|
694
848
|
if (!queryResult.age.gte && !queryResult.age.range && minAge != 0) {
|
|
695
849
|
console.warn("Minimum age should be equal to 0");
|
|
696
850
|
isCorrect = false;
|
|
697
|
-
|
|
851
|
+
queryResultErrors.age.disclose = {
|
|
852
|
+
expected: 0,
|
|
853
|
+
received: minAge,
|
|
854
|
+
message: "Minimum age should be equal to 0",
|
|
855
|
+
};
|
|
698
856
|
}
|
|
699
857
|
if (queryResult.age.disclose &&
|
|
700
858
|
(queryResult.age.disclose.result !== minAge ||
|
|
701
859
|
queryResult.age.disclose.result !== maxAge)) {
|
|
702
860
|
console.warn("Age does not match the disclosed age in query result");
|
|
703
861
|
isCorrect = false;
|
|
704
|
-
|
|
862
|
+
queryResultErrors.age.disclose = {
|
|
863
|
+
expected: `${minAge}`,
|
|
864
|
+
received: `${queryResult.age.disclose.result}`,
|
|
865
|
+
message: "Age does not match the disclosed age in query result",
|
|
866
|
+
};
|
|
705
867
|
}
|
|
706
868
|
}
|
|
707
869
|
else {
|
|
708
870
|
console.warn("Age is not set in the query result");
|
|
709
871
|
isCorrect = false;
|
|
710
|
-
|
|
872
|
+
queryResultErrors.age.disclose = {
|
|
873
|
+
message: "Age is not set in the query result",
|
|
874
|
+
};
|
|
711
875
|
}
|
|
712
876
|
const currentDate = getCurrentDateFromAgeProof(proofData);
|
|
713
877
|
if (currentDate.getTime() !== today.getTime() &&
|
|
714
878
|
currentDate.getTime() !== today.getTime() - 86400000) {
|
|
715
879
|
console.warn("Current date in the proof is too old");
|
|
716
880
|
isCorrect = false;
|
|
717
|
-
|
|
881
|
+
queryResultErrors.age.disclose = {
|
|
882
|
+
expected: `${today.toISOString()}`,
|
|
883
|
+
received: `${currentDate.toISOString()}`,
|
|
884
|
+
message: "Current date in the proof is too old",
|
|
885
|
+
};
|
|
718
886
|
}
|
|
719
887
|
uniqueIdentifier = getCommitmentInFromDisclosureProof(proofData).toString(10);
|
|
720
888
|
}
|
|
@@ -723,7 +891,11 @@ export class ZKPassport {
|
|
|
723
891
|
if (commitmentIn !== commitmentOut) {
|
|
724
892
|
console.warn("Failed to check the link between the validity of the ID and the birthdate derived from it");
|
|
725
893
|
isCorrect = false;
|
|
726
|
-
|
|
894
|
+
queryResultErrors.birthdate.commitment = {
|
|
895
|
+
expected: `Commitment: ${commitmentOut}`,
|
|
896
|
+
received: `Commitment: ${commitmentIn}`,
|
|
897
|
+
message: "Failed to check the link between the validity of the ID and the birthdate derived from it",
|
|
898
|
+
};
|
|
727
899
|
}
|
|
728
900
|
const minDate = getMinDateFromProof(proofData);
|
|
729
901
|
const maxDate = getMaxDateFromProof(proofData);
|
|
@@ -733,14 +905,22 @@ export class ZKPassport {
|
|
|
733
905
|
minDate < queryResult.birthdate.gte.expected) {
|
|
734
906
|
console.warn("Birthdate is not greater than or equal to the expected birthdate");
|
|
735
907
|
isCorrect = false;
|
|
736
|
-
|
|
908
|
+
queryResultErrors.birthdate.gte = {
|
|
909
|
+
expected: queryResult.birthdate.gte.expected,
|
|
910
|
+
received: minDate,
|
|
911
|
+
message: "Birthdate is not greater than or equal to the expected birthdate",
|
|
912
|
+
};
|
|
737
913
|
}
|
|
738
914
|
if (queryResult.birthdate.lte &&
|
|
739
915
|
queryResult.birthdate.lte.result &&
|
|
740
916
|
maxDate > queryResult.birthdate.lte.expected) {
|
|
741
917
|
console.warn("Birthdate is not less than the expected birthdate");
|
|
742
918
|
isCorrect = false;
|
|
743
|
-
|
|
919
|
+
queryResultErrors.birthdate.lte = {
|
|
920
|
+
expected: queryResult.birthdate.lte.expected,
|
|
921
|
+
received: maxDate,
|
|
922
|
+
message: "Birthdate is not less than the expected birthdate",
|
|
923
|
+
};
|
|
744
924
|
}
|
|
745
925
|
if (queryResult.birthdate.range) {
|
|
746
926
|
if (queryResult.birthdate.range.result &&
|
|
@@ -748,7 +928,11 @@ export class ZKPassport {
|
|
|
748
928
|
maxDate > queryResult.birthdate.range.expected[1])) {
|
|
749
929
|
console.warn("Birthdate is not in the expected range");
|
|
750
930
|
isCorrect = false;
|
|
751
|
-
|
|
931
|
+
queryResultErrors.birthdate.range = {
|
|
932
|
+
expected: queryResult.birthdate.range.expected,
|
|
933
|
+
received: [minDate, maxDate],
|
|
934
|
+
message: "Birthdate is not in the expected range",
|
|
935
|
+
};
|
|
752
936
|
}
|
|
753
937
|
}
|
|
754
938
|
if (!queryResult.birthdate.lte &&
|
|
@@ -756,20 +940,30 @@ export class ZKPassport {
|
|
|
756
940
|
maxDate.getTime() != defaultDateValue.getTime()) {
|
|
757
941
|
console.warn("Maximum birthdate should be equal to default date value");
|
|
758
942
|
isCorrect = false;
|
|
759
|
-
|
|
943
|
+
queryResultErrors.birthdate.disclose = {
|
|
944
|
+
expected: `${defaultDateValue.toISOString()}`,
|
|
945
|
+
received: `${maxDate.toISOString()}`,
|
|
946
|
+
message: "Maximum birthdate should be equal to default date value",
|
|
947
|
+
};
|
|
760
948
|
}
|
|
761
949
|
if (!queryResult.birthdate.gte &&
|
|
762
950
|
!queryResult.birthdate.range &&
|
|
763
951
|
minDate.getTime() != defaultDateValue.getTime()) {
|
|
764
952
|
console.warn("Minimum birthdate should be equal to default date value");
|
|
765
953
|
isCorrect = false;
|
|
766
|
-
|
|
954
|
+
queryResultErrors.birthdate.disclose = {
|
|
955
|
+
expected: `${defaultDateValue.toISOString()}`,
|
|
956
|
+
received: `${minDate.toISOString()}`,
|
|
957
|
+
message: "Minimum birthdate should be equal to default date value",
|
|
958
|
+
};
|
|
767
959
|
}
|
|
768
960
|
}
|
|
769
961
|
else {
|
|
770
962
|
console.warn("Birthdate is not set in the query result");
|
|
771
963
|
isCorrect = false;
|
|
772
|
-
|
|
964
|
+
queryResultErrors.birthdate.disclose = {
|
|
965
|
+
message: "Birthdate is not set in the query result",
|
|
966
|
+
};
|
|
773
967
|
}
|
|
774
968
|
uniqueIdentifier = getCommitmentInFromDisclosureProof(proofData).toString(10);
|
|
775
969
|
}
|
|
@@ -778,7 +972,11 @@ export class ZKPassport {
|
|
|
778
972
|
if (commitmentIn !== commitmentOut) {
|
|
779
973
|
console.warn("Failed to check the link between the validity of the ID and its expiry date");
|
|
780
974
|
isCorrect = false;
|
|
781
|
-
|
|
975
|
+
queryResultErrors.expiry_date.commitment = {
|
|
976
|
+
expected: `Commitment: ${commitmentOut}`,
|
|
977
|
+
received: `Commitment: ${commitmentIn}`,
|
|
978
|
+
message: "Failed to check the link between the validity of the ID and its expiry date",
|
|
979
|
+
};
|
|
782
980
|
}
|
|
783
981
|
const minDate = getMinDateFromProof(proofData);
|
|
784
982
|
const maxDate = getMaxDateFromProof(proofData);
|
|
@@ -788,14 +986,22 @@ export class ZKPassport {
|
|
|
788
986
|
minDate < queryResult.expiry_date.gte.expected) {
|
|
789
987
|
console.warn("Expiry date is not greater than or equal to the expected expiry date");
|
|
790
988
|
isCorrect = false;
|
|
791
|
-
|
|
989
|
+
queryResultErrors.expiry_date.gte = {
|
|
990
|
+
expected: queryResult.expiry_date.gte.expected,
|
|
991
|
+
received: minDate,
|
|
992
|
+
message: "Expiry date is not greater than or equal to the expected expiry date",
|
|
993
|
+
};
|
|
792
994
|
}
|
|
793
995
|
if (queryResult.expiry_date.lte &&
|
|
794
996
|
queryResult.expiry_date.lte.result &&
|
|
795
997
|
maxDate > queryResult.expiry_date.lte.expected) {
|
|
796
998
|
console.warn("Expiry date is not less than the expected expiry date");
|
|
797
999
|
isCorrect = false;
|
|
798
|
-
|
|
1000
|
+
queryResultErrors.expiry_date.lte = {
|
|
1001
|
+
expected: queryResult.expiry_date.lte.expected,
|
|
1002
|
+
received: maxDate,
|
|
1003
|
+
message: "Expiry date is not less than the expected expiry date",
|
|
1004
|
+
};
|
|
799
1005
|
}
|
|
800
1006
|
if (queryResult.expiry_date.range) {
|
|
801
1007
|
if (queryResult.expiry_date.range.result &&
|
|
@@ -803,7 +1009,11 @@ export class ZKPassport {
|
|
|
803
1009
|
maxDate > queryResult.expiry_date.range.expected[1])) {
|
|
804
1010
|
console.warn("Expiry date is not in the expected range");
|
|
805
1011
|
isCorrect = false;
|
|
806
|
-
|
|
1012
|
+
queryResultErrors.expiry_date.range = {
|
|
1013
|
+
expected: queryResult.expiry_date.range.expected,
|
|
1014
|
+
received: [minDate, maxDate],
|
|
1015
|
+
message: "Expiry date is not in the expected range",
|
|
1016
|
+
};
|
|
807
1017
|
}
|
|
808
1018
|
}
|
|
809
1019
|
if (!queryResult.expiry_date.lte &&
|
|
@@ -811,20 +1021,30 @@ export class ZKPassport {
|
|
|
811
1021
|
maxDate.getTime() != defaultDateValue.getTime()) {
|
|
812
1022
|
console.warn("Maximum expiry date should be equal to default date value");
|
|
813
1023
|
isCorrect = false;
|
|
814
|
-
|
|
1024
|
+
queryResultErrors.expiry_date.disclose = {
|
|
1025
|
+
expected: `${defaultDateValue.toISOString()}`,
|
|
1026
|
+
received: `${maxDate.toISOString()}`,
|
|
1027
|
+
message: "Maximum expiry date should be equal to default date value",
|
|
1028
|
+
};
|
|
815
1029
|
}
|
|
816
1030
|
if (!queryResult.expiry_date.gte &&
|
|
817
1031
|
!queryResult.expiry_date.range &&
|
|
818
1032
|
minDate.getTime() != defaultDateValue.getTime()) {
|
|
819
1033
|
console.warn("Minimum expiry date should be equal to default date value");
|
|
820
1034
|
isCorrect = false;
|
|
821
|
-
|
|
1035
|
+
queryResultErrors.expiry_date.disclose = {
|
|
1036
|
+
expected: `${defaultDateValue.toISOString()}`,
|
|
1037
|
+
received: `${minDate.toISOString()}`,
|
|
1038
|
+
message: "Minimum expiry date should be equal to default date value",
|
|
1039
|
+
};
|
|
822
1040
|
}
|
|
823
1041
|
}
|
|
824
1042
|
else {
|
|
825
1043
|
console.warn("Expiry date is not set in the query result");
|
|
826
1044
|
isCorrect = false;
|
|
827
|
-
|
|
1045
|
+
queryResultErrors.expiry_date.disclose = {
|
|
1046
|
+
message: "Expiry date is not set in the query result",
|
|
1047
|
+
};
|
|
828
1048
|
}
|
|
829
1049
|
uniqueIdentifier = getNullifierFromDisclosureProof(proofData).toString(10);
|
|
830
1050
|
}
|
|
@@ -833,7 +1053,11 @@ export class ZKPassport {
|
|
|
833
1053
|
if (commitmentIn !== commitmentOut) {
|
|
834
1054
|
console.warn("Failed to check the link between the validity of the ID and the country exclusion check");
|
|
835
1055
|
isCorrect = false;
|
|
836
|
-
|
|
1056
|
+
queryResultErrors.nationality.commitment = {
|
|
1057
|
+
expected: `Commitment: ${commitmentOut}`,
|
|
1058
|
+
received: `Commitment: ${commitmentIn}`,
|
|
1059
|
+
message: "Failed to check the link between the validity of the ID and the country exclusion check",
|
|
1060
|
+
};
|
|
837
1061
|
}
|
|
838
1062
|
const countryList = getCountryListFromExclusionProof(proofData);
|
|
839
1063
|
if (queryResult.nationality &&
|
|
@@ -842,13 +1066,19 @@ export class ZKPassport {
|
|
|
842
1066
|
if (!queryResult.nationality.out.expected?.every((country) => countryList.includes(country))) {
|
|
843
1067
|
console.warn("Country exclusion list does not match the one from the query results");
|
|
844
1068
|
isCorrect = false;
|
|
845
|
-
|
|
1069
|
+
queryResultErrors.nationality.out = {
|
|
1070
|
+
expected: queryResult.nationality.out.expected,
|
|
1071
|
+
received: countryList,
|
|
1072
|
+
message: "Country exclusion list does not match the one from the query results",
|
|
1073
|
+
};
|
|
846
1074
|
}
|
|
847
1075
|
}
|
|
848
1076
|
else if (!queryResult.nationality || !queryResult.nationality.out) {
|
|
849
1077
|
console.warn("Nationality exclusion is not set in the query result");
|
|
850
1078
|
isCorrect = false;
|
|
851
|
-
|
|
1079
|
+
queryResultErrors.nationality.out = {
|
|
1080
|
+
message: "Nationality exclusion is not set in the query result",
|
|
1081
|
+
};
|
|
852
1082
|
}
|
|
853
1083
|
// Check the countryList is in ascending order
|
|
854
1084
|
// If the prover doesn't use a sorted list then the proof cannot be trusted
|
|
@@ -857,7 +1087,9 @@ export class ZKPassport {
|
|
|
857
1087
|
if (countryList[i] < countryList[i - 1]) {
|
|
858
1088
|
console.warn("The nationality exclusion list has not been sorted, and thus the proof cannot be trusted");
|
|
859
1089
|
isCorrect = false;
|
|
860
|
-
|
|
1090
|
+
queryResultErrors.nationality.out = {
|
|
1091
|
+
message: "The nationality exclusion list has not been sorted, and thus the proof cannot be trusted",
|
|
1092
|
+
};
|
|
861
1093
|
}
|
|
862
1094
|
}
|
|
863
1095
|
uniqueIdentifier = getNullifierFromDisclosureProof(proofData).toString(10);
|
|
@@ -867,7 +1099,11 @@ export class ZKPassport {
|
|
|
867
1099
|
if (commitmentIn !== commitmentOut) {
|
|
868
1100
|
console.warn("Failed to check the link between the validity of the ID and the country inclusion check");
|
|
869
1101
|
isCorrect = false;
|
|
870
|
-
|
|
1102
|
+
queryResultErrors.nationality.commitment = {
|
|
1103
|
+
expected: `Commitment: ${commitmentOut}`,
|
|
1104
|
+
received: `Commitment: ${commitmentIn}`,
|
|
1105
|
+
message: "Failed to check the link between the validity of the ID and the country inclusion check",
|
|
1106
|
+
};
|
|
871
1107
|
}
|
|
872
1108
|
const countryList = getCountryListFromInclusionProof(proofData);
|
|
873
1109
|
if (queryResult.nationality &&
|
|
@@ -876,18 +1112,24 @@ export class ZKPassport {
|
|
|
876
1112
|
if (!queryResult.nationality.in.expected?.every((country) => countryList.includes(country))) {
|
|
877
1113
|
console.warn("Country inclusion list does not match the one from the query results");
|
|
878
1114
|
isCorrect = false;
|
|
879
|
-
|
|
1115
|
+
queryResultErrors.nationality.in = {
|
|
1116
|
+
expected: queryResult.nationality.in.expected,
|
|
1117
|
+
received: countryList,
|
|
1118
|
+
message: "Country inclusion list does not match the one from the query results",
|
|
1119
|
+
};
|
|
880
1120
|
}
|
|
881
1121
|
}
|
|
882
1122
|
else if (!queryResult.nationality || !queryResult.nationality.in) {
|
|
883
1123
|
console.warn("Nationality inclusion is not set in the query result");
|
|
884
1124
|
isCorrect = false;
|
|
885
|
-
|
|
1125
|
+
queryResultErrors.nationality.in = {
|
|
1126
|
+
message: "Nationality inclusion is not set in the query result",
|
|
1127
|
+
};
|
|
886
1128
|
}
|
|
887
1129
|
uniqueIdentifier = getNullifierFromDisclosureProof(proofData).toString(10);
|
|
888
1130
|
}
|
|
889
1131
|
}
|
|
890
|
-
return { isCorrect, uniqueIdentifier };
|
|
1132
|
+
return { isCorrect, uniqueIdentifier, queryResultErrors };
|
|
891
1133
|
}
|
|
892
1134
|
/**
|
|
893
1135
|
* @notice Verify the proofs received from the mobile app.
|
|
@@ -902,12 +1144,6 @@ export class ZKPassport {
|
|
|
902
1144
|
// There is a minimum of 4 subproofs to make a complete proof
|
|
903
1145
|
if (!proofs || proofs.length < 4) {
|
|
904
1146
|
proofsToVerify = this.topicToProofs[requestId];
|
|
905
|
-
if (!proofsToVerify || proofsToVerify.length < 4) {
|
|
906
|
-
// It may happen that a request returns a result without proofs
|
|
907
|
-
// Meaning the ID is not supported yet by ZKPassport circuits,
|
|
908
|
-
// so the results has to be trusted and cannot be independently verified
|
|
909
|
-
return { uniqueIdentifier: undefined, verified: false };
|
|
910
|
-
}
|
|
911
1147
|
}
|
|
912
1148
|
const { BarretenbergVerifier } = await import("@aztec/bb.js");
|
|
913
1149
|
const verifier = new BarretenbergVerifier();
|
|
@@ -916,13 +1152,15 @@ export class ZKPassport {
|
|
|
916
1152
|
}*/
|
|
917
1153
|
let verified = true;
|
|
918
1154
|
let uniqueIdentifier;
|
|
1155
|
+
let queryResultErrors;
|
|
919
1156
|
if (queryResult) {
|
|
920
|
-
const { isCorrect, uniqueIdentifier: uniqueIdentifierFromPublicInputs } = await this.checkPublicInputs(proofsToVerify, queryResult);
|
|
1157
|
+
const { isCorrect, uniqueIdentifier: uniqueIdentifierFromPublicInputs, queryResultErrors: queryResultErrorsFromPublicInputs, } = await this.checkPublicInputs(proofsToVerify, queryResult, requestId);
|
|
921
1158
|
uniqueIdentifier = uniqueIdentifierFromPublicInputs;
|
|
922
1159
|
verified = isCorrect;
|
|
1160
|
+
queryResultErrors = isCorrect ? undefined : queryResultErrorsFromPublicInputs;
|
|
923
1161
|
}
|
|
924
1162
|
// Only proceed with the proof verification if the public inputs are correct
|
|
925
|
-
if (verified) {
|
|
1163
|
+
if (verified && queryResult) {
|
|
926
1164
|
for (const proof of proofsToVerify) {
|
|
927
1165
|
const proofData = getProofData(proof.proof, true);
|
|
928
1166
|
const hostedPackagedCircuit = await getHostedPackagedCircuitByName(proof.version, proof.name);
|
|
@@ -942,7 +1180,7 @@ export class ZKPassport {
|
|
|
942
1180
|
}
|
|
943
1181
|
}
|
|
944
1182
|
this.topicToProofs[requestId] = [];
|
|
945
|
-
return { uniqueIdentifier, verified };
|
|
1183
|
+
return { uniqueIdentifier, verified, queryResultErrors };
|
|
946
1184
|
}
|
|
947
1185
|
/**
|
|
948
1186
|
* @notice Returns the URL of the request.
|
|
@@ -960,13 +1198,17 @@ export class ZKPassport {
|
|
|
960
1198
|
* @param requestId The request ID.
|
|
961
1199
|
*/
|
|
962
1200
|
cancelRequest(requestId) {
|
|
963
|
-
this.topicToWebSocketClient[requestId]
|
|
964
|
-
|
|
1201
|
+
if (this.topicToWebSocketClient[requestId]) {
|
|
1202
|
+
this.topicToWebSocketClient[requestId].close();
|
|
1203
|
+
delete this.topicToWebSocketClient[requestId];
|
|
1204
|
+
}
|
|
965
1205
|
delete this.topicToKeyPair[requestId];
|
|
966
1206
|
delete this.topicToConfig[requestId];
|
|
1207
|
+
delete this.topicToLocalConfig[requestId];
|
|
967
1208
|
delete this.topicToSharedSecret[requestId];
|
|
968
1209
|
delete this.topicToProofs[requestId];
|
|
969
1210
|
delete this.topicToExpectedProofCount[requestId];
|
|
1211
|
+
delete this.topicToFailedProofCount[requestId];
|
|
970
1212
|
delete this.topicToResults[requestId];
|
|
971
1213
|
this.onRequestReceivedCallbacks[requestId] = [];
|
|
972
1214
|
this.onGeneratingProofCallbacks[requestId] = [];
|
|
@@ -975,4 +1217,12 @@ export class ZKPassport {
|
|
|
975
1217
|
this.onRejectCallbacks[requestId] = [];
|
|
976
1218
|
this.onErrorCallbacks[requestId] = [];
|
|
977
1219
|
}
|
|
1220
|
+
/**
|
|
1221
|
+
* @notice Clears all requests.
|
|
1222
|
+
*/
|
|
1223
|
+
clearAllRequests() {
|
|
1224
|
+
for (const requestId in this.topicToWebSocketClient) {
|
|
1225
|
+
this.cancelRequest(requestId);
|
|
1226
|
+
}
|
|
1227
|
+
}
|
|
978
1228
|
}
|