@0xpolygonid/js-sdk 1.28.1 → 1.29.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.
- package/dist/browser/esm/index.js +1645 -809
- package/dist/browser/esm/index.js.map +1 -1
- package/dist/browser/umd/index.js +24286 -23448
- package/dist/browser/umd/index.js.map +1 -1
- package/dist/node/cjs/iden3comm/handlers/common.js +63 -1
- package/dist/node/cjs/iden3comm/handlers/contract-request.js +64 -7
- package/dist/node/cjs/iden3comm/types/protocol/contract-request.js +6 -0
- package/dist/node/cjs/iden3comm/utils/contract-request.utils.js +16 -1
- package/dist/node/cjs/proof/proof-service.js +26 -0
- package/dist/node/cjs/storage/blockchain/onchain-zkp-verifier.js +107 -16
- package/dist/node/cjs/storage/blockchain/state.js +5 -6
- package/dist/node/esm/iden3comm/handlers/common.js +62 -2
- package/dist/node/esm/iden3comm/handlers/contract-request.js +66 -9
- package/dist/node/esm/iden3comm/types/protocol/contract-request.js +5 -1
- package/dist/node/esm/iden3comm/utils/contract-request.utils.js +14 -1
- package/dist/node/esm/proof/proof-service.js +26 -0
- package/dist/node/esm/storage/blockchain/onchain-zkp-verifier.js +107 -16
- package/dist/node/esm/storage/blockchain/state.js +5 -6
- package/dist/types/iden3comm/handlers/common.d.ts +16 -1
- package/dist/types/iden3comm/handlers/contract-request.d.ts +3 -1
- package/dist/types/iden3comm/types/protocol/auth.d.ts +8 -0
- package/dist/types/iden3comm/types/protocol/contract-request.d.ts +12 -0
- package/dist/types/iden3comm/utils/contract-request.utils.d.ts +7 -0
- package/dist/types/proof/proof-service.d.ts +14 -2
- package/dist/types/storage/blockchain/onchain-zkp-verifier.d.ts +10 -3
- package/dist/types/storage/interfaces/onchain-zkp-verifier.d.ts +18 -1
- package/package.json +2 -1
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { CircuitId } from '../../circuits/models';
|
|
2
|
-
import { PROTOCOL_MESSAGE_TYPE } from '../constants';
|
|
2
|
+
import { defaultAcceptProfile, PROTOCOL_MESSAGE_TYPE, ProtocolVersion } from '../constants';
|
|
3
3
|
import { DID, ChainIds, getUnixTimestamp } from '@iden3/js-iden3-core';
|
|
4
4
|
import { FunctionSignatures } from '../../storage';
|
|
5
|
-
import { processZeroKnowledgeProofRequests, verifyExpiresTime } from './common';
|
|
5
|
+
import { processProofAuth, processZeroKnowledgeProofRequests, verifyExpiresTime } from './common';
|
|
6
6
|
import { AbstractMessageHandler } from './message-handler';
|
|
7
|
+
import { parseAcceptProfile } from '../utils';
|
|
7
8
|
/**
|
|
8
9
|
*
|
|
9
10
|
* Allows to process ContractInvokeRequest protocol message
|
|
@@ -19,6 +20,7 @@ export class ContractRequestHandler extends AbstractMessageHandler {
|
|
|
19
20
|
* @param {IPackageManager} _packerMgr - package manager to unpack message envelope
|
|
20
21
|
* @param {IProofService} _proofService - proof service to verify zk proofs
|
|
21
22
|
* @param {IOnChainZKPVerifier} _zkpVerifier - zkp verifier to submit response
|
|
23
|
+
* @param {IOnChainVerifierMultiQuery} _verifierMultiQuery - verifier multi-query to submit response
|
|
22
24
|
*
|
|
23
25
|
*/
|
|
24
26
|
constructor(_packerMgr, _proofService, _zkpVerifier) {
|
|
@@ -30,7 +32,12 @@ export class ContractRequestHandler extends AbstractMessageHandler {
|
|
|
30
32
|
CircuitId.AuthV2,
|
|
31
33
|
CircuitId.AtomicQueryMTPV2OnChain,
|
|
32
34
|
CircuitId.AtomicQuerySigV2OnChain,
|
|
33
|
-
CircuitId.AtomicQueryV3OnChain
|
|
35
|
+
CircuitId.AtomicQueryV3OnChain,
|
|
36
|
+
// Now we support off-chain circuits on-chain
|
|
37
|
+
// TODO: We need to create validators for them
|
|
38
|
+
CircuitId.AuthV2,
|
|
39
|
+
CircuitId.AtomicQueryV3,
|
|
40
|
+
CircuitId.LinkedMultiQuery10
|
|
34
41
|
];
|
|
35
42
|
}
|
|
36
43
|
async handle(message, ctx) {
|
|
@@ -66,19 +73,64 @@ export class ContractRequestHandler extends AbstractMessageHandler {
|
|
|
66
73
|
});
|
|
67
74
|
const methodId = message.body.transaction_data.method_id.replace('0x', '');
|
|
68
75
|
switch (methodId) {
|
|
69
|
-
case FunctionSignatures.SubmitZKPResponseV2:
|
|
70
|
-
|
|
76
|
+
case FunctionSignatures.SubmitZKPResponseV2: {
|
|
77
|
+
const txHashZkpResponsesMap = await this._zkpVerifier.submitZKPResponseV2(ethSigner, message.body.transaction_data, zkpResponses);
|
|
78
|
+
const response = new Map();
|
|
79
|
+
for (const [txHash, zkpResponses] of txHashZkpResponsesMap) {
|
|
80
|
+
response.set(txHash, { responses: zkpResponses });
|
|
81
|
+
}
|
|
82
|
+
return response;
|
|
83
|
+
}
|
|
71
84
|
case FunctionSignatures.SubmitZKPResponseV1: {
|
|
72
85
|
const txHashZkpResponseMap = await this._zkpVerifier.submitZKPResponse(ethSigner, message.body.transaction_data, zkpResponses);
|
|
73
86
|
const response = new Map();
|
|
74
87
|
for (const [txHash, zkpResponse] of txHashZkpResponseMap) {
|
|
75
|
-
response.set(txHash, [zkpResponse]);
|
|
88
|
+
response.set(txHash, { responses: [zkpResponse] });
|
|
76
89
|
}
|
|
77
90
|
return response;
|
|
78
91
|
}
|
|
92
|
+
case FunctionSignatures.SubmitResponse: {
|
|
93
|
+
// We need to
|
|
94
|
+
// 1. Generate auth proof from message.body.accept -> authResponse
|
|
95
|
+
// 2. Generate proofs for each query in scope -> zkpResponses
|
|
96
|
+
// Build auth response from accept
|
|
97
|
+
if (!message.to) {
|
|
98
|
+
throw new Error(`failed message. empty 'to' field`);
|
|
99
|
+
}
|
|
100
|
+
// Get first supported accept profile and pass it to processProofAuth
|
|
101
|
+
const acceptProfile = this.getFirstSupportedProfile(PROTOCOL_MESSAGE_TYPE.CONTRACT_INVOKE_REQUEST_MESSAGE_TYPE, message.body.accept);
|
|
102
|
+
const identifier = DID.parse(message.to);
|
|
103
|
+
const authResponse = await processProofAuth(identifier, this._proofService, {
|
|
104
|
+
supportedCircuits: this._supportedCircuits,
|
|
105
|
+
acceptProfile,
|
|
106
|
+
challenge: challenge,
|
|
107
|
+
skipRevocation: true
|
|
108
|
+
});
|
|
109
|
+
return this._zkpVerifier.submitResponse(ethSigner, message.body.transaction_data, authResponse, zkpResponses);
|
|
110
|
+
}
|
|
79
111
|
default:
|
|
80
|
-
throw new Error(`Not supported method id. Only '${FunctionSignatures.SubmitZKPResponseV1} and ${FunctionSignatures.
|
|
112
|
+
throw new Error(`Not supported method id. Only '${FunctionSignatures.SubmitZKPResponseV1}, ${FunctionSignatures.SubmitZKPResponseV2} and ${FunctionSignatures.SubmitResponse} are supported.'`);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
getFirstSupportedProfile(responseType, profile) {
|
|
116
|
+
if (profile?.length) {
|
|
117
|
+
for (const acceptProfileString of profile) {
|
|
118
|
+
// 1. check protocol version
|
|
119
|
+
const acceptProfile = parseAcceptProfile(acceptProfileString);
|
|
120
|
+
const responseTypeVersion = Number(responseType.split('/').at(-2));
|
|
121
|
+
if (acceptProfile.protocolVersion !== ProtocolVersion.V1 ||
|
|
122
|
+
(acceptProfile.protocolVersion === ProtocolVersion.V1 &&
|
|
123
|
+
(responseTypeVersion < 1 || responseTypeVersion >= 2))) {
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
126
|
+
// 2. check packer support
|
|
127
|
+
if (this._packerMgr.isProfileSupported(acceptProfile.env, acceptProfileString)) {
|
|
128
|
+
return acceptProfile;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
81
131
|
}
|
|
132
|
+
// if we don't have supported profiles, we use default
|
|
133
|
+
return defaultAcceptProfile;
|
|
82
134
|
}
|
|
83
135
|
/**
|
|
84
136
|
* unpacks contract-invoke request
|
|
@@ -100,7 +152,7 @@ export class ContractRequestHandler extends AbstractMessageHandler {
|
|
|
100
152
|
* @private
|
|
101
153
|
* @beta
|
|
102
154
|
* @param {ContractInvokeRequest} request - ContractInvokeRequest
|
|
103
|
-
* @param { Map<string,
|
|
155
|
+
* @param { Map<string, ZeroKnowledgeInvokeResponse>} responses - map tx hash to array of ZeroKnowledgeInvokeResponse
|
|
104
156
|
* @returns `Promise<ContractInvokeResponse>`
|
|
105
157
|
*/
|
|
106
158
|
async createContractInvokeResponse(request, txHashToZkpResponseMap) {
|
|
@@ -117,12 +169,17 @@ export class ContractRequestHandler extends AbstractMessageHandler {
|
|
|
117
169
|
created_time: getUnixTimestamp(new Date())
|
|
118
170
|
};
|
|
119
171
|
for (const [txHash, zkpResponses] of txHashToZkpResponseMap) {
|
|
120
|
-
for (const zkpResponse of zkpResponses) {
|
|
172
|
+
for (const zkpResponse of zkpResponses.responses) {
|
|
121
173
|
contractInvokeResponse.body.scope.push({
|
|
122
174
|
txHash,
|
|
123
175
|
...zkpResponse
|
|
124
176
|
});
|
|
125
177
|
}
|
|
178
|
+
contractInvokeResponse.body = {
|
|
179
|
+
...contractInvokeResponse.body,
|
|
180
|
+
crossChainProofs: zkpResponses.crossChainProofs ?? [],
|
|
181
|
+
authProofs: zkpResponses.authProofs ?? []
|
|
182
|
+
};
|
|
126
183
|
}
|
|
127
184
|
return contractInvokeResponse;
|
|
128
185
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { keccak256 } from 'ethers';
|
|
1
|
+
import { ethers, keccak256 } from 'ethers';
|
|
2
2
|
import { byteEncoder, hexToBytes, isEthereumIdentity } from '../../utils';
|
|
3
3
|
import { CircuitId } from '../../circuits';
|
|
4
4
|
import { Hex } from '@iden3/js-crypto';
|
|
@@ -52,3 +52,16 @@ export async function prepareAuthV2ZeroKnowledgeResponse(address, senderDid, pro
|
|
|
52
52
|
}
|
|
53
53
|
];
|
|
54
54
|
}
|
|
55
|
+
export const packZkpProof = (inputs, a, b, c) => {
|
|
56
|
+
return new ethers.AbiCoder().encode(['uint256[] inputs', 'uint256[2]', 'uint256[2][2]', 'uint256[2]'], [inputs, a, b, c]);
|
|
57
|
+
};
|
|
58
|
+
export const prepareZkpProof = (proof) => {
|
|
59
|
+
return {
|
|
60
|
+
a: proof.pi_a.slice(0, 2),
|
|
61
|
+
b: [
|
|
62
|
+
[proof.pi_b[0][1], proof.pi_b[0][0]],
|
|
63
|
+
[proof.pi_b[1][1], proof.pi_b[1][0]]
|
|
64
|
+
],
|
|
65
|
+
c: proof.pi_c.slice(0, 2)
|
|
66
|
+
};
|
|
67
|
+
};
|
|
@@ -128,6 +128,32 @@ export class ProofService {
|
|
|
128
128
|
pub_signals
|
|
129
129
|
};
|
|
130
130
|
}
|
|
131
|
+
/** {@inheritdoc IProofService.generateAuthProof} */
|
|
132
|
+
async generateAuthProof(circuitId, identifier, opts) {
|
|
133
|
+
if (!opts) {
|
|
134
|
+
opts = {
|
|
135
|
+
skipRevocation: false,
|
|
136
|
+
challenge: 0n
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
let zkProof;
|
|
140
|
+
switch (circuitId) {
|
|
141
|
+
case CircuitId.AuthV2:
|
|
142
|
+
{
|
|
143
|
+
const challenge = opts.challenge
|
|
144
|
+
? BytesHelper.intToBytes(opts.challenge).reverse()
|
|
145
|
+
: new Uint8Array(32);
|
|
146
|
+
zkProof = await this.generateAuthV2Proof(challenge, identifier);
|
|
147
|
+
}
|
|
148
|
+
return {
|
|
149
|
+
circuitId: circuitId,
|
|
150
|
+
proof: zkProof.proof,
|
|
151
|
+
pub_signals: zkProof.pub_signals
|
|
152
|
+
};
|
|
153
|
+
default:
|
|
154
|
+
throw new Error(`CircuitId ${circuitId} is not supported`);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
131
157
|
/** {@inheritdoc IProofService.transitState} */
|
|
132
158
|
async transitState(did, oldTreeState, isOldStateGenesis, stateStorage, // for compatibility with previous versions we leave this parameter
|
|
133
159
|
ethSigner) {
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import { JsonRpcProvider, Contract, ethers } from 'ethers';
|
|
2
2
|
import abi from './abi/ZkpVerifier.json';
|
|
3
|
+
//import { UniversalVerifier } from '@iden3/universal-verifier-v2-abi';
|
|
4
|
+
import { IVerifierABI } from '@iden3/universal-verifier-v2-abi';
|
|
3
5
|
import { TransactionService } from '../../blockchain';
|
|
4
6
|
import { chainIDfromDID, DID, Id } from '@iden3/js-iden3-core';
|
|
5
7
|
import { AtomicQueryMTPV2OnChainPubSignals, AtomicQuerySigV2OnChainPubSignals, AtomicQueryV3OnChainPubSignals, AuthV2PubSignals, CircuitId } from '../../circuits';
|
|
6
8
|
import { byteEncoder, DIDDocumentSignature, resolveDidDocument } from '../../utils';
|
|
7
9
|
import { poseidon } from '@iden3/js-crypto';
|
|
8
10
|
import { Hash } from '@iden3/js-merkletree';
|
|
11
|
+
import { packZkpProof, prepareZkpProof } from '../../iden3comm/utils';
|
|
9
12
|
const maxGasLimit = 10000000n;
|
|
10
13
|
/**
|
|
11
14
|
* Supported function signature for SubmitZKPResponse
|
|
@@ -20,6 +23,8 @@ export var FunctionSignatures;
|
|
|
20
23
|
FunctionSignatures["SubmitZKPResponseV1"] = "b68967e2";
|
|
21
24
|
//function submitZKPResponseV2(tuple[](uint64 requestId,bytes zkProof,bytes data),bytes crossChainProof)
|
|
22
25
|
FunctionSignatures["SubmitZKPResponseV2"] = "ade09fcd";
|
|
26
|
+
//function submitResponse(tuple(string authMethod,bytes proof),tuple(uint256 requestId,bytes proof,bytes metadata)[],bytes crossChainProof)
|
|
27
|
+
FunctionSignatures["SubmitResponse"] = "06c86a91";
|
|
23
28
|
})(FunctionSignatures || (FunctionSignatures = {}));
|
|
24
29
|
/**
|
|
25
30
|
* OnChainZKPVerifier is a class that allows to interact with the OnChainZKPVerifier contract
|
|
@@ -45,16 +50,8 @@ export class OnChainZKPVerifier {
|
|
|
45
50
|
}
|
|
46
51
|
const requestID = zkProofResponse.id;
|
|
47
52
|
const inputs = zkProofResponse.pub_signals;
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
inputs,
|
|
51
|
-
zkProofResponse.proof.pi_a.slice(0, 2),
|
|
52
|
-
[
|
|
53
|
-
[zkProofResponse.proof.pi_b[0][1], zkProofResponse.proof.pi_b[0][0]],
|
|
54
|
-
[zkProofResponse.proof.pi_b[1][1], zkProofResponse.proof.pi_b[1][0]]
|
|
55
|
-
],
|
|
56
|
-
zkProofResponse.proof.pi_c.slice(0, 2)
|
|
57
|
-
];
|
|
53
|
+
const preparedZkpProof = prepareZkpProof(zkProofResponse.proof);
|
|
54
|
+
const payload = [requestID, inputs, preparedZkpProof.a, preparedZkpProof.b, preparedZkpProof.c];
|
|
58
55
|
return payload;
|
|
59
56
|
}
|
|
60
57
|
/**
|
|
@@ -152,6 +149,80 @@ export class OnChainZKPVerifier {
|
|
|
152
149
|
const { txnHash } = await transactionService.sendTransactionRequest(ethSigner, request);
|
|
153
150
|
return new Map().set(txnHash, zkProofResponses);
|
|
154
151
|
}
|
|
152
|
+
/**
|
|
153
|
+
* {@inheritDoc IOnChainVerifierMultiQuery.submitResponse}
|
|
154
|
+
*/
|
|
155
|
+
async submitResponse(ethSigner, txData, authResponse, responses) {
|
|
156
|
+
const chainConfig = this._configs.find((i) => i.chainId == txData.chain_id);
|
|
157
|
+
if (!chainConfig) {
|
|
158
|
+
throw new Error(`config for chain id ${txData.chain_id} was not found`);
|
|
159
|
+
}
|
|
160
|
+
if (txData.method_id.replace('0x', '') !== FunctionSignatures.SubmitResponse) {
|
|
161
|
+
throw new Error(`submitResponse function doesn't implement requested method id. Only '0x${FunctionSignatures.SubmitResponse}' is supported.`);
|
|
162
|
+
}
|
|
163
|
+
if (!this._opts?.didResolverUrl) {
|
|
164
|
+
throw new Error(`did resolver url required for crosschain verification`);
|
|
165
|
+
}
|
|
166
|
+
const provider = new JsonRpcProvider(chainConfig.url, chainConfig.chainId);
|
|
167
|
+
ethSigner = ethSigner.connect(provider);
|
|
168
|
+
const txDataArgs = await this.prepareTxArgsSubmit(txData, authResponse, responses);
|
|
169
|
+
const feeData = await provider.getFeeData();
|
|
170
|
+
const maxFeePerGas = chainConfig.maxFeePerGas
|
|
171
|
+
? BigInt(chainConfig.maxFeePerGas)
|
|
172
|
+
: feeData.maxFeePerGas;
|
|
173
|
+
const maxPriorityFeePerGas = chainConfig.maxPriorityFeePerGas
|
|
174
|
+
? BigInt(chainConfig.maxPriorityFeePerGas)
|
|
175
|
+
: feeData.maxPriorityFeePerGas;
|
|
176
|
+
const verifierContract = new Contract(txData.contract_address, IVerifierABI);
|
|
177
|
+
const txRequestData = await verifierContract.submitResponse.populateTransaction(...txDataArgs);
|
|
178
|
+
const request = {
|
|
179
|
+
to: txData.contract_address,
|
|
180
|
+
data: txRequestData.data,
|
|
181
|
+
maxFeePerGas,
|
|
182
|
+
maxPriorityFeePerGas
|
|
183
|
+
};
|
|
184
|
+
let gasLimit;
|
|
185
|
+
try {
|
|
186
|
+
gasLimit = await ethSigner.estimateGas(request);
|
|
187
|
+
}
|
|
188
|
+
catch (e) {
|
|
189
|
+
gasLimit = maxGasLimit;
|
|
190
|
+
}
|
|
191
|
+
request.gasLimit = gasLimit;
|
|
192
|
+
const transactionService = new TransactionService(provider);
|
|
193
|
+
const { txnHash } = await transactionService.sendTransactionRequest(ethSigner, request);
|
|
194
|
+
// return multiple responses for all the responses (single and grouped)
|
|
195
|
+
return new Map().set(txnHash, {
|
|
196
|
+
responses: responses,
|
|
197
|
+
authProofs: [authResponse],
|
|
198
|
+
crossChainProofs: [txDataArgs[2]]
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
static async prepareTxArgsSubmit(resolverUrl, txData, authResponse, responses) {
|
|
202
|
+
if (txData.method_id.replace('0x', '') !== FunctionSignatures.SubmitResponse) {
|
|
203
|
+
throw new Error(`submit cross chain doesn't implement requested method id. Only '0x${FunctionSignatures.SubmitResponse}' is supported.`);
|
|
204
|
+
}
|
|
205
|
+
const gistUpdateArr = [];
|
|
206
|
+
const stateUpdateArr = [];
|
|
207
|
+
const payloadResponses = [];
|
|
208
|
+
// Process all the responses
|
|
209
|
+
for (const zkProof of responses) {
|
|
210
|
+
const { requestID, zkProofEncoded, metadata } = await this._processProof(zkProof);
|
|
211
|
+
payloadResponses.push({
|
|
212
|
+
requestId: requestID,
|
|
213
|
+
proof: zkProofEncoded,
|
|
214
|
+
metadata: metadata
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
const crossChainProofs = this.packCrossChainProofs(gistUpdateArr, stateUpdateArr);
|
|
218
|
+
return [authResponse, payloadResponses, crossChainProofs];
|
|
219
|
+
}
|
|
220
|
+
async prepareTxArgsSubmit(txData, authResponse, responses) {
|
|
221
|
+
if (!this._opts?.didResolverUrl) {
|
|
222
|
+
throw new Error(`did resolver url required for crosschain verification`);
|
|
223
|
+
}
|
|
224
|
+
return OnChainZKPVerifier.prepareTxArgsSubmit(this._opts.didResolverUrl, txData, authResponse, responses);
|
|
225
|
+
}
|
|
155
226
|
static getCrossChainResolvers(source, txDataChainId, type, didResolverUrl) {
|
|
156
227
|
return [
|
|
157
228
|
...new Set(source.map((info) => JSON.stringify({
|
|
@@ -193,10 +264,8 @@ export class OnChainZKPVerifier {
|
|
|
193
264
|
});
|
|
194
265
|
continue;
|
|
195
266
|
}
|
|
196
|
-
const
|
|
197
|
-
|
|
198
|
-
[zkProof.proof.pi_b[1][1], zkProof.proof.pi_b[1][0]]
|
|
199
|
-
], zkProof.proof.pi_c.slice(0, 2));
|
|
267
|
+
const preparedZkpProof = prepareZkpProof(zkProof.proof);
|
|
268
|
+
const zkProofEncoded = packZkpProof(inputs, preparedZkpProof.a, preparedZkpProof.b, preparedZkpProof.c);
|
|
200
269
|
const stateInfo = this.getOnChainGistRootStatePubSignals(proofCircuitId, inputs);
|
|
201
270
|
const chainId = txData.chain_id;
|
|
202
271
|
const gistUpdateResolutions = this.getCrossChainResolvers(stateInfo.gists, chainId, 'gist', resolverUrl);
|
|
@@ -239,8 +308,30 @@ export class OnChainZKPVerifier {
|
|
|
239
308
|
}
|
|
240
309
|
return OnChainZKPVerifier.prepareTxArgsSubmitV2(this._opts.didResolverUrl, txData, zkProofResponses);
|
|
241
310
|
}
|
|
242
|
-
static
|
|
243
|
-
|
|
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 };
|
|
244
335
|
}
|
|
245
336
|
static packCrossChainProofs(gistUpdateArr, stateUpdateArr) {
|
|
246
337
|
const proofs = [];
|
|
@@ -4,6 +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
8
|
export /** @type {EthConnectionConfig} - default configuration for EthConnectionConfig */ const defaultEthConnectionConfig = {
|
|
8
9
|
url: 'http://localhost:8545',
|
|
9
10
|
defaultGasLimit: 600000,
|
|
@@ -73,17 +74,15 @@ export class EthStateStorage {
|
|
|
73
74
|
const { userId, oldUserState, newUserState, isOldStateGenesis } = stateTransitionPubSig;
|
|
74
75
|
const { stateContract, provider } = this.getStateContractAndProviderForId(userId.bigInt());
|
|
75
76
|
const contract = stateContract.connect(signer);
|
|
77
|
+
const preparedZkpProof = prepareZkpProof(proof.proof);
|
|
76
78
|
const payload = [
|
|
77
79
|
userId.bigInt().toString(),
|
|
78
80
|
oldUserState.bigInt().toString(),
|
|
79
81
|
newUserState.bigInt().toString(),
|
|
80
82
|
isOldStateGenesis,
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
[proof.proof.pi_b[1][1], proof.proof.pi_b[1][0]]
|
|
85
|
-
],
|
|
86
|
-
proof.proof.pi_c.slice(0, 2)
|
|
83
|
+
preparedZkpProof.a,
|
|
84
|
+
preparedZkpProof.b,
|
|
85
|
+
preparedZkpProof.c
|
|
87
86
|
];
|
|
88
87
|
const feeData = await provider.getFeeData();
|
|
89
88
|
const maxFeePerGas = defaultEthConnectionConfig.maxFeePerGas
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BasicMessage, JWSPackerParams, ZeroKnowledgeProofRequest, ZeroKnowledgeProofResponse } from '../types';
|
|
1
|
+
import { AcceptProfile, AuthProofResponse, 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';
|
|
@@ -21,9 +21,24 @@ export declare const processZeroKnowledgeProofRequests: (to: DID, requests: Zero
|
|
|
21
21
|
ethSigner?: Signer;
|
|
22
22
|
challenge?: bigint;
|
|
23
23
|
}) => Promise<ZeroKnowledgeProofResponse[]>;
|
|
24
|
+
/**
|
|
25
|
+
* Processes auth proof requests.
|
|
26
|
+
*
|
|
27
|
+
* @param to - The identifier of the recipient.
|
|
28
|
+
* @param proofService - The proof service.
|
|
29
|
+
* @param opts - Additional options for processing the requests.
|
|
30
|
+
* @returns A promise that resolves to an auth proof response.
|
|
31
|
+
*/
|
|
32
|
+
export declare const processProofAuth: (to: DID, proofService: IProofService, opts: {
|
|
33
|
+
supportedCircuits: CircuitId[];
|
|
34
|
+
acceptProfile?: AcceptProfile;
|
|
35
|
+
challenge?: bigint;
|
|
36
|
+
skipRevocation?: boolean;
|
|
37
|
+
}) => Promise<AuthProofResponse>;
|
|
24
38
|
/**
|
|
25
39
|
* Verifies that the expires_time field of a message is not in the past. Throws an error if it is.
|
|
26
40
|
*
|
|
27
41
|
* @param message - Basic message to verify.
|
|
28
42
|
*/
|
|
29
43
|
export declare const verifyExpiresTime: (message: BasicMessage) => void;
|
|
44
|
+
export declare const packEthIdentityProof: (did: DID) => string;
|
|
@@ -58,11 +58,13 @@ export declare class ContractRequestHandler extends AbstractMessageHandler imple
|
|
|
58
58
|
* @param {IPackageManager} _packerMgr - package manager to unpack message envelope
|
|
59
59
|
* @param {IProofService} _proofService - proof service to verify zk proofs
|
|
60
60
|
* @param {IOnChainZKPVerifier} _zkpVerifier - zkp verifier to submit response
|
|
61
|
+
* @param {IOnChainVerifierMultiQuery} _verifierMultiQuery - verifier multi-query to submit response
|
|
61
62
|
*
|
|
62
63
|
*/
|
|
63
64
|
constructor(_packerMgr: IPackageManager, _proofService: IProofService, _zkpVerifier: IOnChainZKPVerifier);
|
|
64
65
|
handle(message: BasicMessage, ctx: ContractMessageHandlerOptions): Promise<BasicMessage | null>;
|
|
65
66
|
private handleContractInvoke;
|
|
67
|
+
private getFirstSupportedProfile;
|
|
66
68
|
/**
|
|
67
69
|
* unpacks contract-invoke request
|
|
68
70
|
* @beta
|
|
@@ -75,7 +77,7 @@ export declare class ContractRequestHandler extends AbstractMessageHandler imple
|
|
|
75
77
|
* @private
|
|
76
78
|
* @beta
|
|
77
79
|
* @param {ContractInvokeRequest} request - ContractInvokeRequest
|
|
78
|
-
* @param { Map<string,
|
|
80
|
+
* @param { Map<string, ZeroKnowledgeInvokeResponse>} responses - map tx hash to array of ZeroKnowledgeInvokeResponse
|
|
79
81
|
* @returns `Promise<ContractInvokeResponse>`
|
|
80
82
|
*/
|
|
81
83
|
private createContractInvokeResponse;
|
|
@@ -5,6 +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
9
|
/** AuthorizationResponseMessage is struct the represents iden3message authorization response */
|
|
9
10
|
export type AuthorizationResponseMessage = BasicMessage & {
|
|
10
11
|
body: AuthorizationMessageResponseBody;
|
|
@@ -53,12 +54,19 @@ export type ZeroKnowledgeProofQuery = {
|
|
|
53
54
|
groupId?: number;
|
|
54
55
|
type: string;
|
|
55
56
|
};
|
|
57
|
+
export type ZeroKnowledgeInvokeResponse = {
|
|
58
|
+
responses: ZeroKnowledgeProofResponse[];
|
|
59
|
+
crossChainProofs?: string[];
|
|
60
|
+
authProofs?: AuthProofResponse[];
|
|
61
|
+
};
|
|
56
62
|
/** ZeroKnowledgeProofResponse represents structure of zkp response */
|
|
57
63
|
export type ZeroKnowledgeProofResponse = {
|
|
58
64
|
id: number;
|
|
59
65
|
circuitId: string;
|
|
60
66
|
vp?: VerifiablePresentation;
|
|
61
67
|
} & ZKProof;
|
|
68
|
+
/** ZeroKnowledgeProofAuthResponse represents structure of zkp auth response */
|
|
69
|
+
export type ZeroKnowledgeProofAuthResponse = Omit<ZeroKnowledgeProofResponse, 'id' | 'vp'>;
|
|
62
70
|
/** VerifiablePresentation represents structure of Verifiable Presentation */
|
|
63
71
|
export type VerifiablePresentation = {
|
|
64
72
|
'@context': string | (string | object)[];
|
|
@@ -12,6 +12,7 @@ export type ContractInvokeRequestBody = {
|
|
|
12
12
|
transaction_data: ContractInvokeTransactionData;
|
|
13
13
|
scope: Array<ZeroKnowledgeProofRequest>;
|
|
14
14
|
did_doc?: DIDDocument;
|
|
15
|
+
accept?: string[];
|
|
15
16
|
};
|
|
16
17
|
/** ContractInvokeResponse represents structure of contract invoke response object */
|
|
17
18
|
export type ContractInvokeResponse = BasicMessage & {
|
|
@@ -23,6 +24,8 @@ export type ContractInvokeResponseBody = {
|
|
|
23
24
|
scope: Array<OnChainZeroKnowledgeProofResponse>;
|
|
24
25
|
transaction_data: ContractInvokeTransactionData;
|
|
25
26
|
did_doc?: DIDDocument;
|
|
27
|
+
crossChainProofs?: string[];
|
|
28
|
+
authProofs?: AuthProofResponse[];
|
|
26
29
|
};
|
|
27
30
|
/** OnChainZeroKnowledgeProofResponse represents structure of onchain zero knowledge proof response */
|
|
28
31
|
export type OnChainZeroKnowledgeProofResponse = ZeroKnowledgeProofResponse & {
|
|
@@ -35,3 +38,12 @@ export type ContractInvokeTransactionData = {
|
|
|
35
38
|
chain_id: number;
|
|
36
39
|
network?: string;
|
|
37
40
|
};
|
|
41
|
+
/** AuthProofResponse represents structure of zkp response */
|
|
42
|
+
export type AuthProofResponse = {
|
|
43
|
+
authMethod: AuthMethod;
|
|
44
|
+
proof: string;
|
|
45
|
+
};
|
|
46
|
+
export declare enum AuthMethod {
|
|
47
|
+
AUTHV2 = "authV2",
|
|
48
|
+
ETH_IDENTITY = "ethIdentity"
|
|
49
|
+
}
|
|
@@ -2,6 +2,7 @@ import { CircuitId } from '../../circuits';
|
|
|
2
2
|
import { DID } from '@iden3/js-iden3-core';
|
|
3
3
|
import { IProofService } from '../../proof';
|
|
4
4
|
import { ZeroKnowledgeProofResponse } from '../types';
|
|
5
|
+
import { ProofData } from '@iden3/js-jwz';
|
|
5
6
|
/**
|
|
6
7
|
* @beta
|
|
7
8
|
* Retrieves the request ID from circuit string.
|
|
@@ -18,3 +19,9 @@ export declare function calculateRequestIdForCircuit(circuitId: CircuitId): numb
|
|
|
18
19
|
* @returns A promise that resolves to an array of ZeroKnowledgeProofResponse objects.
|
|
19
20
|
*/
|
|
20
21
|
export declare function prepareAuthV2ZeroKnowledgeResponse(address: string, senderDid: DID, proofService: IProofService): Promise<ZeroKnowledgeProofResponse[]>;
|
|
22
|
+
export declare const packZkpProof: (inputs: string[], a: string[], b: string[][], c: string[]) => string;
|
|
23
|
+
export declare const prepareZkpProof: (proof: ProofData) => {
|
|
24
|
+
a: string[];
|
|
25
|
+
b: string[][];
|
|
26
|
+
c: string[];
|
|
27
|
+
};
|
|
@@ -7,7 +7,7 @@ import { IZKProver } from './provers/prover';
|
|
|
7
7
|
import { Options } from '@iden3/js-jsonld-merklization';
|
|
8
8
|
import { ZKProof } from '@iden3/js-jwz';
|
|
9
9
|
import { Signer } from 'ethers';
|
|
10
|
-
import { StateVerificationOpts, JSONObject, ZeroKnowledgeProofRequest, ZeroKnowledgeProofResponse } from '../iden3comm';
|
|
10
|
+
import { StateVerificationOpts, JSONObject, ZeroKnowledgeProofRequest, ZeroKnowledgeProofResponse, ZeroKnowledgeProofAuthResponse } from '../iden3comm';
|
|
11
11
|
import { ICircuitStorage, IStateStorage } from '../storage';
|
|
12
12
|
import { ProofGenerationOptions } from './provers/inputs-generator';
|
|
13
13
|
import { VerifyOpts } from './verifiers';
|
|
@@ -74,13 +74,23 @@ export interface IProofService {
|
|
|
74
74
|
*/
|
|
75
75
|
generateAuthV2Inputs(hash: Uint8Array, did: DID, circuitId: CircuitId): Promise<Uint8Array>;
|
|
76
76
|
/**
|
|
77
|
-
* generates auth
|
|
77
|
+
* generates auth v2 proof from given identity
|
|
78
78
|
*
|
|
79
79
|
* @param {Uint8Array} hash - challenge that will be signed
|
|
80
80
|
* @param {DID} did - identity that will generate a proof
|
|
81
81
|
* @returns `Promise<ZKProof>`
|
|
82
82
|
*/
|
|
83
83
|
generateAuthV2Proof(hash: Uint8Array, did: DID): Promise<ZKProof>;
|
|
84
|
+
/**
|
|
85
|
+
* Generate auth proof from given identity with generic params
|
|
86
|
+
*
|
|
87
|
+
* @param {CircuitId} circuitId - circuitId for the proof generation
|
|
88
|
+
* @param {DID} identifier - did that will generate proof
|
|
89
|
+
* @param {ProofGenerationOptions} opts - options that will be used for proof generation
|
|
90
|
+
*
|
|
91
|
+
* @returns `Promise<ZeroKnowledgeProofResponse>`
|
|
92
|
+
*/
|
|
93
|
+
generateAuthProof(circuitId: CircuitId, identifier: DID, opts?: ProofGenerationOptions): Promise<ZeroKnowledgeProofAuthResponse>;
|
|
84
94
|
/**
|
|
85
95
|
* state verification function
|
|
86
96
|
*
|
|
@@ -138,6 +148,8 @@ export declare class ProofService implements IProofService {
|
|
|
138
148
|
verifyZKPResponse(proofResp: ZeroKnowledgeProofResponse, opts: ProofVerifyOpts): Promise<VerificationResultMetadata>;
|
|
139
149
|
/** {@inheritdoc IProofService.generateProof} */
|
|
140
150
|
generateProof(proofReq: ZeroKnowledgeProofRequest, identifier: DID, opts?: ProofGenerationOptions): Promise<ZeroKnowledgeProofResponse>;
|
|
151
|
+
/** {@inheritdoc IProofService.generateAuthProof} */
|
|
152
|
+
generateAuthProof(circuitId: CircuitId, identifier: DID, opts?: ProofGenerationOptions): Promise<ZeroKnowledgeProofAuthResponse>;
|
|
141
153
|
/** {@inheritdoc IProofService.transitState} */
|
|
142
154
|
transitState(did: DID, oldTreeState: TreeState, isOldStateGenesis: boolean, stateStorage: IStateStorage, // for compatibility with previous versions we leave this parameter
|
|
143
155
|
ethSigner: Signer): Promise<string>;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Signer } from 'ethers';
|
|
2
2
|
import { EthConnectionConfig } from './state';
|
|
3
3
|
import { IOnChainZKPVerifier } from '../interfaces/onchain-zkp-verifier';
|
|
4
|
-
import { ContractInvokeTransactionData, JsonDocumentObjectValue, ZeroKnowledgeProofResponse } from '../../iden3comm';
|
|
4
|
+
import { AuthProofResponse, ContractInvokeTransactionData, JsonDocumentObjectValue, ZeroKnowledgeInvokeResponse, ZeroKnowledgeProofResponse } from '../../iden3comm';
|
|
5
5
|
import { GlobalStateUpdate } from '../entities/state';
|
|
6
6
|
/**
|
|
7
7
|
* Supported function signature for SubmitZKPResponse
|
|
@@ -13,7 +13,8 @@ export declare enum FunctionSignatures {
|
|
|
13
13
|
* uint256[2] calldata a, uint256[2][2] calldata b, uint256[2] calldata c) public
|
|
14
14
|
*/
|
|
15
15
|
SubmitZKPResponseV1 = "b68967e2",
|
|
16
|
-
SubmitZKPResponseV2 = "ade09fcd"
|
|
16
|
+
SubmitZKPResponseV2 = "ade09fcd",
|
|
17
|
+
SubmitResponse = "06c86a91"
|
|
17
18
|
}
|
|
18
19
|
/**
|
|
19
20
|
* OnChainZKPVerifierOptions represents OnChainZKPVerifier options
|
|
@@ -56,10 +57,16 @@ export declare class OnChainZKPVerifier implements IOnChainZKPVerifier {
|
|
|
56
57
|
* {@inheritDoc IOnChainZKPVerifier.submitZKPResponseV2}
|
|
57
58
|
*/
|
|
58
59
|
submitZKPResponseV2(ethSigner: Signer, txData: ContractInvokeTransactionData, zkProofResponses: ZeroKnowledgeProofResponse[]): Promise<Map<string, ZeroKnowledgeProofResponse[]>>;
|
|
60
|
+
/**
|
|
61
|
+
* {@inheritDoc IOnChainVerifierMultiQuery.submitResponse}
|
|
62
|
+
*/
|
|
63
|
+
submitResponse(ethSigner: Signer, txData: ContractInvokeTransactionData, authResponse: AuthProofResponse, responses: ZeroKnowledgeProofResponse[]): Promise<Map<string, ZeroKnowledgeInvokeResponse>>;
|
|
64
|
+
static prepareTxArgsSubmit(resolverUrl: string, txData: ContractInvokeTransactionData, authResponse: AuthProofResponse, responses: ZeroKnowledgeProofResponse[]): Promise<JsonDocumentObjectValue[]>;
|
|
65
|
+
prepareTxArgsSubmit(txData: ContractInvokeTransactionData, authResponse: AuthProofResponse, responses: ZeroKnowledgeProofResponse[]): Promise<JsonDocumentObjectValue[]>;
|
|
59
66
|
private static getCrossChainResolvers;
|
|
60
67
|
static prepareTxArgsSubmitV2(resolverUrl: string, txData: ContractInvokeTransactionData, zkProofResponses: ZeroKnowledgeProofResponse[]): Promise<JsonDocumentObjectValue[]>;
|
|
61
68
|
prepareTxArgsSubmitV2(txData: ContractInvokeTransactionData, zkProofResponses: ZeroKnowledgeProofResponse[]): Promise<JsonDocumentObjectValue[]>;
|
|
62
|
-
private static
|
|
69
|
+
private static _processProof;
|
|
63
70
|
private static packCrossChainProofs;
|
|
64
71
|
static packGlobalStateMsg(msg: GlobalStateUpdate): string;
|
|
65
72
|
private static packIdentityStateMsg;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Signer } from 'ethers';
|
|
2
|
-
import { ContractInvokeTransactionData, JsonDocumentObjectValue, ZeroKnowledgeProofResponse } from '../../iden3comm';
|
|
2
|
+
import { AuthProofResponse, ContractInvokeTransactionData, JsonDocumentObjectValue, ZeroKnowledgeInvokeResponse, ZeroKnowledgeProofResponse } from '../../iden3comm';
|
|
3
3
|
/**
|
|
4
4
|
* Interface that defines methods for ZKP verifier
|
|
5
5
|
*
|
|
@@ -25,6 +25,16 @@ export interface IOnChainZKPVerifier {
|
|
|
25
25
|
* @returns {Promise<Map<string, ZeroKnowledgeProofResponse[]>>} - map of transaction hash - ZeroKnowledgeProofResponse[]
|
|
26
26
|
*/
|
|
27
27
|
submitZKPResponseV2(ethSigner: Signer, txData: ContractInvokeTransactionData, zkProofResponses: ZeroKnowledgeProofResponse[]): Promise<Map<string, ZeroKnowledgeProofResponse[]>>;
|
|
28
|
+
/**
|
|
29
|
+
* Submit Response to OnChainZKPVerifier contract.
|
|
30
|
+
* @beta
|
|
31
|
+
* @param {Signer} ethSigner - tx signer
|
|
32
|
+
* @param {txData} ContractInvokeTransactionData - transaction data
|
|
33
|
+
* @param {AuthProofResponse} authResponse - authResponse
|
|
34
|
+
* @param {ZeroKnowledgeProofMultiQueryResponse[]} responses - singleResponses and groupedResponses
|
|
35
|
+
* @returns {Promise<Map<string, ZeroKnowledgeInvokeResponse>>} - map of transaction hash - ZeroKnowledgeInvokeResponse
|
|
36
|
+
*/
|
|
37
|
+
submitResponse(ethSigner: Signer, txData: ContractInvokeTransactionData, authResponse: AuthProofResponse, responses: ZeroKnowledgeProofResponse[]): Promise<Map<string, ZeroKnowledgeInvokeResponse>>;
|
|
28
38
|
/**
|
|
29
39
|
* Returns tx args for the ZKP verifier contract submission (singe tx args for each response).
|
|
30
40
|
* @param txData
|
|
@@ -37,4 +47,11 @@ export interface IOnChainZKPVerifier {
|
|
|
37
47
|
* @param zkProofResponses
|
|
38
48
|
*/
|
|
39
49
|
prepareTxArgsSubmitV2(txData: ContractInvokeTransactionData, zkProofResponses: ZeroKnowledgeProofResponse[]): Promise<JsonDocumentObjectValue[]>;
|
|
50
|
+
/**
|
|
51
|
+
* Returns args for the verifier multi-query contract submission (single tx args for an array of responses).
|
|
52
|
+
* @param {txData} ContractInvokeTransactionData - transaction data
|
|
53
|
+
* @param {AuthProofResponse} authResponse - authResponse
|
|
54
|
+
* @param {ZeroKnowledgeProofMultiQueryResponse[]} responses - singleResponses and groupedResponses
|
|
55
|
+
*/
|
|
56
|
+
prepareTxArgsSubmit(txData: ContractInvokeTransactionData, authResponse: AuthProofResponse, responses: ZeroKnowledgeProofResponse[]): Promise<JsonDocumentObjectValue[]>;
|
|
40
57
|
}
|