@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/src/index.ts
CHANGED
|
@@ -51,6 +51,33 @@ if (typeof globalThis.Buffer === "undefined") {
|
|
|
51
51
|
}
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
+
export type QueryResultError<T> = {
|
|
55
|
+
expected?: T
|
|
56
|
+
received?: T
|
|
57
|
+
message: string
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export type QueryResultErrors = {
|
|
61
|
+
[key in
|
|
62
|
+
| IDCredential
|
|
63
|
+
| "sig_check_dsc"
|
|
64
|
+
| "sig_check_id_data"
|
|
65
|
+
| "data_check_integrity"
|
|
66
|
+
| "disclose"]: {
|
|
67
|
+
disclose?: QueryResultError<string | number | Date>
|
|
68
|
+
gte?: QueryResultError<number | Date>
|
|
69
|
+
lte?: QueryResultError<number | Date>
|
|
70
|
+
lt?: QueryResultError<number | Date>
|
|
71
|
+
range?: QueryResultError<[number | Date, number | Date]>
|
|
72
|
+
in?: QueryResultError<string[]>
|
|
73
|
+
out?: QueryResultError<string[]>
|
|
74
|
+
eq?: QueryResultError<string | number | Date>
|
|
75
|
+
commitment?: QueryResultError<string>
|
|
76
|
+
date?: QueryResultError<string>
|
|
77
|
+
certificate?: QueryResultError<string>
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
54
81
|
registerLocale(i18en)
|
|
55
82
|
|
|
56
83
|
function hasRequestedAccessToField(credentialsRequest: Query, field: IDCredential): boolean {
|
|
@@ -172,6 +199,7 @@ export type QueryBuilderResult = {
|
|
|
172
199
|
uniqueIdentifier: string | undefined
|
|
173
200
|
verified: boolean
|
|
174
201
|
result: QueryResult
|
|
202
|
+
queryResultErrors?: QueryResultErrors
|
|
175
203
|
}) => void,
|
|
176
204
|
) => void
|
|
177
205
|
/**
|
|
@@ -235,13 +263,19 @@ export type QueryBuilder = {
|
|
|
235
263
|
* @param key The attribute to compare.
|
|
236
264
|
* @param value The list of values to check inclusion against.
|
|
237
265
|
*/
|
|
238
|
-
in: <T extends "nationality"
|
|
266
|
+
in: <T extends "nationality" | "issuing_country">(
|
|
267
|
+
key: T,
|
|
268
|
+
value: IDCredentialValue<T>[],
|
|
269
|
+
) => QueryBuilder
|
|
239
270
|
/**
|
|
240
271
|
* Requires this attribute to be excluded from the provided list.
|
|
241
272
|
* @param key The attribute to compare.
|
|
242
273
|
* @param value The list of values to check exclusion against.
|
|
243
274
|
*/
|
|
244
|
-
out: <T extends "nationality"
|
|
275
|
+
out: <T extends "nationality" | "issuing_country">(
|
|
276
|
+
key: T,
|
|
277
|
+
value: IDCredentialValue<T>[],
|
|
278
|
+
) => QueryBuilder
|
|
245
279
|
/**
|
|
246
280
|
* Requires this attribute to be disclosed.
|
|
247
281
|
* @param key The attribute to disclose.
|
|
@@ -276,6 +310,7 @@ export class ZKPassport {
|
|
|
276
310
|
> = {}
|
|
277
311
|
private topicToProofs: Record<string, Array<ProofResult>> = {}
|
|
278
312
|
private topicToExpectedProofCount: Record<string, number> = {}
|
|
313
|
+
private topicToFailedProofCount: Record<string, number> = {}
|
|
279
314
|
private topicToResults: Record<string, QueryResult> = {}
|
|
280
315
|
|
|
281
316
|
private onRequestReceivedCallbacks: Record<string, Array<() => void>> = {}
|
|
@@ -289,6 +324,7 @@ export class ZKPassport {
|
|
|
289
324
|
uniqueIdentifier: string | undefined
|
|
290
325
|
verified: boolean
|
|
291
326
|
result: QueryResult
|
|
327
|
+
queryResultErrors?: QueryResultErrors
|
|
292
328
|
}) => void
|
|
293
329
|
>
|
|
294
330
|
> = {}
|
|
@@ -315,22 +351,27 @@ export class ZKPassport {
|
|
|
315
351
|
// Clear the results straight away to avoid concurrency issues
|
|
316
352
|
delete this.topicToResults[topic]
|
|
317
353
|
// Verify the proofs and extract the unique identifier (aka nullifier) and the verification result
|
|
318
|
-
const { uniqueIdentifier, verified } = await this.verify(
|
|
354
|
+
const { uniqueIdentifier, verified, queryResultErrors } = await this.verify(
|
|
319
355
|
topic,
|
|
320
356
|
this.topicToProofs[topic],
|
|
321
357
|
result,
|
|
322
358
|
)
|
|
359
|
+
const hasFailedProofs = this.topicToFailedProofCount[topic] > 0
|
|
323
360
|
await Promise.all(
|
|
324
361
|
this.onResultCallbacks[topic].map((callback) =>
|
|
325
362
|
callback({
|
|
326
|
-
|
|
327
|
-
verified
|
|
363
|
+
// If there are failed proofs, we don't return the unique identifier
|
|
364
|
+
// and we set the verified result to false
|
|
365
|
+
uniqueIdentifier: hasFailedProofs ? undefined : uniqueIdentifier,
|
|
366
|
+
verified: hasFailedProofs ? false : verified,
|
|
328
367
|
result,
|
|
368
|
+
queryResultErrors,
|
|
329
369
|
}),
|
|
330
370
|
),
|
|
331
371
|
)
|
|
332
|
-
// Clear the expected proof count
|
|
372
|
+
// Clear the expected proof count and failed proof count
|
|
333
373
|
delete this.topicToExpectedProofCount[topic]
|
|
374
|
+
delete this.topicToFailedProofCount[topic]
|
|
334
375
|
}
|
|
335
376
|
|
|
336
377
|
private setExpectedProofCount(topic: string) {
|
|
@@ -364,13 +405,29 @@ export class ZKPassport {
|
|
|
364
405
|
}
|
|
365
406
|
break
|
|
366
407
|
case "in":
|
|
367
|
-
if (
|
|
368
|
-
|
|
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")
|
|
369
418
|
}
|
|
370
419
|
break
|
|
371
420
|
case "out":
|
|
372
|
-
if (
|
|
373
|
-
|
|
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")
|
|
374
431
|
}
|
|
375
432
|
break
|
|
376
433
|
}
|
|
@@ -381,6 +438,7 @@ export class ZKPassport {
|
|
|
381
438
|
// Each separate needed circuit adds 1 disclosure proof
|
|
382
439
|
this.topicToExpectedProofCount[topic] =
|
|
383
440
|
neededCircuits.length === 0 ? 4 : 3 + neededCircuits.length
|
|
441
|
+
this.topicToFailedProofCount[topic] = 0
|
|
384
442
|
}
|
|
385
443
|
|
|
386
444
|
/**
|
|
@@ -441,6 +499,7 @@ export class ZKPassport {
|
|
|
441
499
|
// This means the user has an ID that is not supported yet
|
|
442
500
|
// So we won't receive any proofs and we can handle the result now
|
|
443
501
|
this.topicToExpectedProofCount[topic] = 0
|
|
502
|
+
this.topicToFailedProofCount[topic] += this.topicToExpectedProofCount[topic]
|
|
444
503
|
if (this.topicToResults[topic]) {
|
|
445
504
|
await this.handleResult(topic)
|
|
446
505
|
}
|
|
@@ -448,6 +507,7 @@ export class ZKPassport {
|
|
|
448
507
|
// This means one of the disclosure proofs failed to be generated
|
|
449
508
|
// So we need to remove one from the expected proof count
|
|
450
509
|
this.topicToExpectedProofCount[topic] -= 1
|
|
510
|
+
this.topicToFailedProofCount[topic] += 1
|
|
451
511
|
// If the expected proof count is now equal to the number of proofs received
|
|
452
512
|
// and the results were received, we can handle the result now
|
|
453
513
|
if (
|
|
@@ -494,12 +554,12 @@ export class ZKPassport {
|
|
|
494
554
|
rangeCompare(key, [start, end], topic, this.topicToConfig)
|
|
495
555
|
return this.getZkPassportRequest(topic)
|
|
496
556
|
},
|
|
497
|
-
in: <T extends "nationality">(key: T, value: IDCredentialValue<T>[]) => {
|
|
557
|
+
in: <T extends "nationality" | "issuing_country">(key: T, value: IDCredentialValue<T>[]) => {
|
|
498
558
|
value = value.map((v) => normalizeCountry(v as CountryName)) as IDCredentialValue<T>[]
|
|
499
559
|
generalCompare("in", key, value, topic, this.topicToConfig)
|
|
500
560
|
return this.getZkPassportRequest(topic)
|
|
501
561
|
},
|
|
502
|
-
out: <T extends "nationality">(key: T, value: IDCredentialValue<T>[]) => {
|
|
562
|
+
out: <T extends "nationality" | "issuing_country">(key: T, value: IDCredentialValue<T>[]) => {
|
|
503
563
|
value = value.map((v) => normalizeCountry(v as CountryName)) as IDCredentialValue<T>[]
|
|
504
564
|
generalCompare("out", key, value, topic, this.topicToConfig)
|
|
505
565
|
return this.getZkPassportRequest(topic)
|
|
@@ -511,9 +571,6 @@ export class ZKPassport {
|
|
|
511
571
|
}
|
|
512
572
|
return this.getZkPassportRequest(topic)
|
|
513
573
|
},
|
|
514
|
-
/*checkAML: (country?: CountryName | Alpha2Code | Alpha3Code) => {
|
|
515
|
-
return this.getZkPassportRequest(topic)
|
|
516
|
-
},*/
|
|
517
574
|
done: () => {
|
|
518
575
|
const base64Config = Buffer.from(JSON.stringify(this.topicToConfig[topic])).toString(
|
|
519
576
|
"base64",
|
|
@@ -539,6 +596,7 @@ export class ZKPassport {
|
|
|
539
596
|
uniqueIdentifier: string | undefined
|
|
540
597
|
verified: boolean
|
|
541
598
|
result: QueryResult
|
|
599
|
+
queryResultErrors?: QueryResultErrors
|
|
542
600
|
}) => void,
|
|
543
601
|
) => this.onResultCallbacks[topic].push(callback),
|
|
544
602
|
onReject: (callback: () => void) => this.onRejectCallbacks[topic].push(callback),
|
|
@@ -690,6 +748,23 @@ export class ZKPassport {
|
|
|
690
748
|
0,
|
|
691
749
|
0,
|
|
692
750
|
)
|
|
751
|
+
const queryResultErrors: QueryResultErrors = {
|
|
752
|
+
sig_check_dsc: {},
|
|
753
|
+
sig_check_id_data: {},
|
|
754
|
+
data_check_integrity: {},
|
|
755
|
+
disclose: {},
|
|
756
|
+
age: {},
|
|
757
|
+
birthdate: {},
|
|
758
|
+
expiry_date: {},
|
|
759
|
+
document_type: {},
|
|
760
|
+
issuing_country: {},
|
|
761
|
+
gender: {},
|
|
762
|
+
nationality: {},
|
|
763
|
+
firstname: {},
|
|
764
|
+
lastname: {},
|
|
765
|
+
fullname: {},
|
|
766
|
+
document_number: {},
|
|
767
|
+
}
|
|
693
768
|
|
|
694
769
|
// Since the order is important for the commitments, we need to sort the proofs
|
|
695
770
|
// by their expected order: root signature check -> ID signature check -> integrity check -> disclosure
|
|
@@ -702,8 +777,10 @@ export class ZKPassport {
|
|
|
702
777
|
"compare_age",
|
|
703
778
|
"compare_birthdate",
|
|
704
779
|
"compare_expiry",
|
|
705
|
-
"
|
|
706
|
-
"
|
|
780
|
+
"exclusion_check_nationality",
|
|
781
|
+
"inclusion_check_nationality",
|
|
782
|
+
"exclusion_check_issuing_country",
|
|
783
|
+
"inclusion_check_issuing_country",
|
|
707
784
|
]
|
|
708
785
|
const getIndex = (proof: ProofResult) => {
|
|
709
786
|
const name = proof.name || ""
|
|
@@ -720,7 +797,11 @@ export class ZKPassport {
|
|
|
720
797
|
if (merkleRoot !== expectedMerkleRoot) {
|
|
721
798
|
console.warn("The ID was signed by an unrecognized root certificate")
|
|
722
799
|
isCorrect = false
|
|
723
|
-
|
|
800
|
+
queryResultErrors.sig_check_dsc.certificate = {
|
|
801
|
+
expected: `Certificate registry root: ${expectedMerkleRoot.toString()}`,
|
|
802
|
+
received: `Certificate registry root: ${merkleRoot.toString()}`,
|
|
803
|
+
message: "The ID was signed by an unrecognized root certificate",
|
|
804
|
+
}
|
|
724
805
|
}
|
|
725
806
|
} else if (proof.name?.startsWith("sig_check_id_data")) {
|
|
726
807
|
commitmentIn = getCommitmentInFromIDDataProof(proofData)
|
|
@@ -729,7 +810,11 @@ export class ZKPassport {
|
|
|
729
810
|
"Failed to check the link between the certificate signature and ID signature",
|
|
730
811
|
)
|
|
731
812
|
isCorrect = false
|
|
732
|
-
|
|
813
|
+
queryResultErrors.sig_check_id_data.commitment = {
|
|
814
|
+
expected: `Commitment: ${commitmentOut?.toString() || "undefined"}`,
|
|
815
|
+
received: `Commitment: ${commitmentIn?.toString() || "undefined"}`,
|
|
816
|
+
message: "Failed to check the link between the certificate signature and ID signature",
|
|
817
|
+
}
|
|
733
818
|
}
|
|
734
819
|
commitmentOut = getCommitmentOutFromIDDataProof(proofData)
|
|
735
820
|
} else if (proof.name?.startsWith("data_check_integrity")) {
|
|
@@ -737,7 +822,11 @@ export class ZKPassport {
|
|
|
737
822
|
if (commitmentIn !== commitmentOut) {
|
|
738
823
|
console.warn("Failed to check the link between the ID signature and the data signed")
|
|
739
824
|
isCorrect = false
|
|
740
|
-
|
|
825
|
+
queryResultErrors.data_check_integrity.commitment = {
|
|
826
|
+
expected: `Commitment: ${commitmentOut?.toString() || "undefined"}`,
|
|
827
|
+
received: `Commitment: ${commitmentIn?.toString() || "undefined"}`,
|
|
828
|
+
message: "Failed to check the link between the ID signature and the data signed",
|
|
829
|
+
}
|
|
741
830
|
}
|
|
742
831
|
commitmentOut = getCommitmentOutFromIntegrityProof(proofData)
|
|
743
832
|
const currentDate = getCurrentDateFromIntegrityProof(proofData)
|
|
@@ -750,7 +839,12 @@ export class ZKPassport {
|
|
|
750
839
|
`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`,
|
|
751
840
|
)
|
|
752
841
|
isCorrect = false
|
|
753
|
-
|
|
842
|
+
queryResultErrors.data_check_integrity.date = {
|
|
843
|
+
expected: `Difference: ${this.topicToLocalConfig[topic]?.validity} days`,
|
|
844
|
+
received: `Difference: ${Math.round(todayToCurrentDate / 86400000)} days`,
|
|
845
|
+
message:
|
|
846
|
+
"The date used to check the validity of the ID is older than the validity period",
|
|
847
|
+
}
|
|
754
848
|
}
|
|
755
849
|
} else if (proof.name === "disclose_bytes") {
|
|
756
850
|
commitmentIn = getCommitmentInFromDisclosureProof(proofData)
|
|
@@ -759,7 +853,12 @@ export class ZKPassport {
|
|
|
759
853
|
"Failed to check the link between the validity of the ID and the data to disclose",
|
|
760
854
|
)
|
|
761
855
|
isCorrect = false
|
|
762
|
-
|
|
856
|
+
queryResultErrors.disclose.commitment = {
|
|
857
|
+
expected: `Commitment: ${commitmentOut?.toString() || "undefined"}`,
|
|
858
|
+
received: `Commitment: ${commitmentIn?.toString() || "undefined"}`,
|
|
859
|
+
message:
|
|
860
|
+
"Failed to check the link between the validity of the ID and the data to disclose",
|
|
861
|
+
}
|
|
763
862
|
}
|
|
764
863
|
// We can't be certain that the disclosed data is for a passport or an ID card
|
|
765
864
|
// so we need to check both (unless the document type is revealed)
|
|
@@ -774,12 +873,20 @@ export class ZKPassport {
|
|
|
774
873
|
) {
|
|
775
874
|
console.warn("Document type does not match the expected document type")
|
|
776
875
|
isCorrect = false
|
|
777
|
-
|
|
876
|
+
queryResultErrors.document_type.eq = {
|
|
877
|
+
expected: `${queryResult.document_type.eq.expected}`,
|
|
878
|
+
received: `${disclosedDataPassport.documentType ?? disclosedDataIDCard.documentType}`,
|
|
879
|
+
message: "Document type does not match the expected document type",
|
|
880
|
+
}
|
|
778
881
|
}
|
|
779
882
|
if (queryResult.document_type.disclose?.result !== disclosedDataIDCard.documentType) {
|
|
780
883
|
console.warn("Document type does not match the disclosed document type in query result")
|
|
781
884
|
isCorrect = false
|
|
782
|
-
|
|
885
|
+
queryResultErrors.document_type.disclose = {
|
|
886
|
+
expected: `${queryResult.document_type.disclose?.result}`,
|
|
887
|
+
received: `${disclosedDataIDCard.documentType ?? disclosedDataPassport.documentType}`,
|
|
888
|
+
message: "Document type does not match the disclosed document type in query result",
|
|
889
|
+
}
|
|
783
890
|
}
|
|
784
891
|
}
|
|
785
892
|
if (queryResult.birthdate) {
|
|
@@ -793,7 +900,11 @@ export class ZKPassport {
|
|
|
793
900
|
) {
|
|
794
901
|
console.warn("Birthdate does not match the expected birthdate")
|
|
795
902
|
isCorrect = false
|
|
796
|
-
|
|
903
|
+
queryResultErrors.birthdate.eq = {
|
|
904
|
+
expected: `${queryResult.birthdate.eq.expected.toISOString()}`,
|
|
905
|
+
received: `${birthdatePassport?.toISOString() ?? birthdateIDCard?.toISOString()}`,
|
|
906
|
+
message: "Birthdate does not match the expected birthdate",
|
|
907
|
+
}
|
|
797
908
|
}
|
|
798
909
|
if (
|
|
799
910
|
queryResult.birthdate.disclose &&
|
|
@@ -802,7 +913,11 @@ export class ZKPassport {
|
|
|
802
913
|
) {
|
|
803
914
|
console.warn("Birthdate does not match the disclosed birthdate in query result")
|
|
804
915
|
isCorrect = false
|
|
805
|
-
|
|
916
|
+
queryResultErrors.birthdate.disclose = {
|
|
917
|
+
expected: `${queryResult.birthdate.disclose.result.toISOString()}`,
|
|
918
|
+
received: `${birthdatePassport?.toISOString() ?? birthdateIDCard?.toISOString()}`,
|
|
919
|
+
message: "Birthdate does not match the disclosed birthdate in query result",
|
|
920
|
+
}
|
|
806
921
|
}
|
|
807
922
|
}
|
|
808
923
|
if (queryResult.expiry_date) {
|
|
@@ -816,7 +931,11 @@ export class ZKPassport {
|
|
|
816
931
|
) {
|
|
817
932
|
console.warn("Expiry date does not match the expected expiry date")
|
|
818
933
|
isCorrect = false
|
|
819
|
-
|
|
934
|
+
queryResultErrors.expiry_date.eq = {
|
|
935
|
+
expected: `${queryResult.expiry_date.eq.expected.toISOString()}`,
|
|
936
|
+
received: `${expiryDatePassport?.toISOString() ?? expiryDateIDCard?.toISOString()}`,
|
|
937
|
+
message: "Expiry date does not match the expected expiry date",
|
|
938
|
+
}
|
|
820
939
|
}
|
|
821
940
|
if (
|
|
822
941
|
queryResult.expiry_date.disclose &&
|
|
@@ -825,7 +944,11 @@ export class ZKPassport {
|
|
|
825
944
|
) {
|
|
826
945
|
console.warn("Expiry date does not match the disclosed expiry date in query result")
|
|
827
946
|
isCorrect = false
|
|
828
|
-
|
|
947
|
+
queryResultErrors.expiry_date.disclose = {
|
|
948
|
+
expected: `${queryResult.expiry_date.disclose.result.toISOString()}`,
|
|
949
|
+
received: `${expiryDatePassport?.toISOString() ?? expiryDateIDCard?.toISOString()}`,
|
|
950
|
+
message: "Expiry date does not match the disclosed expiry date in query result",
|
|
951
|
+
}
|
|
829
952
|
}
|
|
830
953
|
}
|
|
831
954
|
if (queryResult.nationality) {
|
|
@@ -839,7 +962,11 @@ export class ZKPassport {
|
|
|
839
962
|
) {
|
|
840
963
|
console.warn("Nationality does not match the expected nationality")
|
|
841
964
|
isCorrect = false
|
|
842
|
-
|
|
965
|
+
queryResultErrors.nationality.eq = {
|
|
966
|
+
expected: `${queryResult.nationality.eq.expected}`,
|
|
967
|
+
received: `${nationalityPassport ?? nationalityIDCard}`,
|
|
968
|
+
message: "Nationality does not match the expected nationality",
|
|
969
|
+
}
|
|
843
970
|
}
|
|
844
971
|
if (
|
|
845
972
|
queryResult.nationality.disclose &&
|
|
@@ -848,7 +975,11 @@ export class ZKPassport {
|
|
|
848
975
|
) {
|
|
849
976
|
console.warn("Nationality does not match the disclosed nationality in query result")
|
|
850
977
|
isCorrect = false
|
|
851
|
-
|
|
978
|
+
queryResultErrors.nationality.disclose = {
|
|
979
|
+
expected: `${queryResult.nationality.disclose.result}`,
|
|
980
|
+
received: `${nationalityPassport ?? nationalityIDCard}`,
|
|
981
|
+
message: "Nationality does not match the disclosed nationality in query result",
|
|
982
|
+
}
|
|
852
983
|
}
|
|
853
984
|
}
|
|
854
985
|
if (queryResult.document_number) {
|
|
@@ -862,7 +993,11 @@ export class ZKPassport {
|
|
|
862
993
|
) {
|
|
863
994
|
console.warn("Document number does not match the expected document number")
|
|
864
995
|
isCorrect = false
|
|
865
|
-
|
|
996
|
+
queryResultErrors.document_number.eq = {
|
|
997
|
+
expected: `${queryResult.document_number.eq.expected}`,
|
|
998
|
+
received: `${documentNumberPassport ?? documentNumberIDCard}`,
|
|
999
|
+
message: "Document number does not match the expected document number",
|
|
1000
|
+
}
|
|
866
1001
|
}
|
|
867
1002
|
if (
|
|
868
1003
|
queryResult.document_number.disclose &&
|
|
@@ -873,7 +1008,12 @@ export class ZKPassport {
|
|
|
873
1008
|
"Document number does not match the disclosed document number in query result",
|
|
874
1009
|
)
|
|
875
1010
|
isCorrect = false
|
|
876
|
-
|
|
1011
|
+
queryResultErrors.document_number.disclose = {
|
|
1012
|
+
expected: `${queryResult.document_number.disclose.result}`,
|
|
1013
|
+
received: `${documentNumberPassport ?? documentNumberIDCard}`,
|
|
1014
|
+
message:
|
|
1015
|
+
"Document number does not match the disclosed document number in query result",
|
|
1016
|
+
}
|
|
877
1017
|
}
|
|
878
1018
|
}
|
|
879
1019
|
if (queryResult.gender) {
|
|
@@ -887,7 +1027,11 @@ export class ZKPassport {
|
|
|
887
1027
|
) {
|
|
888
1028
|
console.warn("Gender does not match the expected gender")
|
|
889
1029
|
isCorrect = false
|
|
890
|
-
|
|
1030
|
+
queryResultErrors.gender.eq = {
|
|
1031
|
+
expected: `${queryResult.gender.eq.expected}`,
|
|
1032
|
+
received: `${genderPassport ?? genderIDCard}`,
|
|
1033
|
+
message: "Gender does not match the expected gender",
|
|
1034
|
+
}
|
|
891
1035
|
}
|
|
892
1036
|
if (
|
|
893
1037
|
queryResult.gender.disclose &&
|
|
@@ -896,7 +1040,11 @@ export class ZKPassport {
|
|
|
896
1040
|
) {
|
|
897
1041
|
console.warn("Gender does not match the disclosed gender in query result")
|
|
898
1042
|
isCorrect = false
|
|
899
|
-
|
|
1043
|
+
queryResultErrors.gender.disclose = {
|
|
1044
|
+
expected: `${queryResult.gender.disclose.result}`,
|
|
1045
|
+
received: `${genderPassport ?? genderIDCard}`,
|
|
1046
|
+
message: "Gender does not match the disclosed gender in query result",
|
|
1047
|
+
}
|
|
900
1048
|
}
|
|
901
1049
|
}
|
|
902
1050
|
if (queryResult.issuing_country) {
|
|
@@ -910,7 +1058,11 @@ export class ZKPassport {
|
|
|
910
1058
|
) {
|
|
911
1059
|
console.warn("Issuing country does not match the expected issuing country")
|
|
912
1060
|
isCorrect = false
|
|
913
|
-
|
|
1061
|
+
queryResultErrors.issuing_country.eq = {
|
|
1062
|
+
expected: `${queryResult.issuing_country.eq.expected}`,
|
|
1063
|
+
received: `${issuingCountryPassport ?? issuingCountryIDCard}`,
|
|
1064
|
+
message: "Issuing country does not match the expected issuing country",
|
|
1065
|
+
}
|
|
914
1066
|
}
|
|
915
1067
|
if (
|
|
916
1068
|
queryResult.issuing_country.disclose &&
|
|
@@ -921,7 +1073,12 @@ export class ZKPassport {
|
|
|
921
1073
|
"Issuing country does not match the disclosed issuing country in query result",
|
|
922
1074
|
)
|
|
923
1075
|
isCorrect = false
|
|
924
|
-
|
|
1076
|
+
queryResultErrors.issuing_country.disclose = {
|
|
1077
|
+
expected: `${queryResult.issuing_country.disclose.result}`,
|
|
1078
|
+
received: `${issuingCountryPassport ?? issuingCountryIDCard}`,
|
|
1079
|
+
message:
|
|
1080
|
+
"Issuing country does not match the disclosed issuing country in query result",
|
|
1081
|
+
}
|
|
925
1082
|
}
|
|
926
1083
|
}
|
|
927
1084
|
if (queryResult.fullname) {
|
|
@@ -937,7 +1094,11 @@ export class ZKPassport {
|
|
|
937
1094
|
) {
|
|
938
1095
|
console.warn("Fullname does not match the expected fullname")
|
|
939
1096
|
isCorrect = false
|
|
940
|
-
|
|
1097
|
+
queryResultErrors.fullname.eq = {
|
|
1098
|
+
expected: `${queryResult.fullname.eq.expected}`,
|
|
1099
|
+
received: `${fullnamePassport ?? fullnameIDCard}`,
|
|
1100
|
+
message: "Fullname does not match the expected fullname",
|
|
1101
|
+
}
|
|
941
1102
|
}
|
|
942
1103
|
if (
|
|
943
1104
|
queryResult.fullname.disclose &&
|
|
@@ -948,7 +1109,11 @@ export class ZKPassport {
|
|
|
948
1109
|
) {
|
|
949
1110
|
console.warn("Fullname does not match the disclosed fullname in query result")
|
|
950
1111
|
isCorrect = false
|
|
951
|
-
|
|
1112
|
+
queryResultErrors.fullname.disclose = {
|
|
1113
|
+
expected: `${queryResult.fullname.disclose.result}`,
|
|
1114
|
+
received: `${fullnamePassport ?? fullnameIDCard}`,
|
|
1115
|
+
message: "Fullname does not match the disclosed fullname in query result",
|
|
1116
|
+
}
|
|
952
1117
|
}
|
|
953
1118
|
}
|
|
954
1119
|
if (queryResult.firstname) {
|
|
@@ -971,7 +1136,11 @@ export class ZKPassport {
|
|
|
971
1136
|
) {
|
|
972
1137
|
console.warn("Firstname does not match the expected firstname")
|
|
973
1138
|
isCorrect = false
|
|
974
|
-
|
|
1139
|
+
queryResultErrors.firstname.eq = {
|
|
1140
|
+
expected: `${queryResult.firstname.eq.expected}`,
|
|
1141
|
+
received: `${firstnamePassport ?? firstnameIDCard}`,
|
|
1142
|
+
message: "Firstname does not match the expected firstname",
|
|
1143
|
+
}
|
|
975
1144
|
}
|
|
976
1145
|
if (
|
|
977
1146
|
queryResult.firstname.disclose &&
|
|
@@ -982,7 +1151,11 @@ export class ZKPassport {
|
|
|
982
1151
|
) {
|
|
983
1152
|
console.warn("Firstname does not match the disclosed firstname in query result")
|
|
984
1153
|
isCorrect = false
|
|
985
|
-
|
|
1154
|
+
queryResultErrors.firstname.disclose = {
|
|
1155
|
+
expected: `${queryResult.firstname.disclose.result}`,
|
|
1156
|
+
received: `${firstnamePassport ?? firstnameIDCard}`,
|
|
1157
|
+
message: "Firstname does not match the disclosed firstname in query result",
|
|
1158
|
+
}
|
|
986
1159
|
}
|
|
987
1160
|
}
|
|
988
1161
|
if (queryResult.lastname) {
|
|
@@ -1005,7 +1178,11 @@ export class ZKPassport {
|
|
|
1005
1178
|
) {
|
|
1006
1179
|
console.warn("Lastname does not match the expected lastname")
|
|
1007
1180
|
isCorrect = false
|
|
1008
|
-
|
|
1181
|
+
queryResultErrors.lastname.eq = {
|
|
1182
|
+
expected: `${queryResult.lastname.eq.expected}`,
|
|
1183
|
+
received: `${lastnamePassport ?? lastnameIDCard}`,
|
|
1184
|
+
message: "Lastname does not match the expected lastname",
|
|
1185
|
+
}
|
|
1009
1186
|
}
|
|
1010
1187
|
if (
|
|
1011
1188
|
queryResult.lastname.disclose &&
|
|
@@ -1016,7 +1193,11 @@ export class ZKPassport {
|
|
|
1016
1193
|
) {
|
|
1017
1194
|
console.warn("Lastname does not match the disclosed lastname in query result")
|
|
1018
1195
|
isCorrect = false
|
|
1019
|
-
|
|
1196
|
+
queryResultErrors.lastname.disclose = {
|
|
1197
|
+
expected: `${queryResult.lastname.disclose.result}`,
|
|
1198
|
+
received: `${lastnamePassport ?? lastnameIDCard}`,
|
|
1199
|
+
message: "Lastname does not match the disclosed lastname in query result",
|
|
1200
|
+
}
|
|
1020
1201
|
}
|
|
1021
1202
|
}
|
|
1022
1203
|
uniqueIdentifier = getNullifierFromDisclosureProof(proofData).toString(10)
|
|
@@ -1027,7 +1208,12 @@ export class ZKPassport {
|
|
|
1027
1208
|
"Failed to check the link between the validity of the ID and the age derived from it",
|
|
1028
1209
|
)
|
|
1029
1210
|
isCorrect = false
|
|
1030
|
-
|
|
1211
|
+
queryResultErrors.age.commitment = {
|
|
1212
|
+
expected: `Commitment: ${commitmentOut}`,
|
|
1213
|
+
received: `Commitment: ${commitmentIn}`,
|
|
1214
|
+
message:
|
|
1215
|
+
"Failed to check the link between the validity of the ID and the age derived from it",
|
|
1216
|
+
}
|
|
1031
1217
|
}
|
|
1032
1218
|
const minAge = getMinAgeFromProof(proofData)
|
|
1033
1219
|
const maxAge = getMaxAgeFromProof(proofData)
|
|
@@ -1039,7 +1225,11 @@ export class ZKPassport {
|
|
|
1039
1225
|
) {
|
|
1040
1226
|
console.warn("Age is not greater than or equal to the expected age")
|
|
1041
1227
|
isCorrect = false
|
|
1042
|
-
|
|
1228
|
+
queryResultErrors.age.gte = {
|
|
1229
|
+
expected: queryResult.age.gte.expected,
|
|
1230
|
+
received: minAge,
|
|
1231
|
+
message: "Age is not greater than or equal to the expected age",
|
|
1232
|
+
}
|
|
1043
1233
|
}
|
|
1044
1234
|
if (
|
|
1045
1235
|
queryResult.age.lt &&
|
|
@@ -1048,7 +1238,11 @@ export class ZKPassport {
|
|
|
1048
1238
|
) {
|
|
1049
1239
|
console.warn("Age is not less than the expected age")
|
|
1050
1240
|
isCorrect = false
|
|
1051
|
-
|
|
1241
|
+
queryResultErrors.age.lt = {
|
|
1242
|
+
expected: queryResult.age.lt.expected,
|
|
1243
|
+
received: maxAge,
|
|
1244
|
+
message: "Age is not less than the expected age",
|
|
1245
|
+
}
|
|
1052
1246
|
}
|
|
1053
1247
|
if (queryResult.age.range) {
|
|
1054
1248
|
if (
|
|
@@ -1058,18 +1252,30 @@ export class ZKPassport {
|
|
|
1058
1252
|
) {
|
|
1059
1253
|
console.warn("Age is not in the expected range")
|
|
1060
1254
|
isCorrect = false
|
|
1061
|
-
|
|
1255
|
+
queryResultErrors.age.range = {
|
|
1256
|
+
expected: queryResult.age.range.expected,
|
|
1257
|
+
received: [minAge, maxAge],
|
|
1258
|
+
message: "Age is not in the expected range",
|
|
1259
|
+
}
|
|
1062
1260
|
}
|
|
1063
1261
|
}
|
|
1064
1262
|
if (!queryResult.age.lt && !queryResult.age.range && maxAge != 0) {
|
|
1065
1263
|
console.warn("Maximum age should be equal to 0")
|
|
1066
1264
|
isCorrect = false
|
|
1067
|
-
|
|
1265
|
+
queryResultErrors.age.disclose = {
|
|
1266
|
+
expected: 0,
|
|
1267
|
+
received: maxAge,
|
|
1268
|
+
message: "Maximum age should be equal to 0",
|
|
1269
|
+
}
|
|
1068
1270
|
}
|
|
1069
1271
|
if (!queryResult.age.gte && !queryResult.age.range && minAge != 0) {
|
|
1070
1272
|
console.warn("Minimum age should be equal to 0")
|
|
1071
1273
|
isCorrect = false
|
|
1072
|
-
|
|
1274
|
+
queryResultErrors.age.disclose = {
|
|
1275
|
+
expected: 0,
|
|
1276
|
+
received: minAge,
|
|
1277
|
+
message: "Minimum age should be equal to 0",
|
|
1278
|
+
}
|
|
1073
1279
|
}
|
|
1074
1280
|
if (
|
|
1075
1281
|
queryResult.age.disclose &&
|
|
@@ -1078,12 +1284,18 @@ export class ZKPassport {
|
|
|
1078
1284
|
) {
|
|
1079
1285
|
console.warn("Age does not match the disclosed age in query result")
|
|
1080
1286
|
isCorrect = false
|
|
1081
|
-
|
|
1287
|
+
queryResultErrors.age.disclose = {
|
|
1288
|
+
expected: `${minAge}`,
|
|
1289
|
+
received: `${queryResult.age.disclose.result}`,
|
|
1290
|
+
message: "Age does not match the disclosed age in query result",
|
|
1291
|
+
}
|
|
1082
1292
|
}
|
|
1083
1293
|
} else {
|
|
1084
1294
|
console.warn("Age is not set in the query result")
|
|
1085
1295
|
isCorrect = false
|
|
1086
|
-
|
|
1296
|
+
queryResultErrors.age.disclose = {
|
|
1297
|
+
message: "Age is not set in the query result",
|
|
1298
|
+
}
|
|
1087
1299
|
}
|
|
1088
1300
|
const currentDate = getCurrentDateFromAgeProof(proofData)
|
|
1089
1301
|
if (
|
|
@@ -1092,7 +1304,11 @@ export class ZKPassport {
|
|
|
1092
1304
|
) {
|
|
1093
1305
|
console.warn("Current date in the proof is too old")
|
|
1094
1306
|
isCorrect = false
|
|
1095
|
-
|
|
1307
|
+
queryResultErrors.age.disclose = {
|
|
1308
|
+
expected: `${today.toISOString()}`,
|
|
1309
|
+
received: `${currentDate.toISOString()}`,
|
|
1310
|
+
message: "Current date in the proof is too old",
|
|
1311
|
+
}
|
|
1096
1312
|
}
|
|
1097
1313
|
uniqueIdentifier = getCommitmentInFromDisclosureProof(proofData).toString(10)
|
|
1098
1314
|
} else if (proof.name === "compare_birthdate") {
|
|
@@ -1102,7 +1318,12 @@ export class ZKPassport {
|
|
|
1102
1318
|
"Failed to check the link between the validity of the ID and the birthdate derived from it",
|
|
1103
1319
|
)
|
|
1104
1320
|
isCorrect = false
|
|
1105
|
-
|
|
1321
|
+
queryResultErrors.birthdate.commitment = {
|
|
1322
|
+
expected: `Commitment: ${commitmentOut}`,
|
|
1323
|
+
received: `Commitment: ${commitmentIn}`,
|
|
1324
|
+
message:
|
|
1325
|
+
"Failed to check the link between the validity of the ID and the birthdate derived from it",
|
|
1326
|
+
}
|
|
1106
1327
|
}
|
|
1107
1328
|
const minDate = getMinDateFromProof(proofData)
|
|
1108
1329
|
const maxDate = getMaxDateFromProof(proofData)
|
|
@@ -1114,7 +1335,11 @@ export class ZKPassport {
|
|
|
1114
1335
|
) {
|
|
1115
1336
|
console.warn("Birthdate is not greater than or equal to the expected birthdate")
|
|
1116
1337
|
isCorrect = false
|
|
1117
|
-
|
|
1338
|
+
queryResultErrors.birthdate.gte = {
|
|
1339
|
+
expected: queryResult.birthdate.gte.expected,
|
|
1340
|
+
received: minDate,
|
|
1341
|
+
message: "Birthdate is not greater than or equal to the expected birthdate",
|
|
1342
|
+
}
|
|
1118
1343
|
}
|
|
1119
1344
|
if (
|
|
1120
1345
|
queryResult.birthdate.lte &&
|
|
@@ -1123,7 +1348,11 @@ export class ZKPassport {
|
|
|
1123
1348
|
) {
|
|
1124
1349
|
console.warn("Birthdate is not less than the expected birthdate")
|
|
1125
1350
|
isCorrect = false
|
|
1126
|
-
|
|
1351
|
+
queryResultErrors.birthdate.lte = {
|
|
1352
|
+
expected: queryResult.birthdate.lte.expected,
|
|
1353
|
+
received: maxDate,
|
|
1354
|
+
message: "Birthdate is not less than the expected birthdate",
|
|
1355
|
+
}
|
|
1127
1356
|
}
|
|
1128
1357
|
if (queryResult.birthdate.range) {
|
|
1129
1358
|
if (
|
|
@@ -1133,7 +1362,11 @@ export class ZKPassport {
|
|
|
1133
1362
|
) {
|
|
1134
1363
|
console.warn("Birthdate is not in the expected range")
|
|
1135
1364
|
isCorrect = false
|
|
1136
|
-
|
|
1365
|
+
queryResultErrors.birthdate.range = {
|
|
1366
|
+
expected: queryResult.birthdate.range.expected,
|
|
1367
|
+
received: [minDate, maxDate],
|
|
1368
|
+
message: "Birthdate is not in the expected range",
|
|
1369
|
+
}
|
|
1137
1370
|
}
|
|
1138
1371
|
}
|
|
1139
1372
|
if (
|
|
@@ -1143,7 +1376,11 @@ export class ZKPassport {
|
|
|
1143
1376
|
) {
|
|
1144
1377
|
console.warn("Maximum birthdate should be equal to default date value")
|
|
1145
1378
|
isCorrect = false
|
|
1146
|
-
|
|
1379
|
+
queryResultErrors.birthdate.disclose = {
|
|
1380
|
+
expected: `${defaultDateValue.toISOString()}`,
|
|
1381
|
+
received: `${maxDate.toISOString()}`,
|
|
1382
|
+
message: "Maximum birthdate should be equal to default date value",
|
|
1383
|
+
}
|
|
1147
1384
|
}
|
|
1148
1385
|
if (
|
|
1149
1386
|
!queryResult.birthdate.gte &&
|
|
@@ -1152,12 +1389,18 @@ export class ZKPassport {
|
|
|
1152
1389
|
) {
|
|
1153
1390
|
console.warn("Minimum birthdate should be equal to default date value")
|
|
1154
1391
|
isCorrect = false
|
|
1155
|
-
|
|
1392
|
+
queryResultErrors.birthdate.disclose = {
|
|
1393
|
+
expected: `${defaultDateValue.toISOString()}`,
|
|
1394
|
+
received: `${minDate.toISOString()}`,
|
|
1395
|
+
message: "Minimum birthdate should be equal to default date value",
|
|
1396
|
+
}
|
|
1156
1397
|
}
|
|
1157
1398
|
} else {
|
|
1158
1399
|
console.warn("Birthdate is not set in the query result")
|
|
1159
1400
|
isCorrect = false
|
|
1160
|
-
|
|
1401
|
+
queryResultErrors.birthdate.disclose = {
|
|
1402
|
+
message: "Birthdate is not set in the query result",
|
|
1403
|
+
}
|
|
1161
1404
|
}
|
|
1162
1405
|
uniqueIdentifier = getCommitmentInFromDisclosureProof(proofData).toString(10)
|
|
1163
1406
|
} else if (proof.name === "compare_expiry") {
|
|
@@ -1167,7 +1410,11 @@ export class ZKPassport {
|
|
|
1167
1410
|
"Failed to check the link between the validity of the ID and its expiry date",
|
|
1168
1411
|
)
|
|
1169
1412
|
isCorrect = false
|
|
1170
|
-
|
|
1413
|
+
queryResultErrors.expiry_date.commitment = {
|
|
1414
|
+
expected: `Commitment: ${commitmentOut}`,
|
|
1415
|
+
received: `Commitment: ${commitmentIn}`,
|
|
1416
|
+
message: "Failed to check the link between the validity of the ID and its expiry date",
|
|
1417
|
+
}
|
|
1171
1418
|
}
|
|
1172
1419
|
const minDate = getMinDateFromProof(proofData)
|
|
1173
1420
|
const maxDate = getMaxDateFromProof(proofData)
|
|
@@ -1179,7 +1426,11 @@ export class ZKPassport {
|
|
|
1179
1426
|
) {
|
|
1180
1427
|
console.warn("Expiry date is not greater than or equal to the expected expiry date")
|
|
1181
1428
|
isCorrect = false
|
|
1182
|
-
|
|
1429
|
+
queryResultErrors.expiry_date.gte = {
|
|
1430
|
+
expected: queryResult.expiry_date.gte.expected,
|
|
1431
|
+
received: minDate,
|
|
1432
|
+
message: "Expiry date is not greater than or equal to the expected expiry date",
|
|
1433
|
+
}
|
|
1183
1434
|
}
|
|
1184
1435
|
if (
|
|
1185
1436
|
queryResult.expiry_date.lte &&
|
|
@@ -1188,7 +1439,11 @@ export class ZKPassport {
|
|
|
1188
1439
|
) {
|
|
1189
1440
|
console.warn("Expiry date is not less than the expected expiry date")
|
|
1190
1441
|
isCorrect = false
|
|
1191
|
-
|
|
1442
|
+
queryResultErrors.expiry_date.lte = {
|
|
1443
|
+
expected: queryResult.expiry_date.lte.expected,
|
|
1444
|
+
received: maxDate,
|
|
1445
|
+
message: "Expiry date is not less than the expected expiry date",
|
|
1446
|
+
}
|
|
1192
1447
|
}
|
|
1193
1448
|
if (queryResult.expiry_date.range) {
|
|
1194
1449
|
if (
|
|
@@ -1198,7 +1453,11 @@ export class ZKPassport {
|
|
|
1198
1453
|
) {
|
|
1199
1454
|
console.warn("Expiry date is not in the expected range")
|
|
1200
1455
|
isCorrect = false
|
|
1201
|
-
|
|
1456
|
+
queryResultErrors.expiry_date.range = {
|
|
1457
|
+
expected: queryResult.expiry_date.range.expected,
|
|
1458
|
+
received: [minDate, maxDate],
|
|
1459
|
+
message: "Expiry date is not in the expected range",
|
|
1460
|
+
}
|
|
1202
1461
|
}
|
|
1203
1462
|
}
|
|
1204
1463
|
if (
|
|
@@ -1208,7 +1467,11 @@ export class ZKPassport {
|
|
|
1208
1467
|
) {
|
|
1209
1468
|
console.warn("Maximum expiry date should be equal to default date value")
|
|
1210
1469
|
isCorrect = false
|
|
1211
|
-
|
|
1470
|
+
queryResultErrors.expiry_date.disclose = {
|
|
1471
|
+
expected: `${defaultDateValue.toISOString()}`,
|
|
1472
|
+
received: `${maxDate.toISOString()}`,
|
|
1473
|
+
message: "Maximum expiry date should be equal to default date value",
|
|
1474
|
+
}
|
|
1212
1475
|
}
|
|
1213
1476
|
if (
|
|
1214
1477
|
!queryResult.expiry_date.gte &&
|
|
@@ -1217,22 +1480,33 @@ export class ZKPassport {
|
|
|
1217
1480
|
) {
|
|
1218
1481
|
console.warn("Minimum expiry date should be equal to default date value")
|
|
1219
1482
|
isCorrect = false
|
|
1220
|
-
|
|
1483
|
+
queryResultErrors.expiry_date.disclose = {
|
|
1484
|
+
expected: `${defaultDateValue.toISOString()}`,
|
|
1485
|
+
received: `${minDate.toISOString()}`,
|
|
1486
|
+
message: "Minimum expiry date should be equal to default date value",
|
|
1487
|
+
}
|
|
1221
1488
|
}
|
|
1222
1489
|
} else {
|
|
1223
1490
|
console.warn("Expiry date is not set in the query result")
|
|
1224
1491
|
isCorrect = false
|
|
1225
|
-
|
|
1492
|
+
queryResultErrors.expiry_date.disclose = {
|
|
1493
|
+
message: "Expiry date is not set in the query result",
|
|
1494
|
+
}
|
|
1226
1495
|
}
|
|
1227
1496
|
uniqueIdentifier = getNullifierFromDisclosureProof(proofData).toString(10)
|
|
1228
|
-
} else if (proof.name === "
|
|
1497
|
+
} else if (proof.name === "exclusion_check_nationality") {
|
|
1229
1498
|
commitmentIn = getCommitmentInFromDisclosureProof(proofData)
|
|
1230
1499
|
if (commitmentIn !== commitmentOut) {
|
|
1231
1500
|
console.warn(
|
|
1232
|
-
"Failed to check the link between the validity of the ID and the
|
|
1501
|
+
"Failed to check the link between the validity of the ID and the nationality exclusion check",
|
|
1233
1502
|
)
|
|
1234
1503
|
isCorrect = false
|
|
1235
|
-
|
|
1504
|
+
queryResultErrors.nationality.commitment = {
|
|
1505
|
+
expected: `Commitment: ${commitmentOut}`,
|
|
1506
|
+
received: `Commitment: ${commitmentIn}`,
|
|
1507
|
+
message:
|
|
1508
|
+
"Failed to check the link between the validity of the ID and the nationality exclusion check",
|
|
1509
|
+
}
|
|
1236
1510
|
}
|
|
1237
1511
|
const countryList = getCountryListFromExclusionProof(proofData)
|
|
1238
1512
|
if (
|
|
@@ -1243,14 +1517,20 @@ export class ZKPassport {
|
|
|
1243
1517
|
if (
|
|
1244
1518
|
!queryResult.nationality.out.expected?.every((country) => countryList.includes(country))
|
|
1245
1519
|
) {
|
|
1246
|
-
console.warn("
|
|
1520
|
+
console.warn("Nationality exclusion list does not match the one from the query results")
|
|
1247
1521
|
isCorrect = false
|
|
1248
|
-
|
|
1522
|
+
queryResultErrors.nationality.out = {
|
|
1523
|
+
expected: queryResult.nationality.out.expected,
|
|
1524
|
+
received: countryList,
|
|
1525
|
+
message: "Nationality exclusion list does not match the one from the query results",
|
|
1526
|
+
}
|
|
1249
1527
|
}
|
|
1250
1528
|
} else if (!queryResult.nationality || !queryResult.nationality.out) {
|
|
1251
1529
|
console.warn("Nationality exclusion is not set in the query result")
|
|
1252
1530
|
isCorrect = false
|
|
1253
|
-
|
|
1531
|
+
queryResultErrors.nationality.out = {
|
|
1532
|
+
message: "Nationality exclusion is not set in the query result",
|
|
1533
|
+
}
|
|
1254
1534
|
}
|
|
1255
1535
|
// Check the countryList is in ascending order
|
|
1256
1536
|
// If the prover doesn't use a sorted list then the proof cannot be trusted
|
|
@@ -1261,18 +1541,85 @@ export class ZKPassport {
|
|
|
1261
1541
|
"The nationality exclusion list has not been sorted, and thus the proof cannot be trusted",
|
|
1262
1542
|
)
|
|
1263
1543
|
isCorrect = false
|
|
1264
|
-
|
|
1544
|
+
queryResultErrors.nationality.out = {
|
|
1545
|
+
message:
|
|
1546
|
+
"The nationality exclusion list has not been sorted, and thus the proof cannot be trusted",
|
|
1547
|
+
}
|
|
1265
1548
|
}
|
|
1266
1549
|
}
|
|
1267
1550
|
uniqueIdentifier = getNullifierFromDisclosureProof(proofData).toString(10)
|
|
1268
|
-
} else if (proof.name === "
|
|
1551
|
+
} else if (proof.name === "exclusion_check_issuing_country") {
|
|
1269
1552
|
commitmentIn = getCommitmentInFromDisclosureProof(proofData)
|
|
1270
1553
|
if (commitmentIn !== commitmentOut) {
|
|
1271
1554
|
console.warn(
|
|
1272
|
-
"Failed to check the link between the validity of the ID and the country
|
|
1555
|
+
"Failed to check the link between the validity of the ID and the issuing country exclusion check",
|
|
1273
1556
|
)
|
|
1274
1557
|
isCorrect = false
|
|
1275
|
-
|
|
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") {
|
|
1611
|
+
commitmentIn = getCommitmentInFromDisclosureProof(proofData)
|
|
1612
|
+
if (commitmentIn !== commitmentOut) {
|
|
1613
|
+
console.warn(
|
|
1614
|
+
"Failed to check the link between the validity of the ID and the nationality inclusion check",
|
|
1615
|
+
)
|
|
1616
|
+
isCorrect = false
|
|
1617
|
+
queryResultErrors.nationality.commitment = {
|
|
1618
|
+
expected: `Commitment: ${commitmentOut}`,
|
|
1619
|
+
received: `Commitment: ${commitmentIn}`,
|
|
1620
|
+
message:
|
|
1621
|
+
"Failed to check the link between the validity of the ID and the nationality inclusion check",
|
|
1622
|
+
}
|
|
1276
1623
|
}
|
|
1277
1624
|
const countryList = getCountryListFromInclusionProof(proofData)
|
|
1278
1625
|
if (
|
|
@@ -1283,19 +1630,69 @@ export class ZKPassport {
|
|
|
1283
1630
|
if (
|
|
1284
1631
|
!queryResult.nationality.in.expected?.every((country) => countryList.includes(country))
|
|
1285
1632
|
) {
|
|
1286
|
-
console.warn("
|
|
1633
|
+
console.warn("Nationality inclusion list does not match the one from the query results")
|
|
1287
1634
|
isCorrect = false
|
|
1288
|
-
|
|
1635
|
+
queryResultErrors.nationality.in = {
|
|
1636
|
+
expected: queryResult.nationality.in.expected,
|
|
1637
|
+
received: countryList,
|
|
1638
|
+
message: "Nationality inclusion list does not match the one from the query results",
|
|
1639
|
+
}
|
|
1289
1640
|
}
|
|
1290
1641
|
} else if (!queryResult.nationality || !queryResult.nationality.in) {
|
|
1291
1642
|
console.warn("Nationality inclusion is not set in the query result")
|
|
1292
1643
|
isCorrect = false
|
|
1293
|
-
|
|
1644
|
+
queryResultErrors.nationality.in = {
|
|
1645
|
+
message: "Nationality inclusion is not set in the query result",
|
|
1646
|
+
}
|
|
1647
|
+
}
|
|
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
|
+
}
|
|
1294
1691
|
}
|
|
1295
1692
|
uniqueIdentifier = getNullifierFromDisclosureProof(proofData).toString(10)
|
|
1296
1693
|
}
|
|
1297
1694
|
}
|
|
1298
|
-
return { isCorrect, uniqueIdentifier }
|
|
1695
|
+
return { isCorrect, uniqueIdentifier, queryResultErrors }
|
|
1299
1696
|
}
|
|
1300
1697
|
|
|
1301
1698
|
/**
|
|
@@ -1310,17 +1707,15 @@ export class ZKPassport {
|
|
|
1310
1707
|
requestId: string,
|
|
1311
1708
|
proofs?: Array<ProofResult>,
|
|
1312
1709
|
queryResult?: QueryResult,
|
|
1313
|
-
): Promise<{
|
|
1710
|
+
): Promise<{
|
|
1711
|
+
uniqueIdentifier: string | undefined
|
|
1712
|
+
verified: boolean
|
|
1713
|
+
queryResultErrors?: QueryResultErrors
|
|
1714
|
+
}> {
|
|
1314
1715
|
let proofsToVerify = proofs
|
|
1315
1716
|
// There is a minimum of 4 subproofs to make a complete proof
|
|
1316
1717
|
if (!proofs || proofs.length < 4) {
|
|
1317
1718
|
proofsToVerify = this.topicToProofs[requestId]
|
|
1318
|
-
if (!proofsToVerify || proofsToVerify.length < 4) {
|
|
1319
|
-
// It may happen that a request returns a result without proofs
|
|
1320
|
-
// Meaning the ID is not supported yet by ZKPassport circuits,
|
|
1321
|
-
// so the results has to be trusted and cannot be independently verified
|
|
1322
|
-
return { uniqueIdentifier: undefined, verified: false }
|
|
1323
|
-
}
|
|
1324
1719
|
}
|
|
1325
1720
|
const { BarretenbergVerifier } = await import("@aztec/bb.js")
|
|
1326
1721
|
const verifier = new BarretenbergVerifier()
|
|
@@ -1329,14 +1724,19 @@ export class ZKPassport {
|
|
|
1329
1724
|
}*/
|
|
1330
1725
|
let verified = true
|
|
1331
1726
|
let uniqueIdentifier: string | undefined
|
|
1727
|
+
let queryResultErrors: QueryResultErrors | undefined
|
|
1332
1728
|
if (queryResult) {
|
|
1333
|
-
const {
|
|
1334
|
-
|
|
1729
|
+
const {
|
|
1730
|
+
isCorrect,
|
|
1731
|
+
uniqueIdentifier: uniqueIdentifierFromPublicInputs,
|
|
1732
|
+
queryResultErrors: queryResultErrorsFromPublicInputs,
|
|
1733
|
+
} = await this.checkPublicInputs(proofsToVerify!, queryResult!, requestId)
|
|
1335
1734
|
uniqueIdentifier = uniqueIdentifierFromPublicInputs
|
|
1336
1735
|
verified = isCorrect
|
|
1736
|
+
queryResultErrors = isCorrect ? undefined : queryResultErrorsFromPublicInputs
|
|
1337
1737
|
}
|
|
1338
1738
|
// Only proceed with the proof verification if the public inputs are correct
|
|
1339
|
-
if (verified) {
|
|
1739
|
+
if (verified && queryResult) {
|
|
1340
1740
|
for (const proof of proofsToVerify!) {
|
|
1341
1741
|
const proofData = getProofData(proof.proof as string, true)
|
|
1342
1742
|
const hostedPackagedCircuit = await getHostedPackagedCircuitByName(
|
|
@@ -1358,7 +1758,7 @@ export class ZKPassport {
|
|
|
1358
1758
|
}
|
|
1359
1759
|
}
|
|
1360
1760
|
this.topicToProofs[requestId] = []
|
|
1361
|
-
return { uniqueIdentifier, verified }
|
|
1761
|
+
return { uniqueIdentifier, verified, queryResultErrors }
|
|
1362
1762
|
}
|
|
1363
1763
|
|
|
1364
1764
|
/**
|
|
@@ -1382,14 +1782,17 @@ export class ZKPassport {
|
|
|
1382
1782
|
* @param requestId The request ID.
|
|
1383
1783
|
*/
|
|
1384
1784
|
public cancelRequest(requestId: string) {
|
|
1385
|
-
this.topicToWebSocketClient[requestId]
|
|
1386
|
-
|
|
1785
|
+
if (this.topicToWebSocketClient[requestId]) {
|
|
1786
|
+
this.topicToWebSocketClient[requestId].close()
|
|
1787
|
+
delete this.topicToWebSocketClient[requestId]
|
|
1788
|
+
}
|
|
1387
1789
|
delete this.topicToKeyPair[requestId]
|
|
1388
1790
|
delete this.topicToConfig[requestId]
|
|
1389
1791
|
delete this.topicToLocalConfig[requestId]
|
|
1390
1792
|
delete this.topicToSharedSecret[requestId]
|
|
1391
1793
|
delete this.topicToProofs[requestId]
|
|
1392
1794
|
delete this.topicToExpectedProofCount[requestId]
|
|
1795
|
+
delete this.topicToFailedProofCount[requestId]
|
|
1393
1796
|
delete this.topicToResults[requestId]
|
|
1394
1797
|
this.onRequestReceivedCallbacks[requestId] = []
|
|
1395
1798
|
this.onGeneratingProofCallbacks[requestId] = []
|
|
@@ -1398,4 +1801,13 @@ export class ZKPassport {
|
|
|
1398
1801
|
this.onRejectCallbacks[requestId] = []
|
|
1399
1802
|
this.onErrorCallbacks[requestId] = []
|
|
1400
1803
|
}
|
|
1804
|
+
|
|
1805
|
+
/**
|
|
1806
|
+
* @notice Clears all requests.
|
|
1807
|
+
*/
|
|
1808
|
+
public clearAllRequests() {
|
|
1809
|
+
for (const requestId in this.topicToWebSocketClient) {
|
|
1810
|
+
this.cancelRequest(requestId)
|
|
1811
|
+
}
|
|
1812
|
+
}
|
|
1401
1813
|
}
|