@zkpassport/sdk 0.2.10 → 0.2.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/index.d.ts +6 -2
- package/dist/cjs/index.js +39 -34
- package/dist/esm/index.d.ts +6 -2
- package/dist/esm/index.js +39 -34
- package/package.json +2 -2
- package/src/index.ts +60 -47
package/dist/cjs/index.d.ts
CHANGED
|
@@ -200,13 +200,17 @@ export declare class ZKPassport {
|
|
|
200
200
|
private checkPublicInputs;
|
|
201
201
|
/**
|
|
202
202
|
* @notice Verify the proofs received from the mobile app.
|
|
203
|
-
* @param requestId The request ID.
|
|
204
203
|
* @param proofs The proofs to verify.
|
|
205
204
|
* @param queryResult The query result to verify against
|
|
205
|
+
* @param validity How many days ago should have the ID been last scanned by the user?
|
|
206
206
|
* @returns An object containing the unique identifier associated to the user
|
|
207
207
|
* and a boolean indicating whether the proofs were successfully verified.
|
|
208
208
|
*/
|
|
209
|
-
verify(
|
|
209
|
+
verify({ proofs, queryResult, validity, }: {
|
|
210
|
+
proofs: Array<ProofResult>;
|
|
211
|
+
queryResult: QueryResult;
|
|
212
|
+
validity?: number;
|
|
213
|
+
}): Promise<{
|
|
210
214
|
uniqueIdentifier: string | undefined;
|
|
211
215
|
verified: boolean;
|
|
212
216
|
queryResultErrors?: QueryResultErrors;
|
package/dist/cjs/index.js
CHANGED
|
@@ -11,8 +11,6 @@ const json_rpc_1 = require("./json-rpc");
|
|
|
11
11
|
const encryption_1 = require("./encryption");
|
|
12
12
|
const logger_1 = require("./logger");
|
|
13
13
|
const pako_1 = require("pako");
|
|
14
|
-
//import initNoirC from '@noir-lang/noirc_abi'
|
|
15
|
-
//import initACVM from '@noir-lang/acvm_js'
|
|
16
14
|
const en_json_1 = tslib_1.__importDefault(require("i18n-iso-countries/langs/en.json"));
|
|
17
15
|
const buffer_1 = require("buffer/");
|
|
18
16
|
// If Buffer is not defined, then we use the Buffer from the buffer package
|
|
@@ -94,18 +92,17 @@ class ZKPassport {
|
|
|
94
92
|
}
|
|
95
93
|
this.domain = _domain || window.location.hostname;
|
|
96
94
|
}
|
|
97
|
-
/*private async initWasmVerifier() {
|
|
98
|
-
const acvm = await import('@noir-lang/acvm_js/web/acvm_js_bg.wasm')
|
|
99
|
-
const noirc = await import('@noir-lang/noirc_abi/web/noirc_abi_wasm_bg.wasm')
|
|
100
|
-
await Promise.all([initACVM(acvm), initNoirC(noirc)])
|
|
101
|
-
this.wasmVerifierInit = true
|
|
102
|
-
}*/
|
|
103
95
|
async handleResult(topic) {
|
|
104
96
|
const result = this.topicToResults[topic];
|
|
105
97
|
// Clear the results straight away to avoid concurrency issues
|
|
106
98
|
delete this.topicToResults[topic];
|
|
107
99
|
// Verify the proofs and extract the unique identifier (aka nullifier) and the verification result
|
|
108
|
-
const { uniqueIdentifier, verified, queryResultErrors } = await this.verify(
|
|
100
|
+
const { uniqueIdentifier, verified, queryResultErrors } = await this.verify({
|
|
101
|
+
proofs: this.topicToProofs[topic],
|
|
102
|
+
queryResult: result,
|
|
103
|
+
validity: this.topicToLocalConfig[topic]?.validity,
|
|
104
|
+
});
|
|
105
|
+
delete this.topicToProofs[topic];
|
|
109
106
|
const hasFailedProofs = this.topicToFailedProofCount[topic] > 0;
|
|
110
107
|
await Promise.all(this.onResultCallbacks[topic].map((callback) => callback({
|
|
111
108
|
// If there are failed proofs, we don't return the unique identifier
|
|
@@ -221,7 +218,15 @@ class ZKPassport {
|
|
|
221
218
|
}
|
|
222
219
|
else if (request.method === "done") {
|
|
223
220
|
logger_1.noLogger.debug(`User sent the query result`);
|
|
224
|
-
|
|
221
|
+
const formattedResult = request.params;
|
|
222
|
+
// Make sure to reconvert the dates to Date objects
|
|
223
|
+
if (formattedResult.birthdate && formattedResult.birthdate.disclose) {
|
|
224
|
+
formattedResult.birthdate.disclose.result = new Date(formattedResult.birthdate.disclose.result);
|
|
225
|
+
}
|
|
226
|
+
if (formattedResult.expiry_date && formattedResult.expiry_date.disclose) {
|
|
227
|
+
formattedResult.expiry_date.disclose.result = new Date(formattedResult.expiry_date.disclose.result);
|
|
228
|
+
}
|
|
229
|
+
this.topicToResults[topic] = formattedResult;
|
|
225
230
|
// Make sure all the proofs have been received, otherwise we'll handle the result later
|
|
226
231
|
// once the proofs have all been received
|
|
227
232
|
if (this.topicToExpectedProofCount[topic] === this.topicToProofs[topic].length) {
|
|
@@ -401,7 +406,7 @@ class ZKPassport {
|
|
|
401
406
|
};
|
|
402
407
|
return this.getZkPassportRequest(topic);
|
|
403
408
|
}
|
|
404
|
-
async checkPublicInputs(proofs, queryResult,
|
|
409
|
+
async checkPublicInputs(proofs, queryResult, validity) {
|
|
405
410
|
let commitmentIn;
|
|
406
411
|
let commitmentOut;
|
|
407
412
|
let isCorrect = true;
|
|
@@ -491,14 +496,15 @@ class ZKPassport {
|
|
|
491
496
|
commitmentOut = (0, utils_1.getCommitmentOutFromIntegrityProof)(proofData);
|
|
492
497
|
const currentDate = (0, utils_1.getCurrentDateFromIntegrityProof)(proofData);
|
|
493
498
|
const todayToCurrentDate = today.getTime() - currentDate.getTime();
|
|
494
|
-
const
|
|
499
|
+
const differenceInDays = validity ?? 180;
|
|
500
|
+
const expectedDifference = differenceInDays * 86400000;
|
|
495
501
|
const actualDifference = today.getTime() - (today.getTime() - expectedDifference);
|
|
496
502
|
// The ID should not expire within the next 6 months (or whatever the custom value is)
|
|
497
503
|
if (todayToCurrentDate >= actualDifference) {
|
|
498
|
-
console.warn(`The date used to check the validity of the ID is older than ${
|
|
504
|
+
console.warn(`The date used to check the validity of the ID is older than ${differenceInDays} days. You can ask the user to rescan their ID or ask them to disclose their expiry date`);
|
|
499
505
|
isCorrect = false;
|
|
500
506
|
queryResultErrors.data_check_integrity.date = {
|
|
501
|
-
expected: `Difference: ${
|
|
507
|
+
expected: `Difference: ${differenceInDays} days`,
|
|
502
508
|
received: `Difference: ${Math.round(todayToCurrentDate / 86400000)} days`,
|
|
503
509
|
message: "The date used to check the validity of the ID is older than the validity period",
|
|
504
510
|
};
|
|
@@ -906,7 +912,7 @@ class ZKPassport {
|
|
|
906
912
|
message: "Current date in the proof is too old",
|
|
907
913
|
};
|
|
908
914
|
}
|
|
909
|
-
uniqueIdentifier = (0, utils_1.
|
|
915
|
+
uniqueIdentifier = (0, utils_1.getNullifierFromDisclosureProof)(proofData).toString(10);
|
|
910
916
|
}
|
|
911
917
|
else if (proof.name === "compare_birthdate") {
|
|
912
918
|
commitmentIn = (0, utils_1.getCommitmentInFromDisclosureProof)(proofData);
|
|
@@ -987,7 +993,7 @@ class ZKPassport {
|
|
|
987
993
|
message: "Birthdate is not set in the query result",
|
|
988
994
|
};
|
|
989
995
|
}
|
|
990
|
-
uniqueIdentifier = (0, utils_1.
|
|
996
|
+
uniqueIdentifier = (0, utils_1.getNullifierFromDisclosureProof)(proofData).toString(10);
|
|
991
997
|
}
|
|
992
998
|
else if (proof.name === "compare_expiry") {
|
|
993
999
|
commitmentIn = (0, utils_1.getCommitmentInFromDisclosureProof)(proofData);
|
|
@@ -1235,35 +1241,33 @@ class ZKPassport {
|
|
|
1235
1241
|
}
|
|
1236
1242
|
/**
|
|
1237
1243
|
* @notice Verify the proofs received from the mobile app.
|
|
1238
|
-
* @param requestId The request ID.
|
|
1239
1244
|
* @param proofs The proofs to verify.
|
|
1240
1245
|
* @param queryResult The query result to verify against
|
|
1246
|
+
* @param validity How many days ago should have the ID been last scanned by the user?
|
|
1241
1247
|
* @returns An object containing the unique identifier associated to the user
|
|
1242
1248
|
* and a boolean indicating whether the proofs were successfully verified.
|
|
1243
1249
|
*/
|
|
1244
|
-
async verify(
|
|
1245
|
-
|
|
1246
|
-
//
|
|
1247
|
-
if (
|
|
1248
|
-
|
|
1250
|
+
async verify({ proofs, queryResult, validity, }) {
|
|
1251
|
+
const formattedResult = queryResult;
|
|
1252
|
+
// Make sure to reconvert the dates to Date objects
|
|
1253
|
+
if (formattedResult.birthdate && formattedResult.birthdate.disclose) {
|
|
1254
|
+
formattedResult.birthdate.disclose.result = new Date(formattedResult.birthdate.disclose.result);
|
|
1255
|
+
}
|
|
1256
|
+
if (formattedResult.expiry_date && formattedResult.expiry_date.disclose) {
|
|
1257
|
+
formattedResult.expiry_date.disclose.result = new Date(formattedResult.expiry_date.disclose.result);
|
|
1249
1258
|
}
|
|
1250
1259
|
const { BarretenbergVerifier } = await Promise.resolve().then(() => tslib_1.__importStar(require("@aztec/bb.js")));
|
|
1251
1260
|
const verifier = new BarretenbergVerifier();
|
|
1252
|
-
/*if (!this.wasmVerifierInit) {
|
|
1253
|
-
await this.initWasmVerifier()
|
|
1254
|
-
}*/
|
|
1255
1261
|
let verified = true;
|
|
1256
1262
|
let uniqueIdentifier;
|
|
1257
1263
|
let queryResultErrors;
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
queryResultErrors = isCorrect ? undefined : queryResultErrorsFromPublicInputs;
|
|
1263
|
-
}
|
|
1264
|
+
const { isCorrect, uniqueIdentifier: uniqueIdentifierFromPublicInputs, queryResultErrors: queryResultErrorsFromPublicInputs, } = await this.checkPublicInputs(proofs, formattedResult, validity);
|
|
1265
|
+
uniqueIdentifier = uniqueIdentifierFromPublicInputs;
|
|
1266
|
+
verified = isCorrect;
|
|
1267
|
+
queryResultErrors = isCorrect ? undefined : queryResultErrorsFromPublicInputs;
|
|
1264
1268
|
// Only proceed with the proof verification if the public inputs are correct
|
|
1265
|
-
if (verified
|
|
1266
|
-
for (const proof of
|
|
1269
|
+
if (verified) {
|
|
1270
|
+
for (const proof of proofs) {
|
|
1267
1271
|
const proofData = (0, utils_1.getProofData)(proof.proof, true);
|
|
1268
1272
|
const hostedPackagedCircuit = await (0, utils_1.getHostedPackagedCircuitByName)(proof.version, proof.name);
|
|
1269
1273
|
const vkeyBytes = buffer_1.Buffer.from(hostedPackagedCircuit.vkey, "base64");
|
|
@@ -1281,7 +1285,8 @@ class ZKPassport {
|
|
|
1281
1285
|
}
|
|
1282
1286
|
}
|
|
1283
1287
|
}
|
|
1284
|
-
|
|
1288
|
+
// If the proofs are not verified, we don't return the unique identifier
|
|
1289
|
+
uniqueIdentifier = verified ? uniqueIdentifier : undefined;
|
|
1285
1290
|
return { uniqueIdentifier, verified, queryResultErrors };
|
|
1286
1291
|
}
|
|
1287
1292
|
/**
|
package/dist/esm/index.d.ts
CHANGED
|
@@ -200,13 +200,17 @@ export declare class ZKPassport {
|
|
|
200
200
|
private checkPublicInputs;
|
|
201
201
|
/**
|
|
202
202
|
* @notice Verify the proofs received from the mobile app.
|
|
203
|
-
* @param requestId The request ID.
|
|
204
203
|
* @param proofs The proofs to verify.
|
|
205
204
|
* @param queryResult The query result to verify against
|
|
205
|
+
* @param validity How many days ago should have the ID been last scanned by the user?
|
|
206
206
|
* @returns An object containing the unique identifier associated to the user
|
|
207
207
|
* and a boolean indicating whether the proofs were successfully verified.
|
|
208
208
|
*/
|
|
209
|
-
verify(
|
|
209
|
+
verify({ proofs, queryResult, validity, }: {
|
|
210
|
+
proofs: Array<ProofResult>;
|
|
211
|
+
queryResult: QueryResult;
|
|
212
|
+
validity?: number;
|
|
213
|
+
}): Promise<{
|
|
210
214
|
uniqueIdentifier: string | undefined;
|
|
211
215
|
verified: boolean;
|
|
212
216
|
queryResultErrors?: QueryResultErrors;
|
package/dist/esm/index.js
CHANGED
|
@@ -7,8 +7,6 @@ import { createEncryptedJsonRpcRequest } from "./json-rpc";
|
|
|
7
7
|
import { decrypt, generateECDHKeyPair, getSharedSecret } from "./encryption";
|
|
8
8
|
import { noLogger as logger } from "./logger";
|
|
9
9
|
import { inflate } from "pako";
|
|
10
|
-
//import initNoirC from '@noir-lang/noirc_abi'
|
|
11
|
-
//import initACVM from '@noir-lang/acvm_js'
|
|
12
10
|
import i18en from "i18n-iso-countries/langs/en.json";
|
|
13
11
|
import { Buffer } from "buffer/";
|
|
14
12
|
// If Buffer is not defined, then we use the Buffer from the buffer package
|
|
@@ -84,18 +82,17 @@ export class ZKPassport {
|
|
|
84
82
|
}
|
|
85
83
|
this.domain = _domain || window.location.hostname;
|
|
86
84
|
}
|
|
87
|
-
/*private async initWasmVerifier() {
|
|
88
|
-
const acvm = await import('@noir-lang/acvm_js/web/acvm_js_bg.wasm')
|
|
89
|
-
const noirc = await import('@noir-lang/noirc_abi/web/noirc_abi_wasm_bg.wasm')
|
|
90
|
-
await Promise.all([initACVM(acvm), initNoirC(noirc)])
|
|
91
|
-
this.wasmVerifierInit = true
|
|
92
|
-
}*/
|
|
93
85
|
async handleResult(topic) {
|
|
94
86
|
const result = this.topicToResults[topic];
|
|
95
87
|
// Clear the results straight away to avoid concurrency issues
|
|
96
88
|
delete this.topicToResults[topic];
|
|
97
89
|
// Verify the proofs and extract the unique identifier (aka nullifier) and the verification result
|
|
98
|
-
const { uniqueIdentifier, verified, queryResultErrors } = await this.verify(
|
|
90
|
+
const { uniqueIdentifier, verified, queryResultErrors } = await this.verify({
|
|
91
|
+
proofs: this.topicToProofs[topic],
|
|
92
|
+
queryResult: result,
|
|
93
|
+
validity: this.topicToLocalConfig[topic]?.validity,
|
|
94
|
+
});
|
|
95
|
+
delete this.topicToProofs[topic];
|
|
99
96
|
const hasFailedProofs = this.topicToFailedProofCount[topic] > 0;
|
|
100
97
|
await Promise.all(this.onResultCallbacks[topic].map((callback) => callback({
|
|
101
98
|
// If there are failed proofs, we don't return the unique identifier
|
|
@@ -211,7 +208,15 @@ export class ZKPassport {
|
|
|
211
208
|
}
|
|
212
209
|
else if (request.method === "done") {
|
|
213
210
|
logger.debug(`User sent the query result`);
|
|
214
|
-
|
|
211
|
+
const formattedResult = request.params;
|
|
212
|
+
// Make sure to reconvert the dates to Date objects
|
|
213
|
+
if (formattedResult.birthdate && formattedResult.birthdate.disclose) {
|
|
214
|
+
formattedResult.birthdate.disclose.result = new Date(formattedResult.birthdate.disclose.result);
|
|
215
|
+
}
|
|
216
|
+
if (formattedResult.expiry_date && formattedResult.expiry_date.disclose) {
|
|
217
|
+
formattedResult.expiry_date.disclose.result = new Date(formattedResult.expiry_date.disclose.result);
|
|
218
|
+
}
|
|
219
|
+
this.topicToResults[topic] = formattedResult;
|
|
215
220
|
// Make sure all the proofs have been received, otherwise we'll handle the result later
|
|
216
221
|
// once the proofs have all been received
|
|
217
222
|
if (this.topicToExpectedProofCount[topic] === this.topicToProofs[topic].length) {
|
|
@@ -391,7 +396,7 @@ export class ZKPassport {
|
|
|
391
396
|
};
|
|
392
397
|
return this.getZkPassportRequest(topic);
|
|
393
398
|
}
|
|
394
|
-
async checkPublicInputs(proofs, queryResult,
|
|
399
|
+
async checkPublicInputs(proofs, queryResult, validity) {
|
|
395
400
|
let commitmentIn;
|
|
396
401
|
let commitmentOut;
|
|
397
402
|
let isCorrect = true;
|
|
@@ -481,14 +486,15 @@ export class ZKPassport {
|
|
|
481
486
|
commitmentOut = getCommitmentOutFromIntegrityProof(proofData);
|
|
482
487
|
const currentDate = getCurrentDateFromIntegrityProof(proofData);
|
|
483
488
|
const todayToCurrentDate = today.getTime() - currentDate.getTime();
|
|
484
|
-
const
|
|
489
|
+
const differenceInDays = validity ?? 180;
|
|
490
|
+
const expectedDifference = differenceInDays * 86400000;
|
|
485
491
|
const actualDifference = today.getTime() - (today.getTime() - expectedDifference);
|
|
486
492
|
// The ID should not expire within the next 6 months (or whatever the custom value is)
|
|
487
493
|
if (todayToCurrentDate >= actualDifference) {
|
|
488
|
-
console.warn(`The date used to check the validity of the ID is older than ${
|
|
494
|
+
console.warn(`The date used to check the validity of the ID is older than ${differenceInDays} days. You can ask the user to rescan their ID or ask them to disclose their expiry date`);
|
|
489
495
|
isCorrect = false;
|
|
490
496
|
queryResultErrors.data_check_integrity.date = {
|
|
491
|
-
expected: `Difference: ${
|
|
497
|
+
expected: `Difference: ${differenceInDays} days`,
|
|
492
498
|
received: `Difference: ${Math.round(todayToCurrentDate / 86400000)} days`,
|
|
493
499
|
message: "The date used to check the validity of the ID is older than the validity period",
|
|
494
500
|
};
|
|
@@ -896,7 +902,7 @@ export class ZKPassport {
|
|
|
896
902
|
message: "Current date in the proof is too old",
|
|
897
903
|
};
|
|
898
904
|
}
|
|
899
|
-
uniqueIdentifier =
|
|
905
|
+
uniqueIdentifier = getNullifierFromDisclosureProof(proofData).toString(10);
|
|
900
906
|
}
|
|
901
907
|
else if (proof.name === "compare_birthdate") {
|
|
902
908
|
commitmentIn = getCommitmentInFromDisclosureProof(proofData);
|
|
@@ -977,7 +983,7 @@ export class ZKPassport {
|
|
|
977
983
|
message: "Birthdate is not set in the query result",
|
|
978
984
|
};
|
|
979
985
|
}
|
|
980
|
-
uniqueIdentifier =
|
|
986
|
+
uniqueIdentifier = getNullifierFromDisclosureProof(proofData).toString(10);
|
|
981
987
|
}
|
|
982
988
|
else if (proof.name === "compare_expiry") {
|
|
983
989
|
commitmentIn = getCommitmentInFromDisclosureProof(proofData);
|
|
@@ -1225,35 +1231,33 @@ export class ZKPassport {
|
|
|
1225
1231
|
}
|
|
1226
1232
|
/**
|
|
1227
1233
|
* @notice Verify the proofs received from the mobile app.
|
|
1228
|
-
* @param requestId The request ID.
|
|
1229
1234
|
* @param proofs The proofs to verify.
|
|
1230
1235
|
* @param queryResult The query result to verify against
|
|
1236
|
+
* @param validity How many days ago should have the ID been last scanned by the user?
|
|
1231
1237
|
* @returns An object containing the unique identifier associated to the user
|
|
1232
1238
|
* and a boolean indicating whether the proofs were successfully verified.
|
|
1233
1239
|
*/
|
|
1234
|
-
async verify(
|
|
1235
|
-
|
|
1236
|
-
//
|
|
1237
|
-
if (
|
|
1238
|
-
|
|
1240
|
+
async verify({ proofs, queryResult, validity, }) {
|
|
1241
|
+
const formattedResult = queryResult;
|
|
1242
|
+
// Make sure to reconvert the dates to Date objects
|
|
1243
|
+
if (formattedResult.birthdate && formattedResult.birthdate.disclose) {
|
|
1244
|
+
formattedResult.birthdate.disclose.result = new Date(formattedResult.birthdate.disclose.result);
|
|
1245
|
+
}
|
|
1246
|
+
if (formattedResult.expiry_date && formattedResult.expiry_date.disclose) {
|
|
1247
|
+
formattedResult.expiry_date.disclose.result = new Date(formattedResult.expiry_date.disclose.result);
|
|
1239
1248
|
}
|
|
1240
1249
|
const { BarretenbergVerifier } = await import("@aztec/bb.js");
|
|
1241
1250
|
const verifier = new BarretenbergVerifier();
|
|
1242
|
-
/*if (!this.wasmVerifierInit) {
|
|
1243
|
-
await this.initWasmVerifier()
|
|
1244
|
-
}*/
|
|
1245
1251
|
let verified = true;
|
|
1246
1252
|
let uniqueIdentifier;
|
|
1247
1253
|
let queryResultErrors;
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
queryResultErrors = isCorrect ? undefined : queryResultErrorsFromPublicInputs;
|
|
1253
|
-
}
|
|
1254
|
+
const { isCorrect, uniqueIdentifier: uniqueIdentifierFromPublicInputs, queryResultErrors: queryResultErrorsFromPublicInputs, } = await this.checkPublicInputs(proofs, formattedResult, validity);
|
|
1255
|
+
uniqueIdentifier = uniqueIdentifierFromPublicInputs;
|
|
1256
|
+
verified = isCorrect;
|
|
1257
|
+
queryResultErrors = isCorrect ? undefined : queryResultErrorsFromPublicInputs;
|
|
1254
1258
|
// Only proceed with the proof verification if the public inputs are correct
|
|
1255
|
-
if (verified
|
|
1256
|
-
for (const proof of
|
|
1259
|
+
if (verified) {
|
|
1260
|
+
for (const proof of proofs) {
|
|
1257
1261
|
const proofData = getProofData(proof.proof, true);
|
|
1258
1262
|
const hostedPackagedCircuit = await getHostedPackagedCircuitByName(proof.version, proof.name);
|
|
1259
1263
|
const vkeyBytes = Buffer.from(hostedPackagedCircuit.vkey, "base64");
|
|
@@ -1271,7 +1275,8 @@ export class ZKPassport {
|
|
|
1271
1275
|
}
|
|
1272
1276
|
}
|
|
1273
1277
|
}
|
|
1274
|
-
|
|
1278
|
+
// If the proofs are not verified, we don't return the unique identifier
|
|
1279
|
+
uniqueIdentifier = verified ? uniqueIdentifier : undefined;
|
|
1275
1280
|
return { uniqueIdentifier, verified, queryResultErrors };
|
|
1276
1281
|
}
|
|
1277
1282
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zkpassport/sdk",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.12",
|
|
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",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
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.
|
|
44
|
+
"@zkpassport/utils": "^0.2.24",
|
|
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
|
@@ -38,8 +38,6 @@ import { createEncryptedJsonRpcRequest } from "./json-rpc"
|
|
|
38
38
|
import { decrypt, generateECDHKeyPair, getSharedSecret } from "./encryption"
|
|
39
39
|
import { noLogger as logger } from "./logger"
|
|
40
40
|
import { inflate } from "pako"
|
|
41
|
-
//import initNoirC from '@noir-lang/noirc_abi'
|
|
42
|
-
//import initACVM from '@noir-lang/acvm_js'
|
|
43
41
|
import i18en from "i18n-iso-countries/langs/en.json"
|
|
44
42
|
import { Buffer } from "buffer/"
|
|
45
43
|
|
|
@@ -339,23 +337,17 @@ export class ZKPassport {
|
|
|
339
337
|
this.domain = _domain || window.location.hostname
|
|
340
338
|
}
|
|
341
339
|
|
|
342
|
-
/*private async initWasmVerifier() {
|
|
343
|
-
const acvm = await import('@noir-lang/acvm_js/web/acvm_js_bg.wasm')
|
|
344
|
-
const noirc = await import('@noir-lang/noirc_abi/web/noirc_abi_wasm_bg.wasm')
|
|
345
|
-
await Promise.all([initACVM(acvm), initNoirC(noirc)])
|
|
346
|
-
this.wasmVerifierInit = true
|
|
347
|
-
}*/
|
|
348
|
-
|
|
349
340
|
private async handleResult(topic: string) {
|
|
350
341
|
const result = this.topicToResults[topic]
|
|
351
342
|
// Clear the results straight away to avoid concurrency issues
|
|
352
343
|
delete this.topicToResults[topic]
|
|
353
344
|
// Verify the proofs and extract the unique identifier (aka nullifier) and the verification result
|
|
354
|
-
const { uniqueIdentifier, verified, queryResultErrors } = await this.verify(
|
|
355
|
-
topic,
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
)
|
|
345
|
+
const { uniqueIdentifier, verified, queryResultErrors } = await this.verify({
|
|
346
|
+
proofs: this.topicToProofs[topic],
|
|
347
|
+
queryResult: result,
|
|
348
|
+
validity: this.topicToLocalConfig[topic]?.validity,
|
|
349
|
+
})
|
|
350
|
+
delete this.topicToProofs[topic]
|
|
359
351
|
const hasFailedProofs = this.topicToFailedProofCount[topic] > 0
|
|
360
352
|
await Promise.all(
|
|
361
353
|
this.onResultCallbacks[topic].map((callback) =>
|
|
@@ -487,7 +479,19 @@ export class ZKPassport {
|
|
|
487
479
|
}
|
|
488
480
|
} else if (request.method === "done") {
|
|
489
481
|
logger.debug(`User sent the query result`)
|
|
490
|
-
|
|
482
|
+
const formattedResult: QueryResult = request.params
|
|
483
|
+
// Make sure to reconvert the dates to Date objects
|
|
484
|
+
if (formattedResult.birthdate && formattedResult.birthdate.disclose) {
|
|
485
|
+
formattedResult.birthdate.disclose.result = new Date(
|
|
486
|
+
formattedResult.birthdate.disclose.result,
|
|
487
|
+
)
|
|
488
|
+
}
|
|
489
|
+
if (formattedResult.expiry_date && formattedResult.expiry_date.disclose) {
|
|
490
|
+
formattedResult.expiry_date.disclose.result = new Date(
|
|
491
|
+
formattedResult.expiry_date.disclose.result,
|
|
492
|
+
)
|
|
493
|
+
}
|
|
494
|
+
this.topicToResults[topic] = formattedResult
|
|
491
495
|
// Make sure all the proofs have been received, otherwise we'll handle the result later
|
|
492
496
|
// once the proofs have all been received
|
|
493
497
|
if (this.topicToExpectedProofCount[topic] === this.topicToProofs[topic].length) {
|
|
@@ -728,7 +732,7 @@ export class ZKPassport {
|
|
|
728
732
|
private async checkPublicInputs(
|
|
729
733
|
proofs: Array<ProofResult>,
|
|
730
734
|
queryResult: QueryResult,
|
|
731
|
-
|
|
735
|
+
validity?: number,
|
|
732
736
|
) {
|
|
733
737
|
let commitmentIn: bigint | undefined
|
|
734
738
|
let commitmentOut: bigint | undefined
|
|
@@ -831,16 +835,17 @@ export class ZKPassport {
|
|
|
831
835
|
commitmentOut = getCommitmentOutFromIntegrityProof(proofData)
|
|
832
836
|
const currentDate = getCurrentDateFromIntegrityProof(proofData)
|
|
833
837
|
const todayToCurrentDate = today.getTime() - currentDate.getTime()
|
|
834
|
-
const
|
|
838
|
+
const differenceInDays = validity ?? 180
|
|
839
|
+
const expectedDifference = differenceInDays * 86400000
|
|
835
840
|
const actualDifference = today.getTime() - (today.getTime() - expectedDifference)
|
|
836
841
|
// The ID should not expire within the next 6 months (or whatever the custom value is)
|
|
837
842
|
if (todayToCurrentDate >= actualDifference) {
|
|
838
843
|
console.warn(
|
|
839
|
-
`The date used to check the validity of the ID is older than ${
|
|
844
|
+
`The date used to check the validity of the ID is older than ${differenceInDays} days. You can ask the user to rescan their ID or ask them to disclose their expiry date`,
|
|
840
845
|
)
|
|
841
846
|
isCorrect = false
|
|
842
847
|
queryResultErrors.data_check_integrity.date = {
|
|
843
|
-
expected: `Difference: ${
|
|
848
|
+
expected: `Difference: ${differenceInDays} days`,
|
|
844
849
|
received: `Difference: ${Math.round(todayToCurrentDate / 86400000)} days`,
|
|
845
850
|
message:
|
|
846
851
|
"The date used to check the validity of the ID is older than the validity period",
|
|
@@ -1310,7 +1315,7 @@ export class ZKPassport {
|
|
|
1310
1315
|
message: "Current date in the proof is too old",
|
|
1311
1316
|
}
|
|
1312
1317
|
}
|
|
1313
|
-
uniqueIdentifier =
|
|
1318
|
+
uniqueIdentifier = getNullifierFromDisclosureProof(proofData).toString(10)
|
|
1314
1319
|
} else if (proof.name === "compare_birthdate") {
|
|
1315
1320
|
commitmentIn = getCommitmentInFromDisclosureProof(proofData)
|
|
1316
1321
|
if (commitmentIn !== commitmentOut) {
|
|
@@ -1402,7 +1407,7 @@ export class ZKPassport {
|
|
|
1402
1407
|
message: "Birthdate is not set in the query result",
|
|
1403
1408
|
}
|
|
1404
1409
|
}
|
|
1405
|
-
uniqueIdentifier =
|
|
1410
|
+
uniqueIdentifier = getNullifierFromDisclosureProof(proofData).toString(10)
|
|
1406
1411
|
} else if (proof.name === "compare_expiry") {
|
|
1407
1412
|
commitmentIn = getCommitmentInFromDisclosureProof(proofData)
|
|
1408
1413
|
if (commitmentIn !== commitmentOut) {
|
|
@@ -1697,47 +1702,54 @@ export class ZKPassport {
|
|
|
1697
1702
|
|
|
1698
1703
|
/**
|
|
1699
1704
|
* @notice Verify the proofs received from the mobile app.
|
|
1700
|
-
* @param requestId The request ID.
|
|
1701
1705
|
* @param proofs The proofs to verify.
|
|
1702
1706
|
* @param queryResult The query result to verify against
|
|
1707
|
+
* @param validity How many days ago should have the ID been last scanned by the user?
|
|
1703
1708
|
* @returns An object containing the unique identifier associated to the user
|
|
1704
1709
|
* and a boolean indicating whether the proofs were successfully verified.
|
|
1705
1710
|
*/
|
|
1706
|
-
public async verify(
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
+
public async verify({
|
|
1712
|
+
proofs,
|
|
1713
|
+
queryResult,
|
|
1714
|
+
validity,
|
|
1715
|
+
}: {
|
|
1716
|
+
proofs: Array<ProofResult>
|
|
1717
|
+
queryResult: QueryResult
|
|
1718
|
+
validity?: number
|
|
1719
|
+
}): Promise<{
|
|
1711
1720
|
uniqueIdentifier: string | undefined
|
|
1712
1721
|
verified: boolean
|
|
1713
1722
|
queryResultErrors?: QueryResultErrors
|
|
1714
1723
|
}> {
|
|
1715
|
-
|
|
1716
|
-
//
|
|
1717
|
-
if (
|
|
1718
|
-
|
|
1724
|
+
const formattedResult: QueryResult = queryResult
|
|
1725
|
+
// Make sure to reconvert the dates to Date objects
|
|
1726
|
+
if (formattedResult.birthdate && formattedResult.birthdate.disclose) {
|
|
1727
|
+
formattedResult.birthdate.disclose.result = new Date(
|
|
1728
|
+
formattedResult.birthdate.disclose.result,
|
|
1729
|
+
)
|
|
1730
|
+
}
|
|
1731
|
+
if (formattedResult.expiry_date && formattedResult.expiry_date.disclose) {
|
|
1732
|
+
formattedResult.expiry_date.disclose.result = new Date(
|
|
1733
|
+
formattedResult.expiry_date.disclose.result,
|
|
1734
|
+
)
|
|
1719
1735
|
}
|
|
1736
|
+
|
|
1720
1737
|
const { BarretenbergVerifier } = await import("@aztec/bb.js")
|
|
1721
1738
|
const verifier = new BarretenbergVerifier()
|
|
1722
|
-
/*if (!this.wasmVerifierInit) {
|
|
1723
|
-
await this.initWasmVerifier()
|
|
1724
|
-
}*/
|
|
1725
1739
|
let verified = true
|
|
1726
1740
|
let uniqueIdentifier: string | undefined
|
|
1727
1741
|
let queryResultErrors: QueryResultErrors | undefined
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
queryResultErrors = isCorrect ? undefined : queryResultErrorsFromPublicInputs
|
|
1737
|
-
}
|
|
1742
|
+
const {
|
|
1743
|
+
isCorrect,
|
|
1744
|
+
uniqueIdentifier: uniqueIdentifierFromPublicInputs,
|
|
1745
|
+
queryResultErrors: queryResultErrorsFromPublicInputs,
|
|
1746
|
+
} = await this.checkPublicInputs(proofs, formattedResult, validity)
|
|
1747
|
+
uniqueIdentifier = uniqueIdentifierFromPublicInputs
|
|
1748
|
+
verified = isCorrect
|
|
1749
|
+
queryResultErrors = isCorrect ? undefined : queryResultErrorsFromPublicInputs
|
|
1738
1750
|
// Only proceed with the proof verification if the public inputs are correct
|
|
1739
|
-
if (verified
|
|
1740
|
-
for (const proof of
|
|
1751
|
+
if (verified) {
|
|
1752
|
+
for (const proof of proofs) {
|
|
1741
1753
|
const proofData = getProofData(proof.proof as string, true)
|
|
1742
1754
|
const hostedPackagedCircuit = await getHostedPackagedCircuitByName(
|
|
1743
1755
|
proof.version as any,
|
|
@@ -1757,7 +1769,8 @@ export class ZKPassport {
|
|
|
1757
1769
|
}
|
|
1758
1770
|
}
|
|
1759
1771
|
}
|
|
1760
|
-
|
|
1772
|
+
// If the proofs are not verified, we don't return the unique identifier
|
|
1773
|
+
uniqueIdentifier = verified ? uniqueIdentifier : undefined
|
|
1761
1774
|
return { uniqueIdentifier, verified, queryResultErrors }
|
|
1762
1775
|
}
|
|
1763
1776
|
|