@zkpassport/sdk 0.4.0 → 0.4.1
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/assets/abi/ZKPassportVerifier.json +51 -9
- package/dist/cjs/index.d.ts +9 -2
- package/dist/cjs/index.js +116 -1
- package/dist/esm/assets/abi/ZKPassportVerifier.json +51 -9
- package/dist/esm/index.d.ts +9 -2
- package/dist/esm/index.js +117 -2
- package/package.json +2 -2
- package/src/assets/abi/ZKPassportVerifier.json +51 -9
- package/src/index.ts +136 -2
package/dist/cjs/index.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { type DisclosableIDCredential, type IDCredential, type IDCredentialValue, type NumericalIDCredential, type ProofResult, type QueryResult, ProofMode } from "@zkpassport/utils";
|
|
1
|
+
import { type DisclosableIDCredential, type IDCredential, type IDCredentialValue, type NumericalIDCredential, type ProofResult, type QueryResult, ProofMode, BoundData } from "@zkpassport/utils";
|
|
2
2
|
export type QueryResultError<T> = {
|
|
3
3
|
expected?: T;
|
|
4
4
|
received?: T;
|
|
5
5
|
message: string;
|
|
6
6
|
};
|
|
7
7
|
export type QueryResultErrors = {
|
|
8
|
-
[key in IDCredential | "sig_check_dsc" | "sig_check_id_data" | "data_check_integrity" | "outer" | "disclose"]: {
|
|
8
|
+
[key in IDCredential | "sig_check_dsc" | "sig_check_id_data" | "data_check_integrity" | "outer" | "disclose" | "bind"]: {
|
|
9
9
|
disclose?: QueryResultError<string | number | Date>;
|
|
10
10
|
gte?: QueryResultError<number | Date>;
|
|
11
11
|
lte?: QueryResultError<number | Date>;
|
|
@@ -150,6 +150,12 @@ export type QueryBuilder = {
|
|
|
150
150
|
* @param key The attribute to disclose.
|
|
151
151
|
*/
|
|
152
152
|
disclose: (key: DisclosableIDCredential) => QueryBuilder;
|
|
153
|
+
/**
|
|
154
|
+
* Binds a value to the request.
|
|
155
|
+
* @param key The key of the value to bind.
|
|
156
|
+
* @param value The value to bind the request to.
|
|
157
|
+
*/
|
|
158
|
+
bind: (key: keyof BoundData, value: BoundData[keyof BoundData]) => QueryBuilder;
|
|
153
159
|
/**
|
|
154
160
|
* Builds the request.
|
|
155
161
|
*
|
|
@@ -224,6 +230,7 @@ export declare class ZKPassport {
|
|
|
224
230
|
private checkIssuingCountryInclusionPublicInputs;
|
|
225
231
|
private checkScopeFromDisclosureProof;
|
|
226
232
|
private checkCertificateRegistryRoot;
|
|
233
|
+
private checkBindPublicInputs;
|
|
227
234
|
private checkPublicInputs;
|
|
228
235
|
/**
|
|
229
236
|
* @notice Verify the proofs received from the mobile app.
|
package/dist/cjs/index.js
CHANGED
|
@@ -201,6 +201,9 @@ class ZKPassport {
|
|
|
201
201
|
}
|
|
202
202
|
}
|
|
203
203
|
}
|
|
204
|
+
if (this.topicToConfig[topic].bind) {
|
|
205
|
+
neededCircuits.push("bind");
|
|
206
|
+
}
|
|
204
207
|
// From the circuits needed, determine the expected proof count
|
|
205
208
|
// There are at least 4 proofs, 3 base proofs and 1 disclosure proof minimum
|
|
206
209
|
// Each separate needed circuit adds 1 disclosure proof
|
|
@@ -323,6 +326,13 @@ class ZKPassport {
|
|
|
323
326
|
};
|
|
324
327
|
return this.getZkPassportRequest(topic);
|
|
325
328
|
},
|
|
329
|
+
bind: (key, value) => {
|
|
330
|
+
this.topicToConfig[topic].bind = {
|
|
331
|
+
...this.topicToConfig[topic].bind,
|
|
332
|
+
[key]: value,
|
|
333
|
+
};
|
|
334
|
+
return this.getZkPassportRequest(topic);
|
|
335
|
+
},
|
|
326
336
|
done: () => {
|
|
327
337
|
const base64Config = buffer_1.Buffer.from(JSON.stringify(this.topicToConfig[topic])).toString("base64");
|
|
328
338
|
const base64Service = buffer_1.Buffer.from(JSON.stringify(this.topicToService[topic])).toString("base64");
|
|
@@ -419,6 +429,7 @@ class ZKPassport {
|
|
|
419
429
|
fullname: {},
|
|
420
430
|
document_number: {},
|
|
421
431
|
outer: {},
|
|
432
|
+
bind: {},
|
|
422
433
|
};
|
|
423
434
|
let isCorrect = true;
|
|
424
435
|
// We can't be certain that the disclosed data is for a passport or an ID card
|
|
@@ -731,6 +742,7 @@ class ZKPassport {
|
|
|
731
742
|
fullname: {},
|
|
732
743
|
document_number: {},
|
|
733
744
|
outer: {},
|
|
745
|
+
bind: {},
|
|
734
746
|
};
|
|
735
747
|
let isCorrect = true;
|
|
736
748
|
const currentTime = new Date();
|
|
@@ -840,6 +852,7 @@ class ZKPassport {
|
|
|
840
852
|
fullname: {},
|
|
841
853
|
document_number: {},
|
|
842
854
|
outer: {},
|
|
855
|
+
bind: {},
|
|
843
856
|
};
|
|
844
857
|
let isCorrect = true;
|
|
845
858
|
const currentTime = new Date();
|
|
@@ -943,6 +956,7 @@ class ZKPassport {
|
|
|
943
956
|
fullname: {},
|
|
944
957
|
document_number: {},
|
|
945
958
|
outer: {},
|
|
959
|
+
bind: {},
|
|
946
960
|
};
|
|
947
961
|
let isCorrect = true;
|
|
948
962
|
const currentTime = new Date();
|
|
@@ -1046,6 +1060,7 @@ class ZKPassport {
|
|
|
1046
1060
|
fullname: {},
|
|
1047
1061
|
document_number: {},
|
|
1048
1062
|
outer: {},
|
|
1063
|
+
bind: {},
|
|
1049
1064
|
};
|
|
1050
1065
|
let isCorrect = true;
|
|
1051
1066
|
if (queryResult.nationality &&
|
|
@@ -1100,6 +1115,7 @@ class ZKPassport {
|
|
|
1100
1115
|
fullname: {},
|
|
1101
1116
|
document_number: {},
|
|
1102
1117
|
outer: {},
|
|
1118
|
+
bind: {},
|
|
1103
1119
|
};
|
|
1104
1120
|
let isCorrect = true;
|
|
1105
1121
|
if (queryResult.issuing_country &&
|
|
@@ -1154,6 +1170,7 @@ class ZKPassport {
|
|
|
1154
1170
|
fullname: {},
|
|
1155
1171
|
document_number: {},
|
|
1156
1172
|
outer: {},
|
|
1173
|
+
bind: {},
|
|
1157
1174
|
};
|
|
1158
1175
|
let isCorrect = true;
|
|
1159
1176
|
if (queryResult.nationality &&
|
|
@@ -1196,6 +1213,7 @@ class ZKPassport {
|
|
|
1196
1213
|
fullname: {},
|
|
1197
1214
|
document_number: {},
|
|
1198
1215
|
outer: {},
|
|
1216
|
+
bind: {},
|
|
1199
1217
|
};
|
|
1200
1218
|
let isCorrect = true;
|
|
1201
1219
|
if (queryResult.issuing_country &&
|
|
@@ -1271,6 +1289,51 @@ class ZKPassport {
|
|
|
1271
1289
|
}
|
|
1272
1290
|
return { isCorrect, queryResultErrors };
|
|
1273
1291
|
}
|
|
1292
|
+
checkBindPublicInputs(queryResult, boundData) {
|
|
1293
|
+
const queryResultErrors = {
|
|
1294
|
+
sig_check_dsc: {},
|
|
1295
|
+
sig_check_id_data: {},
|
|
1296
|
+
data_check_integrity: {},
|
|
1297
|
+
disclose: {},
|
|
1298
|
+
age: {},
|
|
1299
|
+
birthdate: {},
|
|
1300
|
+
expiry_date: {},
|
|
1301
|
+
document_type: {},
|
|
1302
|
+
issuing_country: {},
|
|
1303
|
+
gender: {},
|
|
1304
|
+
nationality: {},
|
|
1305
|
+
firstname: {},
|
|
1306
|
+
lastname: {},
|
|
1307
|
+
fullname: {},
|
|
1308
|
+
document_number: {},
|
|
1309
|
+
outer: {},
|
|
1310
|
+
bind: {},
|
|
1311
|
+
};
|
|
1312
|
+
let isCorrect = true;
|
|
1313
|
+
if (queryResult.bind) {
|
|
1314
|
+
if (queryResult.bind.user_address?.toLowerCase().replace("0x", "") !==
|
|
1315
|
+
boundData.user_address?.toLowerCase().replace("0x", "")) {
|
|
1316
|
+
console.warn("Bound user address does not match the one from the query results");
|
|
1317
|
+
isCorrect = false;
|
|
1318
|
+
queryResultErrors.bind.eq = {
|
|
1319
|
+
expected: queryResult.bind.user_address,
|
|
1320
|
+
received: boundData.user_address,
|
|
1321
|
+
message: "Bound user address does not match the one from the query results",
|
|
1322
|
+
};
|
|
1323
|
+
}
|
|
1324
|
+
if (queryResult.bind.custom_data?.trim().toLowerCase() !==
|
|
1325
|
+
boundData.custom_data?.trim().toLowerCase()) {
|
|
1326
|
+
console.warn("Bound custom data does not match the one from the query results");
|
|
1327
|
+
isCorrect = false;
|
|
1328
|
+
queryResultErrors.bind.eq = {
|
|
1329
|
+
expected: queryResult.bind.custom_data,
|
|
1330
|
+
received: boundData.custom_data,
|
|
1331
|
+
message: "Bound custom data does not match the one from the query results",
|
|
1332
|
+
};
|
|
1333
|
+
}
|
|
1334
|
+
}
|
|
1335
|
+
return { isCorrect, queryResultErrors };
|
|
1336
|
+
}
|
|
1274
1337
|
async checkPublicInputs(proofs, queryResult, validity, scope, chainId) {
|
|
1275
1338
|
let commitmentIn;
|
|
1276
1339
|
let commitmentOut;
|
|
@@ -1295,6 +1358,7 @@ class ZKPassport {
|
|
|
1295
1358
|
fullname: {},
|
|
1296
1359
|
document_number: {},
|
|
1297
1360
|
outer: {},
|
|
1361
|
+
bind: {},
|
|
1298
1362
|
};
|
|
1299
1363
|
// Since the order is important for the commitments, we need to sort the proofs
|
|
1300
1364
|
// by their expected order: root signature check -> ID signature check -> integrity check -> disclosure
|
|
@@ -1311,6 +1375,7 @@ class ZKPassport {
|
|
|
1311
1375
|
"inclusion_check_nationality",
|
|
1312
1376
|
"exclusion_check_issuing_country",
|
|
1313
1377
|
"inclusion_check_issuing_country",
|
|
1378
|
+
"bind",
|
|
1314
1379
|
];
|
|
1315
1380
|
const getIndex = (proof) => {
|
|
1316
1381
|
const name = proof.name || "";
|
|
@@ -1547,6 +1612,27 @@ class ZKPassport {
|
|
|
1547
1612
|
...queryResultErrorsIssuingCountryExclusion,
|
|
1548
1613
|
};
|
|
1549
1614
|
}
|
|
1615
|
+
else if (!!committedInputs?.bind) {
|
|
1616
|
+
const bindCommittedInputs = committedInputs?.bind;
|
|
1617
|
+
const bindParameterCommitment = isForEVM
|
|
1618
|
+
? await (0, utils_1.getBindEVMParameterCommitment)((0, utils_1.formatBoundData)(bindCommittedInputs.data))
|
|
1619
|
+
: await (0, utils_1.getBindParameterCommitment)((0, utils_1.formatBoundData)(bindCommittedInputs.data));
|
|
1620
|
+
if (!paramCommitments.includes(bindParameterCommitment)) {
|
|
1621
|
+
console.warn("This proof does not verify the bound data");
|
|
1622
|
+
isCorrect = false;
|
|
1623
|
+
queryResultErrors.bind.commitment = {
|
|
1624
|
+
expected: `Bind parameter commitment: ${bindParameterCommitment.toString()}`,
|
|
1625
|
+
received: `Parameter commitments included: ${paramCommitments.join(", ")}`,
|
|
1626
|
+
message: "This proof does not verify the bound data",
|
|
1627
|
+
};
|
|
1628
|
+
}
|
|
1629
|
+
const { isCorrect: isCorrectBind, queryResultErrors: queryResultErrorsBind } = this.checkBindPublicInputs(queryResult, bindCommittedInputs.data);
|
|
1630
|
+
isCorrect = isCorrect && isCorrectBind;
|
|
1631
|
+
queryResultErrors = {
|
|
1632
|
+
...queryResultErrors,
|
|
1633
|
+
...queryResultErrorsBind,
|
|
1634
|
+
};
|
|
1635
|
+
}
|
|
1550
1636
|
uniqueIdentifier = (0, utils_1.getNullifierFromOuterProof)(proofData).toString(10);
|
|
1551
1637
|
}
|
|
1552
1638
|
else if (proof.name?.startsWith("sig_check_dsc")) {
|
|
@@ -1868,6 +1954,27 @@ class ZKPassport {
|
|
|
1868
1954
|
};
|
|
1869
1955
|
uniqueIdentifier = (0, utils_1.getNullifierFromDisclosureProof)(proofData).toString(10);
|
|
1870
1956
|
}
|
|
1957
|
+
else if (proof.name === "bind") {
|
|
1958
|
+
const bindCommittedInputs = proof.committedInputs?.bind;
|
|
1959
|
+
const paramCommittment = (0, utils_1.getParameterCommitmentFromDisclosureProof)(proofData);
|
|
1960
|
+
const calculatedParamCommitment = await (0, utils_1.getBindParameterCommitment)((0, utils_1.formatBoundData)(bindCommittedInputs.data));
|
|
1961
|
+
if (paramCommittment !== calculatedParamCommitment) {
|
|
1962
|
+
console.warn("The bound data does not match the one from the proof");
|
|
1963
|
+
isCorrect = false;
|
|
1964
|
+
queryResultErrors.bind.commitment = {
|
|
1965
|
+
expected: `Commitment: ${calculatedParamCommitment}`,
|
|
1966
|
+
received: `Commitment: ${paramCommittment}`,
|
|
1967
|
+
message: "The bound data does not match the one from the proof",
|
|
1968
|
+
};
|
|
1969
|
+
}
|
|
1970
|
+
const { isCorrect: isCorrectBind, queryResultErrors: queryResultErrorsBind } = this.checkBindPublicInputs(queryResult, bindCommittedInputs.data);
|
|
1971
|
+
isCorrect = isCorrect && isCorrectBind;
|
|
1972
|
+
queryResultErrors = {
|
|
1973
|
+
...queryResultErrors,
|
|
1974
|
+
...queryResultErrorsBind,
|
|
1975
|
+
};
|
|
1976
|
+
uniqueIdentifier = (0, utils_1.getNullifierFromDisclosureProof)(proofData).toString(10);
|
|
1977
|
+
}
|
|
1871
1978
|
}
|
|
1872
1979
|
return { isCorrect, uniqueIdentifier, queryResultErrors };
|
|
1873
1980
|
}
|
|
@@ -1983,7 +2090,7 @@ class ZKPassport {
|
|
|
1983
2090
|
if (network === "ethereum_sepolia") {
|
|
1984
2091
|
return {
|
|
1985
2092
|
...baseConfig,
|
|
1986
|
-
address: "
|
|
2093
|
+
address: "0x5e4B11F7B7995F5Cee0134692a422b045091112F",
|
|
1987
2094
|
};
|
|
1988
2095
|
}
|
|
1989
2096
|
else if (network === "local_anvil") {
|
|
@@ -2076,6 +2183,14 @@ class ZKPassport {
|
|
|
2076
2183
|
value.discloseMask.map((x) => x.toString(16).padStart(2, "0")).join("") +
|
|
2077
2184
|
value.disclosedBytes.map((x) => x.toString(16).padStart(2, "0")).join("");
|
|
2078
2185
|
}
|
|
2186
|
+
else if (circuitName === "bind_evm") {
|
|
2187
|
+
const value = proof.committedInputs[circuitName];
|
|
2188
|
+
compressedCommittedInputs =
|
|
2189
|
+
utils_1.ProofType.BIND.toString(16).padStart(2, "0") +
|
|
2190
|
+
(0, utils_1.rightPadArrayWithZeros)((0, utils_1.formatBoundData)(value.data), 500)
|
|
2191
|
+
.map((x) => x.toString(16).padStart(2, "0"))
|
|
2192
|
+
.join("");
|
|
2193
|
+
}
|
|
2079
2194
|
else {
|
|
2080
2195
|
throw new Error(`Unsupported circuit for EVM verification: ${circuitName}`);
|
|
2081
2196
|
}
|