@0xpolygonid/js-sdk 1.5.0 → 1.6.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 (83) hide show
  1. package/dist/browser/esm/index.js +1685 -468
  2. package/dist/browser/esm/index.js.map +1 -1
  3. package/dist/browser/umd/index.js +1706 -473
  4. package/dist/browser/umd/index.js.map +1 -1
  5. package/dist/node/cjs/circuits/atomic-query-mtp-v2-on-chain.js +1 -1
  6. package/dist/node/cjs/circuits/atomic-query-mtp-v2.js +1 -1
  7. package/dist/node/cjs/circuits/atomic-query-sig-v2-on-chain.js +2 -2
  8. package/dist/node/cjs/circuits/atomic-query-sig-v2.js +11 -14
  9. package/dist/node/cjs/circuits/atomic-query-v3-on-chain.js +320 -0
  10. package/dist/node/cjs/circuits/atomic-query-v3.js +275 -0
  11. package/dist/node/cjs/circuits/common.js +5 -7
  12. package/dist/node/cjs/circuits/comparer.js +57 -2
  13. package/dist/node/cjs/circuits/index.js +4 -0
  14. package/dist/node/cjs/circuits/linked-multi-query.js +128 -0
  15. package/dist/node/cjs/circuits/linked-nullifier.js +57 -0
  16. package/dist/node/cjs/circuits/models.js +25 -1
  17. package/dist/node/cjs/credentials/credential-wallet.js +2 -10
  18. package/dist/node/cjs/credentials/index.js +1 -0
  19. package/dist/node/cjs/credentials/utils.js +23 -0
  20. package/dist/node/cjs/iden3comm/handlers/auth.js +49 -8
  21. package/dist/node/cjs/iden3comm/handlers/contract-request.js +20 -8
  22. package/dist/node/cjs/proof/common.js +104 -1
  23. package/dist/node/cjs/proof/inputs-generator.js +393 -0
  24. package/dist/node/cjs/proof/proof-service.js +105 -372
  25. package/dist/node/cjs/schema-processor/json/parser.js +7 -0
  26. package/dist/node/cjs/schema-processor/json/validator.js +1 -0
  27. package/dist/node/cjs/storage/filters/jsonQuery.js +73 -8
  28. package/dist/node/cjs/utils/did-helper.js +14 -0
  29. package/dist/node/cjs/utils/index.js +2 -0
  30. package/dist/node/cjs/utils/object.js +42 -0
  31. package/dist/node/cjs/verifiable/presentation.js +34 -33
  32. package/dist/node/cjs/verifiable/proof.js +2 -0
  33. package/dist/node/esm/circuits/atomic-query-mtp-v2-on-chain.js +1 -1
  34. package/dist/node/esm/circuits/atomic-query-mtp-v2.js +1 -1
  35. package/dist/node/esm/circuits/atomic-query-sig-v2-on-chain.js +2 -2
  36. package/dist/node/esm/circuits/atomic-query-sig-v2.js +11 -14
  37. package/dist/node/esm/circuits/atomic-query-v3-on-chain.js +315 -0
  38. package/dist/node/esm/circuits/atomic-query-v3.js +270 -0
  39. package/dist/node/esm/circuits/common.js +4 -6
  40. package/dist/node/esm/circuits/comparer.js +55 -1
  41. package/dist/node/esm/circuits/index.js +4 -0
  42. package/dist/node/esm/circuits/linked-multi-query.js +123 -0
  43. package/dist/node/esm/circuits/linked-nullifier.js +52 -0
  44. package/dist/node/esm/circuits/models.js +25 -1
  45. package/dist/node/esm/credentials/credential-wallet.js +2 -10
  46. package/dist/node/esm/credentials/index.js +1 -0
  47. package/dist/node/esm/credentials/utils.js +19 -0
  48. package/dist/node/esm/iden3comm/handlers/auth.js +50 -9
  49. package/dist/node/esm/iden3comm/handlers/contract-request.js +20 -8
  50. package/dist/node/esm/proof/common.js +101 -2
  51. package/dist/node/esm/proof/inputs-generator.js +389 -0
  52. package/dist/node/esm/proof/proof-service.js +111 -377
  53. package/dist/node/esm/schema-processor/json/parser.js +7 -0
  54. package/dist/node/esm/schema-processor/json/validator.js +1 -0
  55. package/dist/node/esm/storage/filters/jsonQuery.js +74 -9
  56. package/dist/node/esm/utils/did-helper.js +10 -0
  57. package/dist/node/esm/utils/index.js +2 -0
  58. package/dist/node/esm/utils/object.js +38 -0
  59. package/dist/node/esm/verifiable/presentation.js +30 -29
  60. package/dist/node/esm/verifiable/proof.js +2 -0
  61. package/dist/types/circuits/atomic-query-mtp-v2.d.ts +13 -13
  62. package/dist/types/circuits/atomic-query-v3-on-chain.d.ts +142 -0
  63. package/dist/types/circuits/atomic-query-v3.d.ts +120 -0
  64. package/dist/types/circuits/common.d.ts +4 -4
  65. package/dist/types/circuits/comparer.d.ts +33 -1
  66. package/dist/types/circuits/index.d.ts +4 -0
  67. package/dist/types/circuits/linked-multi-query.d.ts +38 -0
  68. package/dist/types/circuits/linked-nullifier.d.ts +37 -0
  69. package/dist/types/circuits/models.d.ts +20 -2
  70. package/dist/types/credentials/index.d.ts +1 -0
  71. package/dist/types/credentials/utils.d.ts +12 -0
  72. package/dist/types/iden3comm/types/packer.d.ts +1 -2
  73. package/dist/types/iden3comm/types/protocol/auth.d.ts +1 -0
  74. package/dist/types/proof/common.d.ts +34 -3
  75. package/dist/types/proof/inputs-generator.d.ts +46 -0
  76. package/dist/types/proof/proof-service.d.ts +14 -25
  77. package/dist/types/schema-processor/json/parser.d.ts +1 -0
  78. package/dist/types/storage/filters/jsonQuery.d.ts +1 -1
  79. package/dist/types/utils/did-helper.d.ts +6 -0
  80. package/dist/types/utils/index.d.ts +2 -0
  81. package/dist/types/utils/object.d.ts +12 -0
  82. package/dist/types/verifiable/presentation.d.ts +6 -10
  83. package/package.json +3 -3
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.bJJSignatureFromHexString = exports.ProofService = void 0;
3
+ exports.ProofService = void 0;
4
4
  const js_crypto_1 = require("@iden3/js-crypto");
5
5
  const js_iden3_core_1 = require("@iden3/js-iden3-core");
6
6
  const js_merkletree_1 = require("@iden3/js-merkletree");
@@ -11,6 +11,7 @@ const prover_1 = require("./prover");
11
11
  const js_jsonld_merklization_1 = require("@iden3/js-jsonld-merklization");
12
12
  const schema_processor_1 = require("../schema-processor");
13
13
  const encoding_1 = require("../utils/encoding");
14
+ const inputs_generator_1 = require("./inputs-generator");
14
15
  /**
15
16
  * Proof service is an implementation of IProofService
16
17
  * that works with a native groth16 prover
@@ -33,6 +34,7 @@ class ProofService {
33
34
  this._stateStorage = _stateStorage;
34
35
  this._prover = opts?.prover ?? new prover_1.NativeProver(_circuitStorage);
35
36
  this._ldOptions = { ...opts, documentLoader: opts?.documentLoader ?? (0, schema_processor_1.cacheLoader)(opts) };
37
+ this._inputsGenerator = new inputs_generator_1.InputGenerator(_identityWallet, _credentialWallet, _stateStorage);
36
38
  }
37
39
  /** {@inheritdoc IProofService.verifyProof} */
38
40
  async verifyProof(zkp, circuitId) {
@@ -46,20 +48,61 @@ class ProofService {
46
48
  challenge: 0n
47
49
  };
48
50
  }
49
- // find credential
50
- const credential = opts.credential ?? (await this.findCredential(identifier, proofReq.query));
51
+ let credentialWithRevStatus = { cred: opts.credential, revStatus: opts.credentialRevocationStatus };
52
+ if (!opts.credential) {
53
+ credentialWithRevStatus = await this.findCredentialByProofQuery(identifier, proofReq.query);
54
+ }
55
+ if (opts.credential && !opts.credentialRevocationStatus && !opts.skipRevocation) {
56
+ const revStatus = await this._credentialWallet.getRevocationStatusFromCredential(opts.credential);
57
+ credentialWithRevStatus = { cred: opts.credential, revStatus };
58
+ }
59
+ if (!credentialWithRevStatus.cred) {
60
+ throw new Error(`credential not found for query ${JSON.stringify(proofReq.query)}`);
61
+ }
62
+ const credentialCoreClaim = await this._identityWallet.getCoreClaimFromCredential(credentialWithRevStatus.cred);
51
63
  const { nonce: authProfileNonce, genesisDID } = await this._identityWallet.getGenesisDIDMetadata(identifier);
52
- const preparedCredential = await this.getPreparedCredential(credential);
64
+ const preparedCredential = {
65
+ credential: credentialWithRevStatus.cred,
66
+ credentialCoreClaim,
67
+ revStatus: credentialWithRevStatus.revStatus
68
+ };
53
69
  const subjectDID = js_iden3_core_1.DID.parse(preparedCredential.credential.credentialSubject['id']);
54
70
  const { nonce: credentialSubjectProfileNonce, genesisDID: subjectGenesisDID } = await this._identityWallet.getGenesisDIDMetadata(subjectDID);
55
71
  if (subjectGenesisDID.string() !== genesisDID.string()) {
56
72
  throw new Error('subject and auth profiles are not derived from the same did');
57
73
  }
58
- const { inputs, vp } = await this.generateInputs(preparedCredential, genesisDID, proofReq, {
74
+ const propertiesMetadata = (0, common_1.parseCredentialSubject)(proofReq.query.credentialSubject);
75
+ if (!propertiesMetadata.length) {
76
+ throw new Error('no queries in zkp request');
77
+ }
78
+ const mtPosition = preparedCredential.credentialCoreClaim.getMerklizedPosition();
79
+ let mk;
80
+ if (mtPosition !== js_iden3_core_1.MerklizedRootPosition.None) {
81
+ mk = await preparedCredential.credential.merklize(this._ldOptions);
82
+ }
83
+ const context = proofReq.query['context'];
84
+ const groupId = proofReq.query['groupId'];
85
+ const ldContext = await this.loadLdContext(context);
86
+ const credentialType = proofReq.query['type'];
87
+ const queriesMetadata = [];
88
+ const circuitQueries = [];
89
+ for (const propertyMetadata of propertiesMetadata) {
90
+ const queryMetadata = await (0, common_1.parseQueryMetadata)(propertyMetadata, encoding_1.byteDecoder.decode(ldContext), credentialType, this._ldOptions);
91
+ queriesMetadata.push(queryMetadata);
92
+ const circuitQuery = await this.toCircuitsQuery(preparedCredential.credential, queryMetadata, mk);
93
+ circuitQueries.push(circuitQuery);
94
+ }
95
+ const inputs = await this.generateInputs(preparedCredential, genesisDID, proofReq, {
59
96
  ...opts,
60
97
  authProfileNonce,
61
- credentialSubjectProfileNonce
62
- });
98
+ credentialSubjectProfileNonce,
99
+ linkNonce: groupId ? opts.linkNonce : 0n
100
+ }, circuitQueries);
101
+ const sdQueries = queriesMetadata.filter((q) => q.operator === circuits_1.Operators.SD);
102
+ let vp;
103
+ if (sdQueries.length) {
104
+ vp = (0, verifiable_1.createVerifiablePresentation)(context, credentialType, preparedCredential.credential, sdQueries);
105
+ }
63
106
  const { proof, pub_signals } = await this._prover.generate(inputs, proofReq.circuitId);
64
107
  return {
65
108
  id: proofReq.id,
@@ -71,7 +114,7 @@ class ProofService {
71
114
  }
72
115
  /** {@inheritdoc IProofService.transitState} */
73
116
  async transitState(did, oldTreeState, isOldStateGenesis, stateStorage, ethSigner) {
74
- const authInfo = await this.prepareAuthBJJCredential(did, oldTreeState);
117
+ const authInfo = await this._inputsGenerator.prepareAuthBJJCredential(did, oldTreeState);
75
118
  const newTreeModel = await this._identityWallet.getDIDTreeModel(did);
76
119
  const claimsRoot = await newTreeModel.claimsTree.root();
77
120
  const rootOfRoots = await newTreeModel.rootsTree.root();
@@ -83,17 +126,17 @@ class ProofService {
83
126
  rootOfRoots
84
127
  };
85
128
  const challenge = js_crypto_1.Poseidon.hash([oldTreeState.state.bigInt(), newTreeState.state.bigInt()]);
86
- const signature = await this._identityWallet.signChallenge(challenge, authInfo.authCredential);
129
+ const signature = await this._identityWallet.signChallenge(challenge, authInfo.credential);
87
130
  const circuitInputs = new circuits_1.StateTransitionInputs();
88
131
  circuitInputs.id = js_iden3_core_1.DID.idFromDID(did);
89
132
  circuitInputs.signature = signature;
90
133
  circuitInputs.isOldStateGenesis = isOldStateGenesis;
91
- const authClaimIncProofNewState = await this._identityWallet.generateCredentialMtp(did, authInfo.authCredential, newTreeState);
134
+ const authClaimIncProofNewState = await this._identityWallet.generateCredentialMtp(did, authInfo.credential, newTreeState);
92
135
  circuitInputs.newTreeState = authClaimIncProofNewState.treeState;
93
136
  circuitInputs.authClaimNewStateIncProof = authClaimIncProofNewState.proof;
94
137
  circuitInputs.oldTreeState = oldTreeState;
95
138
  circuitInputs.authClaim = {
96
- claim: authInfo.authCoreClaim,
139
+ claim: authInfo.coreClaim,
97
140
  incProof: authInfo.incProof,
98
141
  nonRevProof: authInfo.nonRevProof
99
142
  };
@@ -103,370 +146,65 @@ class ProofService {
103
146
  await this._identityWallet.updateIdentityState(did, true, newTreeState);
104
147
  return txId;
105
148
  }
106
- async getPreparedCredential(credential) {
107
- const revStatus = await this._credentialWallet.getRevocationStatusFromCredential(credential);
108
- const credCoreClaim = await this._identityWallet.getCoreClaimFromCredential(credential);
109
- return { credential, revStatus, credentialCoreClaim: credCoreClaim };
110
- }
111
- async prepareAuthBJJCredential(did, treeStateInfo) {
112
- const authCredential = await this._credentialWallet.getAuthBJJCredential(did);
113
- const incProof = await this._identityWallet.generateCredentialMtp(did, authCredential, treeStateInfo);
114
- const nonRevProof = await this._identityWallet.generateNonRevocationMtp(did, authCredential, treeStateInfo);
115
- const authCoreClaim = authCredential.getCoreClaimFromProof(verifiable_1.ProofType.Iden3SparseMerkleTreeProof);
116
- if (!authCoreClaim) {
117
- throw new Error('auth core claim is not defined for auth bjj credential');
118
- }
119
- return { authCredential, incProof, nonRevProof, authCoreClaim };
120
- }
121
- async generateInputs(preparedCredential, identifier, proofReq, params) {
122
- let generateInputFn;
123
- switch (proofReq.circuitId) {
124
- case circuits_1.CircuitId.AtomicQueryMTPV2:
125
- generateInputFn = this.generateMTPV2Inputs.bind(this);
126
- break;
127
- case circuits_1.CircuitId.AtomicQueryMTPV2OnChain:
128
- generateInputFn = this.generateMTPV2OnChainInputs.bind(this);
129
- break;
130
- case circuits_1.CircuitId.AtomicQuerySigV2:
131
- generateInputFn = this.generateQuerySigV2Inputs.bind(this);
132
- break;
133
- case circuits_1.CircuitId.AtomicQuerySigV2OnChain:
134
- generateInputFn = this.generateQuerySigV2OnChainInputs.bind(this);
135
- break;
136
- default:
137
- throw new Error(`circuit with id ${proofReq.circuitId} is not supported by issuer`);
138
- }
139
- return generateInputFn(preparedCredential, identifier, proofReq, params);
140
- }
141
- async generateMTPV2Inputs(preparedCredential, identifier, proofReq, params) {
142
- const circuitClaimData = await this.newCircuitClaimData(preparedCredential.credential, preparedCredential.credentialCoreClaim);
143
- circuitClaimData.nonRevProof = (0, common_1.toClaimNonRevStatus)(preparedCredential.revStatus);
144
- const circuitInputs = new circuits_1.AtomicQueryMTPV2Inputs();
145
- circuitInputs.id = js_iden3_core_1.DID.idFromDID(identifier);
146
- circuitInputs.requestID = BigInt(proofReq.id);
147
- const { query, vp } = await this.toCircuitsQuery(proofReq.query, preparedCredential.credential, preparedCredential.credentialCoreClaim);
148
- circuitInputs.query = query;
149
- circuitInputs.claim = {
150
- issuerID: circuitClaimData.issuerId,
151
- claim: circuitClaimData.claim,
152
- incProof: { proof: circuitClaimData.proof, treeState: circuitClaimData.treeState },
153
- nonRevProof: circuitClaimData.nonRevProof
154
- };
155
- circuitInputs.currentTimeStamp = (0, js_iden3_core_1.getUnixTimestamp)(new Date());
156
- circuitInputs.claimSubjectProfileNonce = BigInt(params.credentialSubjectProfileNonce);
157
- circuitInputs.profileNonce = BigInt(params.authProfileNonce);
158
- circuitInputs.skipClaimRevocationCheck = params.skipRevocation;
159
- return { inputs: circuitInputs.inputsMarshal(), vp };
160
- }
161
- async generateMTPV2OnChainInputs(preparedCredential, identifier, proofReq, params) {
162
- const circuitClaimData = await this.newCircuitClaimData(preparedCredential.credential, preparedCredential.credentialCoreClaim);
163
- const authPrepared = await this.prepareAuthBJJCredential(identifier);
164
- const authClaimData = await this.newCircuitClaimData(authPrepared.authCredential, authPrepared.authCoreClaim);
165
- circuitClaimData.nonRevProof = (0, common_1.toClaimNonRevStatus)(preparedCredential.revStatus);
166
- const circuitInputs = new circuits_1.AtomicQueryMTPV2OnChainInputs();
167
- const id = js_iden3_core_1.DID.idFromDID(identifier);
168
- circuitInputs.id = js_iden3_core_1.DID.idFromDID(identifier);
169
- circuitInputs.requestID = BigInt(proofReq.id);
170
- const stateProof = await this._stateStorage.getGISTProof(id.bigInt());
171
- const gistProof = (0, common_1.toGISTProof)(stateProof);
172
- circuitInputs.gistProof = gistProof;
173
- if (authClaimData?.treeState) {
174
- circuitInputs.treeState = {
175
- state: authClaimData?.treeState?.state,
176
- claimsRoot: authClaimData?.treeState?.claimsRoot,
177
- revocationRoot: authClaimData?.treeState?.revocationRoot,
178
- rootOfRoots: authClaimData?.treeState?.rootOfRoots
179
- };
180
- }
181
- circuitInputs.authClaim = authClaimData.claim;
182
- circuitInputs.authClaimIncMtp = authClaimData.proof;
183
- circuitInputs.authClaimNonRevMtp = authPrepared.nonRevProof.proof;
184
- if (!params.challenge) {
185
- throw new Error('challenge must be provided for onchain circuits');
186
- }
187
- const signature = await this._identityWallet.signChallenge(params.challenge, authPrepared.authCredential);
188
- circuitInputs.signature = signature;
189
- circuitInputs.challenge = params.challenge;
190
- const { query, vp } = await this.toCircuitsQuery(proofReq.query, preparedCredential.credential, preparedCredential.credentialCoreClaim);
191
- circuitInputs.query = query;
192
- circuitInputs.claim = {
193
- issuerID: circuitClaimData.issuerId,
194
- claim: circuitClaimData.claim,
195
- incProof: { proof: circuitClaimData.proof, treeState: circuitClaimData.treeState },
196
- nonRevProof: circuitClaimData.nonRevProof
197
- };
198
- circuitInputs.currentTimeStamp = (0, js_iden3_core_1.getUnixTimestamp)(new Date());
199
- circuitInputs.claimSubjectProfileNonce = BigInt(params.credentialSubjectProfileNonce);
200
- circuitInputs.profileNonce = BigInt(params.authProfileNonce);
201
- circuitInputs.skipClaimRevocationCheck = params.skipRevocation;
202
- return { inputs: circuitInputs.inputsMarshal(), vp };
203
- }
204
- async generateQuerySigV2Inputs(preparedCredential, identifier, proofReq, params) {
205
- const circuitClaimData = await this.newCircuitClaimData(preparedCredential.credential, preparedCredential.credentialCoreClaim);
206
- circuitClaimData.nonRevProof = (0, common_1.toClaimNonRevStatus)(preparedCredential.revStatus);
207
- const circuitInputs = new circuits_1.AtomicQuerySigV2Inputs();
208
- circuitInputs.id = js_iden3_core_1.DID.idFromDID(identifier);
209
- circuitInputs.claim = {
210
- issuerID: circuitClaimData?.issuerId,
211
- signatureProof: circuitClaimData.signatureProof,
212
- claim: circuitClaimData.claim,
213
- nonRevProof: circuitClaimData.nonRevProof
214
- };
215
- circuitInputs.requestID = BigInt(proofReq.id);
216
- circuitInputs.claimSubjectProfileNonce = BigInt(params.credentialSubjectProfileNonce);
217
- circuitInputs.profileNonce = BigInt(params.authProfileNonce);
218
- circuitInputs.skipClaimRevocationCheck = params.skipRevocation;
219
- const { query, vp } = await this.toCircuitsQuery(proofReq.query, preparedCredential.credential, preparedCredential.credentialCoreClaim);
220
- circuitInputs.query = query;
221
- circuitInputs.currentTimeStamp = (0, js_iden3_core_1.getUnixTimestamp)(new Date());
222
- return { inputs: circuitInputs.inputsMarshal(), vp };
149
+ async generateInputs(preparedCredential, identifier, proofReq, params, circuitQueries) {
150
+ return this._inputsGenerator.generateInputs({
151
+ preparedCredential,
152
+ identifier,
153
+ proofReq,
154
+ params,
155
+ circuitQueries
156
+ });
223
157
  }
224
- async generateQuerySigV2OnChainInputs(preparedCredential, identifier, proofReq, params) {
225
- const circuitClaimData = await this.newCircuitClaimData(preparedCredential.credential, preparedCredential.credentialCoreClaim);
226
- const authPrepared = await this.prepareAuthBJJCredential(identifier);
227
- const authClaimData = await this.newCircuitClaimData(authPrepared.authCredential, authPrepared.authCoreClaim);
228
- circuitClaimData.nonRevProof = (0, common_1.toClaimNonRevStatus)(preparedCredential.revStatus);
229
- const circuitInputs = new circuits_1.AtomicQuerySigV2OnChainInputs();
230
- const id = js_iden3_core_1.DID.idFromDID(identifier);
231
- circuitInputs.id = id;
232
- circuitInputs.claim = {
233
- issuerID: circuitClaimData.issuerId,
234
- signatureProof: circuitClaimData.signatureProof,
235
- claim: circuitClaimData.claim,
236
- nonRevProof: circuitClaimData.nonRevProof
237
- };
238
- circuitInputs.requestID = BigInt(proofReq.id);
239
- circuitInputs.claimSubjectProfileNonce = BigInt(params.credentialSubjectProfileNonce);
240
- circuitInputs.profileNonce = BigInt(params.authProfileNonce);
241
- circuitInputs.skipClaimRevocationCheck = params.skipRevocation;
242
- const { query, vp } = await this.toCircuitsQuery(proofReq.query, preparedCredential.credential, preparedCredential.credentialCoreClaim);
243
- circuitInputs.query = query;
244
- circuitInputs.currentTimeStamp = (0, js_iden3_core_1.getUnixTimestamp)(new Date());
245
- if (authClaimData.treeState) {
246
- circuitInputs.treeState = {
247
- state: authClaimData.treeState?.state,
248
- claimsRoot: authClaimData.treeState?.claimsRoot,
249
- revocationRoot: authClaimData.treeState?.revocationRoot,
250
- rootOfRoots: authClaimData.treeState?.rootOfRoots
251
- };
158
+ async toCircuitsQuery(credential, queryMetadata, merklizedCredential) {
159
+ if (queryMetadata.merklizedSchema && !merklizedCredential) {
160
+ throw new Error('merklized root position is set to None for merklized schema');
252
161
  }
253
- const stateProof = await this._stateStorage.getGISTProof(id.bigInt());
254
- const gistProof = (0, common_1.toGISTProof)(stateProof);
255
- circuitInputs.gistProof = gistProof;
256
- circuitInputs.authClaim = authClaimData.claim;
257
- circuitInputs.authClaimIncMtp = authClaimData.proof;
258
- circuitInputs.authClaimNonRevMtp = authPrepared.nonRevProof.proof;
259
- if (!params.challenge) {
260
- throw new Error('challenge must be provided for onchain circuits');
261
- }
262
- const signature = await this._identityWallet.signChallenge(params.challenge, authPrepared.authCredential);
263
- circuitInputs.signature = signature;
264
- circuitInputs.challenge = params.challenge;
265
- return { inputs: circuitInputs.inputsMarshal(), vp };
266
- }
267
- // NewCircuitClaimData generates circuits claim structure
268
- async newCircuitClaimData(credential, coreClaim) {
269
- const smtProof = credential.getIden3SparseMerkleTreeProof();
270
- const circuitClaim = new circuits_1.CircuitClaim();
271
- circuitClaim.claim = coreClaim;
272
- circuitClaim.issuerId = js_iden3_core_1.DID.idFromDID(js_iden3_core_1.DID.parse(credential.issuer));
273
- if (smtProof) {
274
- circuitClaim.proof = smtProof.mtp;
275
- circuitClaim.treeState = {
276
- state: smtProof.issuerData.state.value,
277
- claimsRoot: smtProof.issuerData.state.claimsTreeRoot,
278
- revocationRoot: smtProof.issuerData.state.revocationTreeRoot,
279
- rootOfRoots: smtProof.issuerData.state.rootOfRoots
280
- };
162
+ if (!queryMetadata.merklizedSchema && merklizedCredential) {
163
+ throw new Error('merklized root position is not set to None for non-merklized schema');
281
164
  }
282
- const sigProof = credential.getBJJSignature2021Proof();
283
- if (sigProof) {
284
- const issuerDID = sigProof.issuerData.id;
285
- let userDID;
286
- if (!credential.credentialSubject.id) {
287
- userDID = issuerDID;
288
- }
289
- else {
290
- if (typeof credential.credentialSubject.id !== 'string') {
291
- throw new Error('credential status `id` is not a string');
292
- }
293
- userDID = js_iden3_core_1.DID.parse(credential.credentialSubject.id);
294
- }
295
- if (!sigProof.issuerData.credentialStatus) {
296
- throw new Error("can't check the validity of issuer auth claim: no credential status in proof");
165
+ const query = new circuits_1.Query();
166
+ query.slotIndex = queryMetadata.slotIndex;
167
+ query.operator = queryMetadata.operator;
168
+ query.values = queryMetadata.values;
169
+ if (queryMetadata.merklizedSchema && merklizedCredential) {
170
+ const { proof, value: mtValue } = await merklizedCredential.proof(queryMetadata.path);
171
+ query.valueProof = new circuits_1.ValueProof();
172
+ query.valueProof.mtp = proof;
173
+ query.valueProof.path = queryMetadata.claimPathKey;
174
+ const mtEntry = await mtValue?.mtEntry();
175
+ if (!mtEntry) {
176
+ throw new Error(`can't merklize credential: no merkle tree entry found`);
297
177
  }
298
- const opts = {
299
- issuerGenesisState: sigProof.issuerData.state,
300
- issuerDID,
301
- userDID
302
- };
303
- const rs = await this._credentialWallet.getRevocationStatus(sigProof.issuerData.credentialStatus, opts);
304
- if (!rs) {
305
- throw new Error("can't fetch the credential status of issuer auth claim");
178
+ query.valueProof.value = mtEntry;
179
+ if (!queryMetadata.fieldName) {
180
+ query.values = [mtEntry];
181
+ return query;
306
182
  }
307
- const issuerAuthNonRevProof = (0, common_1.toClaimNonRevStatus)(rs);
308
- if (!sigProof.issuerData.mtp) {
309
- throw new Error('issuer auth credential must have a mtp proof');
183
+ }
184
+ if (queryMetadata.operator === circuits_1.Operators.SD) {
185
+ const [first, ...rest] = queryMetadata.fieldName.split('.');
186
+ let v = credential.credentialSubject[first];
187
+ for (const part of rest) {
188
+ v = v[part];
310
189
  }
311
- if (!sigProof.issuerData.authCoreClaim) {
312
- throw new Error('issuer auth credential must have a core claim proof');
190
+ if (typeof v === 'undefined') {
191
+ throw new Error(`credential doesn't contain value for field ${queryMetadata.fieldName}`);
313
192
  }
314
- circuitClaim.signatureProof = {
315
- signature: sigProof.signature,
316
- issuerAuthIncProof: {
317
- proof: sigProof.issuerData.mtp,
318
- treeState: {
319
- state: sigProof.issuerData.state.value,
320
- claimsRoot: sigProof.issuerData.state.claimsTreeRoot,
321
- revocationRoot: sigProof.issuerData.state.revocationTreeRoot,
322
- rootOfRoots: sigProof.issuerData.state.rootOfRoots
323
- }
324
- },
325
- issuerAuthClaim: sigProof.issuerData.authCoreClaim,
326
- issuerAuthNonRevProof
327
- };
193
+ query.values = await (0, common_1.transformQueryValueToBigInts)(v, queryMetadata.datatype);
328
194
  }
329
- return circuitClaim;
330
- }
331
- async toCircuitsQuery(query, credential, coreClaim) {
332
- const mtPosition = coreClaim.getMerklizedPosition();
333
- return mtPosition === js_iden3_core_1.MerklizedRootPosition.None
334
- ? this.prepareNonMerklizedQuery(query, credential)
335
- : this.prepareMerklizedQuery(query, credential);
195
+ return query;
336
196
  }
337
- async prepareMerklizedQuery(query, credential) {
338
- const parsedQuery = await this.parseRequest(query.credentialSubject);
339
- const ldContext = await this.loadLdContextFromJSONSchema(credential.credentialSchema.id);
340
- let path = new js_jsonld_merklization_1.Path();
341
- if (parsedQuery.fieldName) {
342
- path = await js_jsonld_merklization_1.Path.getContextPathKey(encoding_1.byteDecoder.decode(ldContext), credential.type[1], parsedQuery.fieldName, this._ldOptions);
343
- }
344
- path.prepend(['https://www.w3.org/2018/credentials#credentialSubject']);
345
- const mk = await credential.merklize(this._ldOptions);
346
- const { proof, value: mtValue } = await mk.proof(path);
347
- const pathKey = await path.mtEntry();
348
- parsedQuery.query.valueProof = new circuits_1.ValueProof();
349
- parsedQuery.query.valueProof.mtp = proof;
350
- parsedQuery.query.valueProof.path = pathKey;
351
- parsedQuery.query.valueProof.mtp = proof;
352
- const mtEntry = await mtValue?.mtEntry();
353
- if (!mtEntry) {
354
- throw new Error(`can't merklize credential: no merkle tree entry found`);
355
- }
356
- parsedQuery.query.valueProof.value = mtEntry;
357
- // for merklized credentials slotIndex in query must be equal to zero
358
- // and not a position of merklization root.
359
- // it has no influence on check in the off-chain circuits, but it aligns with onchain verification standard
360
- parsedQuery.query.slotIndex = 0;
361
- if (!parsedQuery.fieldName) {
362
- const resultQuery = parsedQuery.query;
363
- resultQuery.operator = circuits_1.QueryOperators.$eq;
364
- resultQuery.values = [mtEntry];
365
- return { query: resultQuery };
366
- }
367
- if (parsedQuery.isSelectiveDisclosure) {
368
- const rawValue = mk.rawValue(path);
369
- const vp = (0, verifiable_1.createVerifiablePresentation)(query.context ?? '', query.type ?? '', parsedQuery.fieldName, rawValue);
370
- const resultQuery = parsedQuery.query;
371
- resultQuery.operator = circuits_1.QueryOperators.$eq;
372
- resultQuery.values = [mtEntry];
373
- return { query: resultQuery, vp };
374
- }
375
- if (parsedQuery.rawValue === null || parsedQuery.rawValue === undefined) {
376
- throw new Error('value is not presented in the query');
377
- }
378
- const ldType = await mk.jsonLDType(path);
379
- parsedQuery.query.values = await this.transformQueryValueToBigInts(parsedQuery.rawValue, ldType);
380
- return { query: parsedQuery.query };
381
- }
382
- async prepareNonMerklizedQuery(query, credential) {
383
- const ldContext = await this.loadLdContextFromJSONSchema(credential.credentialSchema.id);
384
- if (query.credentialSubject && Object.keys(query.credentialSubject).length > 1) {
385
- throw new Error('multiple requests are not supported');
386
- }
387
- const parsedQuery = await this.parseRequest(query.credentialSubject);
388
- if (!query.type) {
389
- throw new Error('query type is not defined');
390
- }
391
- parsedQuery.query.slotIndex = await schema_processor_1.Parser.getFieldSlotIndex(parsedQuery.fieldName, query.type, ldContext);
392
- const { vp, mzValue, dataType } = await (0, verifiable_1.verifiablePresentationFromCred)(credential, query, parsedQuery.fieldName, this._ldOptions);
393
- if (parsedQuery.isSelectiveDisclosure) {
394
- const resultQuery = parsedQuery.query;
395
- resultQuery.operator = circuits_1.QueryOperators.$eq;
396
- resultQuery.values = [await mzValue.mtEntry()];
397
- return { query: resultQuery, vp };
398
- }
399
- if (parsedQuery.rawValue === null || parsedQuery.rawValue === undefined) {
400
- throw new Error('value is not presented in the query');
401
- }
402
- parsedQuery.query.values = await this.transformQueryValueToBigInts(parsedQuery.rawValue, dataType);
403
- return { query: parsedQuery.query };
404
- }
405
- async loadLdContextFromJSONSchema(jsonSchemaURL) {
197
+ async loadLdContext(context) {
406
198
  const loader = (0, js_jsonld_merklization_1.getDocumentLoader)(this._ldOptions);
407
- let schema;
408
- try {
409
- schema = (await loader(jsonSchemaURL)).document;
410
- }
411
- catch (e) {
412
- throw new Error(`can't load credential schema ${jsonSchemaURL}`);
413
- }
414
- const jsonSchema = schema;
415
199
  let ldSchema;
416
- let ldContextUrl = '';
417
200
  try {
418
- ldContextUrl = jsonSchema.$metadata.uris['jsonLdContext'];
419
- if (!ldContextUrl) {
420
- throw new Error('ldContext is not defined in json schema metadata');
421
- }
422
- ldSchema = (await loader(ldContextUrl)).document;
201
+ ldSchema = (await loader(context)).document;
423
202
  }
424
203
  catch (e) {
425
- throw new Error(`can't load ld context from url ${ldContextUrl}`);
204
+ throw new Error(`can't load ld context from url ${context}`);
426
205
  }
427
206
  return encoding_1.byteEncoder.encode(JSON.stringify(ldSchema));
428
207
  }
429
- async parseRequest(req) {
430
- if (!req) {
431
- const query = new circuits_1.Query();
432
- query.operator = circuits_1.QueryOperators.$eq;
433
- return { query, fieldName: '' };
434
- }
435
- const entries = Object.entries(req);
436
- if (entries.length > 1) {
437
- throw new Error(`multiple requests not supported`);
438
- }
439
- const [fieldName, fieldReq] = entries[0];
440
- const fieldReqEntries = Object.entries(fieldReq);
441
- if (fieldReqEntries.length > 1) {
442
- throw new Error(`multiple predicates for one field not supported`);
443
- }
444
- const isSelectiveDisclosure = fieldReqEntries.length === 0;
445
- const query = new circuits_1.Query();
446
- if (isSelectiveDisclosure) {
447
- return { query, fieldName, isSelectiveDisclosure };
448
- }
449
- let operator = 0;
450
- const [key, value] = fieldReqEntries[0];
451
- if (!circuits_1.QueryOperators[key]) {
452
- throw new Error(`operator is not supported by lib`);
453
- }
454
- operator = circuits_1.QueryOperators[key];
455
- query.operator = operator;
456
- return { query, fieldName, rawValue: value };
457
- }
458
- async transformQueryValueToBigInts(value, ldType) {
459
- const values = new Array(64).fill(BigInt(0));
460
- if (Array.isArray(value)) {
461
- for (let index = 0; index < value.length; index++) {
462
- values[index] = await js_jsonld_merklization_1.Merklizer.hashValue(ldType, value[index]);
463
- }
464
- }
465
- else {
466
- values[0] = await js_jsonld_merklization_1.Merklizer.hashValue(ldType, value);
467
- }
468
- return values;
469
- }
470
208
  /** {@inheritdoc IProofService.generateAuthV2Inputs} */
471
209
  async generateAuthV2Inputs(hash, did, circuitId) {
472
210
  if (circuitId !== circuits_1.CircuitId.AuthV2) {
@@ -474,9 +212,12 @@ class ProofService {
474
212
  }
475
213
  const { nonce: authProfileNonce, genesisDID } = await this._identityWallet.getGenesisDIDMetadata(did);
476
214
  const challenge = js_iden3_core_1.BytesHelper.bytesToInt(hash.reverse());
477
- const authPrepared = await this.prepareAuthBJJCredential(genesisDID);
478
- const authClaimData = await this.newCircuitClaimData(authPrepared.authCredential, authPrepared.authCoreClaim);
479
- const signature = await this._identityWallet.signChallenge(challenge, authPrepared.authCredential);
215
+ const authPrepared = await this._inputsGenerator.prepareAuthBJJCredential(genesisDID);
216
+ const authClaimData = await this._inputsGenerator.newCircuitClaimData({
217
+ credential: authPrepared.credential,
218
+ credentialCoreClaim: authPrepared.coreClaim
219
+ });
220
+ const signature = await this._identityWallet.signChallenge(challenge, authPrepared.credential);
480
221
  const id = js_iden3_core_1.DID.idFromDID(genesisDID);
481
222
  const stateProof = await this._stateStorage.getGISTProof(id.bigInt());
482
223
  const gistProof = (0, common_1.toGISTProof)(stateProof);
@@ -512,7 +253,7 @@ class ProofService {
512
253
  }
513
254
  return true;
514
255
  }
515
- async findCredential(did, query) {
256
+ async findCredentialByProofQuery(did, query) {
516
257
  const credentials = await this._identityWallet.findOwnedCredentialsByDID(did, query);
517
258
  if (!credentials.length) {
518
259
  throw new Error(`no credentials belong to did or its profiles`);
@@ -520,17 +261,9 @@ class ProofService {
520
261
  // For EQ / IN / NIN / LT / GT operations selective if credential satisfies query - we can get any.
521
262
  // TODO: choose credential for selective credentials
522
263
  const credential = query.skipClaimRevocationCheck
523
- ? credentials[0]
524
- : (await this._credentialWallet.findNonRevokedCredential(credentials)).cred;
264
+ ? { cred: credentials[0], revStatus: undefined }
265
+ : await this._credentialWallet.findNonRevokedCredential(credentials);
525
266
  return credential;
526
267
  }
527
268
  }
528
269
  exports.ProofService = ProofService;
529
- // BJJSignatureFromHexString converts hex to babyjub.Signature
530
- const bJJSignatureFromHexString = async (sigHex) => {
531
- const signatureBytes = js_crypto_1.Hex.decodeString(sigHex);
532
- const compressedSig = Uint8Array.from(signatureBytes).slice(0, 64);
533
- const bjjSig = js_crypto_1.Signature.newFromCompressed(compressedSig);
534
- return bjjSig;
535
- };
536
- exports.bJJSignatureFromHexString = bJJSignatureFromHexString;
@@ -152,6 +152,13 @@ class Parser {
152
152
  const ldCtx = await jsonld.processContext(ldcontext.getInitialContext({}), credential['@context'], opts);
153
153
  return Parser.getSerializationAttrFromParsedContext(ldCtx, tp);
154
154
  }
155
+ // Get `iden3_serialization` attr definition from context document either using
156
+ // type name like DeliverAddressMultiTestForked or by type id like
157
+ // urn:uuid:ac2ede19-b3b9-454d-b1a9-a7b3d5763100.
158
+ static async getSerializationAttrFromContext(context, opts, tp) {
159
+ const ldCtx = await jsonld.processContext(ldcontext.getInitialContext({}), context, opts);
160
+ return Parser.getSerializationAttrFromParsedContext(ldCtx, tp);
161
+ }
155
162
  static async getSerializationAttrFromParsedContext(ldCtx, tp) {
156
163
  const termDef = ldCtx.mappings;
157
164
  if (!termDef) {
@@ -48,6 +48,7 @@ class JsonSchemaValidator {
48
48
  const validate = (schema.$id ? validator.getSchema(schema.$id) : undefined) || validator.compile(schema);
49
49
  const valid = validate(data);
50
50
  if (!valid) {
51
+ // TODO: extract correct error messages
51
52
  throw new Error(validate.errors?.map((e) => e.message).join(', '));
52
53
  }
53
54
  return true;