@zkpassport/sdk 0.2.9 → 0.2.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/index.d.ts +8 -4
- package/dist/cjs/index.js +151 -70
- package/dist/esm/index.d.ts +8 -4
- package/dist/esm/index.js +151 -70
- package/package.json +3 -3
- package/src/index.ts +202 -87
package/dist/cjs/index.d.ts
CHANGED
|
@@ -125,13 +125,13 @@ export type QueryBuilder = {
|
|
|
125
125
|
* @param key The attribute to compare.
|
|
126
126
|
* @param value The list of values to check inclusion against.
|
|
127
127
|
*/
|
|
128
|
-
in: <T extends "nationality">(key: T, value: IDCredentialValue<T>[]) => QueryBuilder;
|
|
128
|
+
in: <T extends "nationality" | "issuing_country">(key: T, value: IDCredentialValue<T>[]) => QueryBuilder;
|
|
129
129
|
/**
|
|
130
130
|
* Requires this attribute to be excluded from the provided list.
|
|
131
131
|
* @param key The attribute to compare.
|
|
132
132
|
* @param value The list of values to check exclusion against.
|
|
133
133
|
*/
|
|
134
|
-
out: <T extends "nationality">(key: T, value: IDCredentialValue<T>[]) => QueryBuilder;
|
|
134
|
+
out: <T extends "nationality" | "issuing_country">(key: T, value: IDCredentialValue<T>[]) => QueryBuilder;
|
|
135
135
|
/**
|
|
136
136
|
* Requires this attribute to be disclosed.
|
|
137
137
|
* @param key The attribute to disclose.
|
|
@@ -200,13 +200,17 @@ export declare class ZKPassport {
|
|
|
200
200
|
private checkPublicInputs;
|
|
201
201
|
/**
|
|
202
202
|
* @notice Verify the proofs received from the mobile app.
|
|
203
|
-
* @param requestId The request ID.
|
|
204
203
|
* @param proofs The proofs to verify.
|
|
205
204
|
* @param queryResult The query result to verify against
|
|
205
|
+
* @param validity How many days ago should have the ID been last scanned by the user?
|
|
206
206
|
* @returns An object containing the unique identifier associated to the user
|
|
207
207
|
* and a boolean indicating whether the proofs were successfully verified.
|
|
208
208
|
*/
|
|
209
|
-
verify(
|
|
209
|
+
verify({ proofs, queryResult, validity, }: {
|
|
210
|
+
proofs: Array<ProofResult>;
|
|
211
|
+
queryResult: QueryResult;
|
|
212
|
+
validity?: number;
|
|
213
|
+
}): Promise<{
|
|
210
214
|
uniqueIdentifier: string | undefined;
|
|
211
215
|
verified: boolean;
|
|
212
216
|
queryResultErrors?: QueryResultErrors;
|
package/dist/cjs/index.js
CHANGED
|
@@ -11,8 +11,6 @@ const json_rpc_1 = require("./json-rpc");
|
|
|
11
11
|
const encryption_1 = require("./encryption");
|
|
12
12
|
const logger_1 = require("./logger");
|
|
13
13
|
const pako_1 = require("pako");
|
|
14
|
-
//import initNoirC from '@noir-lang/noirc_abi'
|
|
15
|
-
//import initACVM from '@noir-lang/acvm_js'
|
|
16
14
|
const en_json_1 = tslib_1.__importDefault(require("i18n-iso-countries/langs/en.json"));
|
|
17
15
|
const buffer_1 = require("buffer/");
|
|
18
16
|
// If Buffer is not defined, then we use the Buffer from the buffer package
|
|
@@ -94,18 +92,17 @@ class ZKPassport {
|
|
|
94
92
|
}
|
|
95
93
|
this.domain = _domain || window.location.hostname;
|
|
96
94
|
}
|
|
97
|
-
/*private async initWasmVerifier() {
|
|
98
|
-
const acvm = await import('@noir-lang/acvm_js/web/acvm_js_bg.wasm')
|
|
99
|
-
const noirc = await import('@noir-lang/noirc_abi/web/noirc_abi_wasm_bg.wasm')
|
|
100
|
-
await Promise.all([initACVM(acvm), initNoirC(noirc)])
|
|
101
|
-
this.wasmVerifierInit = true
|
|
102
|
-
}*/
|
|
103
95
|
async handleResult(topic) {
|
|
104
96
|
const result = this.topicToResults[topic];
|
|
105
97
|
// Clear the results straight away to avoid concurrency issues
|
|
106
98
|
delete this.topicToResults[topic];
|
|
107
99
|
// Verify the proofs and extract the unique identifier (aka nullifier) and the verification result
|
|
108
|
-
const { uniqueIdentifier, verified, queryResultErrors } = await this.verify(
|
|
100
|
+
const { uniqueIdentifier, verified, queryResultErrors } = await this.verify({
|
|
101
|
+
proofs: this.topicToProofs[topic],
|
|
102
|
+
queryResult: result,
|
|
103
|
+
validity: this.topicToLocalConfig[topic]?.validity,
|
|
104
|
+
});
|
|
105
|
+
delete this.topicToProofs[topic];
|
|
109
106
|
const hasFailedProofs = this.topicToFailedProofCount[topic] > 0;
|
|
110
107
|
await Promise.all(this.onResultCallbacks[topic].map((callback) => callback({
|
|
111
108
|
// If there are failed proofs, we don't return the unique identifier
|
|
@@ -151,13 +148,23 @@ class ZKPassport {
|
|
|
151
148
|
}
|
|
152
149
|
break;
|
|
153
150
|
case "in":
|
|
154
|
-
if (field === "nationality" &&
|
|
155
|
-
neededCircuits.
|
|
151
|
+
if (field === "nationality" &&
|
|
152
|
+
!neededCircuits.includes("inclusion_check_nationality")) {
|
|
153
|
+
neededCircuits.push("inclusion_check_nationality");
|
|
154
|
+
}
|
|
155
|
+
else if (field === "issuing_country" &&
|
|
156
|
+
!neededCircuits.includes("inclusion_check_issuing_country")) {
|
|
157
|
+
neededCircuits.push("inclusion_check_issuing_country");
|
|
156
158
|
}
|
|
157
159
|
break;
|
|
158
160
|
case "out":
|
|
159
|
-
if (field === "nationality" &&
|
|
160
|
-
neededCircuits.
|
|
161
|
+
if (field === "nationality" &&
|
|
162
|
+
!neededCircuits.includes("exclusion_check_nationality")) {
|
|
163
|
+
neededCircuits.push("exclusion_check_nationality");
|
|
164
|
+
}
|
|
165
|
+
else if (field === "issuing_country" &&
|
|
166
|
+
!neededCircuits.includes("exclusion_check_issuing_country")) {
|
|
167
|
+
neededCircuits.push("exclusion_check_issuing_country");
|
|
161
168
|
}
|
|
162
169
|
break;
|
|
163
170
|
}
|
|
@@ -391,7 +398,7 @@ class ZKPassport {
|
|
|
391
398
|
};
|
|
392
399
|
return this.getZkPassportRequest(topic);
|
|
393
400
|
}
|
|
394
|
-
async checkPublicInputs(proofs, queryResult,
|
|
401
|
+
async checkPublicInputs(proofs, queryResult, validity) {
|
|
395
402
|
let commitmentIn;
|
|
396
403
|
let commitmentOut;
|
|
397
404
|
let isCorrect = true;
|
|
@@ -428,8 +435,10 @@ class ZKPassport {
|
|
|
428
435
|
"compare_age",
|
|
429
436
|
"compare_birthdate",
|
|
430
437
|
"compare_expiry",
|
|
431
|
-
"
|
|
432
|
-
"
|
|
438
|
+
"exclusion_check_nationality",
|
|
439
|
+
"inclusion_check_nationality",
|
|
440
|
+
"exclusion_check_issuing_country",
|
|
441
|
+
"inclusion_check_issuing_country",
|
|
433
442
|
];
|
|
434
443
|
const getIndex = (proof) => {
|
|
435
444
|
const name = proof.name || "";
|
|
@@ -479,14 +488,15 @@ class ZKPassport {
|
|
|
479
488
|
commitmentOut = (0, utils_1.getCommitmentOutFromIntegrityProof)(proofData);
|
|
480
489
|
const currentDate = (0, utils_1.getCurrentDateFromIntegrityProof)(proofData);
|
|
481
490
|
const todayToCurrentDate = today.getTime() - currentDate.getTime();
|
|
482
|
-
const
|
|
491
|
+
const differenceInDays = validity ?? 180;
|
|
492
|
+
const expectedDifference = differenceInDays * 86400000;
|
|
483
493
|
const actualDifference = today.getTime() - (today.getTime() - expectedDifference);
|
|
484
494
|
// The ID should not expire within the next 6 months (or whatever the custom value is)
|
|
485
495
|
if (todayToCurrentDate >= actualDifference) {
|
|
486
|
-
console.warn(`The date used to check the validity of the ID is older than ${
|
|
496
|
+
console.warn(`The date used to check the validity of the ID is older than ${differenceInDays} days. You can ask the user to rescan their ID or ask them to disclose their expiry date`);
|
|
487
497
|
isCorrect = false;
|
|
488
498
|
queryResultErrors.data_check_integrity.date = {
|
|
489
|
-
expected: `Difference: ${
|
|
499
|
+
expected: `Difference: ${differenceInDays} days`,
|
|
490
500
|
received: `Difference: ${Math.round(todayToCurrentDate / 86400000)} days`,
|
|
491
501
|
message: "The date used to check the validity of the ID is older than the validity period",
|
|
492
502
|
};
|
|
@@ -516,7 +526,7 @@ class ZKPassport {
|
|
|
516
526
|
isCorrect = false;
|
|
517
527
|
queryResultErrors.document_type.eq = {
|
|
518
528
|
expected: `${queryResult.document_type.eq.expected}`,
|
|
519
|
-
received: `${disclosedDataPassport.documentType}`,
|
|
529
|
+
received: `${disclosedDataPassport.documentType ?? disclosedDataIDCard.documentType}`,
|
|
520
530
|
message: "Document type does not match the expected document type",
|
|
521
531
|
};
|
|
522
532
|
}
|
|
@@ -525,7 +535,7 @@ class ZKPassport {
|
|
|
525
535
|
isCorrect = false;
|
|
526
536
|
queryResultErrors.document_type.disclose = {
|
|
527
537
|
expected: `${queryResult.document_type.disclose?.result}`,
|
|
528
|
-
received: `${disclosedDataIDCard.documentType}`,
|
|
538
|
+
received: `${disclosedDataIDCard.documentType ?? disclosedDataPassport.documentType}`,
|
|
529
539
|
message: "Document type does not match the disclosed document type in query result",
|
|
530
540
|
};
|
|
531
541
|
}
|
|
@@ -541,7 +551,7 @@ class ZKPassport {
|
|
|
541
551
|
isCorrect = false;
|
|
542
552
|
queryResultErrors.birthdate.eq = {
|
|
543
553
|
expected: `${queryResult.birthdate.eq.expected.toISOString()}`,
|
|
544
|
-
received: `${birthdatePassport
|
|
554
|
+
received: `${birthdatePassport?.toISOString() ?? birthdateIDCard?.toISOString()}`,
|
|
545
555
|
message: "Birthdate does not match the expected birthdate",
|
|
546
556
|
};
|
|
547
557
|
}
|
|
@@ -552,7 +562,7 @@ class ZKPassport {
|
|
|
552
562
|
isCorrect = false;
|
|
553
563
|
queryResultErrors.birthdate.disclose = {
|
|
554
564
|
expected: `${queryResult.birthdate.disclose.result.toISOString()}`,
|
|
555
|
-
received: `${birthdatePassport
|
|
565
|
+
received: `${birthdatePassport?.toISOString() ?? birthdateIDCard?.toISOString()}`,
|
|
556
566
|
message: "Birthdate does not match the disclosed birthdate in query result",
|
|
557
567
|
};
|
|
558
568
|
}
|
|
@@ -568,7 +578,7 @@ class ZKPassport {
|
|
|
568
578
|
isCorrect = false;
|
|
569
579
|
queryResultErrors.expiry_date.eq = {
|
|
570
580
|
expected: `${queryResult.expiry_date.eq.expected.toISOString()}`,
|
|
571
|
-
received: `${expiryDatePassport
|
|
581
|
+
received: `${expiryDatePassport?.toISOString() ?? expiryDateIDCard?.toISOString()}`,
|
|
572
582
|
message: "Expiry date does not match the expected expiry date",
|
|
573
583
|
};
|
|
574
584
|
}
|
|
@@ -579,7 +589,7 @@ class ZKPassport {
|
|
|
579
589
|
isCorrect = false;
|
|
580
590
|
queryResultErrors.expiry_date.disclose = {
|
|
581
591
|
expected: `${queryResult.expiry_date.disclose.result.toISOString()}`,
|
|
582
|
-
received: `${expiryDatePassport
|
|
592
|
+
received: `${expiryDatePassport?.toISOString() ?? expiryDateIDCard?.toISOString()}`,
|
|
583
593
|
message: "Expiry date does not match the disclosed expiry date in query result",
|
|
584
594
|
};
|
|
585
595
|
}
|
|
@@ -595,7 +605,7 @@ class ZKPassport {
|
|
|
595
605
|
isCorrect = false;
|
|
596
606
|
queryResultErrors.nationality.eq = {
|
|
597
607
|
expected: `${queryResult.nationality.eq.expected}`,
|
|
598
|
-
received: `${nationalityPassport}`,
|
|
608
|
+
received: `${nationalityPassport ?? nationalityIDCard}`,
|
|
599
609
|
message: "Nationality does not match the expected nationality",
|
|
600
610
|
};
|
|
601
611
|
}
|
|
@@ -606,7 +616,7 @@ class ZKPassport {
|
|
|
606
616
|
isCorrect = false;
|
|
607
617
|
queryResultErrors.nationality.disclose = {
|
|
608
618
|
expected: `${queryResult.nationality.disclose.result}`,
|
|
609
|
-
received: `${nationalityPassport}`,
|
|
619
|
+
received: `${nationalityPassport ?? nationalityIDCard}`,
|
|
610
620
|
message: "Nationality does not match the disclosed nationality in query result",
|
|
611
621
|
};
|
|
612
622
|
}
|
|
@@ -622,7 +632,7 @@ class ZKPassport {
|
|
|
622
632
|
isCorrect = false;
|
|
623
633
|
queryResultErrors.document_number.eq = {
|
|
624
634
|
expected: `${queryResult.document_number.eq.expected}`,
|
|
625
|
-
received: `${documentNumberPassport}`,
|
|
635
|
+
received: `${documentNumberPassport ?? documentNumberIDCard}`,
|
|
626
636
|
message: "Document number does not match the expected document number",
|
|
627
637
|
};
|
|
628
638
|
}
|
|
@@ -633,7 +643,7 @@ class ZKPassport {
|
|
|
633
643
|
isCorrect = false;
|
|
634
644
|
queryResultErrors.document_number.disclose = {
|
|
635
645
|
expected: `${queryResult.document_number.disclose.result}`,
|
|
636
|
-
received: `${documentNumberPassport}`,
|
|
646
|
+
received: `${documentNumberPassport ?? documentNumberIDCard}`,
|
|
637
647
|
message: "Document number does not match the disclosed document number in query result",
|
|
638
648
|
};
|
|
639
649
|
}
|
|
@@ -649,7 +659,7 @@ class ZKPassport {
|
|
|
649
659
|
isCorrect = false;
|
|
650
660
|
queryResultErrors.gender.eq = {
|
|
651
661
|
expected: `${queryResult.gender.eq.expected}`,
|
|
652
|
-
received: `${genderPassport}`,
|
|
662
|
+
received: `${genderPassport ?? genderIDCard}`,
|
|
653
663
|
message: "Gender does not match the expected gender",
|
|
654
664
|
};
|
|
655
665
|
}
|
|
@@ -660,7 +670,7 @@ class ZKPassport {
|
|
|
660
670
|
isCorrect = false;
|
|
661
671
|
queryResultErrors.gender.disclose = {
|
|
662
672
|
expected: `${queryResult.gender.disclose.result}`,
|
|
663
|
-
received: `${genderPassport}`,
|
|
673
|
+
received: `${genderPassport ?? genderIDCard}`,
|
|
664
674
|
message: "Gender does not match the disclosed gender in query result",
|
|
665
675
|
};
|
|
666
676
|
}
|
|
@@ -676,7 +686,7 @@ class ZKPassport {
|
|
|
676
686
|
isCorrect = false;
|
|
677
687
|
queryResultErrors.issuing_country.eq = {
|
|
678
688
|
expected: `${queryResult.issuing_country.eq.expected}`,
|
|
679
|
-
received: `${issuingCountryPassport}`,
|
|
689
|
+
received: `${issuingCountryPassport ?? issuingCountryIDCard}`,
|
|
680
690
|
message: "Issuing country does not match the expected issuing country",
|
|
681
691
|
};
|
|
682
692
|
}
|
|
@@ -687,7 +697,7 @@ class ZKPassport {
|
|
|
687
697
|
isCorrect = false;
|
|
688
698
|
queryResultErrors.issuing_country.disclose = {
|
|
689
699
|
expected: `${queryResult.issuing_country.disclose.result}`,
|
|
690
|
-
received: `${issuingCountryPassport}`,
|
|
700
|
+
received: `${issuingCountryPassport ?? issuingCountryIDCard}`,
|
|
691
701
|
message: "Issuing country does not match the disclosed issuing country in query result",
|
|
692
702
|
};
|
|
693
703
|
}
|
|
@@ -705,7 +715,7 @@ class ZKPassport {
|
|
|
705
715
|
isCorrect = false;
|
|
706
716
|
queryResultErrors.fullname.eq = {
|
|
707
717
|
expected: `${queryResult.fullname.eq.expected}`,
|
|
708
|
-
received: `${fullnamePassport}`,
|
|
718
|
+
received: `${fullnamePassport ?? fullnameIDCard}`,
|
|
709
719
|
message: "Fullname does not match the expected fullname",
|
|
710
720
|
};
|
|
711
721
|
}
|
|
@@ -718,7 +728,7 @@ class ZKPassport {
|
|
|
718
728
|
isCorrect = false;
|
|
719
729
|
queryResultErrors.fullname.disclose = {
|
|
720
730
|
expected: `${queryResult.fullname.disclose.result}`,
|
|
721
|
-
received: `${fullnamePassport}`,
|
|
731
|
+
received: `${fullnamePassport ?? fullnameIDCard}`,
|
|
722
732
|
message: "Fullname does not match the disclosed fullname in query result",
|
|
723
733
|
};
|
|
724
734
|
}
|
|
@@ -741,7 +751,7 @@ class ZKPassport {
|
|
|
741
751
|
isCorrect = false;
|
|
742
752
|
queryResultErrors.firstname.eq = {
|
|
743
753
|
expected: `${queryResult.firstname.eq.expected}`,
|
|
744
|
-
received: `${firstnamePassport}`,
|
|
754
|
+
received: `${firstnamePassport ?? firstnameIDCard}`,
|
|
745
755
|
message: "Firstname does not match the expected firstname",
|
|
746
756
|
};
|
|
747
757
|
}
|
|
@@ -754,7 +764,7 @@ class ZKPassport {
|
|
|
754
764
|
isCorrect = false;
|
|
755
765
|
queryResultErrors.firstname.disclose = {
|
|
756
766
|
expected: `${queryResult.firstname.disclose.result}`,
|
|
757
|
-
received: `${firstnamePassport}`,
|
|
767
|
+
received: `${firstnamePassport ?? firstnameIDCard}`,
|
|
758
768
|
message: "Firstname does not match the disclosed firstname in query result",
|
|
759
769
|
};
|
|
760
770
|
}
|
|
@@ -777,7 +787,7 @@ class ZKPassport {
|
|
|
777
787
|
isCorrect = false;
|
|
778
788
|
queryResultErrors.lastname.eq = {
|
|
779
789
|
expected: `${queryResult.lastname.eq.expected}`,
|
|
780
|
-
received: `${lastnamePassport}`,
|
|
790
|
+
received: `${lastnamePassport ?? lastnameIDCard}`,
|
|
781
791
|
message: "Lastname does not match the expected lastname",
|
|
782
792
|
};
|
|
783
793
|
}
|
|
@@ -790,7 +800,7 @@ class ZKPassport {
|
|
|
790
800
|
isCorrect = false;
|
|
791
801
|
queryResultErrors.lastname.disclose = {
|
|
792
802
|
expected: `${queryResult.lastname.disclose.result}`,
|
|
793
|
-
received: `${lastnamePassport}`,
|
|
803
|
+
received: `${lastnamePassport ?? lastnameIDCard}`,
|
|
794
804
|
message: "Lastname does not match the disclosed lastname in query result",
|
|
795
805
|
};
|
|
796
806
|
}
|
|
@@ -894,7 +904,7 @@ class ZKPassport {
|
|
|
894
904
|
message: "Current date in the proof is too old",
|
|
895
905
|
};
|
|
896
906
|
}
|
|
897
|
-
uniqueIdentifier = (0, utils_1.
|
|
907
|
+
uniqueIdentifier = (0, utils_1.getNullifierFromDisclosureProof)(proofData).toString(10);
|
|
898
908
|
}
|
|
899
909
|
else if (proof.name === "compare_birthdate") {
|
|
900
910
|
commitmentIn = (0, utils_1.getCommitmentInFromDisclosureProof)(proofData);
|
|
@@ -975,7 +985,7 @@ class ZKPassport {
|
|
|
975
985
|
message: "Birthdate is not set in the query result",
|
|
976
986
|
};
|
|
977
987
|
}
|
|
978
|
-
uniqueIdentifier = (0, utils_1.
|
|
988
|
+
uniqueIdentifier = (0, utils_1.getNullifierFromDisclosureProof)(proofData).toString(10);
|
|
979
989
|
}
|
|
980
990
|
else if (proof.name === "compare_expiry") {
|
|
981
991
|
commitmentIn = (0, utils_1.getCommitmentInFromDisclosureProof)(proofData);
|
|
@@ -1058,15 +1068,15 @@ class ZKPassport {
|
|
|
1058
1068
|
}
|
|
1059
1069
|
uniqueIdentifier = (0, utils_1.getNullifierFromDisclosureProof)(proofData).toString(10);
|
|
1060
1070
|
}
|
|
1061
|
-
else if (proof.name === "
|
|
1071
|
+
else if (proof.name === "exclusion_check_nationality") {
|
|
1062
1072
|
commitmentIn = (0, utils_1.getCommitmentInFromDisclosureProof)(proofData);
|
|
1063
1073
|
if (commitmentIn !== commitmentOut) {
|
|
1064
|
-
console.warn("Failed to check the link between the validity of the ID and the
|
|
1074
|
+
console.warn("Failed to check the link between the validity of the ID and the nationality exclusion check");
|
|
1065
1075
|
isCorrect = false;
|
|
1066
1076
|
queryResultErrors.nationality.commitment = {
|
|
1067
1077
|
expected: `Commitment: ${commitmentOut}`,
|
|
1068
1078
|
received: `Commitment: ${commitmentIn}`,
|
|
1069
|
-
message: "Failed to check the link between the validity of the ID and the
|
|
1079
|
+
message: "Failed to check the link between the validity of the ID and the nationality exclusion check",
|
|
1070
1080
|
};
|
|
1071
1081
|
}
|
|
1072
1082
|
const countryList = (0, utils_1.getCountryListFromExclusionProof)(proofData);
|
|
@@ -1074,12 +1084,12 @@ class ZKPassport {
|
|
|
1074
1084
|
queryResult.nationality.out &&
|
|
1075
1085
|
queryResult.nationality.out.result) {
|
|
1076
1086
|
if (!queryResult.nationality.out.expected?.every((country) => countryList.includes(country))) {
|
|
1077
|
-
console.warn("
|
|
1087
|
+
console.warn("Nationality exclusion list does not match the one from the query results");
|
|
1078
1088
|
isCorrect = false;
|
|
1079
1089
|
queryResultErrors.nationality.out = {
|
|
1080
1090
|
expected: queryResult.nationality.out.expected,
|
|
1081
1091
|
received: countryList,
|
|
1082
|
-
message: "
|
|
1092
|
+
message: "Nationality exclusion list does not match the one from the query results",
|
|
1083
1093
|
};
|
|
1084
1094
|
}
|
|
1085
1095
|
}
|
|
@@ -1104,15 +1114,61 @@ class ZKPassport {
|
|
|
1104
1114
|
}
|
|
1105
1115
|
uniqueIdentifier = (0, utils_1.getNullifierFromDisclosureProof)(proofData).toString(10);
|
|
1106
1116
|
}
|
|
1107
|
-
else if (proof.name === "
|
|
1117
|
+
else if (proof.name === "exclusion_check_issuing_country") {
|
|
1118
|
+
commitmentIn = (0, utils_1.getCommitmentInFromDisclosureProof)(proofData);
|
|
1119
|
+
if (commitmentIn !== commitmentOut) {
|
|
1120
|
+
console.warn("Failed to check the link between the validity of the ID and the issuing country exclusion check");
|
|
1121
|
+
isCorrect = false;
|
|
1122
|
+
queryResultErrors.nationality.commitment = {
|
|
1123
|
+
expected: `Commitment: ${commitmentOut}`,
|
|
1124
|
+
received: `Commitment: ${commitmentIn}`,
|
|
1125
|
+
message: "Failed to check the link between the validity of the ID and the issuing country exclusion check",
|
|
1126
|
+
};
|
|
1127
|
+
}
|
|
1128
|
+
const countryList = (0, utils_1.getCountryListFromExclusionProof)(proofData);
|
|
1129
|
+
if (queryResult.issuing_country &&
|
|
1130
|
+
queryResult.issuing_country.out &&
|
|
1131
|
+
queryResult.issuing_country.out.result) {
|
|
1132
|
+
if (!queryResult.issuing_country.out.expected?.every((country) => countryList.includes(country))) {
|
|
1133
|
+
console.warn("Issuing country exclusion list does not match the one from the query results");
|
|
1134
|
+
isCorrect = false;
|
|
1135
|
+
queryResultErrors.issuing_country.out = {
|
|
1136
|
+
expected: queryResult.issuing_country.out.expected,
|
|
1137
|
+
received: countryList,
|
|
1138
|
+
message: "Issuing country exclusion list does not match the one from the query results",
|
|
1139
|
+
};
|
|
1140
|
+
}
|
|
1141
|
+
}
|
|
1142
|
+
else if (!queryResult.issuing_country || !queryResult.issuing_country.out) {
|
|
1143
|
+
console.warn("Issuing country exclusion is not set in the query result");
|
|
1144
|
+
isCorrect = false;
|
|
1145
|
+
queryResultErrors.issuing_country.out = {
|
|
1146
|
+
message: "Issuing country exclusion is not set in the query result",
|
|
1147
|
+
};
|
|
1148
|
+
}
|
|
1149
|
+
// Check the countryList is in ascending order
|
|
1150
|
+
// If the prover doesn't use a sorted list then the proof cannot be trusted
|
|
1151
|
+
// as it is requirement in the circuit for the exclusion check to work
|
|
1152
|
+
for (let i = 1; i < countryList.length; i++) {
|
|
1153
|
+
if (countryList[i] < countryList[i - 1]) {
|
|
1154
|
+
console.warn("The issuing country exclusion list has not been sorted, and thus the proof cannot be trusted");
|
|
1155
|
+
isCorrect = false;
|
|
1156
|
+
queryResultErrors.issuing_country.out = {
|
|
1157
|
+
message: "The issuing country exclusion list has not been sorted, and thus the proof cannot be trusted",
|
|
1158
|
+
};
|
|
1159
|
+
}
|
|
1160
|
+
}
|
|
1161
|
+
uniqueIdentifier = (0, utils_1.getNullifierFromDisclosureProof)(proofData).toString(10);
|
|
1162
|
+
}
|
|
1163
|
+
else if (proof.name === "inclusion_check_nationality") {
|
|
1108
1164
|
commitmentIn = (0, utils_1.getCommitmentInFromDisclosureProof)(proofData);
|
|
1109
1165
|
if (commitmentIn !== commitmentOut) {
|
|
1110
|
-
console.warn("Failed to check the link between the validity of the ID and the
|
|
1166
|
+
console.warn("Failed to check the link between the validity of the ID and the nationality inclusion check");
|
|
1111
1167
|
isCorrect = false;
|
|
1112
1168
|
queryResultErrors.nationality.commitment = {
|
|
1113
1169
|
expected: `Commitment: ${commitmentOut}`,
|
|
1114
1170
|
received: `Commitment: ${commitmentIn}`,
|
|
1115
|
-
message: "Failed to check the link between the validity of the ID and the
|
|
1171
|
+
message: "Failed to check the link between the validity of the ID and the nationality inclusion check",
|
|
1116
1172
|
};
|
|
1117
1173
|
}
|
|
1118
1174
|
const countryList = (0, utils_1.getCountryListFromInclusionProof)(proofData);
|
|
@@ -1120,12 +1176,12 @@ class ZKPassport {
|
|
|
1120
1176
|
queryResult.nationality.in &&
|
|
1121
1177
|
queryResult.nationality.in.result) {
|
|
1122
1178
|
if (!queryResult.nationality.in.expected?.every((country) => countryList.includes(country))) {
|
|
1123
|
-
console.warn("
|
|
1179
|
+
console.warn("Nationality inclusion list does not match the one from the query results");
|
|
1124
1180
|
isCorrect = false;
|
|
1125
1181
|
queryResultErrors.nationality.in = {
|
|
1126
1182
|
expected: queryResult.nationality.in.expected,
|
|
1127
1183
|
received: countryList,
|
|
1128
|
-
message: "
|
|
1184
|
+
message: "Nationality inclusion list does not match the one from the query results",
|
|
1129
1185
|
};
|
|
1130
1186
|
}
|
|
1131
1187
|
}
|
|
@@ -1138,40 +1194,64 @@ class ZKPassport {
|
|
|
1138
1194
|
}
|
|
1139
1195
|
uniqueIdentifier = (0, utils_1.getNullifierFromDisclosureProof)(proofData).toString(10);
|
|
1140
1196
|
}
|
|
1197
|
+
else if (proof.name === "inclusion_check_issuing_country") {
|
|
1198
|
+
commitmentIn = (0, utils_1.getCommitmentInFromDisclosureProof)(proofData);
|
|
1199
|
+
if (commitmentIn !== commitmentOut) {
|
|
1200
|
+
console.warn("Failed to check the link between the validity of the ID and the issuing country inclusion check");
|
|
1201
|
+
isCorrect = false;
|
|
1202
|
+
queryResultErrors.nationality.commitment = {
|
|
1203
|
+
expected: `Commitment: ${commitmentOut}`,
|
|
1204
|
+
received: `Commitment: ${commitmentIn}`,
|
|
1205
|
+
message: "Failed to check the link between the validity of the ID and the issuing country inclusion check",
|
|
1206
|
+
};
|
|
1207
|
+
}
|
|
1208
|
+
const countryList = (0, utils_1.getCountryListFromInclusionProof)(proofData);
|
|
1209
|
+
if (queryResult.issuing_country &&
|
|
1210
|
+
queryResult.issuing_country.in &&
|
|
1211
|
+
queryResult.issuing_country.in.result) {
|
|
1212
|
+
if (!queryResult.issuing_country.in.expected?.every((country) => countryList.includes(country))) {
|
|
1213
|
+
console.warn("Issuing country inclusion list does not match the one from the query results");
|
|
1214
|
+
isCorrect = false;
|
|
1215
|
+
queryResultErrors.issuing_country.in = {
|
|
1216
|
+
expected: queryResult.issuing_country.in.expected,
|
|
1217
|
+
received: countryList,
|
|
1218
|
+
message: "Issuing country inclusion list does not match the one from the query results",
|
|
1219
|
+
};
|
|
1220
|
+
}
|
|
1221
|
+
}
|
|
1222
|
+
else if (!queryResult.issuing_country || !queryResult.issuing_country.in) {
|
|
1223
|
+
console.warn("Issuing country inclusion is not set in the query result");
|
|
1224
|
+
isCorrect = false;
|
|
1225
|
+
queryResultErrors.issuing_country.in = {
|
|
1226
|
+
message: "Issuing country inclusion is not set in the query result",
|
|
1227
|
+
};
|
|
1228
|
+
}
|
|
1229
|
+
uniqueIdentifier = (0, utils_1.getNullifierFromDisclosureProof)(proofData).toString(10);
|
|
1230
|
+
}
|
|
1141
1231
|
}
|
|
1142
1232
|
return { isCorrect, uniqueIdentifier, queryResultErrors };
|
|
1143
1233
|
}
|
|
1144
1234
|
/**
|
|
1145
1235
|
* @notice Verify the proofs received from the mobile app.
|
|
1146
|
-
* @param requestId The request ID.
|
|
1147
1236
|
* @param proofs The proofs to verify.
|
|
1148
1237
|
* @param queryResult The query result to verify against
|
|
1238
|
+
* @param validity How many days ago should have the ID been last scanned by the user?
|
|
1149
1239
|
* @returns An object containing the unique identifier associated to the user
|
|
1150
1240
|
* and a boolean indicating whether the proofs were successfully verified.
|
|
1151
1241
|
*/
|
|
1152
|
-
async verify(
|
|
1153
|
-
let proofsToVerify = proofs;
|
|
1154
|
-
// There is a minimum of 4 subproofs to make a complete proof
|
|
1155
|
-
if (!proofs || proofs.length < 4) {
|
|
1156
|
-
proofsToVerify = this.topicToProofs[requestId];
|
|
1157
|
-
}
|
|
1242
|
+
async verify({ proofs, queryResult, validity, }) {
|
|
1158
1243
|
const { BarretenbergVerifier } = await Promise.resolve().then(() => tslib_1.__importStar(require("@aztec/bb.js")));
|
|
1159
1244
|
const verifier = new BarretenbergVerifier();
|
|
1160
|
-
/*if (!this.wasmVerifierInit) {
|
|
1161
|
-
await this.initWasmVerifier()
|
|
1162
|
-
}*/
|
|
1163
1245
|
let verified = true;
|
|
1164
1246
|
let uniqueIdentifier;
|
|
1165
1247
|
let queryResultErrors;
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
queryResultErrors = isCorrect ? undefined : queryResultErrorsFromPublicInputs;
|
|
1171
|
-
}
|
|
1248
|
+
const { isCorrect, uniqueIdentifier: uniqueIdentifierFromPublicInputs, queryResultErrors: queryResultErrorsFromPublicInputs, } = await this.checkPublicInputs(proofs, queryResult, validity);
|
|
1249
|
+
uniqueIdentifier = uniqueIdentifierFromPublicInputs;
|
|
1250
|
+
verified = isCorrect;
|
|
1251
|
+
queryResultErrors = isCorrect ? undefined : queryResultErrorsFromPublicInputs;
|
|
1172
1252
|
// Only proceed with the proof verification if the public inputs are correct
|
|
1173
|
-
if (verified
|
|
1174
|
-
for (const proof of
|
|
1253
|
+
if (verified) {
|
|
1254
|
+
for (const proof of proofs) {
|
|
1175
1255
|
const proofData = (0, utils_1.getProofData)(proof.proof, true);
|
|
1176
1256
|
const hostedPackagedCircuit = await (0, utils_1.getHostedPackagedCircuitByName)(proof.version, proof.name);
|
|
1177
1257
|
const vkeyBytes = buffer_1.Buffer.from(hostedPackagedCircuit.vkey, "base64");
|
|
@@ -1189,7 +1269,8 @@ class ZKPassport {
|
|
|
1189
1269
|
}
|
|
1190
1270
|
}
|
|
1191
1271
|
}
|
|
1192
|
-
|
|
1272
|
+
// If the proofs are not verified, we don't return the unique identifier
|
|
1273
|
+
uniqueIdentifier = verified ? uniqueIdentifier : undefined;
|
|
1193
1274
|
return { uniqueIdentifier, verified, queryResultErrors };
|
|
1194
1275
|
}
|
|
1195
1276
|
/**
|
package/dist/esm/index.d.ts
CHANGED
|
@@ -125,13 +125,13 @@ export type QueryBuilder = {
|
|
|
125
125
|
* @param key The attribute to compare.
|
|
126
126
|
* @param value The list of values to check inclusion against.
|
|
127
127
|
*/
|
|
128
|
-
in: <T extends "nationality">(key: T, value: IDCredentialValue<T>[]) => QueryBuilder;
|
|
128
|
+
in: <T extends "nationality" | "issuing_country">(key: T, value: IDCredentialValue<T>[]) => QueryBuilder;
|
|
129
129
|
/**
|
|
130
130
|
* Requires this attribute to be excluded from the provided list.
|
|
131
131
|
* @param key The attribute to compare.
|
|
132
132
|
* @param value The list of values to check exclusion against.
|
|
133
133
|
*/
|
|
134
|
-
out: <T extends "nationality">(key: T, value: IDCredentialValue<T>[]) => QueryBuilder;
|
|
134
|
+
out: <T extends "nationality" | "issuing_country">(key: T, value: IDCredentialValue<T>[]) => QueryBuilder;
|
|
135
135
|
/**
|
|
136
136
|
* Requires this attribute to be disclosed.
|
|
137
137
|
* @param key The attribute to disclose.
|
|
@@ -200,13 +200,17 @@ export declare class ZKPassport {
|
|
|
200
200
|
private checkPublicInputs;
|
|
201
201
|
/**
|
|
202
202
|
* @notice Verify the proofs received from the mobile app.
|
|
203
|
-
* @param requestId The request ID.
|
|
204
203
|
* @param proofs The proofs to verify.
|
|
205
204
|
* @param queryResult The query result to verify against
|
|
205
|
+
* @param validity How many days ago should have the ID been last scanned by the user?
|
|
206
206
|
* @returns An object containing the unique identifier associated to the user
|
|
207
207
|
* and a boolean indicating whether the proofs were successfully verified.
|
|
208
208
|
*/
|
|
209
|
-
verify(
|
|
209
|
+
verify({ proofs, queryResult, validity, }: {
|
|
210
|
+
proofs: Array<ProofResult>;
|
|
211
|
+
queryResult: QueryResult;
|
|
212
|
+
validity?: number;
|
|
213
|
+
}): Promise<{
|
|
210
214
|
uniqueIdentifier: string | undefined;
|
|
211
215
|
verified: boolean;
|
|
212
216
|
queryResultErrors?: QueryResultErrors;
|