@zkpassport/sdk 0.2.9 → 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.
@@ -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.
package/dist/cjs/index.js CHANGED
@@ -151,13 +151,23 @@ class ZKPassport {
151
151
  }
152
152
  break;
153
153
  case "in":
154
- if (field === "nationality" && !neededCircuits.includes("inclusion_check_country")) {
155
- neededCircuits.push("inclusion_check_country");
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");
156
161
  }
157
162
  break;
158
163
  case "out":
159
- if (field === "nationality" && !neededCircuits.includes("exclusion_check_country")) {
160
- neededCircuits.push("exclusion_check_country");
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");
161
171
  }
162
172
  break;
163
173
  }
@@ -428,8 +438,10 @@ class ZKPassport {
428
438
  "compare_age",
429
439
  "compare_birthdate",
430
440
  "compare_expiry",
431
- "exclusion_check_country",
432
- "inclusion_check_country",
441
+ "exclusion_check_nationality",
442
+ "inclusion_check_nationality",
443
+ "exclusion_check_issuing_country",
444
+ "inclusion_check_issuing_country",
433
445
  ];
434
446
  const getIndex = (proof) => {
435
447
  const name = proof.name || "";
@@ -516,7 +528,7 @@ class ZKPassport {
516
528
  isCorrect = false;
517
529
  queryResultErrors.document_type.eq = {
518
530
  expected: `${queryResult.document_type.eq.expected}`,
519
- received: `${disclosedDataPassport.documentType}`,
531
+ received: `${disclosedDataPassport.documentType ?? disclosedDataIDCard.documentType}`,
520
532
  message: "Document type does not match the expected document type",
521
533
  };
522
534
  }
@@ -525,7 +537,7 @@ class ZKPassport {
525
537
  isCorrect = false;
526
538
  queryResultErrors.document_type.disclose = {
527
539
  expected: `${queryResult.document_type.disclose?.result}`,
528
- received: `${disclosedDataIDCard.documentType}`,
540
+ received: `${disclosedDataIDCard.documentType ?? disclosedDataPassport.documentType}`,
529
541
  message: "Document type does not match the disclosed document type in query result",
530
542
  };
531
543
  }
@@ -541,7 +553,7 @@ class ZKPassport {
541
553
  isCorrect = false;
542
554
  queryResultErrors.birthdate.eq = {
543
555
  expected: `${queryResult.birthdate.eq.expected.toISOString()}`,
544
- received: `${birthdatePassport.toISOString()}`,
556
+ received: `${birthdatePassport?.toISOString() ?? birthdateIDCard?.toISOString()}`,
545
557
  message: "Birthdate does not match the expected birthdate",
546
558
  };
547
559
  }
@@ -552,7 +564,7 @@ class ZKPassport {
552
564
  isCorrect = false;
553
565
  queryResultErrors.birthdate.disclose = {
554
566
  expected: `${queryResult.birthdate.disclose.result.toISOString()}`,
555
- received: `${birthdatePassport.toISOString()}`,
567
+ received: `${birthdatePassport?.toISOString() ?? birthdateIDCard?.toISOString()}`,
556
568
  message: "Birthdate does not match the disclosed birthdate in query result",
557
569
  };
558
570
  }
@@ -568,7 +580,7 @@ class ZKPassport {
568
580
  isCorrect = false;
569
581
  queryResultErrors.expiry_date.eq = {
570
582
  expected: `${queryResult.expiry_date.eq.expected.toISOString()}`,
571
- received: `${expiryDatePassport.toISOString()}`,
583
+ received: `${expiryDatePassport?.toISOString() ?? expiryDateIDCard?.toISOString()}`,
572
584
  message: "Expiry date does not match the expected expiry date",
573
585
  };
574
586
  }
@@ -579,7 +591,7 @@ class ZKPassport {
579
591
  isCorrect = false;
580
592
  queryResultErrors.expiry_date.disclose = {
581
593
  expected: `${queryResult.expiry_date.disclose.result.toISOString()}`,
582
- received: `${expiryDatePassport.toISOString()}`,
594
+ received: `${expiryDatePassport?.toISOString() ?? expiryDateIDCard?.toISOString()}`,
583
595
  message: "Expiry date does not match the disclosed expiry date in query result",
584
596
  };
585
597
  }
@@ -595,7 +607,7 @@ class ZKPassport {
595
607
  isCorrect = false;
596
608
  queryResultErrors.nationality.eq = {
597
609
  expected: `${queryResult.nationality.eq.expected}`,
598
- received: `${nationalityPassport}`,
610
+ received: `${nationalityPassport ?? nationalityIDCard}`,
599
611
  message: "Nationality does not match the expected nationality",
600
612
  };
601
613
  }
@@ -606,7 +618,7 @@ class ZKPassport {
606
618
  isCorrect = false;
607
619
  queryResultErrors.nationality.disclose = {
608
620
  expected: `${queryResult.nationality.disclose.result}`,
609
- received: `${nationalityPassport}`,
621
+ received: `${nationalityPassport ?? nationalityIDCard}`,
610
622
  message: "Nationality does not match the disclosed nationality in query result",
611
623
  };
612
624
  }
@@ -622,7 +634,7 @@ class ZKPassport {
622
634
  isCorrect = false;
623
635
  queryResultErrors.document_number.eq = {
624
636
  expected: `${queryResult.document_number.eq.expected}`,
625
- received: `${documentNumberPassport}`,
637
+ received: `${documentNumberPassport ?? documentNumberIDCard}`,
626
638
  message: "Document number does not match the expected document number",
627
639
  };
628
640
  }
@@ -633,7 +645,7 @@ class ZKPassport {
633
645
  isCorrect = false;
634
646
  queryResultErrors.document_number.disclose = {
635
647
  expected: `${queryResult.document_number.disclose.result}`,
636
- received: `${documentNumberPassport}`,
648
+ received: `${documentNumberPassport ?? documentNumberIDCard}`,
637
649
  message: "Document number does not match the disclosed document number in query result",
638
650
  };
639
651
  }
@@ -649,7 +661,7 @@ class ZKPassport {
649
661
  isCorrect = false;
650
662
  queryResultErrors.gender.eq = {
651
663
  expected: `${queryResult.gender.eq.expected}`,
652
- received: `${genderPassport}`,
664
+ received: `${genderPassport ?? genderIDCard}`,
653
665
  message: "Gender does not match the expected gender",
654
666
  };
655
667
  }
@@ -660,7 +672,7 @@ class ZKPassport {
660
672
  isCorrect = false;
661
673
  queryResultErrors.gender.disclose = {
662
674
  expected: `${queryResult.gender.disclose.result}`,
663
- received: `${genderPassport}`,
675
+ received: `${genderPassport ?? genderIDCard}`,
664
676
  message: "Gender does not match the disclosed gender in query result",
665
677
  };
666
678
  }
@@ -676,7 +688,7 @@ class ZKPassport {
676
688
  isCorrect = false;
677
689
  queryResultErrors.issuing_country.eq = {
678
690
  expected: `${queryResult.issuing_country.eq.expected}`,
679
- received: `${issuingCountryPassport}`,
691
+ received: `${issuingCountryPassport ?? issuingCountryIDCard}`,
680
692
  message: "Issuing country does not match the expected issuing country",
681
693
  };
682
694
  }
@@ -687,7 +699,7 @@ class ZKPassport {
687
699
  isCorrect = false;
688
700
  queryResultErrors.issuing_country.disclose = {
689
701
  expected: `${queryResult.issuing_country.disclose.result}`,
690
- received: `${issuingCountryPassport}`,
702
+ received: `${issuingCountryPassport ?? issuingCountryIDCard}`,
691
703
  message: "Issuing country does not match the disclosed issuing country in query result",
692
704
  };
693
705
  }
@@ -705,7 +717,7 @@ class ZKPassport {
705
717
  isCorrect = false;
706
718
  queryResultErrors.fullname.eq = {
707
719
  expected: `${queryResult.fullname.eq.expected}`,
708
- received: `${fullnamePassport}`,
720
+ received: `${fullnamePassport ?? fullnameIDCard}`,
709
721
  message: "Fullname does not match the expected fullname",
710
722
  };
711
723
  }
@@ -718,7 +730,7 @@ class ZKPassport {
718
730
  isCorrect = false;
719
731
  queryResultErrors.fullname.disclose = {
720
732
  expected: `${queryResult.fullname.disclose.result}`,
721
- received: `${fullnamePassport}`,
733
+ received: `${fullnamePassport ?? fullnameIDCard}`,
722
734
  message: "Fullname does not match the disclosed fullname in query result",
723
735
  };
724
736
  }
@@ -741,7 +753,7 @@ class ZKPassport {
741
753
  isCorrect = false;
742
754
  queryResultErrors.firstname.eq = {
743
755
  expected: `${queryResult.firstname.eq.expected}`,
744
- received: `${firstnamePassport}`,
756
+ received: `${firstnamePassport ?? firstnameIDCard}`,
745
757
  message: "Firstname does not match the expected firstname",
746
758
  };
747
759
  }
@@ -754,7 +766,7 @@ class ZKPassport {
754
766
  isCorrect = false;
755
767
  queryResultErrors.firstname.disclose = {
756
768
  expected: `${queryResult.firstname.disclose.result}`,
757
- received: `${firstnamePassport}`,
769
+ received: `${firstnamePassport ?? firstnameIDCard}`,
758
770
  message: "Firstname does not match the disclosed firstname in query result",
759
771
  };
760
772
  }
@@ -777,7 +789,7 @@ class ZKPassport {
777
789
  isCorrect = false;
778
790
  queryResultErrors.lastname.eq = {
779
791
  expected: `${queryResult.lastname.eq.expected}`,
780
- received: `${lastnamePassport}`,
792
+ received: `${lastnamePassport ?? lastnameIDCard}`,
781
793
  message: "Lastname does not match the expected lastname",
782
794
  };
783
795
  }
@@ -790,7 +802,7 @@ class ZKPassport {
790
802
  isCorrect = false;
791
803
  queryResultErrors.lastname.disclose = {
792
804
  expected: `${queryResult.lastname.disclose.result}`,
793
- received: `${lastnamePassport}`,
805
+ received: `${lastnamePassport ?? lastnameIDCard}`,
794
806
  message: "Lastname does not match the disclosed lastname in query result",
795
807
  };
796
808
  }
@@ -1058,15 +1070,15 @@ class ZKPassport {
1058
1070
  }
1059
1071
  uniqueIdentifier = (0, utils_1.getNullifierFromDisclosureProof)(proofData).toString(10);
1060
1072
  }
1061
- else if (proof.name === "exclusion_check_country") {
1073
+ else if (proof.name === "exclusion_check_nationality") {
1062
1074
  commitmentIn = (0, utils_1.getCommitmentInFromDisclosureProof)(proofData);
1063
1075
  if (commitmentIn !== commitmentOut) {
1064
- console.warn("Failed to check the link between the validity of the ID and the country exclusion check");
1076
+ console.warn("Failed to check the link between the validity of the ID and the nationality exclusion check");
1065
1077
  isCorrect = false;
1066
1078
  queryResultErrors.nationality.commitment = {
1067
1079
  expected: `Commitment: ${commitmentOut}`,
1068
1080
  received: `Commitment: ${commitmentIn}`,
1069
- message: "Failed to check the link between the validity of the ID and the country exclusion check",
1081
+ message: "Failed to check the link between the validity of the ID and the nationality exclusion check",
1070
1082
  };
1071
1083
  }
1072
1084
  const countryList = (0, utils_1.getCountryListFromExclusionProof)(proofData);
@@ -1074,12 +1086,12 @@ class ZKPassport {
1074
1086
  queryResult.nationality.out &&
1075
1087
  queryResult.nationality.out.result) {
1076
1088
  if (!queryResult.nationality.out.expected?.every((country) => countryList.includes(country))) {
1077
- console.warn("Country exclusion list does not match the one from the query results");
1089
+ console.warn("Nationality exclusion list does not match the one from the query results");
1078
1090
  isCorrect = false;
1079
1091
  queryResultErrors.nationality.out = {
1080
1092
  expected: queryResult.nationality.out.expected,
1081
1093
  received: countryList,
1082
- message: "Country exclusion list does not match the one from the query results",
1094
+ message: "Nationality exclusion list does not match the one from the query results",
1083
1095
  };
1084
1096
  }
1085
1097
  }
@@ -1104,15 +1116,61 @@ class ZKPassport {
1104
1116
  }
1105
1117
  uniqueIdentifier = (0, utils_1.getNullifierFromDisclosureProof)(proofData).toString(10);
1106
1118
  }
1107
- else if (proof.name === "inclusion_check_country") {
1119
+ else if (proof.name === "exclusion_check_issuing_country") {
1108
1120
  commitmentIn = (0, utils_1.getCommitmentInFromDisclosureProof)(proofData);
1109
1121
  if (commitmentIn !== commitmentOut) {
1110
- console.warn("Failed to check the link between the validity of the ID and the country inclusion check");
1122
+ console.warn("Failed to check the link between the validity of the ID and the issuing country exclusion check");
1111
1123
  isCorrect = false;
1112
1124
  queryResultErrors.nationality.commitment = {
1113
1125
  expected: `Commitment: ${commitmentOut}`,
1114
1126
  received: `Commitment: ${commitmentIn}`,
1115
- message: "Failed to check the link between the validity of the ID and the country inclusion check",
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",
1116
1174
  };
1117
1175
  }
1118
1176
  const countryList = (0, utils_1.getCountryListFromInclusionProof)(proofData);
@@ -1120,12 +1178,12 @@ class ZKPassport {
1120
1178
  queryResult.nationality.in &&
1121
1179
  queryResult.nationality.in.result) {
1122
1180
  if (!queryResult.nationality.in.expected?.every((country) => countryList.includes(country))) {
1123
- console.warn("Country inclusion list does not match the one from the query results");
1181
+ console.warn("Nationality inclusion list does not match the one from the query results");
1124
1182
  isCorrect = false;
1125
1183
  queryResultErrors.nationality.in = {
1126
1184
  expected: queryResult.nationality.in.expected,
1127
1185
  received: countryList,
1128
- message: "Country inclusion list does not match the one from the query results",
1186
+ message: "Nationality inclusion list does not match the one from the query results",
1129
1187
  };
1130
1188
  }
1131
1189
  }
@@ -1138,6 +1196,40 @@ class ZKPassport {
1138
1196
  }
1139
1197
  uniqueIdentifier = (0, utils_1.getNullifierFromDisclosureProof)(proofData).toString(10);
1140
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
+ };
1230
+ }
1231
+ uniqueIdentifier = (0, utils_1.getNullifierFromDisclosureProof)(proofData).toString(10);
1232
+ }
1141
1233
  }
1142
1234
  return { isCorrect, uniqueIdentifier, queryResultErrors };
1143
1235
  }
@@ -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.
package/dist/esm/index.js CHANGED
@@ -141,13 +141,23 @@ export class ZKPassport {
141
141
  }
142
142
  break;
143
143
  case "in":
144
- if (field === "nationality" && !neededCircuits.includes("inclusion_check_country")) {
145
- neededCircuits.push("inclusion_check_country");
144
+ if (field === "nationality" &&
145
+ !neededCircuits.includes("inclusion_check_nationality")) {
146
+ neededCircuits.push("inclusion_check_nationality");
147
+ }
148
+ else if (field === "issuing_country" &&
149
+ !neededCircuits.includes("inclusion_check_issuing_country")) {
150
+ neededCircuits.push("inclusion_check_issuing_country");
146
151
  }
147
152
  break;
148
153
  case "out":
149
- if (field === "nationality" && !neededCircuits.includes("exclusion_check_country")) {
150
- neededCircuits.push("exclusion_check_country");
154
+ if (field === "nationality" &&
155
+ !neededCircuits.includes("exclusion_check_nationality")) {
156
+ neededCircuits.push("exclusion_check_nationality");
157
+ }
158
+ else if (field === "issuing_country" &&
159
+ !neededCircuits.includes("exclusion_check_issuing_country")) {
160
+ neededCircuits.push("exclusion_check_issuing_country");
151
161
  }
152
162
  break;
153
163
  }
@@ -418,8 +428,10 @@ export class ZKPassport {
418
428
  "compare_age",
419
429
  "compare_birthdate",
420
430
  "compare_expiry",
421
- "exclusion_check_country",
422
- "inclusion_check_country",
431
+ "exclusion_check_nationality",
432
+ "inclusion_check_nationality",
433
+ "exclusion_check_issuing_country",
434
+ "inclusion_check_issuing_country",
423
435
  ];
424
436
  const getIndex = (proof) => {
425
437
  const name = proof.name || "";
@@ -506,7 +518,7 @@ export class ZKPassport {
506
518
  isCorrect = false;
507
519
  queryResultErrors.document_type.eq = {
508
520
  expected: `${queryResult.document_type.eq.expected}`,
509
- received: `${disclosedDataPassport.documentType}`,
521
+ received: `${disclosedDataPassport.documentType ?? disclosedDataIDCard.documentType}`,
510
522
  message: "Document type does not match the expected document type",
511
523
  };
512
524
  }
@@ -515,7 +527,7 @@ export class ZKPassport {
515
527
  isCorrect = false;
516
528
  queryResultErrors.document_type.disclose = {
517
529
  expected: `${queryResult.document_type.disclose?.result}`,
518
- received: `${disclosedDataIDCard.documentType}`,
530
+ received: `${disclosedDataIDCard.documentType ?? disclosedDataPassport.documentType}`,
519
531
  message: "Document type does not match the disclosed document type in query result",
520
532
  };
521
533
  }
@@ -531,7 +543,7 @@ export class ZKPassport {
531
543
  isCorrect = false;
532
544
  queryResultErrors.birthdate.eq = {
533
545
  expected: `${queryResult.birthdate.eq.expected.toISOString()}`,
534
- received: `${birthdatePassport.toISOString()}`,
546
+ received: `${birthdatePassport?.toISOString() ?? birthdateIDCard?.toISOString()}`,
535
547
  message: "Birthdate does not match the expected birthdate",
536
548
  };
537
549
  }
@@ -542,7 +554,7 @@ export class ZKPassport {
542
554
  isCorrect = false;
543
555
  queryResultErrors.birthdate.disclose = {
544
556
  expected: `${queryResult.birthdate.disclose.result.toISOString()}`,
545
- received: `${birthdatePassport.toISOString()}`,
557
+ received: `${birthdatePassport?.toISOString() ?? birthdateIDCard?.toISOString()}`,
546
558
  message: "Birthdate does not match the disclosed birthdate in query result",
547
559
  };
548
560
  }
@@ -558,7 +570,7 @@ export class ZKPassport {
558
570
  isCorrect = false;
559
571
  queryResultErrors.expiry_date.eq = {
560
572
  expected: `${queryResult.expiry_date.eq.expected.toISOString()}`,
561
- received: `${expiryDatePassport.toISOString()}`,
573
+ received: `${expiryDatePassport?.toISOString() ?? expiryDateIDCard?.toISOString()}`,
562
574
  message: "Expiry date does not match the expected expiry date",
563
575
  };
564
576
  }
@@ -569,7 +581,7 @@ export class ZKPassport {
569
581
  isCorrect = false;
570
582
  queryResultErrors.expiry_date.disclose = {
571
583
  expected: `${queryResult.expiry_date.disclose.result.toISOString()}`,
572
- received: `${expiryDatePassport.toISOString()}`,
584
+ received: `${expiryDatePassport?.toISOString() ?? expiryDateIDCard?.toISOString()}`,
573
585
  message: "Expiry date does not match the disclosed expiry date in query result",
574
586
  };
575
587
  }
@@ -585,7 +597,7 @@ export class ZKPassport {
585
597
  isCorrect = false;
586
598
  queryResultErrors.nationality.eq = {
587
599
  expected: `${queryResult.nationality.eq.expected}`,
588
- received: `${nationalityPassport}`,
600
+ received: `${nationalityPassport ?? nationalityIDCard}`,
589
601
  message: "Nationality does not match the expected nationality",
590
602
  };
591
603
  }
@@ -596,7 +608,7 @@ export class ZKPassport {
596
608
  isCorrect = false;
597
609
  queryResultErrors.nationality.disclose = {
598
610
  expected: `${queryResult.nationality.disclose.result}`,
599
- received: `${nationalityPassport}`,
611
+ received: `${nationalityPassport ?? nationalityIDCard}`,
600
612
  message: "Nationality does not match the disclosed nationality in query result",
601
613
  };
602
614
  }
@@ -612,7 +624,7 @@ export class ZKPassport {
612
624
  isCorrect = false;
613
625
  queryResultErrors.document_number.eq = {
614
626
  expected: `${queryResult.document_number.eq.expected}`,
615
- received: `${documentNumberPassport}`,
627
+ received: `${documentNumberPassport ?? documentNumberIDCard}`,
616
628
  message: "Document number does not match the expected document number",
617
629
  };
618
630
  }
@@ -623,7 +635,7 @@ export class ZKPassport {
623
635
  isCorrect = false;
624
636
  queryResultErrors.document_number.disclose = {
625
637
  expected: `${queryResult.document_number.disclose.result}`,
626
- received: `${documentNumberPassport}`,
638
+ received: `${documentNumberPassport ?? documentNumberIDCard}`,
627
639
  message: "Document number does not match the disclosed document number in query result",
628
640
  };
629
641
  }
@@ -639,7 +651,7 @@ export class ZKPassport {
639
651
  isCorrect = false;
640
652
  queryResultErrors.gender.eq = {
641
653
  expected: `${queryResult.gender.eq.expected}`,
642
- received: `${genderPassport}`,
654
+ received: `${genderPassport ?? genderIDCard}`,
643
655
  message: "Gender does not match the expected gender",
644
656
  };
645
657
  }
@@ -650,7 +662,7 @@ export class ZKPassport {
650
662
  isCorrect = false;
651
663
  queryResultErrors.gender.disclose = {
652
664
  expected: `${queryResult.gender.disclose.result}`,
653
- received: `${genderPassport}`,
665
+ received: `${genderPassport ?? genderIDCard}`,
654
666
  message: "Gender does not match the disclosed gender in query result",
655
667
  };
656
668
  }
@@ -666,7 +678,7 @@ export class ZKPassport {
666
678
  isCorrect = false;
667
679
  queryResultErrors.issuing_country.eq = {
668
680
  expected: `${queryResult.issuing_country.eq.expected}`,
669
- received: `${issuingCountryPassport}`,
681
+ received: `${issuingCountryPassport ?? issuingCountryIDCard}`,
670
682
  message: "Issuing country does not match the expected issuing country",
671
683
  };
672
684
  }
@@ -677,7 +689,7 @@ export class ZKPassport {
677
689
  isCorrect = false;
678
690
  queryResultErrors.issuing_country.disclose = {
679
691
  expected: `${queryResult.issuing_country.disclose.result}`,
680
- received: `${issuingCountryPassport}`,
692
+ received: `${issuingCountryPassport ?? issuingCountryIDCard}`,
681
693
  message: "Issuing country does not match the disclosed issuing country in query result",
682
694
  };
683
695
  }
@@ -695,7 +707,7 @@ export class ZKPassport {
695
707
  isCorrect = false;
696
708
  queryResultErrors.fullname.eq = {
697
709
  expected: `${queryResult.fullname.eq.expected}`,
698
- received: `${fullnamePassport}`,
710
+ received: `${fullnamePassport ?? fullnameIDCard}`,
699
711
  message: "Fullname does not match the expected fullname",
700
712
  };
701
713
  }
@@ -708,7 +720,7 @@ export class ZKPassport {
708
720
  isCorrect = false;
709
721
  queryResultErrors.fullname.disclose = {
710
722
  expected: `${queryResult.fullname.disclose.result}`,
711
- received: `${fullnamePassport}`,
723
+ received: `${fullnamePassport ?? fullnameIDCard}`,
712
724
  message: "Fullname does not match the disclosed fullname in query result",
713
725
  };
714
726
  }
@@ -731,7 +743,7 @@ export class ZKPassport {
731
743
  isCorrect = false;
732
744
  queryResultErrors.firstname.eq = {
733
745
  expected: `${queryResult.firstname.eq.expected}`,
734
- received: `${firstnamePassport}`,
746
+ received: `${firstnamePassport ?? firstnameIDCard}`,
735
747
  message: "Firstname does not match the expected firstname",
736
748
  };
737
749
  }
@@ -744,7 +756,7 @@ export class ZKPassport {
744
756
  isCorrect = false;
745
757
  queryResultErrors.firstname.disclose = {
746
758
  expected: `${queryResult.firstname.disclose.result}`,
747
- received: `${firstnamePassport}`,
759
+ received: `${firstnamePassport ?? firstnameIDCard}`,
748
760
  message: "Firstname does not match the disclosed firstname in query result",
749
761
  };
750
762
  }
@@ -767,7 +779,7 @@ export class ZKPassport {
767
779
  isCorrect = false;
768
780
  queryResultErrors.lastname.eq = {
769
781
  expected: `${queryResult.lastname.eq.expected}`,
770
- received: `${lastnamePassport}`,
782
+ received: `${lastnamePassport ?? lastnameIDCard}`,
771
783
  message: "Lastname does not match the expected lastname",
772
784
  };
773
785
  }
@@ -780,7 +792,7 @@ export class ZKPassport {
780
792
  isCorrect = false;
781
793
  queryResultErrors.lastname.disclose = {
782
794
  expected: `${queryResult.lastname.disclose.result}`,
783
- received: `${lastnamePassport}`,
795
+ received: `${lastnamePassport ?? lastnameIDCard}`,
784
796
  message: "Lastname does not match the disclosed lastname in query result",
785
797
  };
786
798
  }
@@ -1048,15 +1060,15 @@ export class ZKPassport {
1048
1060
  }
1049
1061
  uniqueIdentifier = getNullifierFromDisclosureProof(proofData).toString(10);
1050
1062
  }
1051
- else if (proof.name === "exclusion_check_country") {
1063
+ else if (proof.name === "exclusion_check_nationality") {
1052
1064
  commitmentIn = getCommitmentInFromDisclosureProof(proofData);
1053
1065
  if (commitmentIn !== commitmentOut) {
1054
- console.warn("Failed to check the link between the validity of the ID and the country exclusion check");
1066
+ console.warn("Failed to check the link between the validity of the ID and the nationality exclusion check");
1055
1067
  isCorrect = false;
1056
1068
  queryResultErrors.nationality.commitment = {
1057
1069
  expected: `Commitment: ${commitmentOut}`,
1058
1070
  received: `Commitment: ${commitmentIn}`,
1059
- message: "Failed to check the link between the validity of the ID and the country exclusion check",
1071
+ message: "Failed to check the link between the validity of the ID and the nationality exclusion check",
1060
1072
  };
1061
1073
  }
1062
1074
  const countryList = getCountryListFromExclusionProof(proofData);
@@ -1064,12 +1076,12 @@ export class ZKPassport {
1064
1076
  queryResult.nationality.out &&
1065
1077
  queryResult.nationality.out.result) {
1066
1078
  if (!queryResult.nationality.out.expected?.every((country) => countryList.includes(country))) {
1067
- console.warn("Country exclusion list does not match the one from the query results");
1079
+ console.warn("Nationality exclusion list does not match the one from the query results");
1068
1080
  isCorrect = false;
1069
1081
  queryResultErrors.nationality.out = {
1070
1082
  expected: queryResult.nationality.out.expected,
1071
1083
  received: countryList,
1072
- message: "Country exclusion list does not match the one from the query results",
1084
+ message: "Nationality exclusion list does not match the one from the query results",
1073
1085
  };
1074
1086
  }
1075
1087
  }
@@ -1094,15 +1106,61 @@ export class ZKPassport {
1094
1106
  }
1095
1107
  uniqueIdentifier = getNullifierFromDisclosureProof(proofData).toString(10);
1096
1108
  }
1097
- else if (proof.name === "inclusion_check_country") {
1109
+ else if (proof.name === "exclusion_check_issuing_country") {
1098
1110
  commitmentIn = getCommitmentInFromDisclosureProof(proofData);
1099
1111
  if (commitmentIn !== commitmentOut) {
1100
- console.warn("Failed to check the link between the validity of the ID and the country inclusion check");
1112
+ console.warn("Failed to check the link between the validity of the ID and the issuing country exclusion check");
1101
1113
  isCorrect = false;
1102
1114
  queryResultErrors.nationality.commitment = {
1103
1115
  expected: `Commitment: ${commitmentOut}`,
1104
1116
  received: `Commitment: ${commitmentIn}`,
1105
- message: "Failed to check the link between the validity of the ID and the country inclusion check",
1117
+ message: "Failed to check the link between the validity of the ID and the issuing country exclusion check",
1118
+ };
1119
+ }
1120
+ const countryList = getCountryListFromExclusionProof(proofData);
1121
+ if (queryResult.issuing_country &&
1122
+ queryResult.issuing_country.out &&
1123
+ queryResult.issuing_country.out.result) {
1124
+ if (!queryResult.issuing_country.out.expected?.every((country) => countryList.includes(country))) {
1125
+ console.warn("Issuing country exclusion list does not match the one from the query results");
1126
+ isCorrect = false;
1127
+ queryResultErrors.issuing_country.out = {
1128
+ expected: queryResult.issuing_country.out.expected,
1129
+ received: countryList,
1130
+ message: "Issuing country exclusion list does not match the one from the query results",
1131
+ };
1132
+ }
1133
+ }
1134
+ else if (!queryResult.issuing_country || !queryResult.issuing_country.out) {
1135
+ console.warn("Issuing country exclusion is not set in the query result");
1136
+ isCorrect = false;
1137
+ queryResultErrors.issuing_country.out = {
1138
+ message: "Issuing country exclusion is not set in the query result",
1139
+ };
1140
+ }
1141
+ // Check the countryList is in ascending order
1142
+ // If the prover doesn't use a sorted list then the proof cannot be trusted
1143
+ // as it is requirement in the circuit for the exclusion check to work
1144
+ for (let i = 1; i < countryList.length; i++) {
1145
+ if (countryList[i] < countryList[i - 1]) {
1146
+ console.warn("The issuing country exclusion list has not been sorted, and thus the proof cannot be trusted");
1147
+ isCorrect = false;
1148
+ queryResultErrors.issuing_country.out = {
1149
+ message: "The issuing country exclusion list has not been sorted, and thus the proof cannot be trusted",
1150
+ };
1151
+ }
1152
+ }
1153
+ uniqueIdentifier = getNullifierFromDisclosureProof(proofData).toString(10);
1154
+ }
1155
+ else if (proof.name === "inclusion_check_nationality") {
1156
+ commitmentIn = getCommitmentInFromDisclosureProof(proofData);
1157
+ if (commitmentIn !== commitmentOut) {
1158
+ console.warn("Failed to check the link between the validity of the ID and the nationality inclusion check");
1159
+ isCorrect = false;
1160
+ queryResultErrors.nationality.commitment = {
1161
+ expected: `Commitment: ${commitmentOut}`,
1162
+ received: `Commitment: ${commitmentIn}`,
1163
+ message: "Failed to check the link between the validity of the ID and the nationality inclusion check",
1106
1164
  };
1107
1165
  }
1108
1166
  const countryList = getCountryListFromInclusionProof(proofData);
@@ -1110,12 +1168,12 @@ export class ZKPassport {
1110
1168
  queryResult.nationality.in &&
1111
1169
  queryResult.nationality.in.result) {
1112
1170
  if (!queryResult.nationality.in.expected?.every((country) => countryList.includes(country))) {
1113
- console.warn("Country inclusion list does not match the one from the query results");
1171
+ console.warn("Nationality inclusion list does not match the one from the query results");
1114
1172
  isCorrect = false;
1115
1173
  queryResultErrors.nationality.in = {
1116
1174
  expected: queryResult.nationality.in.expected,
1117
1175
  received: countryList,
1118
- message: "Country inclusion list does not match the one from the query results",
1176
+ message: "Nationality inclusion list does not match the one from the query results",
1119
1177
  };
1120
1178
  }
1121
1179
  }
@@ -1128,6 +1186,40 @@ export class ZKPassport {
1128
1186
  }
1129
1187
  uniqueIdentifier = getNullifierFromDisclosureProof(proofData).toString(10);
1130
1188
  }
1189
+ else if (proof.name === "inclusion_check_issuing_country") {
1190
+ commitmentIn = getCommitmentInFromDisclosureProof(proofData);
1191
+ if (commitmentIn !== commitmentOut) {
1192
+ console.warn("Failed to check the link between the validity of the ID and the issuing country inclusion check");
1193
+ isCorrect = false;
1194
+ queryResultErrors.nationality.commitment = {
1195
+ expected: `Commitment: ${commitmentOut}`,
1196
+ received: `Commitment: ${commitmentIn}`,
1197
+ message: "Failed to check the link between the validity of the ID and the issuing country inclusion check",
1198
+ };
1199
+ }
1200
+ const countryList = getCountryListFromInclusionProof(proofData);
1201
+ if (queryResult.issuing_country &&
1202
+ queryResult.issuing_country.in &&
1203
+ queryResult.issuing_country.in.result) {
1204
+ if (!queryResult.issuing_country.in.expected?.every((country) => countryList.includes(country))) {
1205
+ console.warn("Issuing country inclusion list does not match the one from the query results");
1206
+ isCorrect = false;
1207
+ queryResultErrors.issuing_country.in = {
1208
+ expected: queryResult.issuing_country.in.expected,
1209
+ received: countryList,
1210
+ message: "Issuing country inclusion list does not match the one from the query results",
1211
+ };
1212
+ }
1213
+ }
1214
+ else if (!queryResult.issuing_country || !queryResult.issuing_country.in) {
1215
+ console.warn("Issuing country inclusion is not set in the query result");
1216
+ isCorrect = false;
1217
+ queryResultErrors.issuing_country.in = {
1218
+ message: "Issuing country inclusion is not set in the query result",
1219
+ };
1220
+ }
1221
+ uniqueIdentifier = getNullifierFromDisclosureProof(proofData).toString(10);
1222
+ }
1131
1223
  }
1132
1224
  return { isCorrect, uniqueIdentifier, queryResultErrors };
1133
1225
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zkpassport/sdk",
3
- "version": "0.2.9",
3
+ "version": "0.2.10",
4
4
  "description": "Privacy-preserving identity verification using passports and ID cards",
5
5
  "main": "./dist/cjs/index.js",
6
6
  "module": "./dist/esm/index.js",
@@ -38,10 +38,10 @@
38
38
  "typescript": "^5.6.2"
39
39
  },
40
40
  "dependencies": {
41
- "@aztec/bb.js": "^0.67.0",
41
+ "@aztec/bb.js": "^0.76.4",
42
42
  "@noble/ciphers": "^1.2.1",
43
43
  "@noble/secp256k1": "^2.2.3",
44
- "@zkpassport/utils": "^0.2.16",
44
+ "@zkpassport/utils": "^0.2.23",
45
45
  "buffer": "^6.0.3",
46
46
  "i18n-iso-countries": "^7.12.0",
47
47
  "pako": "^2.1.0",
package/src/index.ts CHANGED
@@ -263,13 +263,19 @@ export type QueryBuilder = {
263
263
  * @param key The attribute to compare.
264
264
  * @param value The list of values to check inclusion against.
265
265
  */
266
- in: <T extends "nationality">(key: T, value: IDCredentialValue<T>[]) => QueryBuilder
266
+ in: <T extends "nationality" | "issuing_country">(
267
+ key: T,
268
+ value: IDCredentialValue<T>[],
269
+ ) => QueryBuilder
267
270
  /**
268
271
  * Requires this attribute to be excluded from the provided list.
269
272
  * @param key The attribute to compare.
270
273
  * @param value The list of values to check exclusion against.
271
274
  */
272
- out: <T extends "nationality">(key: T, value: IDCredentialValue<T>[]) => QueryBuilder
275
+ out: <T extends "nationality" | "issuing_country">(
276
+ key: T,
277
+ value: IDCredentialValue<T>[],
278
+ ) => QueryBuilder
273
279
  /**
274
280
  * Requires this attribute to be disclosed.
275
281
  * @param key The attribute to disclose.
@@ -399,13 +405,29 @@ export class ZKPassport {
399
405
  }
400
406
  break
401
407
  case "in":
402
- if (field === "nationality" && !neededCircuits.includes("inclusion_check_country")) {
403
- neededCircuits.push("inclusion_check_country")
408
+ if (
409
+ field === "nationality" &&
410
+ !neededCircuits.includes("inclusion_check_nationality")
411
+ ) {
412
+ neededCircuits.push("inclusion_check_nationality")
413
+ } else if (
414
+ field === "issuing_country" &&
415
+ !neededCircuits.includes("inclusion_check_issuing_country")
416
+ ) {
417
+ neededCircuits.push("inclusion_check_issuing_country")
404
418
  }
405
419
  break
406
420
  case "out":
407
- if (field === "nationality" && !neededCircuits.includes("exclusion_check_country")) {
408
- neededCircuits.push("exclusion_check_country")
421
+ if (
422
+ field === "nationality" &&
423
+ !neededCircuits.includes("exclusion_check_nationality")
424
+ ) {
425
+ neededCircuits.push("exclusion_check_nationality")
426
+ } else if (
427
+ field === "issuing_country" &&
428
+ !neededCircuits.includes("exclusion_check_issuing_country")
429
+ ) {
430
+ neededCircuits.push("exclusion_check_issuing_country")
409
431
  }
410
432
  break
411
433
  }
@@ -532,12 +554,12 @@ export class ZKPassport {
532
554
  rangeCompare(key, [start, end], topic, this.topicToConfig)
533
555
  return this.getZkPassportRequest(topic)
534
556
  },
535
- in: <T extends "nationality">(key: T, value: IDCredentialValue<T>[]) => {
557
+ in: <T extends "nationality" | "issuing_country">(key: T, value: IDCredentialValue<T>[]) => {
536
558
  value = value.map((v) => normalizeCountry(v as CountryName)) as IDCredentialValue<T>[]
537
559
  generalCompare("in", key, value, topic, this.topicToConfig)
538
560
  return this.getZkPassportRequest(topic)
539
561
  },
540
- out: <T extends "nationality">(key: T, value: IDCredentialValue<T>[]) => {
562
+ out: <T extends "nationality" | "issuing_country">(key: T, value: IDCredentialValue<T>[]) => {
541
563
  value = value.map((v) => normalizeCountry(v as CountryName)) as IDCredentialValue<T>[]
542
564
  generalCompare("out", key, value, topic, this.topicToConfig)
543
565
  return this.getZkPassportRequest(topic)
@@ -755,8 +777,10 @@ export class ZKPassport {
755
777
  "compare_age",
756
778
  "compare_birthdate",
757
779
  "compare_expiry",
758
- "exclusion_check_country",
759
- "inclusion_check_country",
780
+ "exclusion_check_nationality",
781
+ "inclusion_check_nationality",
782
+ "exclusion_check_issuing_country",
783
+ "inclusion_check_issuing_country",
760
784
  ]
761
785
  const getIndex = (proof: ProofResult) => {
762
786
  const name = proof.name || ""
@@ -851,7 +875,7 @@ export class ZKPassport {
851
875
  isCorrect = false
852
876
  queryResultErrors.document_type.eq = {
853
877
  expected: `${queryResult.document_type.eq.expected}`,
854
- received: `${disclosedDataPassport.documentType}`,
878
+ received: `${disclosedDataPassport.documentType ?? disclosedDataIDCard.documentType}`,
855
879
  message: "Document type does not match the expected document type",
856
880
  }
857
881
  }
@@ -860,7 +884,7 @@ export class ZKPassport {
860
884
  isCorrect = false
861
885
  queryResultErrors.document_type.disclose = {
862
886
  expected: `${queryResult.document_type.disclose?.result}`,
863
- received: `${disclosedDataIDCard.documentType}`,
887
+ received: `${disclosedDataIDCard.documentType ?? disclosedDataPassport.documentType}`,
864
888
  message: "Document type does not match the disclosed document type in query result",
865
889
  }
866
890
  }
@@ -878,7 +902,7 @@ export class ZKPassport {
878
902
  isCorrect = false
879
903
  queryResultErrors.birthdate.eq = {
880
904
  expected: `${queryResult.birthdate.eq.expected.toISOString()}`,
881
- received: `${birthdatePassport.toISOString()}`,
905
+ received: `${birthdatePassport?.toISOString() ?? birthdateIDCard?.toISOString()}`,
882
906
  message: "Birthdate does not match the expected birthdate",
883
907
  }
884
908
  }
@@ -891,7 +915,7 @@ export class ZKPassport {
891
915
  isCorrect = false
892
916
  queryResultErrors.birthdate.disclose = {
893
917
  expected: `${queryResult.birthdate.disclose.result.toISOString()}`,
894
- received: `${birthdatePassport.toISOString()}`,
918
+ received: `${birthdatePassport?.toISOString() ?? birthdateIDCard?.toISOString()}`,
895
919
  message: "Birthdate does not match the disclosed birthdate in query result",
896
920
  }
897
921
  }
@@ -909,7 +933,7 @@ export class ZKPassport {
909
933
  isCorrect = false
910
934
  queryResultErrors.expiry_date.eq = {
911
935
  expected: `${queryResult.expiry_date.eq.expected.toISOString()}`,
912
- received: `${expiryDatePassport.toISOString()}`,
936
+ received: `${expiryDatePassport?.toISOString() ?? expiryDateIDCard?.toISOString()}`,
913
937
  message: "Expiry date does not match the expected expiry date",
914
938
  }
915
939
  }
@@ -922,7 +946,7 @@ export class ZKPassport {
922
946
  isCorrect = false
923
947
  queryResultErrors.expiry_date.disclose = {
924
948
  expected: `${queryResult.expiry_date.disclose.result.toISOString()}`,
925
- received: `${expiryDatePassport.toISOString()}`,
949
+ received: `${expiryDatePassport?.toISOString() ?? expiryDateIDCard?.toISOString()}`,
926
950
  message: "Expiry date does not match the disclosed expiry date in query result",
927
951
  }
928
952
  }
@@ -940,7 +964,7 @@ export class ZKPassport {
940
964
  isCorrect = false
941
965
  queryResultErrors.nationality.eq = {
942
966
  expected: `${queryResult.nationality.eq.expected}`,
943
- received: `${nationalityPassport}`,
967
+ received: `${nationalityPassport ?? nationalityIDCard}`,
944
968
  message: "Nationality does not match the expected nationality",
945
969
  }
946
970
  }
@@ -953,7 +977,7 @@ export class ZKPassport {
953
977
  isCorrect = false
954
978
  queryResultErrors.nationality.disclose = {
955
979
  expected: `${queryResult.nationality.disclose.result}`,
956
- received: `${nationalityPassport}`,
980
+ received: `${nationalityPassport ?? nationalityIDCard}`,
957
981
  message: "Nationality does not match the disclosed nationality in query result",
958
982
  }
959
983
  }
@@ -971,7 +995,7 @@ export class ZKPassport {
971
995
  isCorrect = false
972
996
  queryResultErrors.document_number.eq = {
973
997
  expected: `${queryResult.document_number.eq.expected}`,
974
- received: `${documentNumberPassport}`,
998
+ received: `${documentNumberPassport ?? documentNumberIDCard}`,
975
999
  message: "Document number does not match the expected document number",
976
1000
  }
977
1001
  }
@@ -986,7 +1010,7 @@ export class ZKPassport {
986
1010
  isCorrect = false
987
1011
  queryResultErrors.document_number.disclose = {
988
1012
  expected: `${queryResult.document_number.disclose.result}`,
989
- received: `${documentNumberPassport}`,
1013
+ received: `${documentNumberPassport ?? documentNumberIDCard}`,
990
1014
  message:
991
1015
  "Document number does not match the disclosed document number in query result",
992
1016
  }
@@ -1005,7 +1029,7 @@ export class ZKPassport {
1005
1029
  isCorrect = false
1006
1030
  queryResultErrors.gender.eq = {
1007
1031
  expected: `${queryResult.gender.eq.expected}`,
1008
- received: `${genderPassport}`,
1032
+ received: `${genderPassport ?? genderIDCard}`,
1009
1033
  message: "Gender does not match the expected gender",
1010
1034
  }
1011
1035
  }
@@ -1018,7 +1042,7 @@ export class ZKPassport {
1018
1042
  isCorrect = false
1019
1043
  queryResultErrors.gender.disclose = {
1020
1044
  expected: `${queryResult.gender.disclose.result}`,
1021
- received: `${genderPassport}`,
1045
+ received: `${genderPassport ?? genderIDCard}`,
1022
1046
  message: "Gender does not match the disclosed gender in query result",
1023
1047
  }
1024
1048
  }
@@ -1036,7 +1060,7 @@ export class ZKPassport {
1036
1060
  isCorrect = false
1037
1061
  queryResultErrors.issuing_country.eq = {
1038
1062
  expected: `${queryResult.issuing_country.eq.expected}`,
1039
- received: `${issuingCountryPassport}`,
1063
+ received: `${issuingCountryPassport ?? issuingCountryIDCard}`,
1040
1064
  message: "Issuing country does not match the expected issuing country",
1041
1065
  }
1042
1066
  }
@@ -1051,7 +1075,7 @@ export class ZKPassport {
1051
1075
  isCorrect = false
1052
1076
  queryResultErrors.issuing_country.disclose = {
1053
1077
  expected: `${queryResult.issuing_country.disclose.result}`,
1054
- received: `${issuingCountryPassport}`,
1078
+ received: `${issuingCountryPassport ?? issuingCountryIDCard}`,
1055
1079
  message:
1056
1080
  "Issuing country does not match the disclosed issuing country in query result",
1057
1081
  }
@@ -1072,7 +1096,7 @@ export class ZKPassport {
1072
1096
  isCorrect = false
1073
1097
  queryResultErrors.fullname.eq = {
1074
1098
  expected: `${queryResult.fullname.eq.expected}`,
1075
- received: `${fullnamePassport}`,
1099
+ received: `${fullnamePassport ?? fullnameIDCard}`,
1076
1100
  message: "Fullname does not match the expected fullname",
1077
1101
  }
1078
1102
  }
@@ -1087,7 +1111,7 @@ export class ZKPassport {
1087
1111
  isCorrect = false
1088
1112
  queryResultErrors.fullname.disclose = {
1089
1113
  expected: `${queryResult.fullname.disclose.result}`,
1090
- received: `${fullnamePassport}`,
1114
+ received: `${fullnamePassport ?? fullnameIDCard}`,
1091
1115
  message: "Fullname does not match the disclosed fullname in query result",
1092
1116
  }
1093
1117
  }
@@ -1114,7 +1138,7 @@ export class ZKPassport {
1114
1138
  isCorrect = false
1115
1139
  queryResultErrors.firstname.eq = {
1116
1140
  expected: `${queryResult.firstname.eq.expected}`,
1117
- received: `${firstnamePassport}`,
1141
+ received: `${firstnamePassport ?? firstnameIDCard}`,
1118
1142
  message: "Firstname does not match the expected firstname",
1119
1143
  }
1120
1144
  }
@@ -1129,7 +1153,7 @@ export class ZKPassport {
1129
1153
  isCorrect = false
1130
1154
  queryResultErrors.firstname.disclose = {
1131
1155
  expected: `${queryResult.firstname.disclose.result}`,
1132
- received: `${firstnamePassport}`,
1156
+ received: `${firstnamePassport ?? firstnameIDCard}`,
1133
1157
  message: "Firstname does not match the disclosed firstname in query result",
1134
1158
  }
1135
1159
  }
@@ -1156,7 +1180,7 @@ export class ZKPassport {
1156
1180
  isCorrect = false
1157
1181
  queryResultErrors.lastname.eq = {
1158
1182
  expected: `${queryResult.lastname.eq.expected}`,
1159
- received: `${lastnamePassport}`,
1183
+ received: `${lastnamePassport ?? lastnameIDCard}`,
1160
1184
  message: "Lastname does not match the expected lastname",
1161
1185
  }
1162
1186
  }
@@ -1171,7 +1195,7 @@ export class ZKPassport {
1171
1195
  isCorrect = false
1172
1196
  queryResultErrors.lastname.disclose = {
1173
1197
  expected: `${queryResult.lastname.disclose.result}`,
1174
- received: `${lastnamePassport}`,
1198
+ received: `${lastnamePassport ?? lastnameIDCard}`,
1175
1199
  message: "Lastname does not match the disclosed lastname in query result",
1176
1200
  }
1177
1201
  }
@@ -1470,18 +1494,18 @@ export class ZKPassport {
1470
1494
  }
1471
1495
  }
1472
1496
  uniqueIdentifier = getNullifierFromDisclosureProof(proofData).toString(10)
1473
- } else if (proof.name === "exclusion_check_country") {
1497
+ } else if (proof.name === "exclusion_check_nationality") {
1474
1498
  commitmentIn = getCommitmentInFromDisclosureProof(proofData)
1475
1499
  if (commitmentIn !== commitmentOut) {
1476
1500
  console.warn(
1477
- "Failed to check the link between the validity of the ID and the country exclusion check",
1501
+ "Failed to check the link between the validity of the ID and the nationality exclusion check",
1478
1502
  )
1479
1503
  isCorrect = false
1480
1504
  queryResultErrors.nationality.commitment = {
1481
1505
  expected: `Commitment: ${commitmentOut}`,
1482
1506
  received: `Commitment: ${commitmentIn}`,
1483
1507
  message:
1484
- "Failed to check the link between the validity of the ID and the country exclusion check",
1508
+ "Failed to check the link between the validity of the ID and the nationality exclusion check",
1485
1509
  }
1486
1510
  }
1487
1511
  const countryList = getCountryListFromExclusionProof(proofData)
@@ -1493,12 +1517,12 @@ export class ZKPassport {
1493
1517
  if (
1494
1518
  !queryResult.nationality.out.expected?.every((country) => countryList.includes(country))
1495
1519
  ) {
1496
- console.warn("Country exclusion list does not match the one from the query results")
1520
+ console.warn("Nationality exclusion list does not match the one from the query results")
1497
1521
  isCorrect = false
1498
1522
  queryResultErrors.nationality.out = {
1499
1523
  expected: queryResult.nationality.out.expected,
1500
1524
  received: countryList,
1501
- message: "Country exclusion list does not match the one from the query results",
1525
+ message: "Nationality exclusion list does not match the one from the query results",
1502
1526
  }
1503
1527
  }
1504
1528
  } else if (!queryResult.nationality || !queryResult.nationality.out) {
@@ -1524,18 +1548,77 @@ export class ZKPassport {
1524
1548
  }
1525
1549
  }
1526
1550
  uniqueIdentifier = getNullifierFromDisclosureProof(proofData).toString(10)
1527
- } else if (proof.name === "inclusion_check_country") {
1551
+ } else if (proof.name === "exclusion_check_issuing_country") {
1552
+ commitmentIn = getCommitmentInFromDisclosureProof(proofData)
1553
+ if (commitmentIn !== commitmentOut) {
1554
+ console.warn(
1555
+ "Failed to check the link between the validity of the ID and the issuing country exclusion check",
1556
+ )
1557
+ isCorrect = false
1558
+ queryResultErrors.nationality.commitment = {
1559
+ expected: `Commitment: ${commitmentOut}`,
1560
+ received: `Commitment: ${commitmentIn}`,
1561
+ message:
1562
+ "Failed to check the link between the validity of the ID and the issuing country exclusion check",
1563
+ }
1564
+ }
1565
+ const countryList = getCountryListFromExclusionProof(proofData)
1566
+ if (
1567
+ queryResult.issuing_country &&
1568
+ queryResult.issuing_country.out &&
1569
+ queryResult.issuing_country.out.result
1570
+ ) {
1571
+ if (
1572
+ !queryResult.issuing_country.out.expected?.every((country) =>
1573
+ countryList.includes(country),
1574
+ )
1575
+ ) {
1576
+ console.warn(
1577
+ "Issuing country exclusion list does not match the one from the query results",
1578
+ )
1579
+ isCorrect = false
1580
+ queryResultErrors.issuing_country.out = {
1581
+ expected: queryResult.issuing_country.out.expected,
1582
+ received: countryList,
1583
+ message:
1584
+ "Issuing country exclusion list does not match the one from the query results",
1585
+ }
1586
+ }
1587
+ } else if (!queryResult.issuing_country || !queryResult.issuing_country.out) {
1588
+ console.warn("Issuing country exclusion is not set in the query result")
1589
+ isCorrect = false
1590
+ queryResultErrors.issuing_country.out = {
1591
+ message: "Issuing country exclusion is not set in the query result",
1592
+ }
1593
+ }
1594
+ // Check the countryList is in ascending order
1595
+ // If the prover doesn't use a sorted list then the proof cannot be trusted
1596
+ // as it is requirement in the circuit for the exclusion check to work
1597
+ for (let i = 1; i < countryList.length; i++) {
1598
+ if (countryList[i] < countryList[i - 1]) {
1599
+ console.warn(
1600
+ "The issuing country exclusion list has not been sorted, and thus the proof cannot be trusted",
1601
+ )
1602
+ isCorrect = false
1603
+ queryResultErrors.issuing_country.out = {
1604
+ message:
1605
+ "The issuing country exclusion list has not been sorted, and thus the proof cannot be trusted",
1606
+ }
1607
+ }
1608
+ }
1609
+ uniqueIdentifier = getNullifierFromDisclosureProof(proofData).toString(10)
1610
+ } else if (proof.name === "inclusion_check_nationality") {
1528
1611
  commitmentIn = getCommitmentInFromDisclosureProof(proofData)
1529
1612
  if (commitmentIn !== commitmentOut) {
1530
1613
  console.warn(
1531
- "Failed to check the link between the validity of the ID and the country inclusion check",
1614
+ "Failed to check the link between the validity of the ID and the nationality inclusion check",
1532
1615
  )
1533
1616
  isCorrect = false
1534
1617
  queryResultErrors.nationality.commitment = {
1535
1618
  expected: `Commitment: ${commitmentOut}`,
1536
1619
  received: `Commitment: ${commitmentIn}`,
1537
1620
  message:
1538
- "Failed to check the link between the validity of the ID and the country inclusion check",
1621
+ "Failed to check the link between the validity of the ID and the nationality inclusion check",
1539
1622
  }
1540
1623
  }
1541
1624
  const countryList = getCountryListFromInclusionProof(proofData)
@@ -1547,12 +1630,12 @@ export class ZKPassport {
1547
1630
  if (
1548
1631
  !queryResult.nationality.in.expected?.every((country) => countryList.includes(country))
1549
1632
  ) {
1550
- console.warn("Country inclusion list does not match the one from the query results")
1633
+ console.warn("Nationality inclusion list does not match the one from the query results")
1551
1634
  isCorrect = false
1552
1635
  queryResultErrors.nationality.in = {
1553
1636
  expected: queryResult.nationality.in.expected,
1554
1637
  received: countryList,
1555
- message: "Country inclusion list does not match the one from the query results",
1638
+ message: "Nationality inclusion list does not match the one from the query results",
1556
1639
  }
1557
1640
  }
1558
1641
  } else if (!queryResult.nationality || !queryResult.nationality.in) {
@@ -1563,6 +1646,50 @@ export class ZKPassport {
1563
1646
  }
1564
1647
  }
1565
1648
  uniqueIdentifier = getNullifierFromDisclosureProof(proofData).toString(10)
1649
+ } else if (proof.name === "inclusion_check_issuing_country") {
1650
+ commitmentIn = getCommitmentInFromDisclosureProof(proofData)
1651
+ if (commitmentIn !== commitmentOut) {
1652
+ console.warn(
1653
+ "Failed to check the link between the validity of the ID and the issuing country inclusion check",
1654
+ )
1655
+ isCorrect = false
1656
+ queryResultErrors.nationality.commitment = {
1657
+ expected: `Commitment: ${commitmentOut}`,
1658
+ received: `Commitment: ${commitmentIn}`,
1659
+ message:
1660
+ "Failed to check the link between the validity of the ID and the issuing country inclusion check",
1661
+ }
1662
+ }
1663
+ const countryList = getCountryListFromInclusionProof(proofData)
1664
+ if (
1665
+ queryResult.issuing_country &&
1666
+ queryResult.issuing_country.in &&
1667
+ queryResult.issuing_country.in.result
1668
+ ) {
1669
+ if (
1670
+ !queryResult.issuing_country.in.expected?.every((country) =>
1671
+ countryList.includes(country),
1672
+ )
1673
+ ) {
1674
+ console.warn(
1675
+ "Issuing country inclusion list does not match the one from the query results",
1676
+ )
1677
+ isCorrect = false
1678
+ queryResultErrors.issuing_country.in = {
1679
+ expected: queryResult.issuing_country.in.expected,
1680
+ received: countryList,
1681
+ message:
1682
+ "Issuing country inclusion list does not match the one from the query results",
1683
+ }
1684
+ }
1685
+ } else if (!queryResult.issuing_country || !queryResult.issuing_country.in) {
1686
+ console.warn("Issuing country inclusion is not set in the query result")
1687
+ isCorrect = false
1688
+ queryResultErrors.issuing_country.in = {
1689
+ message: "Issuing country inclusion is not set in the query result",
1690
+ }
1691
+ }
1692
+ uniqueIdentifier = getNullifierFromDisclosureProof(proofData).toString(10)
1566
1693
  }
1567
1694
  }
1568
1695
  return { isCorrect, uniqueIdentifier, queryResultErrors }