@0xpolygonid/js-sdk 1.29.0 → 1.29.2

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 (35) hide show
  1. package/dist/browser/esm/index.js +8997 -8920
  2. package/dist/browser/esm/index.js.map +1 -1
  3. package/dist/browser/umd/index.js +8998 -8917
  4. package/dist/browser/umd/index.js.map +1 -1
  5. package/dist/node/cjs/iden3comm/handlers/auth.js +1 -1
  6. package/dist/node/cjs/iden3comm/handlers/common.js +79 -23
  7. package/dist/node/cjs/iden3comm/handlers/contract-request.js +8 -7
  8. package/dist/node/cjs/iden3comm/utils/index.js +0 -1
  9. package/dist/node/cjs/proof/proof-service.js +0 -1
  10. package/dist/node/cjs/proof/provers/inputs-generator.js +2 -4
  11. package/dist/node/cjs/storage/blockchain/common.js +19 -0
  12. package/dist/node/cjs/storage/blockchain/onchain-zkp-verifier.js +122 -94
  13. package/dist/node/cjs/storage/blockchain/state.js +2 -2
  14. package/dist/node/esm/iden3comm/handlers/auth.js +1 -1
  15. package/dist/node/esm/iden3comm/handlers/common.js +78 -24
  16. package/dist/node/esm/iden3comm/handlers/contract-request.js +9 -8
  17. package/dist/node/esm/iden3comm/utils/index.js +0 -1
  18. package/dist/node/esm/proof/proof-service.js +0 -1
  19. package/dist/node/esm/proof/provers/inputs-generator.js +2 -4
  20. package/dist/node/esm/storage/blockchain/common.js +14 -0
  21. package/dist/node/esm/storage/blockchain/onchain-zkp-verifier.js +120 -94
  22. package/dist/node/esm/storage/blockchain/state.js +1 -1
  23. package/dist/types/iden3comm/handlers/common.d.ts +32 -5
  24. package/dist/types/iden3comm/types/protocol/auth.d.ts +5 -5
  25. package/dist/types/iden3comm/types/protocol/contract-request.d.ts +16 -5
  26. package/dist/types/iden3comm/utils/index.d.ts +0 -1
  27. package/dist/types/proof/proof-service.d.ts +3 -3
  28. package/dist/types/proof/provers/inputs-generator.d.ts +3 -0
  29. package/dist/types/storage/blockchain/common.d.ts +7 -0
  30. package/dist/types/storage/blockchain/onchain-zkp-verifier.d.ts +45 -6
  31. package/dist/types/storage/interfaces/onchain-zkp-verifier.d.ts +9 -4
  32. package/package.json +1 -1
  33. package/dist/node/cjs/iden3comm/utils/contract-request.utils.js +0 -74
  34. package/dist/node/esm/iden3comm/utils/contract-request.utils.js +0 -67
  35. package/dist/types/iden3comm/utils/contract-request.utils.d.ts +0 -27
@@ -1,10 +1,10 @@
1
- import { getRandomBytes } from '@iden3/js-crypto';
1
+ import { getRandomBytes, poseidon } from '@iden3/js-crypto';
2
2
  import { AuthMethod } from '../types';
3
- import { bytesToHex, mergeObjects } from '../../utils';
4
- import { BytesHelper, DID, getUnixTimestamp } from '@iden3/js-iden3-core';
5
- import { CircuitId } from '../../circuits';
3
+ import { byteEncoder, mergeObjects } from '../../utils';
4
+ import { getUnixTimestamp } from '@iden3/js-iden3-core';
6
5
  import { AcceptJwsAlgorithms, defaultAcceptProfile, MediaType } from '../constants';
7
- import { packZkpProof, prepareZkpProof } from '../utils';
6
+ import { ethers } from 'ethers';
7
+ import { packZkpProof, prepareZkpProof } from '../../storage/blockchain/common';
8
8
  /**
9
9
  * Groups the ZeroKnowledgeProofRequest objects based on their groupId.
10
10
  * Returns a Map where the key is the groupId and the value is an object containing the query and linkNonce.
@@ -96,9 +96,6 @@ export const processProofAuth = async (to, proofService, opts) => {
96
96
  if (!opts.acceptProfile) {
97
97
  opts.acceptProfile = defaultAcceptProfile;
98
98
  }
99
- if (!opts.skipRevocation) {
100
- opts.skipRevocation = true;
101
- }
102
99
  switch (opts.acceptProfile.env) {
103
100
  case MediaType.ZKPMessage:
104
101
  if (!opts.acceptProfile.circuits) {
@@ -108,17 +105,20 @@ export const processProofAuth = async (to, proofService, opts) => {
108
105
  if (!opts.supportedCircuits.includes(circuitId)) {
109
106
  throw new Error(`Circuit ${circuitId} is not supported`);
110
107
  }
111
- const zkpRes = await proofService.generateAuthProof(circuitId, to, { challenge: opts.challenge, skipRevocation: opts.skipRevocation });
112
- switch (circuitId) {
113
- case CircuitId.AuthV2: {
114
- const preparedZkpProof = prepareZkpProof(zkpRes.proof);
115
- const zkProofEncoded = packZkpProof(zkpRes.pub_signals, preparedZkpProof.a, preparedZkpProof.b, preparedZkpProof.c);
116
- return {
117
- authMethod: AuthMethod.AUTHV2,
118
- proof: zkProofEncoded
119
- };
120
- }
108
+ if (!opts.senderAddress) {
109
+ throw new Error('Sender address is not provided');
110
+ }
111
+ if (!opts.zkpResponses || opts.zkpResponses.length === 0) {
112
+ throw new Error('ZKP responses are not provided');
121
113
  }
114
+ const challengeAuth = calcChallengeAuthV2(opts.senderAddress, opts.zkpResponses);
115
+ const zkpRes = await proofService.generateAuthProof(circuitId, to, { challenge: challengeAuth });
116
+ return {
117
+ authProof: {
118
+ authMethod: AuthMethod.AUTHV2,
119
+ zkp: zkpRes
120
+ }
121
+ };
122
122
  }
123
123
  throw new Error(`Auth method is not supported`);
124
124
  case MediaType.SignedMessage:
@@ -126,10 +126,11 @@ export const processProofAuth = async (to, proofService, opts) => {
126
126
  throw new Error('Algorithm not specified');
127
127
  }
128
128
  if (opts.acceptProfile.alg[0] === AcceptJwsAlgorithms.ES256KR) {
129
- const ethIdProof = packEthIdentityProof(to);
130
129
  return {
131
- authMethod: AuthMethod.ETH_IDENTITY,
132
- proof: ethIdProof
130
+ authProof: {
131
+ authMethod: AuthMethod.ETH_IDENTITY,
132
+ userDid: to
133
+ }
133
134
  };
134
135
  }
135
136
  throw new Error(`Algorithm ${opts.acceptProfile.alg[0]} not supported`);
@@ -137,6 +138,62 @@ export const processProofAuth = async (to, proofService, opts) => {
137
138
  throw new Error('Accept env not supported');
138
139
  }
139
140
  };
141
+ /**
142
+ * Processes a ZeroKnowledgeProofResponse object and prepares it for further use.
143
+ * @param zkProof - The ZeroKnowledgeProofResponse object containing the proof data.
144
+ * @returns An object containing the requestId, zkProofEncoded, and metadata.
145
+ */
146
+ export const processProofResponse = (zkProof) => {
147
+ const requestId = zkProof.id;
148
+ const inputs = zkProof.pub_signals;
149
+ const emptyBytes = '0x';
150
+ if (inputs.length === 0) {
151
+ return { requestId, zkProofEncoded: emptyBytes, metadata: emptyBytes };
152
+ }
153
+ const preparedZkpProof = prepareZkpProof(zkProof.proof);
154
+ const zkProofEncoded = packZkpProof(inputs, preparedZkpProof.a, preparedZkpProof.b, preparedZkpProof.c);
155
+ const metadataArr = [];
156
+ if (zkProof.vp) {
157
+ for (const key in zkProof.vp.verifiableCredential.credentialSubject) {
158
+ if (key === '@type') {
159
+ continue;
160
+ }
161
+ const metadataValue = poseidon.hashBytes(byteEncoder.encode(JSON.stringify(zkProof.vp.verifiableCredential.credentialSubject[key])));
162
+ const bytesValue = byteEncoder.encode(metadataValue.toString());
163
+ metadataArr.push({
164
+ key,
165
+ value: bytesValue
166
+ });
167
+ }
168
+ }
169
+ const metadata = metadataArr.length ? packMetadatas(metadataArr) : emptyBytes;
170
+ return { requestId, zkProofEncoded, metadata };
171
+ };
172
+ /**
173
+ * Calculates the challenge authentication V2 value.
174
+ * @param senderAddress - The address of the sender.
175
+ * @param zkpResponses - An array of ZeroKnowledgeProofResponse objects.
176
+ * @returns A bigint representing the challenge authentication value.
177
+ */
178
+ export const calcChallengeAuthV2 = (senderAddress, zkpResponses) => {
179
+ const responses = zkpResponses.map((zkpResponse) => {
180
+ const response = processProofResponse(zkpResponse);
181
+ return {
182
+ requestId: response.requestId,
183
+ proof: response.zkProofEncoded,
184
+ metadata: response.metadata
185
+ };
186
+ });
187
+ return (BigInt(ethers.keccak256(new ethers.AbiCoder().encode(['address', '(uint256 requestId,bytes proof,bytes metadata)[]'], [senderAddress, responses]))) & BigInt('0x0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'));
188
+ };
189
+ /**
190
+ * Packs metadata into a string format suitable for encoding in a transaction.
191
+ * @param metas - An array of objects containing key-value pairs to be packed.
192
+ * @returns A string representing the packed metadata.
193
+ */
194
+ export const packMetadatas = (metas) => {
195
+ return new ethers.AbiCoder().encode(['tuple(' + 'string key,' + 'bytes value' + ')[]'], [metas]);
196
+ };
140
197
  /**
141
198
  * Verifies that the expires_time field of a message is not in the past. Throws an error if it is.
142
199
  *
@@ -147,6 +204,3 @@ export const verifyExpiresTime = (message) => {
147
204
  throw new Error('Message expired');
148
205
  }
149
206
  };
150
- export const packEthIdentityProof = (did) => {
151
- return `0x${bytesToHex(BytesHelper.intToBytes(DID.idFromDID(did).bigInt()))}`;
152
- };
@@ -1,10 +1,11 @@
1
1
  import { CircuitId } from '../../circuits/models';
2
2
  import { defaultAcceptProfile, PROTOCOL_MESSAGE_TYPE, ProtocolVersion } from '../constants';
3
- import { DID, ChainIds, getUnixTimestamp } from '@iden3/js-iden3-core';
3
+ import { DID, ChainIds, getUnixTimestamp, BytesHelper } from '@iden3/js-iden3-core';
4
4
  import { FunctionSignatures } from '../../storage';
5
5
  import { processProofAuth, processZeroKnowledgeProofRequests, verifyExpiresTime } from './common';
6
6
  import { AbstractMessageHandler } from './message-handler';
7
7
  import { parseAcceptProfile } from '../utils';
8
+ import { hexToBytes } from '../../utils';
8
9
  /**
9
10
  *
10
11
  * Allows to process ContractInvokeRequest protocol message
@@ -68,7 +69,7 @@ export class ContractRequestHandler extends AbstractMessageHandler {
68
69
  const { scope = [] } = message.body;
69
70
  const zkpResponses = await processZeroKnowledgeProofRequests(did, scope, verifierDid, this._proofService, {
70
71
  ethSigner,
71
- challenge,
72
+ challenge: challenge ?? BytesHelper.bytesToInt(hexToBytes(await ethSigner.getAddress())),
72
73
  supportedCircuits: this._supportedCircuits
73
74
  });
74
75
  const methodId = message.body.transaction_data.method_id.replace('0x', '');
@@ -100,13 +101,13 @@ export class ContractRequestHandler extends AbstractMessageHandler {
100
101
  // Get first supported accept profile and pass it to processProofAuth
101
102
  const acceptProfile = this.getFirstSupportedProfile(PROTOCOL_MESSAGE_TYPE.CONTRACT_INVOKE_REQUEST_MESSAGE_TYPE, message.body.accept);
102
103
  const identifier = DID.parse(message.to);
103
- const authResponse = await processProofAuth(identifier, this._proofService, {
104
+ const { authProof } = await processProofAuth(identifier, this._proofService, {
104
105
  supportedCircuits: this._supportedCircuits,
105
106
  acceptProfile,
106
- challenge: challenge,
107
- skipRevocation: true
107
+ senderAddress: await ethSigner.getAddress(),
108
+ zkpResponses: zkpResponses
108
109
  });
109
- return this._zkpVerifier.submitResponse(ethSigner, message.body.transaction_data, authResponse, zkpResponses);
110
+ return this._zkpVerifier.submitResponse(ethSigner, message.body.transaction_data, zkpResponses, authProof);
110
111
  }
111
112
  default:
112
113
  throw new Error(`Not supported method id. Only '${FunctionSignatures.SubmitZKPResponseV1}, ${FunctionSignatures.SubmitZKPResponseV2} and ${FunctionSignatures.SubmitResponse} are supported.'`);
@@ -177,8 +178,8 @@ export class ContractRequestHandler extends AbstractMessageHandler {
177
178
  }
178
179
  contractInvokeResponse.body = {
179
180
  ...contractInvokeResponse.body,
180
- crossChainProofs: zkpResponses.crossChainProofs ?? [],
181
- authProofs: zkpResponses.authProofs ?? []
181
+ crossChainProof: zkpResponses.crossChainProof,
182
+ authProof: zkpResponses.authProof
182
183
  };
183
184
  }
184
185
  return contractInvokeResponse;
@@ -1,5 +1,4 @@
1
1
  export * from './envelope';
2
2
  export * from './message';
3
3
  export * from './did';
4
- export * from './contract-request.utils';
5
4
  export * from './accept-profile';
@@ -132,7 +132,6 @@ export class ProofService {
132
132
  async generateAuthProof(circuitId, identifier, opts) {
133
133
  if (!opts) {
134
134
  opts = {
135
- skipRevocation: false,
136
135
  challenge: 0n
137
136
  };
138
137
  }
@@ -234,6 +234,7 @@ export class InputGenerator {
234
234
  return circuitInputs.inputsMarshal();
235
235
  };
236
236
  this.credentialAtomicQueryV3OnChainPrepareInputs = async ({ preparedCredential, identifier, proofReq, params, circuitQueries }) => {
237
+ const id = DID.idFromDID(identifier);
237
238
  const circuitClaimData = await this.newCircuitClaimData(preparedCredential);
238
239
  circuitClaimData.nonRevProof = toClaimNonRevStatus(preparedCredential.revStatus);
239
240
  let proofType;
@@ -283,20 +284,17 @@ export class InputGenerator {
283
284
  const isEthIdentity = isEthereumIdentity(identifier);
284
285
  circuitInputs.isBJJAuthEnabled = isEthIdentity ? 0 : 1;
285
286
  circuitInputs.challenge = BigInt(params.challenge ?? 0);
286
- const { nonce: authProfileNonce, genesisDID } = await this._identityWallet.getGenesisDIDMetadata(identifier);
287
- const id = DID.idFromDID(genesisDID);
288
287
  const stateProof = await this._stateStorage.getGISTProof(id.bigInt());
289
288
  const gistProof = toGISTProof(stateProof);
290
289
  circuitInputs.gistProof = gistProof;
291
290
  // auth inputs
292
291
  if (circuitInputs.isBJJAuthEnabled === 1) {
293
- const authPrepared = await this.prepareAuthBJJCredential(genesisDID);
292
+ const authPrepared = await this.prepareAuthBJJCredential(identifier);
294
293
  const authClaimData = await this.newCircuitClaimData({
295
294
  credential: authPrepared.credential,
296
295
  credentialCoreClaim: authPrepared.coreClaim
297
296
  });
298
297
  const signature = await this._identityWallet.signChallenge(circuitInputs.challenge, authPrepared.credential);
299
- circuitInputs.profileNonce = BigInt(authProfileNonce);
300
298
  circuitInputs.authClaim = authClaimData.claim;
301
299
  circuitInputs.authClaimIncMtp = authClaimData.proof;
302
300
  circuitInputs.authClaimNonRevMtp = authPrepared.nonRevProof.proof;
@@ -0,0 +1,14 @@
1
+ import { ethers } from 'ethers';
2
+ export const packZkpProof = (inputs, a, b, c) => {
3
+ return new ethers.AbiCoder().encode(['uint256[] inputs', 'uint256[2]', 'uint256[2][2]', 'uint256[2]'], [inputs, a, b, c]);
4
+ };
5
+ export const prepareZkpProof = (proof) => {
6
+ return {
7
+ a: proof.pi_a.slice(0, 2),
8
+ b: [
9
+ [proof.pi_b[0][1], proof.pi_b[0][0]],
10
+ [proof.pi_b[1][1], proof.pi_b[1][0]]
11
+ ],
12
+ c: proof.pi_c.slice(0, 2)
13
+ };
14
+ };
@@ -1,14 +1,14 @@
1
1
  import { JsonRpcProvider, Contract, ethers } from 'ethers';
2
+ import { AuthMethod, processProofResponse } from '../../iden3comm';
2
3
  import abi from './abi/ZkpVerifier.json';
3
4
  //import { UniversalVerifier } from '@iden3/universal-verifier-v2-abi';
4
5
  import { IVerifierABI } from '@iden3/universal-verifier-v2-abi';
5
6
  import { TransactionService } from '../../blockchain';
6
- import { chainIDfromDID, DID, Id } from '@iden3/js-iden3-core';
7
+ import { BytesHelper, chainIDfromDID, DID, Id } from '@iden3/js-iden3-core';
7
8
  import { AtomicQueryMTPV2OnChainPubSignals, AtomicQuerySigV2OnChainPubSignals, AtomicQueryV3OnChainPubSignals, AuthV2PubSignals, CircuitId } from '../../circuits';
8
- import { byteEncoder, DIDDocumentSignature, resolveDidDocument } from '../../utils';
9
- import { poseidon } from '@iden3/js-crypto';
9
+ import { byteEncoder, bytesToHex, DIDDocumentSignature, resolveDidDocument } from '../../utils';
10
10
  import { Hash } from '@iden3/js-merkletree';
11
- import { packZkpProof, prepareZkpProof } from '../../iden3comm/utils';
11
+ import { packZkpProof, prepareZkpProof } from './common';
12
12
  const maxGasLimit = 10000000n;
13
13
  /**
14
14
  * Supported function signature for SubmitZKPResponse
@@ -26,6 +26,22 @@ export var FunctionSignatures;
26
26
  //function submitResponse(tuple(string authMethod,bytes proof),tuple(uint256 requestId,bytes proof,bytes metadata)[],bytes crossChainProof)
27
27
  FunctionSignatures["SubmitResponse"] = "06c86a91";
28
28
  })(FunctionSignatures || (FunctionSignatures = {}));
29
+ export const toTxDataArgs = function (res) {
30
+ return [
31
+ {
32
+ authMethod: res.authProof.raw.authMethod,
33
+ proof: res.authProof.encoded
34
+ },
35
+ res.proofs.map((p) => {
36
+ return {
37
+ requestId: p.requestId,
38
+ proof: p.encoded,
39
+ metadata: p.metadata
40
+ };
41
+ }),
42
+ res.crossChainProof.encoded
43
+ ];
44
+ };
29
45
  /**
30
46
  * OnChainZKPVerifier is a class that allows to interact with the OnChainZKPVerifier contract
31
47
  * and submitZKPResponse.
@@ -152,7 +168,7 @@ export class OnChainZKPVerifier {
152
168
  /**
153
169
  * {@inheritDoc IOnChainVerifierMultiQuery.submitResponse}
154
170
  */
155
- async submitResponse(ethSigner, txData, authResponse, responses) {
171
+ async submitResponse(ethSigner, txData, responses, authProof) {
156
172
  const chainConfig = this._configs.find((i) => i.chainId == txData.chain_id);
157
173
  if (!chainConfig) {
158
174
  throw new Error(`config for chain id ${txData.chain_id} was not found`);
@@ -165,7 +181,7 @@ export class OnChainZKPVerifier {
165
181
  }
166
182
  const provider = new JsonRpcProvider(chainConfig.url, chainConfig.chainId);
167
183
  ethSigner = ethSigner.connect(provider);
168
- const txDataArgs = await this.prepareTxArgsSubmit(txData, authResponse, responses);
184
+ const txPreparationResult = await this.prepareTxArgsSubmit(txData, responses, authProof);
169
185
  const feeData = await provider.getFeeData();
170
186
  const maxFeePerGas = chainConfig.maxFeePerGas
171
187
  ? BigInt(chainConfig.maxFeePerGas)
@@ -174,7 +190,7 @@ export class OnChainZKPVerifier {
174
190
  ? BigInt(chainConfig.maxPriorityFeePerGas)
175
191
  : feeData.maxPriorityFeePerGas;
176
192
  const verifierContract = new Contract(txData.contract_address, IVerifierABI);
177
- const txRequestData = await verifierContract.submitResponse.populateTransaction(...txDataArgs);
193
+ const txRequestData = await verifierContract.submitResponse.populateTransaction(...txPreparationResult.txDataArgs);
178
194
  const request = {
179
195
  to: txData.contract_address,
180
196
  data: txRequestData.data,
@@ -193,35 +209,90 @@ export class OnChainZKPVerifier {
193
209
  const { txnHash } = await transactionService.sendTransactionRequest(ethSigner, request);
194
210
  // return multiple responses for all the responses (single and grouped)
195
211
  return new Map().set(txnHash, {
196
- responses: responses,
197
- authProofs: [authResponse],
198
- crossChainProofs: [txDataArgs[2]]
212
+ authProof: txPreparationResult.result.authProof.raw,
213
+ crossChainProof: txPreparationResult.result.crossChainProof.raw,
214
+ responses: txPreparationResult.result.proofs.map((m) => m.proof)
199
215
  });
200
216
  }
201
- static async prepareTxArgsSubmit(resolverUrl, txData, authResponse, responses) {
217
+ static async prepareTxArgsSubmit(resolverUrl, txData, responses, authProof) {
202
218
  if (txData.method_id.replace('0x', '') !== FunctionSignatures.SubmitResponse) {
203
219
  throw new Error(`submit cross chain doesn't implement requested method id. Only '0x${FunctionSignatures.SubmitResponse}' is supported.`);
204
220
  }
205
- const gistUpdateArr = [];
206
- const stateUpdateArr = [];
221
+ const gistUpdatesArr = [];
222
+ const stateUpdatesArr = [];
207
223
  const payloadResponses = [];
224
+ const emptyBytes = '0x';
225
+ let encodedAuthProof = '';
226
+ switch (authProof.authMethod) {
227
+ case AuthMethod.AUTHV2: {
228
+ const preparedZkpProof = prepareZkpProof(authProof.zkp.proof);
229
+ encodedAuthProof = packZkpProof(authProof.zkp.pub_signals, preparedZkpProof.a, preparedZkpProof.b, preparedZkpProof.c);
230
+ break;
231
+ }
232
+ case AuthMethod.ETH_IDENTITY: {
233
+ encodedAuthProof = packEthIdentityProof(authProof.userDid);
234
+ break;
235
+ }
236
+ default:
237
+ throw new Error('auth proof must use method AuthV2 or ethIdentity');
238
+ }
208
239
  // Process all the responses
209
240
  for (const zkProof of responses) {
210
- const { requestID, zkProofEncoded, metadata } = await this._processProof(zkProof);
241
+ this.checkSupportedCircuit(zkProof.circuitId);
242
+ const { requestId, zkProofEncoded, metadata } = processProofResponse(zkProof);
211
243
  payloadResponses.push({
212
- requestId: requestID,
213
- proof: zkProofEncoded,
244
+ proof: zkProof,
245
+ requestId: requestId,
246
+ encoded: zkProofEncoded,
214
247
  metadata: metadata
215
248
  });
216
249
  }
217
- const crossChainProofs = this.packCrossChainProofs(gistUpdateArr, stateUpdateArr);
218
- return [authResponse, payloadResponses, crossChainProofs];
250
+ // Process all zkProofs and prepare cross chain proofs
251
+ const allZkProofs = responses.map((zkProof) => ({
252
+ circuitId: zkProof.circuitId,
253
+ pub_signals: zkProof.pub_signals
254
+ }));
255
+ if (authProof.authMethod == AuthMethod.AUTHV2) {
256
+ allZkProofs.push({
257
+ circuitId: authProof.zkp.circuitId,
258
+ pub_signals: authProof.zkp.pub_signals
259
+ });
260
+ }
261
+ for (const zkProof of allZkProofs) {
262
+ const { gistUpdateResolutions, stateUpdateResolutions } = this.getUpdateResolutions(resolverUrl, txData.chain_id, zkProof.circuitId, zkProof.pub_signals);
263
+ if (gistUpdateResolutions.length > 0) {
264
+ gistUpdatesArr.push(...(await Promise.all(gistUpdateResolutions)));
265
+ }
266
+ if (stateUpdateResolutions.length > 0) {
267
+ stateUpdatesArr.push(...(await Promise.all(stateUpdateResolutions)));
268
+ }
269
+ }
270
+ const encodedCrossChainProof = gistUpdatesArr.length || stateUpdatesArr.length
271
+ ? this.packCrossChainProofs(gistUpdatesArr, stateUpdatesArr)
272
+ : emptyBytes;
273
+ const preparationResult = {
274
+ authProof: { raw: authProof, encoded: encodedAuthProof },
275
+ proofs: payloadResponses,
276
+ crossChainProof: {
277
+ raw: {
278
+ globalStateProofs: gistUpdatesArr || [],
279
+ identityStateProofs: stateUpdatesArr || []
280
+ },
281
+ encoded: encodedCrossChainProof
282
+ }
283
+ };
284
+ return { result: preparationResult, txDataArgs: toTxDataArgs(preparationResult) };
219
285
  }
220
- async prepareTxArgsSubmit(txData, authResponse, responses) {
286
+ async prepareTxArgsSubmit(txData, responses, authProof) {
221
287
  if (!this._opts?.didResolverUrl) {
222
288
  throw new Error(`did resolver url required for crosschain verification`);
223
289
  }
224
- return OnChainZKPVerifier.prepareTxArgsSubmit(this._opts.didResolverUrl, txData, authResponse, responses);
290
+ return OnChainZKPVerifier.prepareTxArgsSubmit(this._opts.didResolverUrl, txData, responses, authProof);
291
+ }
292
+ static checkSupportedCircuit(circuitId) {
293
+ if (!this._supportedCircuits.includes(circuitId)) {
294
+ throw new Error(`Circuit ${circuitId} not supported by OnChainZKPVerifier`);
295
+ }
225
296
  }
226
297
  static getCrossChainResolvers(source, txDataChainId, type, didResolverUrl) {
227
298
  return [
@@ -246,61 +317,30 @@ export class OnChainZKPVerifier {
246
317
  if (txData.method_id.replace('0x', '') !== FunctionSignatures.SubmitZKPResponseV2) {
247
318
  throw new Error(`submit cross chain doesn't implement requested method id. Only '0x${FunctionSignatures.SubmitZKPResponseV2}' is supported.`);
248
319
  }
249
- const gistUpdates = [];
250
- const stateUpdates = [];
251
- const payload = [];
320
+ const gistUpdatesArr = [];
321
+ const stateUpdatesArr = [];
322
+ const payloadResponses = [];
252
323
  const emptyBytes = '0x';
253
324
  for (const zkProof of zkProofResponses) {
254
- const { id: requestId, pub_signals: inputs } = zkProof;
255
- const proofCircuitId = zkProof.circuitId;
256
- if (!this._supportedCircuits.includes(proofCircuitId)) {
257
- throw new Error(`Circuit ${zkProof.circuitId} not supported by OnChainZKPVerifier`);
258
- }
259
- if (inputs.length === 0) {
260
- payload.push({
261
- requestId: requestId,
262
- zkProof: emptyBytes,
263
- data: emptyBytes
264
- });
265
- continue;
266
- }
267
- const preparedZkpProof = prepareZkpProof(zkProof.proof);
268
- const zkProofEncoded = packZkpProof(inputs, preparedZkpProof.a, preparedZkpProof.b, preparedZkpProof.c);
269
- const stateInfo = this.getOnChainGistRootStatePubSignals(proofCircuitId, inputs);
270
- const chainId = txData.chain_id;
271
- const gistUpdateResolutions = this.getCrossChainResolvers(stateInfo.gists, chainId, 'gist', resolverUrl);
272
- const stateUpdateResolutions = this.getCrossChainResolvers(stateInfo.states, chainId, 'state', resolverUrl);
273
- if (gistUpdateResolutions.length > 0) {
274
- gistUpdates.push(...(await Promise.all(gistUpdateResolutions)));
275
- }
276
- if (stateUpdateResolutions.length > 0) {
277
- stateUpdates.push(...(await Promise.all(stateUpdateResolutions)));
278
- }
279
- const metadataArr = [];
280
- if (zkProof.vp) {
281
- for (const key in zkProof.vp.verifiableCredential.credentialSubject) {
282
- if (key === '@type') {
283
- continue;
284
- }
285
- const metadataValue = poseidon.hashBytes(byteEncoder.encode(JSON.stringify(zkProof.vp.verifiableCredential.credentialSubject[key])));
286
- const bytesValue = byteEncoder.encode(metadataValue.toString());
287
- metadataArr.push({
288
- key,
289
- value: bytesValue
290
- });
291
- }
292
- }
293
- const metadata = metadataArr.length ? this.packMetadatas(metadataArr) : emptyBytes;
294
- payload.push({
325
+ this.checkSupportedCircuit(zkProof.circuitId);
326
+ const { requestId, zkProofEncoded, metadata } = processProofResponse(zkProof);
327
+ payloadResponses.push({
295
328
  requestId: requestId,
296
329
  zkProof: zkProofEncoded,
297
330
  data: metadata
298
331
  });
332
+ const { gistUpdateResolutions, stateUpdateResolutions } = this.getUpdateResolutions(resolverUrl, txData.chain_id, zkProof.circuitId, zkProof.pub_signals);
333
+ if (gistUpdateResolutions.length > 0) {
334
+ gistUpdatesArr.push(...(await Promise.all(gistUpdateResolutions)));
335
+ }
336
+ if (stateUpdateResolutions.length > 0) {
337
+ stateUpdatesArr.push(...(await Promise.all(stateUpdateResolutions)));
338
+ }
299
339
  }
300
- const crossChainProofs = gistUpdates.length || stateUpdates.length
301
- ? this.packCrossChainProofs(gistUpdates, stateUpdates)
340
+ const crossChainProofEncoded = gistUpdatesArr.length || stateUpdatesArr.length
341
+ ? this.packCrossChainProofs(gistUpdatesArr, stateUpdatesArr)
302
342
  : emptyBytes;
303
- return [payload, crossChainProofs];
343
+ return [payloadResponses, crossChainProofEncoded];
304
344
  }
305
345
  async prepareTxArgsSubmitV2(txData, zkProofResponses) {
306
346
  if (!this._opts?.didResolverUrl) {
@@ -308,30 +348,11 @@ export class OnChainZKPVerifier {
308
348
  }
309
349
  return OnChainZKPVerifier.prepareTxArgsSubmitV2(this._opts.didResolverUrl, txData, zkProofResponses);
310
350
  }
311
- static async _processProof(zkProof) {
312
- const requestID = zkProof.id;
313
- const inputs = zkProof.pub_signals;
314
- if (!this._supportedCircuits.includes(zkProof.circuitId)) {
315
- throw new Error(`Circuit ${zkProof.circuitId} not supported by OnChainZKPVerifier`);
316
- }
317
- const preparedZkpProof = prepareZkpProof(zkProof.proof);
318
- const zkProofEncoded = packZkpProof(inputs, preparedZkpProof.a, preparedZkpProof.b, preparedZkpProof.c);
319
- const metadataArr = [];
320
- if (zkProof.vp) {
321
- for (const key in zkProof.vp.verifiableCredential.credentialSubject) {
322
- if (key === '@type') {
323
- continue;
324
- }
325
- const metadataValue = poseidon.hashBytes(byteEncoder.encode(JSON.stringify(zkProof.vp.verifiableCredential.credentialSubject[key])));
326
- const bytesValue = byteEncoder.encode(metadataValue.toString());
327
- metadataArr.push({
328
- key,
329
- value: bytesValue
330
- });
331
- }
332
- }
333
- const metadata = metadataArr.length ? this.packMetadatas(metadataArr) : '0x';
334
- return { requestID, zkProofEncoded, metadata };
351
+ static getUpdateResolutions(resolverUrl, chainId, proofCircuitId, inputs) {
352
+ const stateInfo = this.getOnChainGistRootStatePubSignals(proofCircuitId, inputs);
353
+ const gistUpdateResolutions = this.getCrossChainResolvers(stateInfo.gists, chainId, 'gist', resolverUrl);
354
+ const stateUpdateResolutions = this.getCrossChainResolvers(stateInfo.states, chainId, 'state', resolverUrl);
355
+ return { gistUpdateResolutions, stateUpdateResolutions };
335
356
  }
336
357
  static packCrossChainProofs(gistUpdateArr, stateUpdateArr) {
337
358
  const proofs = [];
@@ -375,9 +396,6 @@ export class OnChainZKPVerifier {
375
396
  ')'
376
397
  ], [msg]);
377
398
  }
378
- static packMetadatas(metas) {
379
- return new ethers.AbiCoder().encode(['tuple(' + 'string key,' + 'bytes value' + ')[]'], [metas]);
380
- }
381
399
  static getOnChainGistRootStatePubSignals(onChainCircuitId, inputs) {
382
400
  const PubSignals = this._supportedCircuitsPubSignalsMap[onChainCircuitId];
383
401
  if (!PubSignals) {
@@ -436,3 +454,11 @@ OnChainZKPVerifier._supportedCircuitsPubSignalsMap = {
436
454
  [CircuitId.AtomicQueryV3OnChain]: AtomicQueryV3OnChainPubSignals,
437
455
  [CircuitId.AuthV2]: AuthV2PubSignals
438
456
  };
457
+ /**
458
+ * Packs an Ethereum identity proof from a Decentralized Identifier (DID).
459
+ * @param did - Decentralized Identifier (DID) to pack.
460
+ * @returns A hexadecimal string representing the packed DID identity proof.
461
+ */
462
+ export const packEthIdentityProof = (did) => {
463
+ return `0x${bytesToHex(BytesHelper.intToBytes(DID.idFromDID(did).bigInt()))}`;
464
+ };
@@ -4,7 +4,7 @@ import { byteEncoder } from '../../utils';
4
4
  import abi from './abi/State.json';
5
5
  import { DID, getChainId, Id } from '@iden3/js-iden3-core';
6
6
  import { TransactionService } from '../../blockchain';
7
- import { prepareZkpProof } from '../../iden3comm/utils';
7
+ import { prepareZkpProof } from './common';
8
8
  export /** @type {EthConnectionConfig} - default configuration for EthConnectionConfig */ const defaultEthConnectionConfig = {
9
9
  url: 'http://localhost:8545',
10
10
  defaultGasLimit: 600000,
@@ -1,4 +1,4 @@
1
- import { AcceptProfile, AuthProofResponse, BasicMessage, JWSPackerParams, ZeroKnowledgeProofRequest, ZeroKnowledgeProofResponse } from '../types';
1
+ import { AcceptProfile, AuthProof, BasicMessage, JWSPackerParams, ZeroKnowledgeProofRequest, ZeroKnowledgeProofResponse } from '../types';
2
2
  import { DID } from '@iden3/js-iden3-core';
3
3
  import { IProofService } from '../../proof';
4
4
  import { CircuitId } from '../../circuits';
@@ -32,13 +32,40 @@ export declare const processZeroKnowledgeProofRequests: (to: DID, requests: Zero
32
32
  export declare const processProofAuth: (to: DID, proofService: IProofService, opts: {
33
33
  supportedCircuits: CircuitId[];
34
34
  acceptProfile?: AcceptProfile;
35
- challenge?: bigint;
36
- skipRevocation?: boolean;
37
- }) => Promise<AuthProofResponse>;
35
+ senderAddress: string;
36
+ zkpResponses: ZeroKnowledgeProofResponse[];
37
+ }) => Promise<{
38
+ authProof: AuthProof;
39
+ }>;
40
+ /**
41
+ * Processes a ZeroKnowledgeProofResponse object and prepares it for further use.
42
+ * @param zkProof - The ZeroKnowledgeProofResponse object containing the proof data.
43
+ * @returns An object containing the requestId, zkProofEncoded, and metadata.
44
+ */
45
+ export declare const processProofResponse: (zkProof: ZeroKnowledgeProofResponse) => {
46
+ requestId: string | number;
47
+ zkProofEncoded: string;
48
+ metadata: string;
49
+ };
50
+ /**
51
+ * Calculates the challenge authentication V2 value.
52
+ * @param senderAddress - The address of the sender.
53
+ * @param zkpResponses - An array of ZeroKnowledgeProofResponse objects.
54
+ * @returns A bigint representing the challenge authentication value.
55
+ */
56
+ export declare const calcChallengeAuthV2: (senderAddress: string, zkpResponses: ZeroKnowledgeProofResponse[]) => bigint;
57
+ /**
58
+ * Packs metadata into a string format suitable for encoding in a transaction.
59
+ * @param metas - An array of objects containing key-value pairs to be packed.
60
+ * @returns A string representing the packed metadata.
61
+ */
62
+ export declare const packMetadatas: (metas: {
63
+ key: string;
64
+ value: Uint8Array;
65
+ }[]) => string;
38
66
  /**
39
67
  * Verifies that the expires_time field of a message is not in the past. Throws an error if it is.
40
68
  *
41
69
  * @param message - Basic message to verify.
42
70
  */
43
71
  export declare const verifyExpiresTime: (message: BasicMessage) => void;
44
- export declare const packEthIdentityProof: (did: DID) => string;
@@ -5,7 +5,7 @@ import { ProofType } from '../../../verifiable';
5
5
  import { CircuitId } from '../../../circuits';
6
6
  import { DIDDocument as DidResolverDidDocument, VerificationMethod as DidResolverVerificationMethod } from 'did-resolver';
7
7
  import { RootInfo, StateInfo } from '../../../storage';
8
- import { AuthProofResponse } from './contract-request';
8
+ import { AuthProof, CrossChainProof } from './contract-request';
9
9
  /** AuthorizationResponseMessage is struct the represents iden3message authorization response */
10
10
  export type AuthorizationResponseMessage = BasicMessage & {
11
11
  body: AuthorizationMessageResponseBody;
@@ -36,7 +36,7 @@ export type AuthorizationRequestMessageBody = {
36
36
  };
37
37
  /** ZeroKnowledgeProofRequest represents structure of zkp request object */
38
38
  export type ZeroKnowledgeProofRequest = {
39
- id: number;
39
+ id: number | string;
40
40
  circuitId: CircuitId;
41
41
  optional?: boolean;
42
42
  query: ZeroKnowledgeProofQuery;
@@ -56,12 +56,12 @@ export type ZeroKnowledgeProofQuery = {
56
56
  };
57
57
  export type ZeroKnowledgeInvokeResponse = {
58
58
  responses: ZeroKnowledgeProofResponse[];
59
- crossChainProofs?: string[];
60
- authProofs?: AuthProofResponse[];
59
+ crossChainProof?: CrossChainProof;
60
+ authProof?: AuthProof;
61
61
  };
62
62
  /** ZeroKnowledgeProofResponse represents structure of zkp response */
63
63
  export type ZeroKnowledgeProofResponse = {
64
- id: number;
64
+ id: number | string;
65
65
  circuitId: string;
66
66
  vp?: VerifiablePresentation;
67
67
  } & ZKProof;