@0xpolygonid/js-sdk 1.7.5 → 1.8.0

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.
Files changed (92) hide show
  1. package/dist/browser/esm/index.js +13041 -11748
  2. package/dist/browser/esm/index.js.map +1 -1
  3. package/dist/browser/umd/index.js +13070 -11755
  4. package/dist/browser/umd/index.js.map +1 -1
  5. package/dist/node/cjs/circuits/atomic-query-mtp-v2.js +3 -3
  6. package/dist/node/cjs/circuits/atomic-query-sig-v2.js +3 -3
  7. package/dist/node/cjs/circuits/auth-v2.js +1 -1
  8. package/dist/node/cjs/credentials/credential-wallet.js +1 -3
  9. package/dist/node/cjs/credentials/index.js +1 -0
  10. package/dist/node/cjs/credentials/models.js +2 -0
  11. package/dist/node/cjs/credentials/status/credential-status-publisher.js +23 -4
  12. package/dist/node/cjs/iden3comm/constants.js +3 -1
  13. package/dist/node/cjs/iden3comm/handlers/auth.js +119 -14
  14. package/dist/node/cjs/kms/key-providers/sec256k1-provider.js +5 -2
  15. package/dist/node/cjs/proof/common.js +3 -4
  16. package/dist/node/cjs/proof/index.js +2 -1
  17. package/dist/node/cjs/proof/proof-service.js +22 -2
  18. package/dist/node/cjs/proof/provers/index.js +19 -0
  19. package/dist/node/cjs/proof/{inputs-generator.js → provers/inputs-generator.js} +42 -23
  20. package/dist/node/cjs/proof/{prover.js → provers/prover.js} +1 -1
  21. package/dist/node/cjs/proof/verifiers/index.js +18 -0
  22. package/dist/node/cjs/proof/verifiers/pub-signals-verifier.js +344 -0
  23. package/dist/node/cjs/proof/verifiers/query.js +190 -0
  24. package/dist/node/cjs/schema-processor/json/parser.js +39 -198
  25. package/dist/node/cjs/schema-processor/utils.js +13 -26
  26. package/dist/node/cjs/storage/blockchain/state.js +53 -8
  27. package/dist/node/cjs/utils/compare-func.js +11 -0
  28. package/dist/node/cjs/utils/index.js +2 -0
  29. package/dist/node/cjs/utils/message-bus.js +73 -0
  30. package/dist/node/cjs/verifiable/core-utils.js +234 -0
  31. package/dist/node/cjs/verifiable/credential.js +139 -1
  32. package/dist/node/cjs/verifiable/index.js +1 -0
  33. package/dist/node/esm/circuits/atomic-query-mtp-v2.js +3 -3
  34. package/dist/node/esm/circuits/atomic-query-sig-v2.js +3 -3
  35. package/dist/node/esm/circuits/auth-v2.js +2 -2
  36. package/dist/node/esm/credentials/credential-wallet.js +1 -3
  37. package/dist/node/esm/credentials/index.js +1 -0
  38. package/dist/node/esm/credentials/models.js +1 -0
  39. package/dist/node/esm/credentials/status/credential-status-publisher.js +23 -4
  40. package/dist/node/esm/iden3comm/constants.js +3 -1
  41. package/dist/node/esm/iden3comm/handlers/auth.js +116 -13
  42. package/dist/node/esm/kms/key-providers/sec256k1-provider.js +5 -2
  43. package/dist/node/esm/proof/common.js +4 -5
  44. package/dist/node/esm/proof/index.js +2 -1
  45. package/dist/node/esm/proof/proof-service.js +22 -2
  46. package/dist/node/esm/proof/provers/index.js +3 -0
  47. package/dist/node/esm/proof/{inputs-generator.js → provers/inputs-generator.js} +39 -20
  48. package/dist/node/esm/proof/{prover.js → provers/prover.js} +1 -1
  49. package/dist/node/esm/proof/verifiers/index.js +2 -0
  50. package/dist/node/esm/proof/verifiers/pub-signals-verifier.js +340 -0
  51. package/dist/node/esm/proof/verifiers/query.js +186 -0
  52. package/dist/node/esm/schema-processor/json/parser.js +40 -199
  53. package/dist/node/esm/schema-processor/utils.js +13 -26
  54. package/dist/node/esm/storage/blockchain/state.js +53 -8
  55. package/dist/node/esm/utils/compare-func.js +7 -0
  56. package/dist/node/esm/utils/index.js +2 -0
  57. package/dist/node/esm/utils/message-bus.js +66 -0
  58. package/dist/node/esm/verifiable/core-utils.js +200 -0
  59. package/dist/node/esm/verifiable/credential.js +118 -3
  60. package/dist/node/esm/verifiable/index.js +1 -0
  61. package/dist/types/credentials/credential-wallet.d.ts +2 -60
  62. package/dist/types/credentials/index.d.ts +1 -0
  63. package/dist/types/credentials/models.d.ts +68 -0
  64. package/dist/types/credentials/status/credential-status-publisher.d.ts +2 -0
  65. package/dist/types/iden3comm/constants.d.ts +1 -0
  66. package/dist/types/iden3comm/handlers/auth.d.ts +53 -13
  67. package/dist/types/iden3comm/types/protocol/credentials.d.ts +16 -0
  68. package/dist/types/identity/identity-wallet.d.ts +3 -1
  69. package/dist/types/kms/key-providers/sec256k1-provider.d.ts +1 -1
  70. package/dist/types/proof/index.d.ts +2 -1
  71. package/dist/types/proof/proof-service.d.ts +28 -3
  72. package/dist/types/proof/provers/index.d.ts +3 -0
  73. package/dist/types/proof/{inputs-generator.d.ts → provers/inputs-generator.d.ts} +14 -7
  74. package/dist/types/proof/{prover.d.ts → provers/prover.d.ts} +2 -2
  75. package/dist/types/proof/verifiers/index.d.ts +2 -0
  76. package/dist/types/proof/verifiers/pub-signals-verifier.d.ts +58 -0
  77. package/dist/types/proof/verifiers/query.d.ts +25 -0
  78. package/dist/types/schema-processor/json/parser.d.ts +47 -28
  79. package/dist/types/schema-processor/utils.d.ts +9 -4
  80. package/dist/types/storage/blockchain/state.d.ts +5 -1
  81. package/dist/types/storage/interfaces/state.d.ts +8 -0
  82. package/dist/types/utils/compare-func.d.ts +1 -0
  83. package/dist/types/utils/index.d.ts +2 -0
  84. package/dist/types/utils/message-bus.d.ts +62 -0
  85. package/dist/types/verifiable/core-utils.d.ts +84 -0
  86. package/dist/types/verifiable/credential.d.ts +11 -1
  87. package/dist/types/verifiable/index.d.ts +1 -0
  88. package/dist/types/verifiable/proof.d.ts +4 -0
  89. package/package.json +10 -10
  90. /package/dist/node/cjs/proof/{witness_calculator.js → provers/witness_calculator.js} +0 -0
  91. /package/dist/node/esm/proof/{witness_calculator.js → provers/witness_calculator.js} +0 -0
  92. /package/dist/types/proof/{witness_calculator.d.ts → provers/witness_calculator.d.ts} +0 -0
@@ -0,0 +1,344 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PubSignalsVerifier = exports.userStateError = void 0;
4
+ const js_crypto_1 = require("@iden3/js-crypto");
5
+ const js_iden3_core_1 = require("@iden3/js-iden3-core");
6
+ const js_jsonld_merklization_1 = require("@iden3/js-jsonld-merklization");
7
+ const utils_1 = require("../../utils");
8
+ const verifiable_1 = require("../../verifiable");
9
+ const atomic_query_mtp_v2_1 = require("../../circuits/atomic-query-mtp-v2");
10
+ const atomic_query_sig_v2_1 = require("../../circuits/atomic-query-sig-v2");
11
+ const atomic_query_v3_1 = require("../../circuits/atomic-query-v3");
12
+ const auth_v2_1 = require("../../circuits/auth-v2");
13
+ const common_1 = require("../../circuits/common");
14
+ const linked_multi_query_1 = require("../../circuits/linked-multi-query");
15
+ const models_1 = require("../../circuits/models");
16
+ const query_1 = require("./query");
17
+ const common_2 = require("../common");
18
+ exports.userStateError = new Error(`user state is not valid`);
19
+ const zeroInt = 0n;
20
+ const defaultProofVerifyOpts = 1 * 60 * 60 * 1000; // 1 hour
21
+ const defaultAuthVerifyOpts = 5 * 60 * 1000; // 5 minutes
22
+ /**
23
+ * PubSignalsVerifier provides verify method
24
+ * @public
25
+ * @class PubSignalsVerifier
26
+ */
27
+ class PubSignalsVerifier {
28
+ /**
29
+ * Creates an instance of PubSignalsVerifier.
30
+ * @param {DocumentLoader} _documentLoader document loader
31
+ * @param {IStateStorage} _stateStorage state storage
32
+ */
33
+ constructor(_documentLoader, _stateStorage) {
34
+ this._documentLoader = _documentLoader;
35
+ this._stateStorage = _stateStorage;
36
+ this.credentialAtomicQueryMTPV2Verify = async ({ query, verifiablePresentation, sender, challenge, pubSignals, opts }) => {
37
+ let mtpv2PubSignals = new atomic_query_mtp_v2_1.AtomicQueryMTPV2PubSignals();
38
+ mtpv2PubSignals = mtpv2PubSignals.pubSignalsUnmarshal(utils_1.byteEncoder.encode(JSON.stringify(pubSignals)));
39
+ if (!mtpv2PubSignals.userID) {
40
+ throw new Error('user id is not presented in proof public signals');
41
+ }
42
+ if (!mtpv2PubSignals.requestID) {
43
+ throw new Error('requestId is not presented in proof public signals');
44
+ }
45
+ this.userId = mtpv2PubSignals.userID;
46
+ this.challenge = mtpv2PubSignals.requestID;
47
+ // verify query
48
+ const outs = {
49
+ issuerId: mtpv2PubSignals.issuerID,
50
+ schemaHash: mtpv2PubSignals.claimSchema,
51
+ slotIndex: mtpv2PubSignals.slotIndex,
52
+ operator: mtpv2PubSignals.operator,
53
+ value: mtpv2PubSignals.value,
54
+ timestamp: mtpv2PubSignals.timestamp,
55
+ merklized: mtpv2PubSignals.merklized,
56
+ claimPathKey: mtpv2PubSignals.claimPathKey,
57
+ claimPathNotExists: mtpv2PubSignals.claimPathNotExists,
58
+ valueArraySize: mtpv2PubSignals.getValueArrSize(),
59
+ isRevocationChecked: mtpv2PubSignals.isRevocationChecked
60
+ };
61
+ await (0, query_1.checkQueryRequest)(query, outs, models_1.CircuitId.AtomicQueryMTPV2, this._documentLoader, verifiablePresentation, opts);
62
+ // verify state
63
+ await this.checkStateExistenceForId(mtpv2PubSignals.issuerID, mtpv2PubSignals.issuerClaimIdenState);
64
+ if (mtpv2PubSignals.isRevocationChecked !== 0) {
65
+ await this.checkRevocationState(mtpv2PubSignals.issuerID, mtpv2PubSignals.issuerClaimNonRevState, opts);
66
+ }
67
+ // verify ID ownership
68
+ this.verifyIdOwnership(sender, challenge);
69
+ return mtpv2PubSignals;
70
+ };
71
+ this.credentialAtomicQuerySigV2Verify = async ({ query, verifiablePresentation, sender, challenge, pubSignals, opts }) => {
72
+ let sigV2PubSignals = new atomic_query_sig_v2_1.AtomicQuerySigV2PubSignals();
73
+ sigV2PubSignals = sigV2PubSignals.pubSignalsUnmarshal(utils_1.byteEncoder.encode(JSON.stringify(pubSignals)));
74
+ this.userId = sigV2PubSignals.userID;
75
+ this.challenge = sigV2PubSignals.requestID;
76
+ // verify query
77
+ const outs = {
78
+ issuerId: sigV2PubSignals.issuerID,
79
+ schemaHash: sigV2PubSignals.claimSchema,
80
+ slotIndex: sigV2PubSignals.slotIndex,
81
+ operator: sigV2PubSignals.operator,
82
+ value: sigV2PubSignals.value,
83
+ timestamp: sigV2PubSignals.timestamp,
84
+ merklized: sigV2PubSignals.merklized,
85
+ claimPathKey: sigV2PubSignals.claimPathKey,
86
+ claimPathNotExists: sigV2PubSignals.claimPathNotExists,
87
+ valueArraySize: sigV2PubSignals.getValueArrSize(),
88
+ isRevocationChecked: sigV2PubSignals.isRevocationChecked
89
+ };
90
+ await (0, query_1.checkQueryRequest)(query, outs, models_1.CircuitId.AtomicQuerySigV2, this._documentLoader, verifiablePresentation, opts);
91
+ // verify state
92
+ await this.checkStateExistenceForId(sigV2PubSignals.issuerID, sigV2PubSignals.issuerAuthState);
93
+ if (sigV2PubSignals.isRevocationChecked !== 0) {
94
+ await this.checkRevocationState(sigV2PubSignals.issuerID, sigV2PubSignals.issuerClaimNonRevState, opts);
95
+ }
96
+ // verify Id ownership
97
+ this.verifyIdOwnership(sender, challenge);
98
+ return sigV2PubSignals;
99
+ };
100
+ this.credentialAtomicQueryV3Verify = async ({ query, verifiablePresentation, sender, challenge, pubSignals, opts, params }) => {
101
+ let v3PubSignals = new atomic_query_v3_1.AtomicQueryV3PubSignals();
102
+ v3PubSignals = v3PubSignals.pubSignalsUnmarshal(utils_1.byteEncoder.encode(JSON.stringify(pubSignals)));
103
+ this.userId = v3PubSignals.userID;
104
+ this.challenge = v3PubSignals.requestID;
105
+ // verify query
106
+ const outs = {
107
+ issuerId: v3PubSignals.issuerID,
108
+ schemaHash: v3PubSignals.claimSchema,
109
+ slotIndex: v3PubSignals.slotIndex,
110
+ operator: v3PubSignals.operator,
111
+ value: v3PubSignals.value,
112
+ timestamp: v3PubSignals.timestamp,
113
+ merklized: v3PubSignals.merklized,
114
+ claimPathKey: v3PubSignals.claimPathKey,
115
+ claimPathNotExists: v3PubSignals.claimPathNotExists,
116
+ valueArraySize: v3PubSignals.getValueArrSize(),
117
+ isRevocationChecked: v3PubSignals.isRevocationChecked
118
+ };
119
+ await (0, query_1.checkQueryRequest)(query, outs, models_1.CircuitId.AtomicQueryV3, this._documentLoader, verifiablePresentation, opts);
120
+ const { proofType, verifierID, nullifier, nullifierSessionID, linkID } = v3PubSignals;
121
+ switch (query.proofType) {
122
+ case verifiable_1.ProofType.BJJSignature:
123
+ if (proofType !== 1) {
124
+ throw new Error('wrong proof type for BJJSignature');
125
+ }
126
+ break;
127
+ case verifiable_1.ProofType.Iden3SparseMerkleTreeProof:
128
+ if (proofType !== 2) {
129
+ throw new Error('wrong proof type for Iden3SparseMerkleTreeProof');
130
+ }
131
+ break;
132
+ default:
133
+ throw new Error('invalid proof type');
134
+ }
135
+ const nSessionId = BigInt(params?.nullifierSessionId ?? 0);
136
+ if (nSessionId !== 0n) {
137
+ if (BigInt(nullifier ?? 0) === 0n) {
138
+ throw new Error('nullifier should be provided for nullification and should not be 0');
139
+ }
140
+ // verify nullifier information
141
+ const verifierDIDParam = params?.verifierDid;
142
+ if (!verifierDIDParam) {
143
+ throw new Error('verifierDid is required');
144
+ }
145
+ const id = js_iden3_core_1.DID.idFromDID(verifierDIDParam);
146
+ if (verifierID.bigInt() != id.bigInt()) {
147
+ throw new Error('wrong verifier is used for nullification');
148
+ }
149
+ if (nullifierSessionID !== nSessionId) {
150
+ throw new Error(`wrong verifier session id is used for nullification, expected ${nSessionId}, got ${nullifierSessionID}`);
151
+ }
152
+ }
153
+ else if (nullifierSessionID !== 0n) {
154
+ throw new Error(`Nullifier id is generated but wasn't requested`);
155
+ }
156
+ if (!query.groupId && linkID !== 0n) {
157
+ throw new Error(`proof contains link id, but group id is not provided`);
158
+ }
159
+ if (query.groupId && linkID === 0n) {
160
+ throw new Error("proof doesn't contain link id, but group id is provided");
161
+ }
162
+ // verify state
163
+ await this.checkStateExistenceForId(v3PubSignals.issuerID, v3PubSignals.issuerState);
164
+ if (v3PubSignals.isRevocationChecked !== 0) {
165
+ await this.checkRevocationState(v3PubSignals.issuerID, v3PubSignals.issuerClaimNonRevState, opts);
166
+ }
167
+ this.verifyIdOwnership(sender, challenge);
168
+ return v3PubSignals;
169
+ };
170
+ this.authV2Verify = async ({ sender, challenge, pubSignals, opts }) => {
171
+ let authV2PubSignals = new auth_v2_1.AuthV2PubSignals();
172
+ authV2PubSignals = authV2PubSignals.pubSignalsUnmarshal(utils_1.byteEncoder.encode(JSON.stringify(pubSignals)));
173
+ this.userId = authV2PubSignals.userID;
174
+ this.challenge = authV2PubSignals.challenge;
175
+ // no query verification
176
+ // verify state
177
+ const gist = await this.checkGlobalState(authV2PubSignals.GISTRoot);
178
+ let acceptedStateTransitionDelay = defaultAuthVerifyOpts;
179
+ if (opts?.acceptedStateTransitionDelay) {
180
+ acceptedStateTransitionDelay = opts.acceptedStateTransitionDelay;
181
+ }
182
+ if (!gist.latest) {
183
+ const timeDiff = Date.now() - (0, js_iden3_core_1.getDateFromUnixTimestamp)(Number(gist.transitionTimestamp)).getTime();
184
+ if (timeDiff > acceptedStateTransitionDelay) {
185
+ throw new Error('global state is outdated');
186
+ }
187
+ }
188
+ // verify Id ownership
189
+ this.verifyIdOwnership(sender, challenge);
190
+ return new common_1.BaseConfig();
191
+ };
192
+ this.linkedMultiQuery10Verify = async ({ query, pubSignals }) => {
193
+ let multiQueryPubSignals = new linked_multi_query_1.LinkedMultiQueryPubSignals();
194
+ multiQueryPubSignals = multiQueryPubSignals.pubSignalsUnmarshal(utils_1.byteEncoder.encode(JSON.stringify(pubSignals)));
195
+ // verify query
196
+ let schema;
197
+ const ldOpts = { documentLoader: this._documentLoader };
198
+ try {
199
+ schema = (await ldOpts.documentLoader(query.context || '')).document;
200
+ }
201
+ catch (e) {
202
+ throw new Error(`can't load schema for request query`);
203
+ }
204
+ const ldContextJSON = JSON.stringify(schema);
205
+ const credentialSubject = query.credentialSubject;
206
+ const schemaId = await js_jsonld_merklization_1.Path.getTypeIDFromContext(JSON.stringify(schema), query.type || '', ldOpts);
207
+ const schemaHash = (0, verifiable_1.caclulateCoreSchemaHash)(utils_1.byteEncoder.encode(schemaId));
208
+ const queriesMetadata = await (0, common_2.parseQueriesMetadata)(query.type || '', ldContextJSON, credentialSubject, ldOpts);
209
+ const queryHashes = queriesMetadata.map((queryMeta) => {
210
+ const valueHash = js_crypto_1.poseidon.spongeHashX(queryMeta.values, 6);
211
+ return js_crypto_1.poseidon.hash([
212
+ schemaHash.bigInt(),
213
+ BigInt(queryMeta.slotIndex),
214
+ BigInt(queryMeta.operator),
215
+ BigInt(queryMeta.claimPathKey),
216
+ queryMeta.merklizedSchema ? 0n : 1n,
217
+ valueHash
218
+ ]);
219
+ });
220
+ const circuitQueryHashes = multiQueryPubSignals.circuitQueryHash
221
+ .filter((i) => i !== 0n)
222
+ .sort(utils_1.bigIntCompare);
223
+ queryHashes.sort(utils_1.bigIntCompare);
224
+ if (!queryHashes.every((queryHash, i) => queryHash === circuitQueryHashes[i])) {
225
+ throw new Error('query hashes do not match');
226
+ }
227
+ return multiQueryPubSignals;
228
+ };
229
+ this.verifyIdOwnership = (sender, challenge) => {
230
+ const senderId = js_iden3_core_1.DID.idFromDID(js_iden3_core_1.DID.parse(sender));
231
+ if (senderId.string() !== this.userId.string()) {
232
+ throw new Error(`sender id is not used for proof creation, expected ${sender}, user from public signals: ${this.userId.string()}`);
233
+ }
234
+ if (challenge !== this.challenge) {
235
+ throw new Error(`challenge is not used for proof creation, expected ${challenge}, challenge from public signals: ${this.challenge} `);
236
+ }
237
+ };
238
+ this.checkStateExistenceForId = async (userId, userState) => {
239
+ const { latest } = await this.resolve(userId, userState.bigInt());
240
+ if (!latest) {
241
+ throw exports.userStateError;
242
+ }
243
+ };
244
+ this.checkGlobalState = async (state) => {
245
+ const gistStateResolved = await this.rootResolve(state.bigInt());
246
+ return gistStateResolved;
247
+ };
248
+ this.checkRevocationStateForId = async (issuerId, issuerClaimNonRevState) => {
249
+ const issuerNonRevStateResolved = await this.resolve(issuerId, issuerClaimNonRevState.bigInt());
250
+ return issuerNonRevStateResolved;
251
+ };
252
+ this.checkRevocationState = async (issuerID, issuerClaimNonRevState, opts) => {
253
+ const issuerNonRevStateResolved = await this.checkRevocationStateForId(issuerID, issuerClaimNonRevState);
254
+ const acceptedStateTransitionDelay = opts?.acceptedStateTransitionDelay ?? defaultProofVerifyOpts;
255
+ if (!issuerNonRevStateResolved.latest) {
256
+ const timeDiff = Date.now() -
257
+ (0, js_iden3_core_1.getDateFromUnixTimestamp)(Number(issuerNonRevStateResolved.transitionTimestamp)).getTime();
258
+ if (timeDiff > acceptedStateTransitionDelay) {
259
+ throw new Error('issuer state is outdated');
260
+ }
261
+ }
262
+ };
263
+ }
264
+ /**
265
+ * verify public signals
266
+ *
267
+ * @param {string} circuitId circuit id
268
+ * @param {VerifyContext} ctx verification parameters
269
+ * @returns `Promise<BaseConfig>`
270
+ */
271
+ async verify(circuitId, ctx) {
272
+ const fnName = `${circuitId.split('-')[0]}Verify`;
273
+ const fn = this[fnName];
274
+ if (!fn) {
275
+ throw new Error(`public signals verifier for ${circuitId} not found`);
276
+ }
277
+ return fn(ctx);
278
+ }
279
+ async resolve(id, state) {
280
+ const idBigInt = id.bigInt();
281
+ const did = js_iden3_core_1.DID.parseFromId(id);
282
+ // check if id is genesis
283
+ const isGenesis = (0, utils_1.isGenesisState)(did, state);
284
+ let contractState;
285
+ try {
286
+ contractState = await this._stateStorage.getStateInfoByIdAndState(idBigInt, state);
287
+ }
288
+ catch (e) {
289
+ if (e.errorArgs[0] === 'State does not exist') {
290
+ if (isGenesis) {
291
+ return {
292
+ latest: true,
293
+ transitionTimestamp: 0
294
+ };
295
+ }
296
+ throw new Error('State is not genesis and not registered in the smart contract');
297
+ }
298
+ throw e;
299
+ }
300
+ if (!contractState.id || contractState.id.toString() !== idBigInt.toString()) {
301
+ throw new Error(`state was recorded for another identity`);
302
+ }
303
+ if (!contractState.state || contractState.state.toString() !== state.toString()) {
304
+ if (!contractState.replacedAtTimestamp ||
305
+ contractState.replacedAtTimestamp.toString() === zeroInt.toString()) {
306
+ throw new Error(`no information about state transition`);
307
+ }
308
+ return {
309
+ latest: false,
310
+ transitionTimestamp: contractState.replacedAtTimestamp.toString()
311
+ };
312
+ }
313
+ return { latest: true, transitionTimestamp: 0 };
314
+ }
315
+ async rootResolve(state) {
316
+ let globalStateInfo;
317
+ try {
318
+ globalStateInfo = await this._stateStorage.getGISTRootInfo(state);
319
+ }
320
+ catch (e) {
321
+ if (e.errorArgs[0] === 'Root does not exist') {
322
+ throw new Error('GIST root does not exist in the smart contract');
323
+ }
324
+ throw e;
325
+ }
326
+ if (globalStateInfo.root.toString() !== state.toString()) {
327
+ throw new Error(`gist info contains invalid state`);
328
+ }
329
+ if (globalStateInfo.replacedByRoot.toString() !== zeroInt.toString()) {
330
+ if (globalStateInfo.replacedAtTimestamp.toString() === zeroInt.toString()) {
331
+ throw new Error(`state was replaced, but replaced time unknown`);
332
+ }
333
+ return {
334
+ latest: false,
335
+ transitionTimestamp: globalStateInfo.replacedAtTimestamp.toString()
336
+ };
337
+ }
338
+ return {
339
+ latest: true,
340
+ transitionTimestamp: 0
341
+ };
342
+ }
343
+ }
344
+ exports.PubSignalsVerifier = PubSignalsVerifier;
@@ -0,0 +1,190 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.checkQueryRequest = void 0;
4
+ const js_iden3_core_1 = require("@iden3/js-iden3-core");
5
+ const js_jsonld_merklization_1 = require("@iden3/js-jsonld-merklization");
6
+ const utils_1 = require("../../utils");
7
+ const comparer_1 = require("../../circuits/comparer");
8
+ const verifiable_1 = require("../../verifiable");
9
+ const common_1 = require("../common");
10
+ const provers_1 = require("../provers");
11
+ const defaultProofGenerationDelayOpts = 24 * 60 * 60 * 1000; // 24 hours
12
+ async function checkQueryRequest(query, outputs, circuitId, schemaLoader, verifiablePresentation, opts) {
13
+ // validate issuer
14
+ const userDID = js_iden3_core_1.DID.parseFromId(outputs.issuerId);
15
+ const issuerAllowed = !query.allowedIssuers ||
16
+ query.allowedIssuers?.some((issuer) => issuer === '*' || issuer === userDID.string());
17
+ if (!issuerAllowed) {
18
+ throw new Error('issuer is not in allowed list');
19
+ }
20
+ // validate schema
21
+ let schema;
22
+ try {
23
+ const loader = schemaLoader ?? (0, js_jsonld_merklization_1.getDocumentLoader)();
24
+ schema = (await loader(query.context ?? '')).document;
25
+ }
26
+ catch (e) {
27
+ throw new Error(`can't load schema for request query`);
28
+ }
29
+ if (!query.type) {
30
+ throw new Error(`proof query type is undefined`);
31
+ }
32
+ const schemaId = await js_jsonld_merklization_1.Path.getTypeIDFromContext(JSON.stringify(schema), query.type, {
33
+ documentLoader: schemaLoader
34
+ });
35
+ const schemaHash = (0, verifiable_1.caclulateCoreSchemaHash)(utils_1.byteEncoder.encode(schemaId));
36
+ if (schemaHash.bigInt() !== outputs.schemaHash.bigInt()) {
37
+ throw new Error(`schema that was used is not equal to requested in query`);
38
+ }
39
+ if (!query.skipClaimRevocationCheck && outputs.isRevocationChecked === 0) {
40
+ throw new Error(`check revocation is required`);
41
+ }
42
+ const queriesMetadata = await (0, common_1.parseQueriesMetadata)(query.type, JSON.stringify(schema), query.credentialSubject, {
43
+ documentLoader: schemaLoader
44
+ });
45
+ const circuitValidationData = provers_1.circuitValidator[circuitId];
46
+ if (queriesMetadata.length > circuitValidationData.maxQueriesCount) {
47
+ throw new Error(`circuit ${circuitId} supports only ${provers_1.circuitValidator[circuitId].maxQueriesCount} queries`);
48
+ }
49
+ const notSupportedOpIndx = queriesMetadata.findIndex((i) => !circuitValidationData.supportedOperations.includes(i.operator));
50
+ if (notSupportedOpIndx > -1) {
51
+ throw new Error(`circuit ${circuitId} not support ${queriesMetadata[notSupportedOpIndx].operator} operator`);
52
+ }
53
+ queriesMetadata.forEach(async (metadata) => {
54
+ if (!query.type) {
55
+ throw new Error(`proof query type is undefined`);
56
+ }
57
+ // validate selective disclosure
58
+ if (metadata.operator === comparer_1.Operators.SD) {
59
+ try {
60
+ await validateDisclosure(metadata, outputs, verifiablePresentation, schemaLoader);
61
+ }
62
+ catch (e) {
63
+ throw new Error(`failed to validate selective disclosure: ${e.message}`);
64
+ }
65
+ }
66
+ else if (!metadata.fieldName && metadata.operator == comparer_1.Operators.NOOP) {
67
+ try {
68
+ await validateEmptyCredentialSubject(metadata, outputs);
69
+ return;
70
+ }
71
+ catch (e) {
72
+ throw new Error(`failed to validate operators: ${e.message}`);
73
+ }
74
+ }
75
+ else {
76
+ try {
77
+ await validateOperators(metadata, outputs);
78
+ }
79
+ catch (e) {
80
+ throw new Error(`failed to validate operators: ${e.message}`);
81
+ }
82
+ }
83
+ // verify claim
84
+ if (outputs.merklized === 1) {
85
+ if (outputs.claimPathNotExists === 1) {
86
+ throw new Error(`proof doesn't contains target query key`);
87
+ }
88
+ if (outputs.claimPathKey !== metadata.claimPathKey) {
89
+ throw new Error(`proof was generated for another path`);
90
+ }
91
+ }
92
+ else {
93
+ if (outputs.slotIndex !== metadata.slotIndex) {
94
+ throw new Error(`wrong claim slot was used in claim`);
95
+ }
96
+ }
97
+ // verify timestamp
98
+ let acceptedProofGenerationDelay = defaultProofGenerationDelayOpts;
99
+ if (opts?.acceptedProofGenerationDelay) {
100
+ acceptedProofGenerationDelay = opts.acceptedProofGenerationDelay;
101
+ }
102
+ const timeDiff = Date.now() - (0, js_iden3_core_1.getDateFromUnixTimestamp)(Number(outputs.timestamp)).getTime();
103
+ if (timeDiff > acceptedProofGenerationDelay) {
104
+ throw new Error('generated proof is outdated');
105
+ }
106
+ });
107
+ return;
108
+ }
109
+ exports.checkQueryRequest = checkQueryRequest;
110
+ async function validateEmptyCredentialSubject(cq, outputs) {
111
+ if (outputs.operator !== comparer_1.Operators.EQ) {
112
+ throw new Error('empty credentialSubject request available only for equal operation');
113
+ }
114
+ for (let index = 1; index < outputs.value.length; index++) {
115
+ if (outputs.value[index] !== 0n) {
116
+ throw new Error(`empty credentialSubject request not available for array of values`);
117
+ }
118
+ }
119
+ const path = js_jsonld_merklization_1.Path.newPath([verifiable_1.VerifiableConstants.CREDENTIAL_SUBJECT_PATH]);
120
+ const subjectEntry = await path.mtEntry();
121
+ if (outputs.claimPathKey !== subjectEntry) {
122
+ throw new Error(`proof doesn't contain credentialSubject in claimPathKey`);
123
+ }
124
+ return;
125
+ }
126
+ async function validateOperators(cq, outputs) {
127
+ if (outputs.operator !== cq.operator) {
128
+ throw new Error(`operator that was used is not equal to request`);
129
+ }
130
+ if (outputs.operator === comparer_1.Operators.NOOP) {
131
+ // for noop operator slot and value are not used in this case
132
+ return;
133
+ }
134
+ for (let index = 0; index < outputs.value.length; index++) {
135
+ if (outputs.value[index] !== cq.values[index]) {
136
+ throw new Error(`comparison value that was used is not equal to requested in query`);
137
+ }
138
+ }
139
+ }
140
+ async function validateDisclosure(cq, outputs, verifiablePresentation, ldLoader) {
141
+ if (!verifiablePresentation) {
142
+ throw new Error(`verifiablePresentation is required for selective disclosure request`);
143
+ }
144
+ if (outputs.operator !== comparer_1.Operators.EQ) {
145
+ throw new Error(`operator for selective disclosure must be $eq`);
146
+ }
147
+ for (let index = 1; index < outputs.value.length; index++) {
148
+ if (outputs.value[index] !== 0n) {
149
+ throw new Error(`selective disclosure not available for array of values`);
150
+ }
151
+ }
152
+ let mz;
153
+ const strVerifiablePresentation = JSON.stringify(verifiablePresentation);
154
+ try {
155
+ mz = await js_jsonld_merklization_1.Merklizer.merklizeJSONLD(strVerifiablePresentation, {
156
+ documentLoader: ldLoader
157
+ });
158
+ }
159
+ catch (e) {
160
+ throw new Error(`can't merklize verifiablePresentation`);
161
+ }
162
+ let merklizedPath;
163
+ try {
164
+ const p = `verifiableCredential.credentialSubject.${cq.fieldName}`;
165
+ merklizedPath = await js_jsonld_merklization_1.Path.fromDocument(null, strVerifiablePresentation, p, {
166
+ documentLoader: ldLoader
167
+ });
168
+ }
169
+ catch (e) {
170
+ throw new Error(`can't build path to '${cq.fieldName}' key`);
171
+ }
172
+ let proof;
173
+ let value;
174
+ try {
175
+ ({ proof, value } = await mz.proof(merklizedPath));
176
+ }
177
+ catch (e) {
178
+ throw new Error(`can't get value by path '${cq.fieldName}'`);
179
+ }
180
+ if (!value) {
181
+ throw new Error(`can't get merkle value for field '${cq.fieldName}'`);
182
+ }
183
+ if (!proof.existence) {
184
+ throw new Error(`path [${merklizedPath.parts}] doesn't exist in verifiablePresentation document`);
185
+ }
186
+ const bi = await value.mtEntry();
187
+ if (bi !== outputs.value[0]) {
188
+ throw new Error(`value that was used is not equal to requested in query`);
189
+ }
190
+ }