@0xpolygonid/js-sdk 1.17.7 → 1.18.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 +977 -65
- package/dist/browser/esm/index.js.map +1 -1
- package/dist/browser/umd/index.js +977 -64
- package/dist/browser/umd/index.js.map +1 -1
- package/dist/node/cjs/circuits/atomic-query-mtp-v2-on-chain.js +10 -0
- package/dist/node/cjs/circuits/atomic-query-sig-v2-on-chain.js +10 -0
- package/dist/node/cjs/circuits/atomic-query-v3-on-chain.js +10 -0
- package/dist/node/cjs/iden3comm/constants.js +2 -0
- package/dist/node/cjs/iden3comm/handlers/contract-request.js +73 -10
- package/dist/node/cjs/storage/blockchain/abi/ZkpVerifier.json +530 -9
- package/dist/node/cjs/storage/blockchain/onchain-zkp-verifier.js +293 -42
- package/dist/node/cjs/utils/did-helper.js +37 -1
- package/dist/node/cjs/verifiable/credential.js +1 -1
- package/dist/node/esm/circuits/atomic-query-mtp-v2-on-chain.js +10 -0
- package/dist/node/esm/circuits/atomic-query-sig-v2-on-chain.js +10 -0
- package/dist/node/esm/circuits/atomic-query-v3-on-chain.js +10 -0
- package/dist/node/esm/iden3comm/constants.js +2 -0
- package/dist/node/esm/iden3comm/handlers/contract-request.js +73 -10
- package/dist/node/esm/storage/blockchain/abi/ZkpVerifier.json +530 -9
- package/dist/node/esm/storage/blockchain/onchain-zkp-verifier.js +293 -42
- package/dist/node/esm/utils/did-helper.js +35 -0
- package/dist/node/esm/verifiable/credential.js +1 -1
- package/dist/types/circuits/atomic-query-mtp-v2-on-chain.d.ts +4 -2
- package/dist/types/circuits/atomic-query-sig-v2-on-chain.d.ts +4 -2
- package/dist/types/circuits/atomic-query-v3-on-chain.d.ts +4 -2
- package/dist/types/circuits/common.d.ts +31 -0
- package/dist/types/iden3comm/constants.d.ts +1 -0
- package/dist/types/iden3comm/handlers/contract-request.d.ts +14 -3
- package/dist/types/iden3comm/types/protocol/auth.d.ts +11 -1
- package/dist/types/iden3comm/types/protocol/contract-request.d.ts +16 -1
- package/dist/types/proof/verifiers/pub-signals-verifier.d.ts +2 -2
- package/dist/types/proof/verifiers/query.d.ts +4 -3
- package/dist/types/storage/blockchain/onchain-zkp-verifier.d.ts +44 -12
- package/dist/types/storage/entities/state.d.ts +44 -0
- package/dist/types/storage/interfaces/onchain-zkp-verifier.d.ts +22 -1
- package/dist/types/utils/did-helper.d.ts +12 -1
- package/dist/types/verifiable/presentation.d.ts +2 -2
- package/package.json +1 -1
|
@@ -1,6 +1,25 @@
|
|
|
1
|
-
import { JsonRpcProvider, Contract } from 'ethers';
|
|
1
|
+
import { JsonRpcProvider, Contract, ethers } from 'ethers';
|
|
2
2
|
import abi from './abi/ZkpVerifier.json';
|
|
3
3
|
import { TransactionService } from '../../blockchain';
|
|
4
|
+
import { DID } from '@iden3/js-iden3-core';
|
|
5
|
+
import { AtomicQueryMTPV2OnChainPubSignals, AtomicQuerySigV2OnChainPubSignals, AtomicQueryV3OnChainPubSignals, CircuitId } from '../../circuits';
|
|
6
|
+
import { byteEncoder, DIDDocumentSignature, resolveDidDocument } from '../../utils';
|
|
7
|
+
import { poseidon } from '@iden3/js-crypto';
|
|
8
|
+
const maxGasLimit = 10000000n;
|
|
9
|
+
/**
|
|
10
|
+
* Supported function signature for SubmitZKPResponse
|
|
11
|
+
*/
|
|
12
|
+
export var FunctionSignatures;
|
|
13
|
+
(function (FunctionSignatures) {
|
|
14
|
+
/**
|
|
15
|
+
* solidity identifier for function signature:
|
|
16
|
+
* function submitZKPResponse(uint64 requestId, uint256[] calldata inputs,
|
|
17
|
+
* uint256[2] calldata a, uint256[2][2] calldata b, uint256[2] calldata c) public
|
|
18
|
+
*/
|
|
19
|
+
FunctionSignatures["SumbitZKPResponseV1"] = "b68967e2";
|
|
20
|
+
//function submitZKPResponseV2(tuple[](uint64 requestId,bytes zkProof,bytes data),bytes crossChainProof)
|
|
21
|
+
FunctionSignatures["SumbitZKPResponseV2"] = "ade09fcd";
|
|
22
|
+
})(FunctionSignatures || (FunctionSignatures = {}));
|
|
4
23
|
/**
|
|
5
24
|
* OnChainZKPVerifier is a class that allows to interact with the OnChainZKPVerifier contract
|
|
6
25
|
* and submitZKPResponse.
|
|
@@ -15,69 +34,301 @@ export class OnChainZKPVerifier {
|
|
|
15
34
|
* @beta
|
|
16
35
|
* @param {EthConnectionConfig[]} - array of ETH configs
|
|
17
36
|
*/
|
|
18
|
-
constructor(_configs) {
|
|
37
|
+
constructor(_configs, _opts) {
|
|
19
38
|
this._configs = _configs;
|
|
39
|
+
this._opts = _opts;
|
|
40
|
+
/**
|
|
41
|
+
* supported circuits
|
|
42
|
+
*/
|
|
43
|
+
this._supportedCircuits = [
|
|
44
|
+
CircuitId.AtomicQueryMTPV2OnChain,
|
|
45
|
+
CircuitId.AtomicQuerySigV2OnChain,
|
|
46
|
+
CircuitId.AtomicQueryV3OnChain
|
|
47
|
+
];
|
|
20
48
|
/**
|
|
21
|
-
*
|
|
22
|
-
* function submitZKPResponse(uint64 requestId, uint256[] calldata inputs,
|
|
23
|
-
* uint256[2] calldata a, uint256[2][2] calldata b, uint256[2] calldata c) public
|
|
49
|
+
* abi coder to encode/decode structures to solidity bytes
|
|
24
50
|
*/
|
|
25
|
-
this.
|
|
51
|
+
this._abiCoder = new ethers.AbiCoder();
|
|
26
52
|
}
|
|
27
53
|
/**
|
|
28
|
-
*
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
54
|
+
* {@inheritDoc IOnChainZKPVerifier.prepareTxArgsSubmitV1}
|
|
55
|
+
*/
|
|
56
|
+
async prepareTxArgsSubmitV1(txData, zkProofResponse) {
|
|
57
|
+
if (txData.method_id.replace('0x', '') !== FunctionSignatures.SumbitZKPResponseV1) {
|
|
58
|
+
throw new Error(`prepareTxArgsSubmitV1 function doesn't implement requested method id. Only '0x${FunctionSignatures.SumbitZKPResponseV1}' is supported.`);
|
|
59
|
+
}
|
|
60
|
+
const requestID = zkProofResponse.id;
|
|
61
|
+
const inputs = zkProofResponse.pub_signals;
|
|
62
|
+
const payload = [
|
|
63
|
+
requestID,
|
|
64
|
+
inputs,
|
|
65
|
+
zkProofResponse.proof.pi_a.slice(0, 2),
|
|
66
|
+
[
|
|
67
|
+
[zkProofResponse.proof.pi_b[0][1], zkProofResponse.proof.pi_b[0][0]],
|
|
68
|
+
[zkProofResponse.proof.pi_b[1][1], zkProofResponse.proof.pi_b[1][0]]
|
|
69
|
+
],
|
|
70
|
+
zkProofResponse.proof.pi_c.slice(0, 2)
|
|
71
|
+
];
|
|
72
|
+
return payload;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* {@inheritDoc IOnChainZKPVerifier.submitZKPResponse}
|
|
34
76
|
*/
|
|
35
77
|
async submitZKPResponse(ethSigner, txData, zkProofResponses) {
|
|
36
78
|
const chainConfig = this._configs.find((i) => i.chainId == txData.chain_id);
|
|
37
79
|
if (!chainConfig) {
|
|
38
80
|
throw new Error(`config for chain id ${txData.chain_id} was not found`);
|
|
39
81
|
}
|
|
40
|
-
if (txData.method_id.replace('0x', '') !==
|
|
41
|
-
throw new Error(`
|
|
82
|
+
if (txData.method_id.replace('0x', '') !== FunctionSignatures.SumbitZKPResponseV1) {
|
|
83
|
+
throw new Error(`submitZKPResponse function doesn't implement requested method id. Only '0x${FunctionSignatures.SumbitZKPResponseV1}' is supported.`);
|
|
42
84
|
}
|
|
43
85
|
const provider = new JsonRpcProvider(chainConfig.url, chainConfig.chainId);
|
|
44
|
-
const verifierContract = new Contract(txData.contract_address, abi, provider);
|
|
45
86
|
ethSigner = ethSigner.connect(provider);
|
|
46
|
-
const contract = verifierContract.connect(ethSigner);
|
|
47
87
|
const response = new Map();
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
zkProof.proof.pi_c.slice(0, 2)
|
|
60
|
-
];
|
|
61
|
-
const feeData = await provider.getFeeData();
|
|
62
|
-
const maxFeePerGas = chainConfig.maxFeePerGas
|
|
63
|
-
? BigInt(chainConfig.maxFeePerGas)
|
|
64
|
-
: feeData.maxFeePerGas;
|
|
65
|
-
const maxPriorityFeePerGas = chainConfig.maxPriorityFeePerGas
|
|
66
|
-
? BigInt(chainConfig.maxPriorityFeePerGas)
|
|
67
|
-
: feeData.maxPriorityFeePerGas;
|
|
68
|
-
const gasLimit = await contract.submitZKPResponse.estimateGas(...payload);
|
|
69
|
-
const txData = await contract.submitZKPResponse.populateTransaction(...payload);
|
|
88
|
+
const feeData = await provider.getFeeData();
|
|
89
|
+
const maxFeePerGas = chainConfig.maxFeePerGas
|
|
90
|
+
? BigInt(chainConfig.maxFeePerGas)
|
|
91
|
+
: feeData.maxFeePerGas;
|
|
92
|
+
const maxPriorityFeePerGas = chainConfig.maxPriorityFeePerGas
|
|
93
|
+
? BigInt(chainConfig.maxPriorityFeePerGas)
|
|
94
|
+
: feeData.maxPriorityFeePerGas;
|
|
95
|
+
const verifierContract = new Contract(txData.contract_address, abi);
|
|
96
|
+
for (const zkProofResponse of zkProofResponses) {
|
|
97
|
+
const txArgs = await this.prepareTxArgsSubmitV1(txData, zkProofResponse);
|
|
98
|
+
const payload = await verifierContract.submitZKPResponse.populateTransaction(...txArgs);
|
|
70
99
|
const request = {
|
|
71
|
-
to: txData.
|
|
72
|
-
data:
|
|
73
|
-
gasLimit,
|
|
100
|
+
to: txData.contract_address,
|
|
101
|
+
data: payload.data,
|
|
74
102
|
maxFeePerGas,
|
|
75
103
|
maxPriorityFeePerGas
|
|
76
104
|
};
|
|
105
|
+
let gasLimit;
|
|
106
|
+
try {
|
|
107
|
+
gasLimit = await ethSigner.estimateGas(request);
|
|
108
|
+
}
|
|
109
|
+
catch (e) {
|
|
110
|
+
gasLimit = maxGasLimit;
|
|
111
|
+
}
|
|
112
|
+
request.gasLimit = gasLimit;
|
|
77
113
|
const transactionService = new TransactionService(provider);
|
|
78
114
|
const { txnHash } = await transactionService.sendTransactionRequest(ethSigner, request);
|
|
79
|
-
response.set(txnHash,
|
|
115
|
+
response.set(txnHash, zkProofResponse);
|
|
80
116
|
}
|
|
81
117
|
return response;
|
|
82
118
|
}
|
|
119
|
+
/**
|
|
120
|
+
* {@inheritDoc IOnChainZKPVerifier.submitZKPResponseV2}
|
|
121
|
+
*/
|
|
122
|
+
async submitZKPResponseV2(ethSigner, txData, zkProofResponses) {
|
|
123
|
+
const chainConfig = this._configs.find((i) => i.chainId == txData.chain_id);
|
|
124
|
+
if (!chainConfig) {
|
|
125
|
+
throw new Error(`config for chain id ${txData.chain_id} was not found`);
|
|
126
|
+
}
|
|
127
|
+
if (txData.method_id.replace('0x', '') !== FunctionSignatures.SumbitZKPResponseV2) {
|
|
128
|
+
throw new Error(`submitZKPResponseV2 function doesn't implement requested method id. Only '0x${FunctionSignatures.SumbitZKPResponseV2}' is supported.`);
|
|
129
|
+
}
|
|
130
|
+
if (!this._opts?.didResolverUrl) {
|
|
131
|
+
throw new Error(`did resolver url required for crosschain verification`);
|
|
132
|
+
}
|
|
133
|
+
const provider = new JsonRpcProvider(chainConfig.url, chainConfig.chainId);
|
|
134
|
+
ethSigner = ethSigner.connect(provider);
|
|
135
|
+
const txDataArgs = await this.prepareTxArgsSubmitV2(txData, zkProofResponses);
|
|
136
|
+
const feeData = await provider.getFeeData();
|
|
137
|
+
const maxFeePerGas = chainConfig.maxFeePerGas
|
|
138
|
+
? BigInt(chainConfig.maxFeePerGas)
|
|
139
|
+
: feeData.maxFeePerGas;
|
|
140
|
+
const maxPriorityFeePerGas = chainConfig.maxPriorityFeePerGas
|
|
141
|
+
? BigInt(chainConfig.maxPriorityFeePerGas)
|
|
142
|
+
: feeData.maxPriorityFeePerGas;
|
|
143
|
+
const verifierContract = new Contract(txData.contract_address, abi);
|
|
144
|
+
const txRequestData = await verifierContract.submitZKPResponseV2.populateTransaction(...txDataArgs);
|
|
145
|
+
const request = {
|
|
146
|
+
to: txData.contract_address,
|
|
147
|
+
data: txRequestData.data,
|
|
148
|
+
maxFeePerGas,
|
|
149
|
+
maxPriorityFeePerGas
|
|
150
|
+
};
|
|
151
|
+
let gasLimit;
|
|
152
|
+
try {
|
|
153
|
+
gasLimit = await ethSigner.estimateGas(request);
|
|
154
|
+
}
|
|
155
|
+
catch (e) {
|
|
156
|
+
gasLimit = maxGasLimit;
|
|
157
|
+
}
|
|
158
|
+
request.gasLimit = gasLimit;
|
|
159
|
+
const transactionService = new TransactionService(provider);
|
|
160
|
+
const { txnHash } = await transactionService.sendTransactionRequest(ethSigner, request);
|
|
161
|
+
return new Map().set(txnHash, zkProofResponses);
|
|
162
|
+
}
|
|
163
|
+
async prepareTxArgsSubmitV2(txData, zkProofResponses) {
|
|
164
|
+
if (txData.method_id.replace('0x', '') !== FunctionSignatures.SumbitZKPResponseV2) {
|
|
165
|
+
throw new Error(`submit cross chain doesn't implement requested method id. Only '0x${FunctionSignatures.SumbitZKPResponseV2}' is supported.`);
|
|
166
|
+
}
|
|
167
|
+
if (!this._opts?.didResolverUrl) {
|
|
168
|
+
throw new Error(`did resolver url required for crosschain verification`);
|
|
169
|
+
}
|
|
170
|
+
const gistUpdateArr = [];
|
|
171
|
+
const stateUpdateArr = [];
|
|
172
|
+
const payload = [];
|
|
173
|
+
// Resolved gists and states to avoid duplicate requests
|
|
174
|
+
const gistUpdateResolutionsPending = [];
|
|
175
|
+
const stateUpdateResolutionsPending = [];
|
|
176
|
+
for (const zkProof of zkProofResponses) {
|
|
177
|
+
const requestID = zkProof.id;
|
|
178
|
+
const inputs = zkProof.pub_signals;
|
|
179
|
+
if (!this._supportedCircuits.includes(zkProof.circuitId)) {
|
|
180
|
+
throw new Error(`Circuit ${zkProof.circuitId} not supported by OnChainZKPVerifier`);
|
|
181
|
+
}
|
|
182
|
+
const zkProofEncoded = this.packZkpProof(inputs, zkProof.proof.pi_a.slice(0, 2), [
|
|
183
|
+
[zkProof.proof.pi_b[0][1], zkProof.proof.pi_b[0][0]],
|
|
184
|
+
[zkProof.proof.pi_b[1][1], zkProof.proof.pi_b[1][0]]
|
|
185
|
+
], zkProof.proof.pi_c.slice(0, 2));
|
|
186
|
+
const stateInfo = this.getOnChainGistRootStatePubSignals(zkProof.circuitId, zkProof.pub_signals);
|
|
187
|
+
const gistUpdateResolutions = [];
|
|
188
|
+
for (const gist of stateInfo.gists) {
|
|
189
|
+
const gistResolutionPending = gistUpdateResolutionsPending.find((g) => g == JSON.stringify(gist));
|
|
190
|
+
if (gistResolutionPending) {
|
|
191
|
+
continue;
|
|
192
|
+
}
|
|
193
|
+
gistUpdateResolutionsPending.push(JSON.stringify(gist));
|
|
194
|
+
gistUpdateResolutions.push(this.resolveDidDocumentEip712MessageAndSignature(DID.parseFromId(gist.id), this._opts.didResolverUrl, { gist: gist.root }));
|
|
195
|
+
}
|
|
196
|
+
const stateUpdateResolutions = [];
|
|
197
|
+
for (const state of stateInfo.states) {
|
|
198
|
+
const stateResolutionPending = stateUpdateResolutionsPending.find((s) => s == JSON.stringify(state));
|
|
199
|
+
if (stateResolutionPending) {
|
|
200
|
+
continue;
|
|
201
|
+
}
|
|
202
|
+
stateUpdateResolutionsPending.push(JSON.stringify(state));
|
|
203
|
+
stateUpdateResolutions.push(this.resolveDidDocumentEip712MessageAndSignature(DID.parseFromId(state.id), this._opts.didResolverUrl, {
|
|
204
|
+
state: state.state
|
|
205
|
+
}));
|
|
206
|
+
}
|
|
207
|
+
if (gistUpdateResolutions.length > 0) {
|
|
208
|
+
gistUpdateArr.push(...(await Promise.all(gistUpdateResolutions)));
|
|
209
|
+
}
|
|
210
|
+
if (stateUpdateResolutions.length > 0) {
|
|
211
|
+
stateUpdateArr.push(...(await Promise.all(stateUpdateResolutions)));
|
|
212
|
+
}
|
|
213
|
+
const metadataArr = [];
|
|
214
|
+
if (zkProof.vp) {
|
|
215
|
+
for (const key in zkProof.vp.verifiableCredential.credentialSubject) {
|
|
216
|
+
if (key === '@type') {
|
|
217
|
+
continue;
|
|
218
|
+
}
|
|
219
|
+
const metadataValue = poseidon.hashBytes(byteEncoder.encode(JSON.stringify(zkProof.vp.verifiableCredential.credentialSubject[key])));
|
|
220
|
+
const bytesValue = byteEncoder.encode(metadataValue.toString());
|
|
221
|
+
metadataArr.push({
|
|
222
|
+
key,
|
|
223
|
+
value: bytesValue
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
const metadata = this.packMetadatas(metadataArr);
|
|
228
|
+
payload.push({
|
|
229
|
+
requestId: requestID,
|
|
230
|
+
zkProof: zkProofEncoded,
|
|
231
|
+
data: metadata
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
const crossChainProofs = this.packCrossChainProofs(gistUpdateArr, stateUpdateArr);
|
|
235
|
+
return [payload, crossChainProofs];
|
|
236
|
+
}
|
|
237
|
+
packZkpProof(inputs, a, b, c) {
|
|
238
|
+
return this._abiCoder.encode(['uint256[] inputs', 'uint256[2]', 'uint256[2][2]', 'uint256[2]'], [inputs, a, b, c]);
|
|
239
|
+
}
|
|
240
|
+
packCrossChainProofs(gistUpdateArr, stateUpdateArr) {
|
|
241
|
+
const proofs = [];
|
|
242
|
+
for (const globalStateUpdate of gistUpdateArr) {
|
|
243
|
+
proofs.push({
|
|
244
|
+
proofType: 'globalStateProof',
|
|
245
|
+
proof: this.packGlobalStateMsg(globalStateUpdate)
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
for (const stateUpdate of stateUpdateArr) {
|
|
249
|
+
proofs.push({
|
|
250
|
+
proofType: 'stateProof',
|
|
251
|
+
proof: this.packIdentityStateMsg(stateUpdate)
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
return this._abiCoder.encode(['tuple(' + 'string proofType,' + 'bytes proof' + ')[]'], [proofs]);
|
|
255
|
+
}
|
|
256
|
+
packGlobalStateMsg(msg) {
|
|
257
|
+
return this._abiCoder.encode([
|
|
258
|
+
'tuple(' +
|
|
259
|
+
'tuple(' +
|
|
260
|
+
'uint256 timestamp,' +
|
|
261
|
+
'bytes2 idType,' +
|
|
262
|
+
'uint256 root,' +
|
|
263
|
+
'uint256 replacedAtTimestamp' +
|
|
264
|
+
') globalStateMsg,' +
|
|
265
|
+
'bytes signature,' +
|
|
266
|
+
')'
|
|
267
|
+
], [msg]);
|
|
268
|
+
}
|
|
269
|
+
packIdentityStateMsg(msg) {
|
|
270
|
+
return this._abiCoder.encode([
|
|
271
|
+
'tuple(' +
|
|
272
|
+
'tuple(' +
|
|
273
|
+
'uint256 timestamp,' +
|
|
274
|
+
'uint256 id,' +
|
|
275
|
+
'uint256 state,' +
|
|
276
|
+
'uint256 replacedAtTimestamp' +
|
|
277
|
+
') idStateMsg,' +
|
|
278
|
+
'bytes signature,' +
|
|
279
|
+
')'
|
|
280
|
+
], [msg]);
|
|
281
|
+
}
|
|
282
|
+
packMetadatas(metas) {
|
|
283
|
+
return this._abiCoder.encode(['tuple(' + 'string key,' + 'bytes value' + ')[]'], [metas]);
|
|
284
|
+
}
|
|
285
|
+
getOnChainGistRootStatePubSignals(onChainCircuitId, inputs) {
|
|
286
|
+
let atomicQueryPubSignals;
|
|
287
|
+
switch (onChainCircuitId) {
|
|
288
|
+
case CircuitId.AtomicQueryMTPV2OnChain:
|
|
289
|
+
atomicQueryPubSignals = new AtomicQueryMTPV2OnChainPubSignals();
|
|
290
|
+
break;
|
|
291
|
+
case CircuitId.AtomicQuerySigV2OnChain:
|
|
292
|
+
atomicQueryPubSignals = new AtomicQuerySigV2OnChainPubSignals();
|
|
293
|
+
break;
|
|
294
|
+
case CircuitId.AtomicQueryV3OnChain:
|
|
295
|
+
atomicQueryPubSignals = new AtomicQueryV3OnChainPubSignals();
|
|
296
|
+
break;
|
|
297
|
+
}
|
|
298
|
+
const encodedInputs = byteEncoder.encode(JSON.stringify(inputs));
|
|
299
|
+
atomicQueryPubSignals.pubSignalsUnmarshal(encodedInputs);
|
|
300
|
+
return atomicQueryPubSignals.getStatesInfo();
|
|
301
|
+
}
|
|
302
|
+
async resolveDidDocumentEip712MessageAndSignature(did, resolverUrl, opts) {
|
|
303
|
+
const didDoc = await resolveDidDocument(did, resolverUrl, {
|
|
304
|
+
...opts,
|
|
305
|
+
signature: DIDDocumentSignature.EthereumEip712Signature2021
|
|
306
|
+
});
|
|
307
|
+
if (!didDoc.didResolutionMetadata.proof?.length) {
|
|
308
|
+
throw new Error('No proof found in resolved DID document');
|
|
309
|
+
}
|
|
310
|
+
const message = didDoc.didResolutionMetadata.proof[0].eip712.message;
|
|
311
|
+
const signature = didDoc.didResolutionMetadata.proof[0].proofValue;
|
|
312
|
+
const isGistRequest = opts?.gist && !opts.state;
|
|
313
|
+
if (isGistRequest) {
|
|
314
|
+
return {
|
|
315
|
+
globalStateMsg: {
|
|
316
|
+
timestamp: message.timestamp,
|
|
317
|
+
idType: message.idType,
|
|
318
|
+
root: message.root,
|
|
319
|
+
replacedAtTimestamp: message.replacedAtTimestamp
|
|
320
|
+
},
|
|
321
|
+
signature
|
|
322
|
+
};
|
|
323
|
+
}
|
|
324
|
+
return {
|
|
325
|
+
idStateMsg: {
|
|
326
|
+
timestamp: message.timestamp,
|
|
327
|
+
id: message.id,
|
|
328
|
+
state: message.state,
|
|
329
|
+
replacedAtTimestamp: message.replacedAtTimestamp
|
|
330
|
+
},
|
|
331
|
+
signature
|
|
332
|
+
};
|
|
333
|
+
}
|
|
83
334
|
}
|
|
@@ -3,6 +3,13 @@ import { Id, buildDIDType, genesisFromEthAddress, DID } from '@iden3/js-iden3-co
|
|
|
3
3
|
import { Hash } from '@iden3/js-merkletree';
|
|
4
4
|
import { keccak256 } from 'js-sha3';
|
|
5
5
|
import { hexToBytes } from './encoding';
|
|
6
|
+
/**
|
|
7
|
+
* Supported DID Document Signatures
|
|
8
|
+
*/
|
|
9
|
+
export var DIDDocumentSignature;
|
|
10
|
+
(function (DIDDocumentSignature) {
|
|
11
|
+
DIDDocumentSignature["EthereumEip712Signature2021"] = "EthereumEip712Signature2021";
|
|
12
|
+
})(DIDDocumentSignature || (DIDDocumentSignature = {}));
|
|
6
13
|
/**
|
|
7
14
|
* Checks if state is genesis state
|
|
8
15
|
*
|
|
@@ -66,6 +73,34 @@ export const resolveDIDDocumentAuth = async (did, resolveURL, state) => {
|
|
|
66
73
|
const didResolutionRes = (await resp.json());
|
|
67
74
|
return didResolutionRes.didDocument?.verificationMethod?.find((i) => i.type === 'Iden3StateInfo2023');
|
|
68
75
|
};
|
|
76
|
+
function emptyStateDID(did) {
|
|
77
|
+
const id = DID.idFromDID(did);
|
|
78
|
+
const didType = buildDIDType(DID.methodFromId(id), DID.blockchainFromId(id), DID.networkIdFromId(id));
|
|
79
|
+
const identifier = Id.idGenesisFromIdenState(didType, 0n);
|
|
80
|
+
const emptyDID = DID.parseFromId(identifier);
|
|
81
|
+
return emptyDID;
|
|
82
|
+
}
|
|
83
|
+
export const resolveDidDocument = async (did, resolverUrl, opts) => {
|
|
84
|
+
let didString = did.string().replace(/:/g, '%3A');
|
|
85
|
+
// for gist resolve we have to `hide` user did (look into resolver implementation)
|
|
86
|
+
const isGistRequest = opts?.gist && !opts.state;
|
|
87
|
+
if (isGistRequest) {
|
|
88
|
+
didString = emptyStateDID(did).string();
|
|
89
|
+
}
|
|
90
|
+
let url = `${resolverUrl}/1.0/identifiers/${didString}`;
|
|
91
|
+
if (opts?.signature) {
|
|
92
|
+
url += `?signature=${opts.signature}`;
|
|
93
|
+
}
|
|
94
|
+
if (opts?.state) {
|
|
95
|
+
url += `${url.includes('?') ? '&' : '?'}state=${opts.state.hex()}`;
|
|
96
|
+
}
|
|
97
|
+
if (opts?.gist) {
|
|
98
|
+
url += `${url.includes('?') ? '&' : '?'}gist=${opts.gist.hex()}`;
|
|
99
|
+
}
|
|
100
|
+
const resp = await fetch(url);
|
|
101
|
+
const data = await resp.json();
|
|
102
|
+
return data;
|
|
103
|
+
};
|
|
69
104
|
export const buildDIDFromEthPubKey = (didType, pubKeyEth) => {
|
|
70
105
|
// Use Keccak-256 hash function to get public key hash
|
|
71
106
|
const hashOfPublicKey = keccak256(hexToBytes(pubKeyEth));
|
|
@@ -50,7 +50,7 @@ export class W3CCredential {
|
|
|
50
50
|
}
|
|
51
51
|
static fromJSON(obj) {
|
|
52
52
|
const w = new W3CCredential();
|
|
53
|
-
Object.assign(w, obj);
|
|
53
|
+
Object.assign(w, structuredClone(obj));
|
|
54
54
|
w.proof = Array.isArray(w.proof)
|
|
55
55
|
? w.proof.map(W3CCredential.proofFromJSON)
|
|
56
56
|
: W3CCredential.proofFromJSON(w.proof);
|
|
@@ -2,7 +2,7 @@ import { Id, Claim } from '@iden3/js-iden3-core';
|
|
|
2
2
|
import { Signature } from '@iden3/js-crypto';
|
|
3
3
|
import { Query, TreeState, GISTProof, ClaimWithMTPProof } from './models';
|
|
4
4
|
import { Hash, Proof } from '@iden3/js-merkletree';
|
|
5
|
-
import { BaseConfig } from './common';
|
|
5
|
+
import { BaseConfig, IStateInfoPubSignals, StatesInfo } from './common';
|
|
6
6
|
/**
|
|
7
7
|
* AtomicQueryMTPV2OnChainInputs ZK private inputs for credentialAtomicQueryMTPV2OnChain.circom
|
|
8
8
|
*
|
|
@@ -45,7 +45,7 @@ export declare class AtomicQueryMTPV2OnChainInputs extends BaseConfig {
|
|
|
45
45
|
* @class AtomicQueryMTPV2OnChainPubSignals
|
|
46
46
|
* @extends {BaseConfig}
|
|
47
47
|
*/
|
|
48
|
-
export declare class AtomicQueryMTPV2OnChainPubSignals extends BaseConfig {
|
|
48
|
+
export declare class AtomicQueryMTPV2OnChainPubSignals extends BaseConfig implements IStateInfoPubSignals {
|
|
49
49
|
requestID: bigint;
|
|
50
50
|
userID: Id;
|
|
51
51
|
issuerID: Id;
|
|
@@ -64,4 +64,6 @@ export declare class AtomicQueryMTPV2OnChainPubSignals extends BaseConfig {
|
|
|
64
64
|
* @returns AtomicQuerySigV2PubSignals
|
|
65
65
|
*/
|
|
66
66
|
pubSignalsUnmarshal(data: Uint8Array): AtomicQueryMTPV2OnChainPubSignals;
|
|
67
|
+
/** {@inheritDoc IStateInfoPubSignals.getStatesInfo} */
|
|
68
|
+
getStatesInfo(): StatesInfo;
|
|
67
69
|
}
|
|
@@ -2,7 +2,7 @@ import { Id, Claim } from '@iden3/js-iden3-core';
|
|
|
2
2
|
import { Signature } from '@iden3/js-crypto';
|
|
3
3
|
import { Query, ClaimWithSigProof, TreeState, GISTProof } from './models';
|
|
4
4
|
import { Hash, Proof } from '@iden3/js-merkletree';
|
|
5
|
-
import { BaseConfig } from './common';
|
|
5
|
+
import { BaseConfig, IStateInfoPubSignals, StatesInfo } from './common';
|
|
6
6
|
/**
|
|
7
7
|
* AtomicQuerySigV2OnChainInputs ZK private inputs for credentialAtomicQuerySig.circom
|
|
8
8
|
*
|
|
@@ -112,7 +112,7 @@ export declare class AtomicQuerySigV2OnChainCircuitInputs {
|
|
|
112
112
|
* @class AtomicQuerySigV2OnChainPubSignals
|
|
113
113
|
* @extends {BaseConfig}
|
|
114
114
|
*/
|
|
115
|
-
export declare class AtomicQuerySigV2OnChainPubSignals extends BaseConfig {
|
|
115
|
+
export declare class AtomicQuerySigV2OnChainPubSignals extends BaseConfig implements IStateInfoPubSignals {
|
|
116
116
|
requestID: bigint;
|
|
117
117
|
userID: Id;
|
|
118
118
|
issuerID: Id;
|
|
@@ -131,4 +131,6 @@ export declare class AtomicQuerySigV2OnChainPubSignals extends BaseConfig {
|
|
|
131
131
|
* @returns AtomicQuerySigV2PubSignals
|
|
132
132
|
*/
|
|
133
133
|
pubSignalsUnmarshal(data: Uint8Array): AtomicQuerySigV2OnChainPubSignals;
|
|
134
|
+
/** {@inheritDoc IStateInfoPubSignals.getStatesInfo} */
|
|
135
|
+
getStatesInfo(): StatesInfo;
|
|
134
136
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Claim, Id } from '@iden3/js-iden3-core';
|
|
2
|
-
import { BaseConfig } from './common';
|
|
2
|
+
import { BaseConfig, IStateInfoPubSignals, StatesInfo } from './common';
|
|
3
3
|
import { GISTProof, Query, TreeState } from './models';
|
|
4
4
|
import { Hash, Proof } from '@iden3/js-merkletree';
|
|
5
5
|
import { ClaimWithSigAndMTPProof } from './atomic-query-v3';
|
|
@@ -118,7 +118,7 @@ interface AtomicQueryV3OnChainCircuitInputs {
|
|
|
118
118
|
* @beta
|
|
119
119
|
* AtomicQueryV3OnChainPubSignals public inputs
|
|
120
120
|
*/
|
|
121
|
-
export declare class AtomicQueryV3OnChainPubSignals extends BaseConfig {
|
|
121
|
+
export declare class AtomicQueryV3OnChainPubSignals extends BaseConfig implements IStateInfoPubSignals {
|
|
122
122
|
requestID: bigint;
|
|
123
123
|
userID: Id;
|
|
124
124
|
issuerID: Id;
|
|
@@ -134,5 +134,7 @@ export declare class AtomicQueryV3OnChainPubSignals extends BaseConfig {
|
|
|
134
134
|
operatorOutput: bigint;
|
|
135
135
|
isBJJAuthEnabled: number;
|
|
136
136
|
pubSignalsUnmarshal(data: Uint8Array): AtomicQueryV3OnChainPubSignals;
|
|
137
|
+
/** {@inheritDoc IStateInfoPubSignals.getStatesInfo} */
|
|
138
|
+
getStatesInfo(): StatesInfo;
|
|
137
139
|
}
|
|
138
140
|
export {};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Hash, Proof } from '@iden3/js-merkletree';
|
|
2
2
|
import { TreeState } from './models';
|
|
3
|
+
import { Id } from '@iden3/js-iden3-core';
|
|
3
4
|
export declare const defaultMTLevels = 40;
|
|
4
5
|
export declare const defaultValueArraySize = 64;
|
|
5
6
|
export declare const defaultMTLevelsOnChain = 64;
|
|
@@ -119,3 +120,33 @@ export declare const existenceToInt: (b: boolean) => number;
|
|
|
119
120
|
* @returns object
|
|
120
121
|
*/
|
|
121
122
|
export declare function getProperties(obj: object): object;
|
|
123
|
+
/**
|
|
124
|
+
* states info from pub signals
|
|
125
|
+
*
|
|
126
|
+
* @public
|
|
127
|
+
* @type StatesInfo
|
|
128
|
+
*/
|
|
129
|
+
export type StatesInfo = {
|
|
130
|
+
states: {
|
|
131
|
+
id: Id;
|
|
132
|
+
state: Hash;
|
|
133
|
+
}[];
|
|
134
|
+
gists: {
|
|
135
|
+
id: Id;
|
|
136
|
+
root: Hash;
|
|
137
|
+
}[];
|
|
138
|
+
};
|
|
139
|
+
/**
|
|
140
|
+
* state pub signals
|
|
141
|
+
*
|
|
142
|
+
* @public
|
|
143
|
+
* @interface IStatePubSignals
|
|
144
|
+
*/
|
|
145
|
+
export interface IStateInfoPubSignals {
|
|
146
|
+
/**
|
|
147
|
+
* return object with state params
|
|
148
|
+
*
|
|
149
|
+
* @returns {OnChainStateInfo}
|
|
150
|
+
*/
|
|
151
|
+
getStatesInfo(): StatesInfo;
|
|
152
|
+
}
|
|
@@ -16,6 +16,7 @@ export declare const PROTOCOL_MESSAGE_TYPE: Readonly<{
|
|
|
16
16
|
REVOCATION_STATUS_REQUEST_MESSAGE_TYPE: "https://iden3-communication.io/revocation/1.0/request-status";
|
|
17
17
|
REVOCATION_STATUS_RESPONSE_MESSAGE_TYPE: "https://iden3-communication.io/revocation/1.0/status";
|
|
18
18
|
CONTRACT_INVOKE_REQUEST_MESSAGE_TYPE: "https://iden3-communication.io/proofs/1.0/contract-invoke-request";
|
|
19
|
+
CONTRACT_INVOKE_RESPONSE_MESSAGE_TYPE: "https://iden3-communication.io/proofs/1.0/contract-invoke-response";
|
|
19
20
|
CREDENTIAL_ONCHAIN_OFFER_MESSAGE_TYPE: "https://iden3-communication.io/credentials/1.0/onchain-offer";
|
|
20
21
|
PROPOSAL_REQUEST_MESSAGE_TYPE: "https://iden3-communication.io/credentials/0.1/proposal-request";
|
|
21
22
|
PROPOSAL_MESSAGE_TYPE: "https://iden3-communication.io/credentials/0.1/proposal";
|
|
@@ -13,14 +13,14 @@ import { AbstractMessageHandler, IProtocolMessageHandler } from './message-handl
|
|
|
13
13
|
*/
|
|
14
14
|
export interface IContractRequestHandler {
|
|
15
15
|
/**
|
|
16
|
-
* unpacks contract
|
|
16
|
+
* unpacks contract invoke request
|
|
17
17
|
* @beta
|
|
18
18
|
* @param {Uint8Array} request - raw byte message
|
|
19
19
|
* @returns `Promise<ContractInvokeRequest>`
|
|
20
20
|
*/
|
|
21
21
|
parseContractInvokeRequest(request: Uint8Array): Promise<ContractInvokeRequest>;
|
|
22
22
|
/**
|
|
23
|
-
* handle contract
|
|
23
|
+
* handle contract invoke request
|
|
24
24
|
* @beta
|
|
25
25
|
* @param {did} did - sender DID
|
|
26
26
|
* @param {Uint8Array} request - raw byte message
|
|
@@ -71,8 +71,19 @@ export declare class ContractRequestHandler extends AbstractMessageHandler imple
|
|
|
71
71
|
*/
|
|
72
72
|
parseContractInvokeRequest(request: Uint8Array): Promise<ContractInvokeRequest>;
|
|
73
73
|
/**
|
|
74
|
-
*
|
|
74
|
+
* creates contract invoke response
|
|
75
|
+
* @private
|
|
75
76
|
* @beta
|
|
77
|
+
* @param {ContractInvokeRequest} request - ContractInvokeRequest
|
|
78
|
+
* @param { Map<string, ZeroKnowledgeProofResponse[]>} responses - map tx hash to array of ZeroKnowledgeProofResponses
|
|
79
|
+
* @returns `Promise<ContractInvokeResponse>`
|
|
80
|
+
*/
|
|
81
|
+
private createContractInvokeResponse;
|
|
82
|
+
/**
|
|
83
|
+
* handle contract invoke request
|
|
84
|
+
* supports only 0xb68967e2 method id
|
|
85
|
+
* @beta
|
|
86
|
+
* @deprecated
|
|
76
87
|
* @param {did} did - sender DID
|
|
77
88
|
* @param {ContractInvokeRequest} request - contract invoke request
|
|
78
89
|
* @param {ContractInvokeHandlerOptions} opts - handler options
|
|
@@ -42,5 +42,15 @@ export type ZeroKnowledgeProofRequest = {
|
|
|
42
42
|
export type ZeroKnowledgeProofResponse = {
|
|
43
43
|
id: number;
|
|
44
44
|
circuitId: string;
|
|
45
|
-
vp?:
|
|
45
|
+
vp?: VerifiablePresentation;
|
|
46
46
|
} & ZKProof;
|
|
47
|
+
/** VerifiablePresentation represents structure of Verifiable Presentation */
|
|
48
|
+
export type VerifiablePresentation = {
|
|
49
|
+
'@context': string | (string | object)[];
|
|
50
|
+
'@type': string;
|
|
51
|
+
verifiableCredential: {
|
|
52
|
+
'@context': string | string[];
|
|
53
|
+
'@type': string | string[];
|
|
54
|
+
credentialSubject: JsonDocumentObject;
|
|
55
|
+
};
|
|
56
|
+
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { PROTOCOL_MESSAGE_TYPE } from '../../constants';
|
|
2
2
|
import { BasicMessage } from '../packer';
|
|
3
|
-
import { ZeroKnowledgeProofRequest } from './auth';
|
|
3
|
+
import { ZeroKnowledgeProofRequest, ZeroKnowledgeProofResponse } from './auth';
|
|
4
4
|
/** ContractInvokeRequest represents structure of contract invoke request object */
|
|
5
5
|
export type ContractInvokeRequest = BasicMessage & {
|
|
6
6
|
body: ContractInvokeRequestBody;
|
|
@@ -12,6 +12,21 @@ export type ContractInvokeRequestBody = {
|
|
|
12
12
|
transaction_data: ContractInvokeTransactionData;
|
|
13
13
|
scope: Array<ZeroKnowledgeProofRequest>;
|
|
14
14
|
};
|
|
15
|
+
/** ContractInvokeResponse represents structure of contract invoke response object */
|
|
16
|
+
export type ContractInvokeResponse = BasicMessage & {
|
|
17
|
+
body: ContractInvokeResponseBody;
|
|
18
|
+
type: typeof PROTOCOL_MESSAGE_TYPE.CONTRACT_INVOKE_RESPONSE_MESSAGE_TYPE;
|
|
19
|
+
};
|
|
20
|
+
/** ContractInvokeResponseBody represents structure of contract invoke response body object */
|
|
21
|
+
export type ContractInvokeResponseBody = {
|
|
22
|
+
scope: Array<OnChainZeroKnowledgeProofResponse>;
|
|
23
|
+
transaction_data: ContractInvokeTransactionData;
|
|
24
|
+
reason: string;
|
|
25
|
+
};
|
|
26
|
+
/** OnChainZeroKnowledgeProofResponse represents structure of onchain zero knowledge proof response */
|
|
27
|
+
export type OnChainZeroKnowledgeProofResponse = ZeroKnowledgeProofResponse & {
|
|
28
|
+
txHash: string;
|
|
29
|
+
};
|
|
15
30
|
/** ContractInvokeTransactionData represents structure of contract invoke transaction data object */
|
|
16
31
|
export type ContractInvokeTransactionData = {
|
|
17
32
|
contract_address: string;
|
|
@@ -4,7 +4,7 @@ import { IStateStorage } from '../../storage';
|
|
|
4
4
|
import { ProofQuery } from '../../verifiable';
|
|
5
5
|
import { BaseConfig } from '../../circuits/common';
|
|
6
6
|
import { VerifyOpts } from './query';
|
|
7
|
-
import { JSONObject } from '../../iden3comm';
|
|
7
|
+
import { JSONObject, VerifiablePresentation } from '../../iden3comm';
|
|
8
8
|
/**
|
|
9
9
|
* Verify Context - params for pub signal verification
|
|
10
10
|
* @type VerifyContext
|
|
@@ -12,7 +12,7 @@ import { JSONObject } from '../../iden3comm';
|
|
|
12
12
|
export type VerifyContext = {
|
|
13
13
|
pubSignals: string[];
|
|
14
14
|
query: ProofQuery;
|
|
15
|
-
verifiablePresentation?:
|
|
15
|
+
verifiablePresentation?: VerifiablePresentation;
|
|
16
16
|
sender: string;
|
|
17
17
|
challenge: bigint;
|
|
18
18
|
opts?: VerifyOpts;
|