@zkpassport/sdk 0.2.8 → 0.2.10
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 +29 -2
- package/dist/cjs/index.js +416 -86
- package/dist/esm/index.d.ts +29 -2
- package/dist/esm/index.js +416 -86
- package/package.json +3 -3
- package/src/index.ts +504 -92
package/dist/cjs/index.js
CHANGED
|
@@ -80,6 +80,7 @@ class ZKPassport {
|
|
|
80
80
|
this.topicToService = {};
|
|
81
81
|
this.topicToProofs = {};
|
|
82
82
|
this.topicToExpectedProofCount = {};
|
|
83
|
+
this.topicToFailedProofCount = {};
|
|
83
84
|
this.topicToResults = {};
|
|
84
85
|
this.onRequestReceivedCallbacks = {};
|
|
85
86
|
this.onGeneratingProofCallbacks = {};
|
|
@@ -104,14 +105,19 @@ class ZKPassport {
|
|
|
104
105
|
// Clear the results straight away to avoid concurrency issues
|
|
105
106
|
delete this.topicToResults[topic];
|
|
106
107
|
// Verify the proofs and extract the unique identifier (aka nullifier) and the verification result
|
|
107
|
-
const { uniqueIdentifier, verified } = await this.verify(topic, this.topicToProofs[topic], result);
|
|
108
|
+
const { uniqueIdentifier, verified, queryResultErrors } = await this.verify(topic, this.topicToProofs[topic], result);
|
|
109
|
+
const hasFailedProofs = this.topicToFailedProofCount[topic] > 0;
|
|
108
110
|
await Promise.all(this.onResultCallbacks[topic].map((callback) => callback({
|
|
109
|
-
|
|
110
|
-
verified
|
|
111
|
+
// If there are failed proofs, we don't return the unique identifier
|
|
112
|
+
// and we set the verified result to false
|
|
113
|
+
uniqueIdentifier: hasFailedProofs ? undefined : uniqueIdentifier,
|
|
114
|
+
verified: hasFailedProofs ? false : verified,
|
|
111
115
|
result,
|
|
116
|
+
queryResultErrors,
|
|
112
117
|
})));
|
|
113
|
-
// Clear the expected proof count
|
|
118
|
+
// Clear the expected proof count and failed proof count
|
|
114
119
|
delete this.topicToExpectedProofCount[topic];
|
|
120
|
+
delete this.topicToFailedProofCount[topic];
|
|
115
121
|
}
|
|
116
122
|
setExpectedProofCount(topic) {
|
|
117
123
|
const fields = Object.keys(this.topicToConfig[topic]).filter((key) => hasRequestedAccessToField(this.topicToConfig[topic], key));
|
|
@@ -145,13 +151,23 @@ class ZKPassport {
|
|
|
145
151
|
}
|
|
146
152
|
break;
|
|
147
153
|
case "in":
|
|
148
|
-
if (field === "nationality" &&
|
|
149
|
-
neededCircuits.
|
|
154
|
+
if (field === "nationality" &&
|
|
155
|
+
!neededCircuits.includes("inclusion_check_nationality")) {
|
|
156
|
+
neededCircuits.push("inclusion_check_nationality");
|
|
157
|
+
}
|
|
158
|
+
else if (field === "issuing_country" &&
|
|
159
|
+
!neededCircuits.includes("inclusion_check_issuing_country")) {
|
|
160
|
+
neededCircuits.push("inclusion_check_issuing_country");
|
|
150
161
|
}
|
|
151
162
|
break;
|
|
152
163
|
case "out":
|
|
153
|
-
if (field === "nationality" &&
|
|
154
|
-
neededCircuits.
|
|
164
|
+
if (field === "nationality" &&
|
|
165
|
+
!neededCircuits.includes("exclusion_check_nationality")) {
|
|
166
|
+
neededCircuits.push("exclusion_check_nationality");
|
|
167
|
+
}
|
|
168
|
+
else if (field === "issuing_country" &&
|
|
169
|
+
!neededCircuits.includes("exclusion_check_issuing_country")) {
|
|
170
|
+
neededCircuits.push("exclusion_check_issuing_country");
|
|
155
171
|
}
|
|
156
172
|
break;
|
|
157
173
|
}
|
|
@@ -162,6 +178,7 @@ class ZKPassport {
|
|
|
162
178
|
// Each separate needed circuit adds 1 disclosure proof
|
|
163
179
|
this.topicToExpectedProofCount[topic] =
|
|
164
180
|
neededCircuits.length === 0 ? 4 : 3 + neededCircuits.length;
|
|
181
|
+
this.topicToFailedProofCount[topic] = 0;
|
|
165
182
|
}
|
|
166
183
|
/**
|
|
167
184
|
* @notice Handle an encrypted message.
|
|
@@ -217,6 +234,7 @@ class ZKPassport {
|
|
|
217
234
|
// This means the user has an ID that is not supported yet
|
|
218
235
|
// So we won't receive any proofs and we can handle the result now
|
|
219
236
|
this.topicToExpectedProofCount[topic] = 0;
|
|
237
|
+
this.topicToFailedProofCount[topic] += this.topicToExpectedProofCount[topic];
|
|
220
238
|
if (this.topicToResults[topic]) {
|
|
221
239
|
await this.handleResult(topic);
|
|
222
240
|
}
|
|
@@ -225,6 +243,7 @@ class ZKPassport {
|
|
|
225
243
|
// This means one of the disclosure proofs failed to be generated
|
|
226
244
|
// So we need to remove one from the expected proof count
|
|
227
245
|
this.topicToExpectedProofCount[topic] -= 1;
|
|
246
|
+
this.topicToFailedProofCount[topic] += 1;
|
|
228
247
|
// If the expected proof count is now equal to the number of proofs received
|
|
229
248
|
// and the results were received, we can handle the result now
|
|
230
249
|
if (this.topicToResults[topic] &&
|
|
@@ -281,9 +300,6 @@ class ZKPassport {
|
|
|
281
300
|
};
|
|
282
301
|
return this.getZkPassportRequest(topic);
|
|
283
302
|
},
|
|
284
|
-
/*checkAML: (country?: CountryName | Alpha2Code | Alpha3Code) => {
|
|
285
|
-
return this.getZkPassportRequest(topic)
|
|
286
|
-
},*/
|
|
287
303
|
done: () => {
|
|
288
304
|
const base64Config = buffer_1.Buffer.from(JSON.stringify(this.topicToConfig[topic])).toString("base64");
|
|
289
305
|
const base64Service = buffer_1.Buffer.from(JSON.stringify(this.topicToService[topic])).toString("base64");
|
|
@@ -394,6 +410,23 @@ class ZKPassport {
|
|
|
394
410
|
const defaultDateValue = new Date(1111, 10, 11);
|
|
395
411
|
const currentTime = new Date();
|
|
396
412
|
const today = new Date(currentTime.getFullYear(), currentTime.getMonth(), currentTime.getDate(), 0, 0, 0, 0);
|
|
413
|
+
const queryResultErrors = {
|
|
414
|
+
sig_check_dsc: {},
|
|
415
|
+
sig_check_id_data: {},
|
|
416
|
+
data_check_integrity: {},
|
|
417
|
+
disclose: {},
|
|
418
|
+
age: {},
|
|
419
|
+
birthdate: {},
|
|
420
|
+
expiry_date: {},
|
|
421
|
+
document_type: {},
|
|
422
|
+
issuing_country: {},
|
|
423
|
+
gender: {},
|
|
424
|
+
nationality: {},
|
|
425
|
+
firstname: {},
|
|
426
|
+
lastname: {},
|
|
427
|
+
fullname: {},
|
|
428
|
+
document_number: {},
|
|
429
|
+
};
|
|
397
430
|
// Since the order is important for the commitments, we need to sort the proofs
|
|
398
431
|
// by their expected order: root signature check -> ID signature check -> integrity check -> disclosure
|
|
399
432
|
const sortedProofs = proofs.sort((a, b) => {
|
|
@@ -405,8 +438,10 @@ class ZKPassport {
|
|
|
405
438
|
"compare_age",
|
|
406
439
|
"compare_birthdate",
|
|
407
440
|
"compare_expiry",
|
|
408
|
-
"
|
|
409
|
-
"
|
|
441
|
+
"exclusion_check_nationality",
|
|
442
|
+
"inclusion_check_nationality",
|
|
443
|
+
"exclusion_check_issuing_country",
|
|
444
|
+
"inclusion_check_issuing_country",
|
|
410
445
|
];
|
|
411
446
|
const getIndex = (proof) => {
|
|
412
447
|
const name = proof.name || "";
|
|
@@ -422,7 +457,11 @@ class ZKPassport {
|
|
|
422
457
|
if (merkleRoot !== expectedMerkleRoot) {
|
|
423
458
|
console.warn("The ID was signed by an unrecognized root certificate");
|
|
424
459
|
isCorrect = false;
|
|
425
|
-
|
|
460
|
+
queryResultErrors.sig_check_dsc.certificate = {
|
|
461
|
+
expected: `Certificate registry root: ${expectedMerkleRoot.toString()}`,
|
|
462
|
+
received: `Certificate registry root: ${merkleRoot.toString()}`,
|
|
463
|
+
message: "The ID was signed by an unrecognized root certificate",
|
|
464
|
+
};
|
|
426
465
|
}
|
|
427
466
|
}
|
|
428
467
|
else if (proof.name?.startsWith("sig_check_id_data")) {
|
|
@@ -430,7 +469,11 @@ class ZKPassport {
|
|
|
430
469
|
if (commitmentIn !== commitmentOut) {
|
|
431
470
|
console.warn("Failed to check the link between the certificate signature and ID signature");
|
|
432
471
|
isCorrect = false;
|
|
433
|
-
|
|
472
|
+
queryResultErrors.sig_check_id_data.commitment = {
|
|
473
|
+
expected: `Commitment: ${commitmentOut?.toString() || "undefined"}`,
|
|
474
|
+
received: `Commitment: ${commitmentIn?.toString() || "undefined"}`,
|
|
475
|
+
message: "Failed to check the link between the certificate signature and ID signature",
|
|
476
|
+
};
|
|
434
477
|
}
|
|
435
478
|
commitmentOut = (0, utils_1.getCommitmentOutFromIDDataProof)(proofData);
|
|
436
479
|
}
|
|
@@ -439,7 +482,11 @@ class ZKPassport {
|
|
|
439
482
|
if (commitmentIn !== commitmentOut) {
|
|
440
483
|
console.warn("Failed to check the link between the ID signature and the data signed");
|
|
441
484
|
isCorrect = false;
|
|
442
|
-
|
|
485
|
+
queryResultErrors.data_check_integrity.commitment = {
|
|
486
|
+
expected: `Commitment: ${commitmentOut?.toString() || "undefined"}`,
|
|
487
|
+
received: `Commitment: ${commitmentIn?.toString() || "undefined"}`,
|
|
488
|
+
message: "Failed to check the link between the ID signature and the data signed",
|
|
489
|
+
};
|
|
443
490
|
}
|
|
444
491
|
commitmentOut = (0, utils_1.getCommitmentOutFromIntegrityProof)(proofData);
|
|
445
492
|
const currentDate = (0, utils_1.getCurrentDateFromIntegrityProof)(proofData);
|
|
@@ -450,7 +497,11 @@ class ZKPassport {
|
|
|
450
497
|
if (todayToCurrentDate >= actualDifference) {
|
|
451
498
|
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`);
|
|
452
499
|
isCorrect = false;
|
|
453
|
-
|
|
500
|
+
queryResultErrors.data_check_integrity.date = {
|
|
501
|
+
expected: `Difference: ${this.topicToLocalConfig[topic]?.validity} days`,
|
|
502
|
+
received: `Difference: ${Math.round(todayToCurrentDate / 86400000)} days`,
|
|
503
|
+
message: "The date used to check the validity of the ID is older than the validity period",
|
|
504
|
+
};
|
|
454
505
|
}
|
|
455
506
|
}
|
|
456
507
|
else if (proof.name === "disclose_bytes") {
|
|
@@ -458,7 +509,11 @@ class ZKPassport {
|
|
|
458
509
|
if (commitmentIn !== commitmentOut) {
|
|
459
510
|
console.warn("Failed to check the link between the validity of the ID and the data to disclose");
|
|
460
511
|
isCorrect = false;
|
|
461
|
-
|
|
512
|
+
queryResultErrors.disclose.commitment = {
|
|
513
|
+
expected: `Commitment: ${commitmentOut?.toString() || "undefined"}`,
|
|
514
|
+
received: `Commitment: ${commitmentIn?.toString() || "undefined"}`,
|
|
515
|
+
message: "Failed to check the link between the validity of the ID and the data to disclose",
|
|
516
|
+
};
|
|
462
517
|
}
|
|
463
518
|
// We can't be certain that the disclosed data is for a passport or an ID card
|
|
464
519
|
// so we need to check both (unless the document type is revealed)
|
|
@@ -471,12 +526,20 @@ class ZKPassport {
|
|
|
471
526
|
queryResult.document_type.eq.expected !== disclosedDataPassport.documentType) {
|
|
472
527
|
console.warn("Document type does not match the expected document type");
|
|
473
528
|
isCorrect = false;
|
|
474
|
-
|
|
529
|
+
queryResultErrors.document_type.eq = {
|
|
530
|
+
expected: `${queryResult.document_type.eq.expected}`,
|
|
531
|
+
received: `${disclosedDataPassport.documentType ?? disclosedDataIDCard.documentType}`,
|
|
532
|
+
message: "Document type does not match the expected document type",
|
|
533
|
+
};
|
|
475
534
|
}
|
|
476
535
|
if (queryResult.document_type.disclose?.result !== disclosedDataIDCard.documentType) {
|
|
477
536
|
console.warn("Document type does not match the disclosed document type in query result");
|
|
478
537
|
isCorrect = false;
|
|
479
|
-
|
|
538
|
+
queryResultErrors.document_type.disclose = {
|
|
539
|
+
expected: `${queryResult.document_type.disclose?.result}`,
|
|
540
|
+
received: `${disclosedDataIDCard.documentType ?? disclosedDataPassport.documentType}`,
|
|
541
|
+
message: "Document type does not match the disclosed document type in query result",
|
|
542
|
+
};
|
|
480
543
|
}
|
|
481
544
|
}
|
|
482
545
|
if (queryResult.birthdate) {
|
|
@@ -488,14 +551,22 @@ class ZKPassport {
|
|
|
488
551
|
queryResult.birthdate.eq.expected.getTime() !== birthdateIDCard.getTime()) {
|
|
489
552
|
console.warn("Birthdate does not match the expected birthdate");
|
|
490
553
|
isCorrect = false;
|
|
491
|
-
|
|
554
|
+
queryResultErrors.birthdate.eq = {
|
|
555
|
+
expected: `${queryResult.birthdate.eq.expected.toISOString()}`,
|
|
556
|
+
received: `${birthdatePassport?.toISOString() ?? birthdateIDCard?.toISOString()}`,
|
|
557
|
+
message: "Birthdate does not match the expected birthdate",
|
|
558
|
+
};
|
|
492
559
|
}
|
|
493
560
|
if (queryResult.birthdate.disclose &&
|
|
494
561
|
queryResult.birthdate.disclose.result.getTime() !== birthdatePassport.getTime() &&
|
|
495
562
|
queryResult.birthdate.disclose.result.getTime() !== birthdateIDCard.getTime()) {
|
|
496
563
|
console.warn("Birthdate does not match the disclosed birthdate in query result");
|
|
497
564
|
isCorrect = false;
|
|
498
|
-
|
|
565
|
+
queryResultErrors.birthdate.disclose = {
|
|
566
|
+
expected: `${queryResult.birthdate.disclose.result.toISOString()}`,
|
|
567
|
+
received: `${birthdatePassport?.toISOString() ?? birthdateIDCard?.toISOString()}`,
|
|
568
|
+
message: "Birthdate does not match the disclosed birthdate in query result",
|
|
569
|
+
};
|
|
499
570
|
}
|
|
500
571
|
}
|
|
501
572
|
if (queryResult.expiry_date) {
|
|
@@ -507,14 +578,22 @@ class ZKPassport {
|
|
|
507
578
|
queryResult.expiry_date.eq.expected.getTime() !== expiryDateIDCard.getTime()) {
|
|
508
579
|
console.warn("Expiry date does not match the expected expiry date");
|
|
509
580
|
isCorrect = false;
|
|
510
|
-
|
|
581
|
+
queryResultErrors.expiry_date.eq = {
|
|
582
|
+
expected: `${queryResult.expiry_date.eq.expected.toISOString()}`,
|
|
583
|
+
received: `${expiryDatePassport?.toISOString() ?? expiryDateIDCard?.toISOString()}`,
|
|
584
|
+
message: "Expiry date does not match the expected expiry date",
|
|
585
|
+
};
|
|
511
586
|
}
|
|
512
587
|
if (queryResult.expiry_date.disclose &&
|
|
513
588
|
queryResult.expiry_date.disclose.result.getTime() !== expiryDatePassport.getTime() &&
|
|
514
589
|
queryResult.expiry_date.disclose.result.getTime() !== expiryDateIDCard.getTime()) {
|
|
515
590
|
console.warn("Expiry date does not match the disclosed expiry date in query result");
|
|
516
591
|
isCorrect = false;
|
|
517
|
-
|
|
592
|
+
queryResultErrors.expiry_date.disclose = {
|
|
593
|
+
expected: `${queryResult.expiry_date.disclose.result.toISOString()}`,
|
|
594
|
+
received: `${expiryDatePassport?.toISOString() ?? expiryDateIDCard?.toISOString()}`,
|
|
595
|
+
message: "Expiry date does not match the disclosed expiry date in query result",
|
|
596
|
+
};
|
|
518
597
|
}
|
|
519
598
|
}
|
|
520
599
|
if (queryResult.nationality) {
|
|
@@ -526,14 +605,22 @@ class ZKPassport {
|
|
|
526
605
|
queryResult.nationality.eq.expected !== nationalityIDCard) {
|
|
527
606
|
console.warn("Nationality does not match the expected nationality");
|
|
528
607
|
isCorrect = false;
|
|
529
|
-
|
|
608
|
+
queryResultErrors.nationality.eq = {
|
|
609
|
+
expected: `${queryResult.nationality.eq.expected}`,
|
|
610
|
+
received: `${nationalityPassport ?? nationalityIDCard}`,
|
|
611
|
+
message: "Nationality does not match the expected nationality",
|
|
612
|
+
};
|
|
530
613
|
}
|
|
531
614
|
if (queryResult.nationality.disclose &&
|
|
532
615
|
queryResult.nationality.disclose.result !== nationalityPassport &&
|
|
533
616
|
queryResult.nationality.disclose.result !== nationalityIDCard) {
|
|
534
617
|
console.warn("Nationality does not match the disclosed nationality in query result");
|
|
535
618
|
isCorrect = false;
|
|
536
|
-
|
|
619
|
+
queryResultErrors.nationality.disclose = {
|
|
620
|
+
expected: `${queryResult.nationality.disclose.result}`,
|
|
621
|
+
received: `${nationalityPassport ?? nationalityIDCard}`,
|
|
622
|
+
message: "Nationality does not match the disclosed nationality in query result",
|
|
623
|
+
};
|
|
537
624
|
}
|
|
538
625
|
}
|
|
539
626
|
if (queryResult.document_number) {
|
|
@@ -545,14 +632,22 @@ class ZKPassport {
|
|
|
545
632
|
queryResult.document_number.eq.expected !== documentNumberIDCard) {
|
|
546
633
|
console.warn("Document number does not match the expected document number");
|
|
547
634
|
isCorrect = false;
|
|
548
|
-
|
|
635
|
+
queryResultErrors.document_number.eq = {
|
|
636
|
+
expected: `${queryResult.document_number.eq.expected}`,
|
|
637
|
+
received: `${documentNumberPassport ?? documentNumberIDCard}`,
|
|
638
|
+
message: "Document number does not match the expected document number",
|
|
639
|
+
};
|
|
549
640
|
}
|
|
550
641
|
if (queryResult.document_number.disclose &&
|
|
551
642
|
queryResult.document_number.disclose.result !== documentNumberPassport &&
|
|
552
643
|
queryResult.document_number.disclose.result !== documentNumberIDCard) {
|
|
553
644
|
console.warn("Document number does not match the disclosed document number in query result");
|
|
554
645
|
isCorrect = false;
|
|
555
|
-
|
|
646
|
+
queryResultErrors.document_number.disclose = {
|
|
647
|
+
expected: `${queryResult.document_number.disclose.result}`,
|
|
648
|
+
received: `${documentNumberPassport ?? documentNumberIDCard}`,
|
|
649
|
+
message: "Document number does not match the disclosed document number in query result",
|
|
650
|
+
};
|
|
556
651
|
}
|
|
557
652
|
}
|
|
558
653
|
if (queryResult.gender) {
|
|
@@ -564,14 +659,22 @@ class ZKPassport {
|
|
|
564
659
|
queryResult.gender.eq.expected !== genderIDCard) {
|
|
565
660
|
console.warn("Gender does not match the expected gender");
|
|
566
661
|
isCorrect = false;
|
|
567
|
-
|
|
662
|
+
queryResultErrors.gender.eq = {
|
|
663
|
+
expected: `${queryResult.gender.eq.expected}`,
|
|
664
|
+
received: `${genderPassport ?? genderIDCard}`,
|
|
665
|
+
message: "Gender does not match the expected gender",
|
|
666
|
+
};
|
|
568
667
|
}
|
|
569
668
|
if (queryResult.gender.disclose &&
|
|
570
669
|
queryResult.gender.disclose.result !== genderPassport &&
|
|
571
670
|
queryResult.gender.disclose.result !== genderIDCard) {
|
|
572
671
|
console.warn("Gender does not match the disclosed gender in query result");
|
|
573
672
|
isCorrect = false;
|
|
574
|
-
|
|
673
|
+
queryResultErrors.gender.disclose = {
|
|
674
|
+
expected: `${queryResult.gender.disclose.result}`,
|
|
675
|
+
received: `${genderPassport ?? genderIDCard}`,
|
|
676
|
+
message: "Gender does not match the disclosed gender in query result",
|
|
677
|
+
};
|
|
575
678
|
}
|
|
576
679
|
}
|
|
577
680
|
if (queryResult.issuing_country) {
|
|
@@ -583,14 +686,22 @@ class ZKPassport {
|
|
|
583
686
|
queryResult.issuing_country.eq.expected !== issuingCountryIDCard) {
|
|
584
687
|
console.warn("Issuing country does not match the expected issuing country");
|
|
585
688
|
isCorrect = false;
|
|
586
|
-
|
|
689
|
+
queryResultErrors.issuing_country.eq = {
|
|
690
|
+
expected: `${queryResult.issuing_country.eq.expected}`,
|
|
691
|
+
received: `${issuingCountryPassport ?? issuingCountryIDCard}`,
|
|
692
|
+
message: "Issuing country does not match the expected issuing country",
|
|
693
|
+
};
|
|
587
694
|
}
|
|
588
695
|
if (queryResult.issuing_country.disclose &&
|
|
589
696
|
queryResult.issuing_country.disclose.result !== issuingCountryPassport &&
|
|
590
697
|
queryResult.issuing_country.disclose.result !== issuingCountryIDCard) {
|
|
591
698
|
console.warn("Issuing country does not match the disclosed issuing country in query result");
|
|
592
699
|
isCorrect = false;
|
|
593
|
-
|
|
700
|
+
queryResultErrors.issuing_country.disclose = {
|
|
701
|
+
expected: `${queryResult.issuing_country.disclose.result}`,
|
|
702
|
+
received: `${issuingCountryPassport ?? issuingCountryIDCard}`,
|
|
703
|
+
message: "Issuing country does not match the disclosed issuing country in query result",
|
|
704
|
+
};
|
|
594
705
|
}
|
|
595
706
|
}
|
|
596
707
|
if (queryResult.fullname) {
|
|
@@ -604,7 +715,11 @@ class ZKPassport {
|
|
|
604
715
|
fullnameIDCard.toLowerCase()) {
|
|
605
716
|
console.warn("Fullname does not match the expected fullname");
|
|
606
717
|
isCorrect = false;
|
|
607
|
-
|
|
718
|
+
queryResultErrors.fullname.eq = {
|
|
719
|
+
expected: `${queryResult.fullname.eq.expected}`,
|
|
720
|
+
received: `${fullnamePassport ?? fullnameIDCard}`,
|
|
721
|
+
message: "Fullname does not match the expected fullname",
|
|
722
|
+
};
|
|
608
723
|
}
|
|
609
724
|
if (queryResult.fullname.disclose &&
|
|
610
725
|
(0, utils_1.formatName)(queryResult.fullname.disclose.result).toLowerCase() !==
|
|
@@ -613,7 +728,11 @@ class ZKPassport {
|
|
|
613
728
|
fullnameIDCard.toLowerCase()) {
|
|
614
729
|
console.warn("Fullname does not match the disclosed fullname in query result");
|
|
615
730
|
isCorrect = false;
|
|
616
|
-
|
|
731
|
+
queryResultErrors.fullname.disclose = {
|
|
732
|
+
expected: `${queryResult.fullname.disclose.result}`,
|
|
733
|
+
received: `${fullnamePassport ?? fullnameIDCard}`,
|
|
734
|
+
message: "Fullname does not match the disclosed fullname in query result",
|
|
735
|
+
};
|
|
617
736
|
}
|
|
618
737
|
}
|
|
619
738
|
if (queryResult.firstname) {
|
|
@@ -632,7 +751,11 @@ class ZKPassport {
|
|
|
632
751
|
firstnameIDCard.toLowerCase()) {
|
|
633
752
|
console.warn("Firstname does not match the expected firstname");
|
|
634
753
|
isCorrect = false;
|
|
635
|
-
|
|
754
|
+
queryResultErrors.firstname.eq = {
|
|
755
|
+
expected: `${queryResult.firstname.eq.expected}`,
|
|
756
|
+
received: `${firstnamePassport ?? firstnameIDCard}`,
|
|
757
|
+
message: "Firstname does not match the expected firstname",
|
|
758
|
+
};
|
|
636
759
|
}
|
|
637
760
|
if (queryResult.firstname.disclose &&
|
|
638
761
|
(0, utils_1.formatName)(queryResult.firstname.disclose.result).toLowerCase() !==
|
|
@@ -641,7 +764,11 @@ class ZKPassport {
|
|
|
641
764
|
firstnameIDCard.toLowerCase()) {
|
|
642
765
|
console.warn("Firstname does not match the disclosed firstname in query result");
|
|
643
766
|
isCorrect = false;
|
|
644
|
-
|
|
767
|
+
queryResultErrors.firstname.disclose = {
|
|
768
|
+
expected: `${queryResult.firstname.disclose.result}`,
|
|
769
|
+
received: `${firstnamePassport ?? firstnameIDCard}`,
|
|
770
|
+
message: "Firstname does not match the disclosed firstname in query result",
|
|
771
|
+
};
|
|
645
772
|
}
|
|
646
773
|
}
|
|
647
774
|
if (queryResult.lastname) {
|
|
@@ -660,7 +787,11 @@ class ZKPassport {
|
|
|
660
787
|
lastnameIDCard.toLowerCase()) {
|
|
661
788
|
console.warn("Lastname does not match the expected lastname");
|
|
662
789
|
isCorrect = false;
|
|
663
|
-
|
|
790
|
+
queryResultErrors.lastname.eq = {
|
|
791
|
+
expected: `${queryResult.lastname.eq.expected}`,
|
|
792
|
+
received: `${lastnamePassport ?? lastnameIDCard}`,
|
|
793
|
+
message: "Lastname does not match the expected lastname",
|
|
794
|
+
};
|
|
664
795
|
}
|
|
665
796
|
if (queryResult.lastname.disclose &&
|
|
666
797
|
(0, utils_1.formatName)(queryResult.lastname.disclose.result).toLowerCase() !==
|
|
@@ -669,7 +800,11 @@ class ZKPassport {
|
|
|
669
800
|
lastnameIDCard.toLowerCase()) {
|
|
670
801
|
console.warn("Lastname does not match the disclosed lastname in query result");
|
|
671
802
|
isCorrect = false;
|
|
672
|
-
|
|
803
|
+
queryResultErrors.lastname.disclose = {
|
|
804
|
+
expected: `${queryResult.lastname.disclose.result}`,
|
|
805
|
+
received: `${lastnamePassport ?? lastnameIDCard}`,
|
|
806
|
+
message: "Lastname does not match the disclosed lastname in query result",
|
|
807
|
+
};
|
|
673
808
|
}
|
|
674
809
|
}
|
|
675
810
|
uniqueIdentifier = (0, utils_1.getNullifierFromDisclosureProof)(proofData).toString(10);
|
|
@@ -679,7 +814,11 @@ class ZKPassport {
|
|
|
679
814
|
if (commitmentIn !== commitmentOut) {
|
|
680
815
|
console.warn("Failed to check the link between the validity of the ID and the age derived from it");
|
|
681
816
|
isCorrect = false;
|
|
682
|
-
|
|
817
|
+
queryResultErrors.age.commitment = {
|
|
818
|
+
expected: `Commitment: ${commitmentOut}`,
|
|
819
|
+
received: `Commitment: ${commitmentIn}`,
|
|
820
|
+
message: "Failed to check the link between the validity of the ID and the age derived from it",
|
|
821
|
+
};
|
|
683
822
|
}
|
|
684
823
|
const minAge = (0, utils_1.getMinAgeFromProof)(proofData);
|
|
685
824
|
const maxAge = (0, utils_1.getMaxAgeFromProof)(proofData);
|
|
@@ -689,14 +828,22 @@ class ZKPassport {
|
|
|
689
828
|
minAge < queryResult.age.gte.expected) {
|
|
690
829
|
console.warn("Age is not greater than or equal to the expected age");
|
|
691
830
|
isCorrect = false;
|
|
692
|
-
|
|
831
|
+
queryResultErrors.age.gte = {
|
|
832
|
+
expected: queryResult.age.gte.expected,
|
|
833
|
+
received: minAge,
|
|
834
|
+
message: "Age is not greater than or equal to the expected age",
|
|
835
|
+
};
|
|
693
836
|
}
|
|
694
837
|
if (queryResult.age.lt &&
|
|
695
838
|
queryResult.age.lt.result &&
|
|
696
839
|
maxAge >= queryResult.age.lt.expected) {
|
|
697
840
|
console.warn("Age is not less than the expected age");
|
|
698
841
|
isCorrect = false;
|
|
699
|
-
|
|
842
|
+
queryResultErrors.age.lt = {
|
|
843
|
+
expected: queryResult.age.lt.expected,
|
|
844
|
+
received: maxAge,
|
|
845
|
+
message: "Age is not less than the expected age",
|
|
846
|
+
};
|
|
700
847
|
}
|
|
701
848
|
if (queryResult.age.range) {
|
|
702
849
|
if (queryResult.age.range.result &&
|
|
@@ -704,38 +851,60 @@ class ZKPassport {
|
|
|
704
851
|
maxAge >= queryResult.age.range.expected[1])) {
|
|
705
852
|
console.warn("Age is not in the expected range");
|
|
706
853
|
isCorrect = false;
|
|
707
|
-
|
|
854
|
+
queryResultErrors.age.range = {
|
|
855
|
+
expected: queryResult.age.range.expected,
|
|
856
|
+
received: [minAge, maxAge],
|
|
857
|
+
message: "Age is not in the expected range",
|
|
858
|
+
};
|
|
708
859
|
}
|
|
709
860
|
}
|
|
710
861
|
if (!queryResult.age.lt && !queryResult.age.range && maxAge != 0) {
|
|
711
862
|
console.warn("Maximum age should be equal to 0");
|
|
712
863
|
isCorrect = false;
|
|
713
|
-
|
|
864
|
+
queryResultErrors.age.disclose = {
|
|
865
|
+
expected: 0,
|
|
866
|
+
received: maxAge,
|
|
867
|
+
message: "Maximum age should be equal to 0",
|
|
868
|
+
};
|
|
714
869
|
}
|
|
715
870
|
if (!queryResult.age.gte && !queryResult.age.range && minAge != 0) {
|
|
716
871
|
console.warn("Minimum age should be equal to 0");
|
|
717
872
|
isCorrect = false;
|
|
718
|
-
|
|
873
|
+
queryResultErrors.age.disclose = {
|
|
874
|
+
expected: 0,
|
|
875
|
+
received: minAge,
|
|
876
|
+
message: "Minimum age should be equal to 0",
|
|
877
|
+
};
|
|
719
878
|
}
|
|
720
879
|
if (queryResult.age.disclose &&
|
|
721
880
|
(queryResult.age.disclose.result !== minAge ||
|
|
722
881
|
queryResult.age.disclose.result !== maxAge)) {
|
|
723
882
|
console.warn("Age does not match the disclosed age in query result");
|
|
724
883
|
isCorrect = false;
|
|
725
|
-
|
|
884
|
+
queryResultErrors.age.disclose = {
|
|
885
|
+
expected: `${minAge}`,
|
|
886
|
+
received: `${queryResult.age.disclose.result}`,
|
|
887
|
+
message: "Age does not match the disclosed age in query result",
|
|
888
|
+
};
|
|
726
889
|
}
|
|
727
890
|
}
|
|
728
891
|
else {
|
|
729
892
|
console.warn("Age is not set in the query result");
|
|
730
893
|
isCorrect = false;
|
|
731
|
-
|
|
894
|
+
queryResultErrors.age.disclose = {
|
|
895
|
+
message: "Age is not set in the query result",
|
|
896
|
+
};
|
|
732
897
|
}
|
|
733
898
|
const currentDate = (0, utils_1.getCurrentDateFromAgeProof)(proofData);
|
|
734
899
|
if (currentDate.getTime() !== today.getTime() &&
|
|
735
900
|
currentDate.getTime() !== today.getTime() - 86400000) {
|
|
736
901
|
console.warn("Current date in the proof is too old");
|
|
737
902
|
isCorrect = false;
|
|
738
|
-
|
|
903
|
+
queryResultErrors.age.disclose = {
|
|
904
|
+
expected: `${today.toISOString()}`,
|
|
905
|
+
received: `${currentDate.toISOString()}`,
|
|
906
|
+
message: "Current date in the proof is too old",
|
|
907
|
+
};
|
|
739
908
|
}
|
|
740
909
|
uniqueIdentifier = (0, utils_1.getCommitmentInFromDisclosureProof)(proofData).toString(10);
|
|
741
910
|
}
|
|
@@ -744,7 +913,11 @@ class ZKPassport {
|
|
|
744
913
|
if (commitmentIn !== commitmentOut) {
|
|
745
914
|
console.warn("Failed to check the link between the validity of the ID and the birthdate derived from it");
|
|
746
915
|
isCorrect = false;
|
|
747
|
-
|
|
916
|
+
queryResultErrors.birthdate.commitment = {
|
|
917
|
+
expected: `Commitment: ${commitmentOut}`,
|
|
918
|
+
received: `Commitment: ${commitmentIn}`,
|
|
919
|
+
message: "Failed to check the link between the validity of the ID and the birthdate derived from it",
|
|
920
|
+
};
|
|
748
921
|
}
|
|
749
922
|
const minDate = (0, utils_1.getMinDateFromProof)(proofData);
|
|
750
923
|
const maxDate = (0, utils_1.getMaxDateFromProof)(proofData);
|
|
@@ -754,14 +927,22 @@ class ZKPassport {
|
|
|
754
927
|
minDate < queryResult.birthdate.gte.expected) {
|
|
755
928
|
console.warn("Birthdate is not greater than or equal to the expected birthdate");
|
|
756
929
|
isCorrect = false;
|
|
757
|
-
|
|
930
|
+
queryResultErrors.birthdate.gte = {
|
|
931
|
+
expected: queryResult.birthdate.gte.expected,
|
|
932
|
+
received: minDate,
|
|
933
|
+
message: "Birthdate is not greater than or equal to the expected birthdate",
|
|
934
|
+
};
|
|
758
935
|
}
|
|
759
936
|
if (queryResult.birthdate.lte &&
|
|
760
937
|
queryResult.birthdate.lte.result &&
|
|
761
938
|
maxDate > queryResult.birthdate.lte.expected) {
|
|
762
939
|
console.warn("Birthdate is not less than the expected birthdate");
|
|
763
940
|
isCorrect = false;
|
|
764
|
-
|
|
941
|
+
queryResultErrors.birthdate.lte = {
|
|
942
|
+
expected: queryResult.birthdate.lte.expected,
|
|
943
|
+
received: maxDate,
|
|
944
|
+
message: "Birthdate is not less than the expected birthdate",
|
|
945
|
+
};
|
|
765
946
|
}
|
|
766
947
|
if (queryResult.birthdate.range) {
|
|
767
948
|
if (queryResult.birthdate.range.result &&
|
|
@@ -769,7 +950,11 @@ class ZKPassport {
|
|
|
769
950
|
maxDate > queryResult.birthdate.range.expected[1])) {
|
|
770
951
|
console.warn("Birthdate is not in the expected range");
|
|
771
952
|
isCorrect = false;
|
|
772
|
-
|
|
953
|
+
queryResultErrors.birthdate.range = {
|
|
954
|
+
expected: queryResult.birthdate.range.expected,
|
|
955
|
+
received: [minDate, maxDate],
|
|
956
|
+
message: "Birthdate is not in the expected range",
|
|
957
|
+
};
|
|
773
958
|
}
|
|
774
959
|
}
|
|
775
960
|
if (!queryResult.birthdate.lte &&
|
|
@@ -777,20 +962,30 @@ class ZKPassport {
|
|
|
777
962
|
maxDate.getTime() != defaultDateValue.getTime()) {
|
|
778
963
|
console.warn("Maximum birthdate should be equal to default date value");
|
|
779
964
|
isCorrect = false;
|
|
780
|
-
|
|
965
|
+
queryResultErrors.birthdate.disclose = {
|
|
966
|
+
expected: `${defaultDateValue.toISOString()}`,
|
|
967
|
+
received: `${maxDate.toISOString()}`,
|
|
968
|
+
message: "Maximum birthdate should be equal to default date value",
|
|
969
|
+
};
|
|
781
970
|
}
|
|
782
971
|
if (!queryResult.birthdate.gte &&
|
|
783
972
|
!queryResult.birthdate.range &&
|
|
784
973
|
minDate.getTime() != defaultDateValue.getTime()) {
|
|
785
974
|
console.warn("Minimum birthdate should be equal to default date value");
|
|
786
975
|
isCorrect = false;
|
|
787
|
-
|
|
976
|
+
queryResultErrors.birthdate.disclose = {
|
|
977
|
+
expected: `${defaultDateValue.toISOString()}`,
|
|
978
|
+
received: `${minDate.toISOString()}`,
|
|
979
|
+
message: "Minimum birthdate should be equal to default date value",
|
|
980
|
+
};
|
|
788
981
|
}
|
|
789
982
|
}
|
|
790
983
|
else {
|
|
791
984
|
console.warn("Birthdate is not set in the query result");
|
|
792
985
|
isCorrect = false;
|
|
793
|
-
|
|
986
|
+
queryResultErrors.birthdate.disclose = {
|
|
987
|
+
message: "Birthdate is not set in the query result",
|
|
988
|
+
};
|
|
794
989
|
}
|
|
795
990
|
uniqueIdentifier = (0, utils_1.getCommitmentInFromDisclosureProof)(proofData).toString(10);
|
|
796
991
|
}
|
|
@@ -799,7 +994,11 @@ class ZKPassport {
|
|
|
799
994
|
if (commitmentIn !== commitmentOut) {
|
|
800
995
|
console.warn("Failed to check the link between the validity of the ID and its expiry date");
|
|
801
996
|
isCorrect = false;
|
|
802
|
-
|
|
997
|
+
queryResultErrors.expiry_date.commitment = {
|
|
998
|
+
expected: `Commitment: ${commitmentOut}`,
|
|
999
|
+
received: `Commitment: ${commitmentIn}`,
|
|
1000
|
+
message: "Failed to check the link between the validity of the ID and its expiry date",
|
|
1001
|
+
};
|
|
803
1002
|
}
|
|
804
1003
|
const minDate = (0, utils_1.getMinDateFromProof)(proofData);
|
|
805
1004
|
const maxDate = (0, utils_1.getMaxDateFromProof)(proofData);
|
|
@@ -809,14 +1008,22 @@ class ZKPassport {
|
|
|
809
1008
|
minDate < queryResult.expiry_date.gte.expected) {
|
|
810
1009
|
console.warn("Expiry date is not greater than or equal to the expected expiry date");
|
|
811
1010
|
isCorrect = false;
|
|
812
|
-
|
|
1011
|
+
queryResultErrors.expiry_date.gte = {
|
|
1012
|
+
expected: queryResult.expiry_date.gte.expected,
|
|
1013
|
+
received: minDate,
|
|
1014
|
+
message: "Expiry date is not greater than or equal to the expected expiry date",
|
|
1015
|
+
};
|
|
813
1016
|
}
|
|
814
1017
|
if (queryResult.expiry_date.lte &&
|
|
815
1018
|
queryResult.expiry_date.lte.result &&
|
|
816
1019
|
maxDate > queryResult.expiry_date.lte.expected) {
|
|
817
1020
|
console.warn("Expiry date is not less than the expected expiry date");
|
|
818
1021
|
isCorrect = false;
|
|
819
|
-
|
|
1022
|
+
queryResultErrors.expiry_date.lte = {
|
|
1023
|
+
expected: queryResult.expiry_date.lte.expected,
|
|
1024
|
+
received: maxDate,
|
|
1025
|
+
message: "Expiry date is not less than the expected expiry date",
|
|
1026
|
+
};
|
|
820
1027
|
}
|
|
821
1028
|
if (queryResult.expiry_date.range) {
|
|
822
1029
|
if (queryResult.expiry_date.range.result &&
|
|
@@ -824,7 +1031,11 @@ class ZKPassport {
|
|
|
824
1031
|
maxDate > queryResult.expiry_date.range.expected[1])) {
|
|
825
1032
|
console.warn("Expiry date is not in the expected range");
|
|
826
1033
|
isCorrect = false;
|
|
827
|
-
|
|
1034
|
+
queryResultErrors.expiry_date.range = {
|
|
1035
|
+
expected: queryResult.expiry_date.range.expected,
|
|
1036
|
+
received: [minDate, maxDate],
|
|
1037
|
+
message: "Expiry date is not in the expected range",
|
|
1038
|
+
};
|
|
828
1039
|
}
|
|
829
1040
|
}
|
|
830
1041
|
if (!queryResult.expiry_date.lte &&
|
|
@@ -832,44 +1043,64 @@ class ZKPassport {
|
|
|
832
1043
|
maxDate.getTime() != defaultDateValue.getTime()) {
|
|
833
1044
|
console.warn("Maximum expiry date should be equal to default date value");
|
|
834
1045
|
isCorrect = false;
|
|
835
|
-
|
|
1046
|
+
queryResultErrors.expiry_date.disclose = {
|
|
1047
|
+
expected: `${defaultDateValue.toISOString()}`,
|
|
1048
|
+
received: `${maxDate.toISOString()}`,
|
|
1049
|
+
message: "Maximum expiry date should be equal to default date value",
|
|
1050
|
+
};
|
|
836
1051
|
}
|
|
837
1052
|
if (!queryResult.expiry_date.gte &&
|
|
838
1053
|
!queryResult.expiry_date.range &&
|
|
839
1054
|
minDate.getTime() != defaultDateValue.getTime()) {
|
|
840
1055
|
console.warn("Minimum expiry date should be equal to default date value");
|
|
841
1056
|
isCorrect = false;
|
|
842
|
-
|
|
1057
|
+
queryResultErrors.expiry_date.disclose = {
|
|
1058
|
+
expected: `${defaultDateValue.toISOString()}`,
|
|
1059
|
+
received: `${minDate.toISOString()}`,
|
|
1060
|
+
message: "Minimum expiry date should be equal to default date value",
|
|
1061
|
+
};
|
|
843
1062
|
}
|
|
844
1063
|
}
|
|
845
1064
|
else {
|
|
846
1065
|
console.warn("Expiry date is not set in the query result");
|
|
847
1066
|
isCorrect = false;
|
|
848
|
-
|
|
1067
|
+
queryResultErrors.expiry_date.disclose = {
|
|
1068
|
+
message: "Expiry date is not set in the query result",
|
|
1069
|
+
};
|
|
849
1070
|
}
|
|
850
1071
|
uniqueIdentifier = (0, utils_1.getNullifierFromDisclosureProof)(proofData).toString(10);
|
|
851
1072
|
}
|
|
852
|
-
else if (proof.name === "
|
|
1073
|
+
else if (proof.name === "exclusion_check_nationality") {
|
|
853
1074
|
commitmentIn = (0, utils_1.getCommitmentInFromDisclosureProof)(proofData);
|
|
854
1075
|
if (commitmentIn !== commitmentOut) {
|
|
855
|
-
console.warn("Failed to check the link between the validity of the ID and the
|
|
1076
|
+
console.warn("Failed to check the link between the validity of the ID and the nationality exclusion check");
|
|
856
1077
|
isCorrect = false;
|
|
857
|
-
|
|
1078
|
+
queryResultErrors.nationality.commitment = {
|
|
1079
|
+
expected: `Commitment: ${commitmentOut}`,
|
|
1080
|
+
received: `Commitment: ${commitmentIn}`,
|
|
1081
|
+
message: "Failed to check the link between the validity of the ID and the nationality exclusion check",
|
|
1082
|
+
};
|
|
858
1083
|
}
|
|
859
1084
|
const countryList = (0, utils_1.getCountryListFromExclusionProof)(proofData);
|
|
860
1085
|
if (queryResult.nationality &&
|
|
861
1086
|
queryResult.nationality.out &&
|
|
862
1087
|
queryResult.nationality.out.result) {
|
|
863
1088
|
if (!queryResult.nationality.out.expected?.every((country) => countryList.includes(country))) {
|
|
864
|
-
console.warn("
|
|
1089
|
+
console.warn("Nationality exclusion list does not match the one from the query results");
|
|
865
1090
|
isCorrect = false;
|
|
866
|
-
|
|
1091
|
+
queryResultErrors.nationality.out = {
|
|
1092
|
+
expected: queryResult.nationality.out.expected,
|
|
1093
|
+
received: countryList,
|
|
1094
|
+
message: "Nationality exclusion list does not match the one from the query results",
|
|
1095
|
+
};
|
|
867
1096
|
}
|
|
868
1097
|
}
|
|
869
1098
|
else if (!queryResult.nationality || !queryResult.nationality.out) {
|
|
870
1099
|
console.warn("Nationality exclusion is not set in the query result");
|
|
871
1100
|
isCorrect = false;
|
|
872
|
-
|
|
1101
|
+
queryResultErrors.nationality.out = {
|
|
1102
|
+
message: "Nationality exclusion is not set in the query result",
|
|
1103
|
+
};
|
|
873
1104
|
}
|
|
874
1105
|
// Check the countryList is in ascending order
|
|
875
1106
|
// If the prover doesn't use a sorted list then the proof cannot be trusted
|
|
@@ -878,37 +1109,129 @@ class ZKPassport {
|
|
|
878
1109
|
if (countryList[i] < countryList[i - 1]) {
|
|
879
1110
|
console.warn("The nationality exclusion list has not been sorted, and thus the proof cannot be trusted");
|
|
880
1111
|
isCorrect = false;
|
|
881
|
-
|
|
1112
|
+
queryResultErrors.nationality.out = {
|
|
1113
|
+
message: "The nationality exclusion list has not been sorted, and thus the proof cannot be trusted",
|
|
1114
|
+
};
|
|
882
1115
|
}
|
|
883
1116
|
}
|
|
884
1117
|
uniqueIdentifier = (0, utils_1.getNullifierFromDisclosureProof)(proofData).toString(10);
|
|
885
1118
|
}
|
|
886
|
-
else if (proof.name === "
|
|
1119
|
+
else if (proof.name === "exclusion_check_issuing_country") {
|
|
887
1120
|
commitmentIn = (0, utils_1.getCommitmentInFromDisclosureProof)(proofData);
|
|
888
1121
|
if (commitmentIn !== commitmentOut) {
|
|
889
|
-
console.warn("Failed to check the link between the validity of the ID and the country
|
|
1122
|
+
console.warn("Failed to check the link between the validity of the ID and the issuing country exclusion check");
|
|
890
1123
|
isCorrect = false;
|
|
891
|
-
|
|
1124
|
+
queryResultErrors.nationality.commitment = {
|
|
1125
|
+
expected: `Commitment: ${commitmentOut}`,
|
|
1126
|
+
received: `Commitment: ${commitmentIn}`,
|
|
1127
|
+
message: "Failed to check the link between the validity of the ID and the issuing country exclusion check",
|
|
1128
|
+
};
|
|
1129
|
+
}
|
|
1130
|
+
const countryList = (0, utils_1.getCountryListFromExclusionProof)(proofData);
|
|
1131
|
+
if (queryResult.issuing_country &&
|
|
1132
|
+
queryResult.issuing_country.out &&
|
|
1133
|
+
queryResult.issuing_country.out.result) {
|
|
1134
|
+
if (!queryResult.issuing_country.out.expected?.every((country) => countryList.includes(country))) {
|
|
1135
|
+
console.warn("Issuing country exclusion list does not match the one from the query results");
|
|
1136
|
+
isCorrect = false;
|
|
1137
|
+
queryResultErrors.issuing_country.out = {
|
|
1138
|
+
expected: queryResult.issuing_country.out.expected,
|
|
1139
|
+
received: countryList,
|
|
1140
|
+
message: "Issuing country exclusion list does not match the one from the query results",
|
|
1141
|
+
};
|
|
1142
|
+
}
|
|
1143
|
+
}
|
|
1144
|
+
else if (!queryResult.issuing_country || !queryResult.issuing_country.out) {
|
|
1145
|
+
console.warn("Issuing country exclusion is not set in the query result");
|
|
1146
|
+
isCorrect = false;
|
|
1147
|
+
queryResultErrors.issuing_country.out = {
|
|
1148
|
+
message: "Issuing country exclusion is not set in the query result",
|
|
1149
|
+
};
|
|
1150
|
+
}
|
|
1151
|
+
// Check the countryList is in ascending order
|
|
1152
|
+
// If the prover doesn't use a sorted list then the proof cannot be trusted
|
|
1153
|
+
// as it is requirement in the circuit for the exclusion check to work
|
|
1154
|
+
for (let i = 1; i < countryList.length; i++) {
|
|
1155
|
+
if (countryList[i] < countryList[i - 1]) {
|
|
1156
|
+
console.warn("The issuing country exclusion list has not been sorted, and thus the proof cannot be trusted");
|
|
1157
|
+
isCorrect = false;
|
|
1158
|
+
queryResultErrors.issuing_country.out = {
|
|
1159
|
+
message: "The issuing country exclusion list has not been sorted, and thus the proof cannot be trusted",
|
|
1160
|
+
};
|
|
1161
|
+
}
|
|
1162
|
+
}
|
|
1163
|
+
uniqueIdentifier = (0, utils_1.getNullifierFromDisclosureProof)(proofData).toString(10);
|
|
1164
|
+
}
|
|
1165
|
+
else if (proof.name === "inclusion_check_nationality") {
|
|
1166
|
+
commitmentIn = (0, utils_1.getCommitmentInFromDisclosureProof)(proofData);
|
|
1167
|
+
if (commitmentIn !== commitmentOut) {
|
|
1168
|
+
console.warn("Failed to check the link between the validity of the ID and the nationality inclusion check");
|
|
1169
|
+
isCorrect = false;
|
|
1170
|
+
queryResultErrors.nationality.commitment = {
|
|
1171
|
+
expected: `Commitment: ${commitmentOut}`,
|
|
1172
|
+
received: `Commitment: ${commitmentIn}`,
|
|
1173
|
+
message: "Failed to check the link between the validity of the ID and the nationality inclusion check",
|
|
1174
|
+
};
|
|
892
1175
|
}
|
|
893
1176
|
const countryList = (0, utils_1.getCountryListFromInclusionProof)(proofData);
|
|
894
1177
|
if (queryResult.nationality &&
|
|
895
1178
|
queryResult.nationality.in &&
|
|
896
1179
|
queryResult.nationality.in.result) {
|
|
897
1180
|
if (!queryResult.nationality.in.expected?.every((country) => countryList.includes(country))) {
|
|
898
|
-
console.warn("
|
|
1181
|
+
console.warn("Nationality inclusion list does not match the one from the query results");
|
|
899
1182
|
isCorrect = false;
|
|
900
|
-
|
|
1183
|
+
queryResultErrors.nationality.in = {
|
|
1184
|
+
expected: queryResult.nationality.in.expected,
|
|
1185
|
+
received: countryList,
|
|
1186
|
+
message: "Nationality inclusion list does not match the one from the query results",
|
|
1187
|
+
};
|
|
901
1188
|
}
|
|
902
1189
|
}
|
|
903
1190
|
else if (!queryResult.nationality || !queryResult.nationality.in) {
|
|
904
1191
|
console.warn("Nationality inclusion is not set in the query result");
|
|
905
1192
|
isCorrect = false;
|
|
906
|
-
|
|
1193
|
+
queryResultErrors.nationality.in = {
|
|
1194
|
+
message: "Nationality inclusion is not set in the query result",
|
|
1195
|
+
};
|
|
1196
|
+
}
|
|
1197
|
+
uniqueIdentifier = (0, utils_1.getNullifierFromDisclosureProof)(proofData).toString(10);
|
|
1198
|
+
}
|
|
1199
|
+
else if (proof.name === "inclusion_check_issuing_country") {
|
|
1200
|
+
commitmentIn = (0, utils_1.getCommitmentInFromDisclosureProof)(proofData);
|
|
1201
|
+
if (commitmentIn !== commitmentOut) {
|
|
1202
|
+
console.warn("Failed to check the link between the validity of the ID and the issuing country inclusion check");
|
|
1203
|
+
isCorrect = false;
|
|
1204
|
+
queryResultErrors.nationality.commitment = {
|
|
1205
|
+
expected: `Commitment: ${commitmentOut}`,
|
|
1206
|
+
received: `Commitment: ${commitmentIn}`,
|
|
1207
|
+
message: "Failed to check the link between the validity of the ID and the issuing country inclusion check",
|
|
1208
|
+
};
|
|
1209
|
+
}
|
|
1210
|
+
const countryList = (0, utils_1.getCountryListFromInclusionProof)(proofData);
|
|
1211
|
+
if (queryResult.issuing_country &&
|
|
1212
|
+
queryResult.issuing_country.in &&
|
|
1213
|
+
queryResult.issuing_country.in.result) {
|
|
1214
|
+
if (!queryResult.issuing_country.in.expected?.every((country) => countryList.includes(country))) {
|
|
1215
|
+
console.warn("Issuing country inclusion list does not match the one from the query results");
|
|
1216
|
+
isCorrect = false;
|
|
1217
|
+
queryResultErrors.issuing_country.in = {
|
|
1218
|
+
expected: queryResult.issuing_country.in.expected,
|
|
1219
|
+
received: countryList,
|
|
1220
|
+
message: "Issuing country inclusion list does not match the one from the query results",
|
|
1221
|
+
};
|
|
1222
|
+
}
|
|
1223
|
+
}
|
|
1224
|
+
else if (!queryResult.issuing_country || !queryResult.issuing_country.in) {
|
|
1225
|
+
console.warn("Issuing country inclusion is not set in the query result");
|
|
1226
|
+
isCorrect = false;
|
|
1227
|
+
queryResultErrors.issuing_country.in = {
|
|
1228
|
+
message: "Issuing country inclusion is not set in the query result",
|
|
1229
|
+
};
|
|
907
1230
|
}
|
|
908
1231
|
uniqueIdentifier = (0, utils_1.getNullifierFromDisclosureProof)(proofData).toString(10);
|
|
909
1232
|
}
|
|
910
1233
|
}
|
|
911
|
-
return { isCorrect, uniqueIdentifier };
|
|
1234
|
+
return { isCorrect, uniqueIdentifier, queryResultErrors };
|
|
912
1235
|
}
|
|
913
1236
|
/**
|
|
914
1237
|
* @notice Verify the proofs received from the mobile app.
|
|
@@ -923,12 +1246,6 @@ class ZKPassport {
|
|
|
923
1246
|
// There is a minimum of 4 subproofs to make a complete proof
|
|
924
1247
|
if (!proofs || proofs.length < 4) {
|
|
925
1248
|
proofsToVerify = this.topicToProofs[requestId];
|
|
926
|
-
if (!proofsToVerify || proofsToVerify.length < 4) {
|
|
927
|
-
// It may happen that a request returns a result without proofs
|
|
928
|
-
// Meaning the ID is not supported yet by ZKPassport circuits,
|
|
929
|
-
// so the results has to be trusted and cannot be independently verified
|
|
930
|
-
return { uniqueIdentifier: undefined, verified: false };
|
|
931
|
-
}
|
|
932
1249
|
}
|
|
933
1250
|
const { BarretenbergVerifier } = await Promise.resolve().then(() => tslib_1.__importStar(require("@aztec/bb.js")));
|
|
934
1251
|
const verifier = new BarretenbergVerifier();
|
|
@@ -937,13 +1254,15 @@ class ZKPassport {
|
|
|
937
1254
|
}*/
|
|
938
1255
|
let verified = true;
|
|
939
1256
|
let uniqueIdentifier;
|
|
1257
|
+
let queryResultErrors;
|
|
940
1258
|
if (queryResult) {
|
|
941
|
-
const { isCorrect, uniqueIdentifier: uniqueIdentifierFromPublicInputs } = await this.checkPublicInputs(proofsToVerify, queryResult, requestId);
|
|
1259
|
+
const { isCorrect, uniqueIdentifier: uniqueIdentifierFromPublicInputs, queryResultErrors: queryResultErrorsFromPublicInputs, } = await this.checkPublicInputs(proofsToVerify, queryResult, requestId);
|
|
942
1260
|
uniqueIdentifier = uniqueIdentifierFromPublicInputs;
|
|
943
1261
|
verified = isCorrect;
|
|
1262
|
+
queryResultErrors = isCorrect ? undefined : queryResultErrorsFromPublicInputs;
|
|
944
1263
|
}
|
|
945
1264
|
// Only proceed with the proof verification if the public inputs are correct
|
|
946
|
-
if (verified) {
|
|
1265
|
+
if (verified && queryResult) {
|
|
947
1266
|
for (const proof of proofsToVerify) {
|
|
948
1267
|
const proofData = (0, utils_1.getProofData)(proof.proof, true);
|
|
949
1268
|
const hostedPackagedCircuit = await (0, utils_1.getHostedPackagedCircuitByName)(proof.version, proof.name);
|
|
@@ -963,7 +1282,7 @@ class ZKPassport {
|
|
|
963
1282
|
}
|
|
964
1283
|
}
|
|
965
1284
|
this.topicToProofs[requestId] = [];
|
|
966
|
-
return { uniqueIdentifier, verified };
|
|
1285
|
+
return { uniqueIdentifier, verified, queryResultErrors };
|
|
967
1286
|
}
|
|
968
1287
|
/**
|
|
969
1288
|
* @notice Returns the URL of the request.
|
|
@@ -981,14 +1300,17 @@ class ZKPassport {
|
|
|
981
1300
|
* @param requestId The request ID.
|
|
982
1301
|
*/
|
|
983
1302
|
cancelRequest(requestId) {
|
|
984
|
-
this.topicToWebSocketClient[requestId]
|
|
985
|
-
|
|
1303
|
+
if (this.topicToWebSocketClient[requestId]) {
|
|
1304
|
+
this.topicToWebSocketClient[requestId].close();
|
|
1305
|
+
delete this.topicToWebSocketClient[requestId];
|
|
1306
|
+
}
|
|
986
1307
|
delete this.topicToKeyPair[requestId];
|
|
987
1308
|
delete this.topicToConfig[requestId];
|
|
988
1309
|
delete this.topicToLocalConfig[requestId];
|
|
989
1310
|
delete this.topicToSharedSecret[requestId];
|
|
990
1311
|
delete this.topicToProofs[requestId];
|
|
991
1312
|
delete this.topicToExpectedProofCount[requestId];
|
|
1313
|
+
delete this.topicToFailedProofCount[requestId];
|
|
992
1314
|
delete this.topicToResults[requestId];
|
|
993
1315
|
this.onRequestReceivedCallbacks[requestId] = [];
|
|
994
1316
|
this.onGeneratingProofCallbacks[requestId] = [];
|
|
@@ -997,5 +1319,13 @@ class ZKPassport {
|
|
|
997
1319
|
this.onRejectCallbacks[requestId] = [];
|
|
998
1320
|
this.onErrorCallbacks[requestId] = [];
|
|
999
1321
|
}
|
|
1322
|
+
/**
|
|
1323
|
+
* @notice Clears all requests.
|
|
1324
|
+
*/
|
|
1325
|
+
clearAllRequests() {
|
|
1326
|
+
for (const requestId in this.topicToWebSocketClient) {
|
|
1327
|
+
this.cancelRequest(requestId);
|
|
1328
|
+
}
|
|
1329
|
+
}
|
|
1000
1330
|
}
|
|
1001
1331
|
exports.ZKPassport = ZKPassport;
|