@0xpolygonid/js-sdk 1.7.4 → 1.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser/esm/index.js +13086 -11852
- package/dist/browser/esm/index.js.map +1 -1
- package/dist/browser/umd/index.js +13115 -11861
- package/dist/browser/umd/index.js.map +1 -1
- package/dist/node/cjs/circuits/atomic-query-mtp-v2.js +3 -3
- package/dist/node/cjs/circuits/atomic-query-sig-v2.js +3 -3
- package/dist/node/cjs/circuits/atomic-query-v3.js +18 -13
- package/dist/node/cjs/circuits/auth-v2.js +1 -1
- package/dist/node/cjs/circuits/index.js +0 -1
- package/dist/node/cjs/circuits/linked-multi-query.js +16 -6
- package/dist/node/cjs/circuits/models.js +0 -5
- package/dist/node/cjs/credentials/credential-wallet.js +1 -3
- package/dist/node/cjs/credentials/index.js +1 -0
- package/dist/node/cjs/credentials/models.js +2 -0
- package/dist/node/cjs/credentials/status/credential-status-publisher.js +23 -4
- package/dist/node/cjs/iden3comm/constants.js +3 -1
- package/dist/node/cjs/iden3comm/handlers/auth.js +119 -14
- package/dist/node/cjs/kms/key-providers/sec256k1-provider.js +5 -2
- package/dist/node/cjs/proof/common.js +3 -4
- package/dist/node/cjs/proof/index.js +2 -1
- package/dist/node/cjs/proof/proof-service.js +22 -2
- package/dist/node/cjs/proof/provers/index.js +19 -0
- package/dist/node/cjs/proof/{inputs-generator.js → provers/inputs-generator.js} +43 -40
- package/dist/node/cjs/proof/{prover.js → provers/prover.js} +1 -1
- package/dist/node/cjs/proof/verifiers/index.js +18 -0
- package/dist/node/cjs/proof/verifiers/pub-signals-verifier.js +344 -0
- package/dist/node/cjs/proof/verifiers/query.js +190 -0
- package/dist/node/cjs/schema-processor/json/parser.js +39 -198
- package/dist/node/cjs/schema-processor/utils.js +13 -26
- package/dist/node/cjs/storage/blockchain/state.js +53 -8
- package/dist/node/cjs/storage/filters/jsonQuery.js +2 -2
- package/dist/node/cjs/utils/compare-func.js +11 -0
- package/dist/node/cjs/utils/index.js +2 -0
- package/dist/node/cjs/utils/message-bus.js +73 -0
- package/dist/node/cjs/verifiable/core-utils.js +234 -0
- package/dist/node/cjs/verifiable/credential.js +139 -1
- package/dist/node/cjs/verifiable/index.js +1 -0
- package/dist/node/esm/circuits/atomic-query-mtp-v2.js +3 -3
- package/dist/node/esm/circuits/atomic-query-sig-v2.js +3 -3
- package/dist/node/esm/circuits/atomic-query-v3.js +18 -13
- package/dist/node/esm/circuits/auth-v2.js +2 -2
- package/dist/node/esm/circuits/index.js +0 -1
- package/dist/node/esm/circuits/linked-multi-query.js +16 -6
- package/dist/node/esm/circuits/models.js +0 -5
- package/dist/node/esm/credentials/credential-wallet.js +1 -3
- package/dist/node/esm/credentials/index.js +1 -0
- package/dist/node/esm/credentials/models.js +1 -0
- package/dist/node/esm/credentials/status/credential-status-publisher.js +23 -4
- package/dist/node/esm/iden3comm/constants.js +3 -1
- package/dist/node/esm/iden3comm/handlers/auth.js +116 -13
- package/dist/node/esm/kms/key-providers/sec256k1-provider.js +5 -2
- package/dist/node/esm/proof/common.js +4 -5
- package/dist/node/esm/proof/index.js +2 -1
- package/dist/node/esm/proof/proof-service.js +22 -2
- package/dist/node/esm/proof/provers/index.js +3 -0
- package/dist/node/esm/proof/{inputs-generator.js → provers/inputs-generator.js} +40 -37
- package/dist/node/esm/proof/{prover.js → provers/prover.js} +1 -1
- package/dist/node/esm/proof/verifiers/index.js +2 -0
- package/dist/node/esm/proof/verifiers/pub-signals-verifier.js +340 -0
- package/dist/node/esm/proof/verifiers/query.js +186 -0
- package/dist/node/esm/schema-processor/json/parser.js +40 -199
- package/dist/node/esm/schema-processor/utils.js +13 -26
- package/dist/node/esm/storage/blockchain/state.js +53 -8
- package/dist/node/esm/storage/filters/jsonQuery.js +2 -2
- package/dist/node/esm/utils/compare-func.js +7 -0
- package/dist/node/esm/utils/index.js +2 -0
- package/dist/node/esm/utils/message-bus.js +66 -0
- package/dist/node/esm/verifiable/core-utils.js +200 -0
- package/dist/node/esm/verifiable/credential.js +118 -3
- package/dist/node/esm/verifiable/index.js +1 -0
- package/dist/types/circuits/index.d.ts +0 -1
- package/dist/types/circuits/linked-multi-query.d.ts +3 -3
- package/dist/types/circuits/models.d.ts +0 -4
- package/dist/types/credentials/credential-wallet.d.ts +2 -60
- package/dist/types/credentials/index.d.ts +1 -0
- package/dist/types/credentials/models.d.ts +68 -0
- package/dist/types/credentials/status/credential-status-publisher.d.ts +2 -0
- package/dist/types/iden3comm/constants.d.ts +1 -0
- package/dist/types/iden3comm/handlers/auth.d.ts +53 -13
- package/dist/types/iden3comm/types/protocol/credentials.d.ts +16 -0
- package/dist/types/identity/identity-wallet.d.ts +3 -1
- package/dist/types/kms/key-providers/sec256k1-provider.d.ts +1 -1
- package/dist/types/proof/index.d.ts +2 -1
- package/dist/types/proof/proof-service.d.ts +28 -3
- package/dist/types/proof/provers/index.d.ts +3 -0
- package/dist/types/proof/{inputs-generator.d.ts → provers/inputs-generator.d.ts} +15 -9
- package/dist/types/proof/{prover.d.ts → provers/prover.d.ts} +2 -2
- package/dist/types/proof/verifiers/index.d.ts +2 -0
- package/dist/types/proof/verifiers/pub-signals-verifier.d.ts +58 -0
- package/dist/types/proof/verifiers/query.d.ts +25 -0
- package/dist/types/schema-processor/json/parser.d.ts +47 -28
- package/dist/types/schema-processor/utils.d.ts +9 -4
- package/dist/types/storage/blockchain/state.d.ts +5 -1
- package/dist/types/storage/interfaces/state.d.ts +8 -0
- package/dist/types/utils/compare-func.d.ts +1 -0
- package/dist/types/utils/index.d.ts +2 -0
- package/dist/types/utils/message-bus.d.ts +62 -0
- package/dist/types/verifiable/core-utils.d.ts +84 -0
- package/dist/types/verifiable/credential.d.ts +11 -1
- package/dist/types/verifiable/index.d.ts +1 -0
- package/dist/types/verifiable/proof.d.ts +4 -0
- package/package.json +10 -10
- package/dist/node/cjs/circuits/linked-nullifier.js +0 -57
- package/dist/node/esm/circuits/linked-nullifier.js +0 -52
- package/dist/types/circuits/linked-nullifier.d.ts +0 -37
- /package/dist/node/cjs/proof/{witness_calculator.js → provers/witness_calculator.js} +0 -0
- /package/dist/node/esm/proof/{witness_calculator.js → provers/witness_calculator.js} +0 -0
- /package/dist/types/proof/{witness_calculator.d.ts → provers/witness_calculator.d.ts} +0 -0
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.checkQueryRequest = void 0;
|
|
4
|
+
const js_iden3_core_1 = require("@iden3/js-iden3-core");
|
|
5
|
+
const js_jsonld_merklization_1 = require("@iden3/js-jsonld-merklization");
|
|
6
|
+
const utils_1 = require("../../utils");
|
|
7
|
+
const comparer_1 = require("../../circuits/comparer");
|
|
8
|
+
const verifiable_1 = require("../../verifiable");
|
|
9
|
+
const common_1 = require("../common");
|
|
10
|
+
const provers_1 = require("../provers");
|
|
11
|
+
const defaultProofGenerationDelayOpts = 24 * 60 * 60 * 1000; // 24 hours
|
|
12
|
+
async function checkQueryRequest(query, outputs, circuitId, schemaLoader, verifiablePresentation, opts) {
|
|
13
|
+
// validate issuer
|
|
14
|
+
const userDID = js_iden3_core_1.DID.parseFromId(outputs.issuerId);
|
|
15
|
+
const issuerAllowed = !query.allowedIssuers ||
|
|
16
|
+
query.allowedIssuers?.some((issuer) => issuer === '*' || issuer === userDID.string());
|
|
17
|
+
if (!issuerAllowed) {
|
|
18
|
+
throw new Error('issuer is not in allowed list');
|
|
19
|
+
}
|
|
20
|
+
// validate schema
|
|
21
|
+
let schema;
|
|
22
|
+
try {
|
|
23
|
+
const loader = schemaLoader ?? (0, js_jsonld_merklization_1.getDocumentLoader)();
|
|
24
|
+
schema = (await loader(query.context ?? '')).document;
|
|
25
|
+
}
|
|
26
|
+
catch (e) {
|
|
27
|
+
throw new Error(`can't load schema for request query`);
|
|
28
|
+
}
|
|
29
|
+
if (!query.type) {
|
|
30
|
+
throw new Error(`proof query type is undefined`);
|
|
31
|
+
}
|
|
32
|
+
const schemaId = await js_jsonld_merklization_1.Path.getTypeIDFromContext(JSON.stringify(schema), query.type, {
|
|
33
|
+
documentLoader: schemaLoader
|
|
34
|
+
});
|
|
35
|
+
const schemaHash = (0, verifiable_1.caclulateCoreSchemaHash)(utils_1.byteEncoder.encode(schemaId));
|
|
36
|
+
if (schemaHash.bigInt() !== outputs.schemaHash.bigInt()) {
|
|
37
|
+
throw new Error(`schema that was used is not equal to requested in query`);
|
|
38
|
+
}
|
|
39
|
+
if (!query.skipClaimRevocationCheck && outputs.isRevocationChecked === 0) {
|
|
40
|
+
throw new Error(`check revocation is required`);
|
|
41
|
+
}
|
|
42
|
+
const queriesMetadata = await (0, common_1.parseQueriesMetadata)(query.type, JSON.stringify(schema), query.credentialSubject, {
|
|
43
|
+
documentLoader: schemaLoader
|
|
44
|
+
});
|
|
45
|
+
const circuitValidationData = provers_1.circuitValidator[circuitId];
|
|
46
|
+
if (queriesMetadata.length > circuitValidationData.maxQueriesCount) {
|
|
47
|
+
throw new Error(`circuit ${circuitId} supports only ${provers_1.circuitValidator[circuitId].maxQueriesCount} queries`);
|
|
48
|
+
}
|
|
49
|
+
const notSupportedOpIndx = queriesMetadata.findIndex((i) => !circuitValidationData.supportedOperations.includes(i.operator));
|
|
50
|
+
if (notSupportedOpIndx > -1) {
|
|
51
|
+
throw new Error(`circuit ${circuitId} not support ${queriesMetadata[notSupportedOpIndx].operator} operator`);
|
|
52
|
+
}
|
|
53
|
+
queriesMetadata.forEach(async (metadata) => {
|
|
54
|
+
if (!query.type) {
|
|
55
|
+
throw new Error(`proof query type is undefined`);
|
|
56
|
+
}
|
|
57
|
+
// validate selective disclosure
|
|
58
|
+
if (metadata.operator === comparer_1.Operators.SD) {
|
|
59
|
+
try {
|
|
60
|
+
await validateDisclosure(metadata, outputs, verifiablePresentation, schemaLoader);
|
|
61
|
+
}
|
|
62
|
+
catch (e) {
|
|
63
|
+
throw new Error(`failed to validate selective disclosure: ${e.message}`);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
else if (!metadata.fieldName && metadata.operator == comparer_1.Operators.NOOP) {
|
|
67
|
+
try {
|
|
68
|
+
await validateEmptyCredentialSubject(metadata, outputs);
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
catch (e) {
|
|
72
|
+
throw new Error(`failed to validate operators: ${e.message}`);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
try {
|
|
77
|
+
await validateOperators(metadata, outputs);
|
|
78
|
+
}
|
|
79
|
+
catch (e) {
|
|
80
|
+
throw new Error(`failed to validate operators: ${e.message}`);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
// verify claim
|
|
84
|
+
if (outputs.merklized === 1) {
|
|
85
|
+
if (outputs.claimPathNotExists === 1) {
|
|
86
|
+
throw new Error(`proof doesn't contains target query key`);
|
|
87
|
+
}
|
|
88
|
+
if (outputs.claimPathKey !== metadata.claimPathKey) {
|
|
89
|
+
throw new Error(`proof was generated for another path`);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
if (outputs.slotIndex !== metadata.slotIndex) {
|
|
94
|
+
throw new Error(`wrong claim slot was used in claim`);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
// verify timestamp
|
|
98
|
+
let acceptedProofGenerationDelay = defaultProofGenerationDelayOpts;
|
|
99
|
+
if (opts?.acceptedProofGenerationDelay) {
|
|
100
|
+
acceptedProofGenerationDelay = opts.acceptedProofGenerationDelay;
|
|
101
|
+
}
|
|
102
|
+
const timeDiff = Date.now() - (0, js_iden3_core_1.getDateFromUnixTimestamp)(Number(outputs.timestamp)).getTime();
|
|
103
|
+
if (timeDiff > acceptedProofGenerationDelay) {
|
|
104
|
+
throw new Error('generated proof is outdated');
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
exports.checkQueryRequest = checkQueryRequest;
|
|
110
|
+
async function validateEmptyCredentialSubject(cq, outputs) {
|
|
111
|
+
if (outputs.operator !== comparer_1.Operators.EQ) {
|
|
112
|
+
throw new Error('empty credentialSubject request available only for equal operation');
|
|
113
|
+
}
|
|
114
|
+
for (let index = 1; index < outputs.value.length; index++) {
|
|
115
|
+
if (outputs.value[index] !== 0n) {
|
|
116
|
+
throw new Error(`empty credentialSubject request not available for array of values`);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
const path = js_jsonld_merklization_1.Path.newPath([verifiable_1.VerifiableConstants.CREDENTIAL_SUBJECT_PATH]);
|
|
120
|
+
const subjectEntry = await path.mtEntry();
|
|
121
|
+
if (outputs.claimPathKey !== subjectEntry) {
|
|
122
|
+
throw new Error(`proof doesn't contain credentialSubject in claimPathKey`);
|
|
123
|
+
}
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
async function validateOperators(cq, outputs) {
|
|
127
|
+
if (outputs.operator !== cq.operator) {
|
|
128
|
+
throw new Error(`operator that was used is not equal to request`);
|
|
129
|
+
}
|
|
130
|
+
if (outputs.operator === comparer_1.Operators.NOOP) {
|
|
131
|
+
// for noop operator slot and value are not used in this case
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
for (let index = 0; index < outputs.value.length; index++) {
|
|
135
|
+
if (outputs.value[index] !== cq.values[index]) {
|
|
136
|
+
throw new Error(`comparison value that was used is not equal to requested in query`);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
async function validateDisclosure(cq, outputs, verifiablePresentation, ldLoader) {
|
|
141
|
+
if (!verifiablePresentation) {
|
|
142
|
+
throw new Error(`verifiablePresentation is required for selective disclosure request`);
|
|
143
|
+
}
|
|
144
|
+
if (outputs.operator !== comparer_1.Operators.EQ) {
|
|
145
|
+
throw new Error(`operator for selective disclosure must be $eq`);
|
|
146
|
+
}
|
|
147
|
+
for (let index = 1; index < outputs.value.length; index++) {
|
|
148
|
+
if (outputs.value[index] !== 0n) {
|
|
149
|
+
throw new Error(`selective disclosure not available for array of values`);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
let mz;
|
|
153
|
+
const strVerifiablePresentation = JSON.stringify(verifiablePresentation);
|
|
154
|
+
try {
|
|
155
|
+
mz = await js_jsonld_merklization_1.Merklizer.merklizeJSONLD(strVerifiablePresentation, {
|
|
156
|
+
documentLoader: ldLoader
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
catch (e) {
|
|
160
|
+
throw new Error(`can't merklize verifiablePresentation`);
|
|
161
|
+
}
|
|
162
|
+
let merklizedPath;
|
|
163
|
+
try {
|
|
164
|
+
const p = `verifiableCredential.credentialSubject.${cq.fieldName}`;
|
|
165
|
+
merklizedPath = await js_jsonld_merklization_1.Path.fromDocument(null, strVerifiablePresentation, p, {
|
|
166
|
+
documentLoader: ldLoader
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
catch (e) {
|
|
170
|
+
throw new Error(`can't build path to '${cq.fieldName}' key`);
|
|
171
|
+
}
|
|
172
|
+
let proof;
|
|
173
|
+
let value;
|
|
174
|
+
try {
|
|
175
|
+
({ proof, value } = await mz.proof(merklizedPath));
|
|
176
|
+
}
|
|
177
|
+
catch (e) {
|
|
178
|
+
throw new Error(`can't get value by path '${cq.fieldName}'`);
|
|
179
|
+
}
|
|
180
|
+
if (!value) {
|
|
181
|
+
throw new Error(`can't get merkle value for field '${cq.fieldName}'`);
|
|
182
|
+
}
|
|
183
|
+
if (!proof.existence) {
|
|
184
|
+
throw new Error(`path [${merklizedPath.parts}] doesn't exist in verifiablePresentation document`);
|
|
185
|
+
}
|
|
186
|
+
const bi = await value.mtEntry();
|
|
187
|
+
if (bi !== outputs.value[0]) {
|
|
188
|
+
throw new Error(`value that was used is not equal to requested in query`);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
@@ -25,18 +25,8 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
25
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
26
|
exports.Parser = void 0;
|
|
27
27
|
const verifiable_1 = require("../../verifiable");
|
|
28
|
-
const js_iden3_core_1 = require("@iden3/js-iden3-core");
|
|
29
|
-
const utils_1 = require("../utils");
|
|
30
|
-
const utils_2 = require("../../utils");
|
|
31
|
-
const js_jsonld_merklization_1 = require("@iden3/js-jsonld-merklization");
|
|
32
28
|
const jsonld = __importStar(require("jsonld/lib"));
|
|
33
29
|
const ldcontext = __importStar(require("jsonld/lib/context"));
|
|
34
|
-
const credentialSubjectFullKey = 'https://www.w3.org/2018/credentials#credentialSubject';
|
|
35
|
-
const verifiableCredentialFullKey = 'https://www.w3.org/2018/credentials#VerifiableCredential';
|
|
36
|
-
const typeFullKey = '@type';
|
|
37
|
-
const contextFullKey = '@context';
|
|
38
|
-
const serializationFullKey = 'iden3_serialization';
|
|
39
|
-
const fieldPrefix = 'iden3:v1:';
|
|
40
30
|
/**
|
|
41
31
|
* Parser can parse claim and schema data according to specification
|
|
42
32
|
*
|
|
@@ -45,6 +35,7 @@ const fieldPrefix = 'iden3:v1:';
|
|
|
45
35
|
*/
|
|
46
36
|
class Parser {
|
|
47
37
|
/**
|
|
38
|
+
* @deprecated The method should not be used. Use credential.toCoreClaim instead.
|
|
48
39
|
* ParseClaim creates core.Claim object from W3CCredential
|
|
49
40
|
*
|
|
50
41
|
* @param {W3CCredential} credential - Verifiable Credential
|
|
@@ -52,163 +43,53 @@ class Parser {
|
|
|
52
43
|
* @returns `Promise<CoreClaim>`
|
|
53
44
|
*/
|
|
54
45
|
static async parseClaim(credential, opts) {
|
|
55
|
-
|
|
56
|
-
opts = {
|
|
57
|
-
revNonce: 0,
|
|
58
|
-
version: 0,
|
|
59
|
-
subjectPosition: verifiable_1.SubjectPosition.Index,
|
|
60
|
-
merklizedRootPosition: verifiable_1.MerklizedRootPosition.None,
|
|
61
|
-
updatable: false,
|
|
62
|
-
merklizeOpts: {}
|
|
63
|
-
};
|
|
64
|
-
}
|
|
65
|
-
const mz = await credential.merklize(opts.merklizeOpts);
|
|
66
|
-
const credentialType = Parser.findCredentialType(mz);
|
|
67
|
-
const subjectId = credential.credentialSubject['id'];
|
|
68
|
-
const { slots, nonMerklized } = await this.parseSlots(mz, credential, credentialType);
|
|
69
|
-
// if schema is for non merklized credential, root position must be set to none ('')
|
|
70
|
-
// otherwise default position for merklized position is index.
|
|
71
|
-
if (nonMerklized && opts.merklizedRootPosition !== verifiable_1.MerklizedRootPosition.None) {
|
|
72
|
-
throw new Error('merklized root position is not supported for non-merklized claims');
|
|
73
|
-
}
|
|
74
|
-
if (!nonMerklized && opts.merklizedRootPosition === verifiable_1.MerklizedRootPosition.None) {
|
|
75
|
-
opts.merklizedRootPosition = verifiable_1.MerklizedRootPosition.Index;
|
|
76
|
-
}
|
|
77
|
-
const schemaHash = (0, utils_1.createSchemaHash)(utils_2.byteEncoder.encode(credentialType));
|
|
78
|
-
const claim = js_iden3_core_1.Claim.newClaim(schemaHash, js_iden3_core_1.ClaimOptions.withIndexDataBytes(slots.indexA, slots.indexB), js_iden3_core_1.ClaimOptions.withValueDataBytes(slots.valueA, slots.valueB), js_iden3_core_1.ClaimOptions.withRevocationNonce(BigInt(opts.revNonce)), js_iden3_core_1.ClaimOptions.withVersion(opts.version));
|
|
79
|
-
if (opts.updatable) {
|
|
80
|
-
claim.setFlagUpdatable(opts.updatable);
|
|
81
|
-
}
|
|
82
|
-
if (credential.expirationDate) {
|
|
83
|
-
claim.setExpirationDate(new Date(credential.expirationDate));
|
|
84
|
-
}
|
|
85
|
-
if (subjectId) {
|
|
86
|
-
const did = js_iden3_core_1.DID.parse(subjectId.toString());
|
|
87
|
-
const id = js_iden3_core_1.DID.idFromDID(did);
|
|
88
|
-
switch (opts.subjectPosition) {
|
|
89
|
-
case '':
|
|
90
|
-
case verifiable_1.SubjectPosition.Index:
|
|
91
|
-
claim.setIndexId(id);
|
|
92
|
-
break;
|
|
93
|
-
case verifiable_1.SubjectPosition.Value:
|
|
94
|
-
claim.setValueId(id);
|
|
95
|
-
break;
|
|
96
|
-
default:
|
|
97
|
-
throw new Error('unknown subject position');
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
switch (opts.merklizedRootPosition) {
|
|
101
|
-
case verifiable_1.MerklizedRootPosition.Index: {
|
|
102
|
-
const mk = await credential.merklize(opts.merklizeOpts);
|
|
103
|
-
claim.setIndexMerklizedRoot((await mk.root()).bigInt());
|
|
104
|
-
break;
|
|
105
|
-
}
|
|
106
|
-
case verifiable_1.MerklizedRootPosition.Value: {
|
|
107
|
-
const mk = await credential.merklize(opts.merklizeOpts);
|
|
108
|
-
claim.setValueMerklizedRoot((await mk.root()).bigInt());
|
|
109
|
-
break;
|
|
110
|
-
}
|
|
111
|
-
case verifiable_1.MerklizedRootPosition.None:
|
|
112
|
-
break;
|
|
113
|
-
default:
|
|
114
|
-
throw new Error('unknown merklized root position');
|
|
115
|
-
}
|
|
116
|
-
return claim;
|
|
46
|
+
return credential.toCoreClaim(opts);
|
|
117
47
|
}
|
|
48
|
+
/**
|
|
49
|
+
* @deprecated The method should not be used. Use findCredentialType from verifiable.
|
|
50
|
+
*/
|
|
118
51
|
static findCredentialType(mz) {
|
|
119
|
-
|
|
120
|
-
try {
|
|
121
|
-
// try to look into credentialSubject.@type to get type of credentials
|
|
122
|
-
const path1 = new js_jsonld_merklization_1.Path([credentialSubjectFullKey, typeFullKey], opts.hasher);
|
|
123
|
-
const e = mz.rawValue(path1);
|
|
124
|
-
return e;
|
|
125
|
-
}
|
|
126
|
-
catch (err) {
|
|
127
|
-
// if type of credentials not found in credentialSubject.@type, loop at
|
|
128
|
-
// top level @types if it contains two elements: type we are looking for
|
|
129
|
-
// and "VerifiableCredential" type.
|
|
130
|
-
const path2 = new js_jsonld_merklization_1.Path([typeFullKey], opts.hasher);
|
|
131
|
-
const topLevelTypes = mz.rawValue(path2);
|
|
132
|
-
if (!Array.isArray(topLevelTypes)) {
|
|
133
|
-
throw new Error('top level @type expected to be an array');
|
|
134
|
-
}
|
|
135
|
-
if (topLevelTypes.length !== 2) {
|
|
136
|
-
throw new Error('top level @type expected to be of length 2');
|
|
137
|
-
}
|
|
138
|
-
switch (verifiableCredentialFullKey) {
|
|
139
|
-
case topLevelTypes[0]:
|
|
140
|
-
return topLevelTypes[1];
|
|
141
|
-
case topLevelTypes[1]:
|
|
142
|
-
return topLevelTypes[0];
|
|
143
|
-
default:
|
|
144
|
-
throw new Error('@type(s) are expected to contain VerifiableCredential type');
|
|
145
|
-
}
|
|
146
|
-
}
|
|
52
|
+
return (0, verifiable_1.findCredentialType)(mz);
|
|
147
53
|
}
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
54
|
+
/**
|
|
55
|
+
* @deprecated The method should not be used. Use credential.getSerializationAttr instead.
|
|
56
|
+
*
|
|
57
|
+
* Get `iden3_serialization` attr definition from context document either using
|
|
58
|
+
* type name like DeliverAddressMultiTestForked or by type id like
|
|
59
|
+
* urn:uuid:ac2ede19-b3b9-454d-b1a9-a7b3d5763100.
|
|
60
|
+
* */
|
|
151
61
|
static async getSerializationAttr(credential, opts, tp) {
|
|
152
62
|
const ldCtx = await jsonld.processContext(ldcontext.getInitialContext({}), credential['@context'], opts);
|
|
153
63
|
return Parser.getSerializationAttrFromParsedContext(ldCtx, tp);
|
|
154
64
|
}
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
65
|
+
/**
|
|
66
|
+
* @deprecated The method should not be used. Use getSerializationAttrFromContext from verifiable.
|
|
67
|
+
*
|
|
68
|
+
* Get `iden3_serialization` attr definition from context document either using
|
|
69
|
+
* type name like DeliverAddressMultiTestForked or by type id like
|
|
70
|
+
* urn:uuid:ac2ede19-b3b9-454d-b1a9-a7b3d5763100.
|
|
71
|
+
*
|
|
72
|
+
*/
|
|
158
73
|
static async getSerializationAttrFromContext(context, opts, tp) {
|
|
159
|
-
|
|
160
|
-
return Parser.getSerializationAttrFromParsedContext(ldCtx, tp);
|
|
74
|
+
return (0, verifiable_1.getSerializationAttrFromContext)(context, opts, tp);
|
|
161
75
|
}
|
|
76
|
+
/**
|
|
77
|
+
* @deprecated The method should not be used. Use getSerializationAttrFromParsedContext from verifiable.
|
|
78
|
+
*
|
|
79
|
+
* */
|
|
162
80
|
static async getSerializationAttrFromParsedContext(ldCtx, tp) {
|
|
163
|
-
|
|
164
|
-
if (!termDef) {
|
|
165
|
-
throw new Error('terms definitions is not of correct type');
|
|
166
|
-
}
|
|
167
|
-
const term = termDef.get(tp) ?? [...termDef.values()].find((value) => value['@id'] === tp);
|
|
168
|
-
if (!term) {
|
|
169
|
-
return '';
|
|
170
|
-
}
|
|
171
|
-
const termCtx = term[contextFullKey];
|
|
172
|
-
if (!termCtx) {
|
|
173
|
-
throw new Error('type @context is not of correct type');
|
|
174
|
-
}
|
|
175
|
-
const serStr = termCtx[serializationFullKey] ?? '';
|
|
176
|
-
return serStr;
|
|
81
|
+
return (0, verifiable_1.getSerializationAttrFromParsedContext)(ldCtx, tp);
|
|
177
82
|
}
|
|
83
|
+
/**
|
|
84
|
+
* @deprecated The method should not be used. Use parseSerializationAttr from verifiable.
|
|
85
|
+
*
|
|
86
|
+
*/
|
|
178
87
|
static parseSerializationAttr(serAttr) {
|
|
179
|
-
|
|
180
|
-
throw new Error('serialization attribute does not have correct prefix');
|
|
181
|
-
}
|
|
182
|
-
const parts = serAttr.slice(fieldPrefix.length).split('&');
|
|
183
|
-
if (parts.length > 4) {
|
|
184
|
-
throw new Error('serialization attribute has too many parts');
|
|
185
|
-
}
|
|
186
|
-
const paths = {};
|
|
187
|
-
for (const part of parts) {
|
|
188
|
-
const kv = part.split('=');
|
|
189
|
-
if (kv.length !== 2) {
|
|
190
|
-
throw new Error('serialization attribute part does not have correct format');
|
|
191
|
-
}
|
|
192
|
-
switch (kv[0]) {
|
|
193
|
-
case 'slotIndexA':
|
|
194
|
-
paths.indexAPath = kv[1];
|
|
195
|
-
break;
|
|
196
|
-
case 'slotIndexB':
|
|
197
|
-
paths.indexBPath = kv[1];
|
|
198
|
-
break;
|
|
199
|
-
case 'slotValueA':
|
|
200
|
-
paths.valueAPath = kv[1];
|
|
201
|
-
break;
|
|
202
|
-
case 'slotValueB':
|
|
203
|
-
paths.valueBPath = kv[1];
|
|
204
|
-
break;
|
|
205
|
-
default:
|
|
206
|
-
throw new Error('unknown serialization attribute slot');
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
return paths;
|
|
88
|
+
return (0, verifiable_1.parseSerializationAttr)(serAttr);
|
|
210
89
|
}
|
|
211
90
|
/**
|
|
91
|
+
*
|
|
92
|
+
* @deprecated The method should not be used. Use credential.parseSlots instead.
|
|
212
93
|
* ParseSlots converts payload to claim slots using provided schema
|
|
213
94
|
*
|
|
214
95
|
* @param {Merklizer} mz - Merklizer
|
|
@@ -217,30 +98,12 @@ class Parser {
|
|
|
217
98
|
* @returns `ParsedSlots`
|
|
218
99
|
*/
|
|
219
100
|
static async parseSlots(mz, credential, credentialType) {
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
indexA: new Uint8Array(32),
|
|
223
|
-
indexB: new Uint8Array(32),
|
|
224
|
-
valueA: new Uint8Array(32),
|
|
225
|
-
valueB: new Uint8Array(32)
|
|
226
|
-
};
|
|
227
|
-
const jsonLDOpts = mz.options;
|
|
228
|
-
const serAttr = await Parser.getSerializationAttr(credential, jsonLDOpts, credentialType);
|
|
229
|
-
if (!serAttr) {
|
|
230
|
-
return { slots, nonMerklized: false };
|
|
231
|
-
}
|
|
232
|
-
const sPaths = Parser.parseSerializationAttr(serAttr);
|
|
233
|
-
const isSPathEmpty = !Object.values(sPaths).some(Boolean);
|
|
234
|
-
if (isSPathEmpty) {
|
|
235
|
-
return { slots, nonMerklized: true };
|
|
236
|
-
}
|
|
237
|
-
await (0, utils_1.fillSlot)(slots.indexA, mz, sPaths.indexAPath);
|
|
238
|
-
await (0, utils_1.fillSlot)(slots.indexB, mz, sPaths.indexBPath);
|
|
239
|
-
await (0, utils_1.fillSlot)(slots.valueA, mz, sPaths.valueAPath);
|
|
240
|
-
await (0, utils_1.fillSlot)(slots.valueB, mz, sPaths.valueBPath);
|
|
241
|
-
return { slots, nonMerklized: true };
|
|
101
|
+
const ldCtx = await jsonld.processContext(ldcontext.getInitialContext({}), credential['@context'], mz.options);
|
|
102
|
+
return (0, verifiable_1.parseCoreClaimSlots)(ldCtx, mz, credentialType);
|
|
242
103
|
}
|
|
243
104
|
/**
|
|
105
|
+
* @deprecated The method should not be used. Use getFieldSlotIndex from verifiable.
|
|
106
|
+
*
|
|
244
107
|
* GetFieldSlotIndex return index of slot from 0 to 7 (each claim has by default 8 slots) for non-merklized claims
|
|
245
108
|
*
|
|
246
109
|
* @param {string} field - field name
|
|
@@ -248,29 +111,7 @@ class Parser {
|
|
|
248
111
|
* @returns `number`
|
|
249
112
|
*/
|
|
250
113
|
static async getFieldSlotIndex(field, typeName, schemaBytes) {
|
|
251
|
-
|
|
252
|
-
ctxDoc = ctxDoc[contextFullKey];
|
|
253
|
-
if (ctxDoc === undefined) {
|
|
254
|
-
throw new Error('document has no @context');
|
|
255
|
-
}
|
|
256
|
-
const ldCtx = await jsonld.processContext(ldcontext.getInitialContext({}), ctxDoc, {});
|
|
257
|
-
const serAttr = await Parser.getSerializationAttrFromParsedContext(ldCtx, typeName);
|
|
258
|
-
if (!serAttr) {
|
|
259
|
-
throw new Error('serialization attribute is not set');
|
|
260
|
-
}
|
|
261
|
-
const sPaths = Parser.parseSerializationAttr(serAttr);
|
|
262
|
-
switch (field) {
|
|
263
|
-
case sPaths.indexAPath:
|
|
264
|
-
return 2;
|
|
265
|
-
case sPaths.indexBPath:
|
|
266
|
-
return 3;
|
|
267
|
-
case sPaths.valueAPath:
|
|
268
|
-
return 6;
|
|
269
|
-
case sPaths.valueBPath:
|
|
270
|
-
return 7;
|
|
271
|
-
default:
|
|
272
|
-
throw new Error(`field ${field} not specified in serialization info`);
|
|
273
|
-
}
|
|
114
|
+
return (0, verifiable_1.getFieldSlotIndex)(field, typeName, schemaBytes);
|
|
274
115
|
}
|
|
275
116
|
/**
|
|
276
117
|
* ExtractCredentialSubjectProperties return credential subject types from JSON schema
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
const js_crypto_1 = require("@iden3/js-crypto");
|
|
3
|
+
exports.credentialSubjectKey = exports.fillSlot = exports.createSchemaHash = exports.checkDataInField = exports.dataFillsSlot = exports.fieldToByteArray = exports.swapEndianness = void 0;
|
|
5
4
|
const js_iden3_core_1 = require("@iden3/js-iden3-core");
|
|
6
|
-
const
|
|
5
|
+
const verifiable_1 = require("../verifiable");
|
|
7
6
|
/**
|
|
8
7
|
* SwapEndianness swaps the endianness of the value encoded in buf. If buf is
|
|
9
8
|
* Big-Endian, the result will be Little-Endian and vice-versa.
|
|
@@ -55,41 +54,29 @@ function checkDataInField(data) {
|
|
|
55
54
|
}
|
|
56
55
|
exports.checkDataInField = checkDataInField;
|
|
57
56
|
/**
|
|
57
|
+
*
|
|
58
|
+
* @deprecated The method should not be used. Use caclulateCoreSchemaHash from verifiable.
|
|
58
59
|
* Calculates schema hash
|
|
59
60
|
*
|
|
60
61
|
* @param {Uint8Array} schemaId
|
|
61
62
|
* @returns {*} {SchemaHash}
|
|
62
63
|
*/
|
|
63
64
|
const createSchemaHash = (schemaId) => {
|
|
64
|
-
|
|
65
|
-
return new js_iden3_core_1.SchemaHash(sHash.slice(sHash.length - 16, sHash.length));
|
|
65
|
+
return (0, verifiable_1.caclulateCoreSchemaHash)(schemaId);
|
|
66
66
|
};
|
|
67
67
|
exports.createSchemaHash = createSchemaHash;
|
|
68
|
-
exports.credentialSubjectKey = 'credentialSubject';
|
|
69
68
|
/**
|
|
69
|
+
*
|
|
70
|
+
* @deprecated The method should not be used. Use fillCoreClaimSlot from verifiable.
|
|
70
71
|
* checks if data can fill the slot
|
|
71
72
|
*
|
|
72
|
-
* @param {
|
|
73
|
-
* @param {
|
|
74
|
-
* @
|
|
73
|
+
* @param {Uint8Array} slotData - slot data
|
|
74
|
+
* @param {Merklizer} mz - merklizer
|
|
75
|
+
* @param {string} path - path
|
|
76
|
+
* @returns {void}
|
|
75
77
|
*/
|
|
76
78
|
const fillSlot = async (slotData, mz, path) => {
|
|
77
|
-
|
|
78
|
-
return;
|
|
79
|
-
}
|
|
80
|
-
path = exports.credentialSubjectKey + '.' + path;
|
|
81
|
-
try {
|
|
82
|
-
const p = await mz.resolveDocPath(path, mz.options);
|
|
83
|
-
const entry = await mz.entry(p);
|
|
84
|
-
const intVal = await entry.getValueMtEntry();
|
|
85
|
-
const bytesVal = js_iden3_core_1.BytesHelper.intToBytes(intVal);
|
|
86
|
-
slotData.set(bytesVal, 0);
|
|
87
|
-
}
|
|
88
|
-
catch (err) {
|
|
89
|
-
if (err.toString().includes('entry not found')) {
|
|
90
|
-
throw new Error(`field not found in credential ${path}`);
|
|
91
|
-
}
|
|
92
|
-
throw err;
|
|
93
|
-
}
|
|
79
|
+
return (0, verifiable_1.fillCoreClaimSlot)(slotData, mz, path);
|
|
94
80
|
};
|
|
95
81
|
exports.fillSlot = fillSlot;
|
|
82
|
+
exports.credentialSubjectKey = 'credentialSubject';
|
|
@@ -8,6 +8,7 @@ const ethers_1 = require("ethers");
|
|
|
8
8
|
const circuits_1 = require("../../circuits");
|
|
9
9
|
const utils_1 = require("../../utils");
|
|
10
10
|
const State_json_1 = __importDefault(require("./abi/State.json"));
|
|
11
|
+
const js_iden3_core_1 = require("@iden3/js-iden3-core");
|
|
11
12
|
exports.defaultEthConnectionConfig = {
|
|
12
13
|
url: 'http://localhost:8545',
|
|
13
14
|
defaultGasLimit: 600000,
|
|
@@ -33,14 +34,31 @@ class EthStateStorage {
|
|
|
33
34
|
* Creates an instance of EthStateStorage.
|
|
34
35
|
* @param {EthConnectionConfig} [ethConfig=defaultEthConnectionConfig]
|
|
35
36
|
*/
|
|
36
|
-
constructor(ethConfig
|
|
37
|
+
constructor(ethConfig) {
|
|
37
38
|
this.ethConfig = ethConfig;
|
|
38
|
-
|
|
39
|
-
this.
|
|
39
|
+
const config = Array.isArray(ethConfig) ? ethConfig[0] : ethConfig;
|
|
40
|
+
this.provider = new ethers_1.JsonRpcProvider(config.url);
|
|
41
|
+
this.stateContract = new ethers_1.Contract(config.contractAddress, State_json_1.default, this.provider);
|
|
40
42
|
}
|
|
41
43
|
/** {@inheritdoc IStateStorage.getLatestStateById} */
|
|
42
44
|
async getLatestStateById(id) {
|
|
43
|
-
const
|
|
45
|
+
const { stateContract } = this.getStateContractAndProviderForId(id);
|
|
46
|
+
const rawData = await stateContract.getStateInfoById(id);
|
|
47
|
+
const stateInfo = {
|
|
48
|
+
id: BigInt(rawData[0]),
|
|
49
|
+
state: BigInt(rawData[1]),
|
|
50
|
+
replacedByState: BigInt(rawData[2]),
|
|
51
|
+
createdAtTimestamp: BigInt(rawData[3]),
|
|
52
|
+
replacedAtTimestamp: BigInt(rawData[4]),
|
|
53
|
+
createdAtBlock: BigInt(rawData[5]),
|
|
54
|
+
replacedAtBlock: BigInt(rawData[6])
|
|
55
|
+
};
|
|
56
|
+
return stateInfo;
|
|
57
|
+
}
|
|
58
|
+
/** {@inheritdoc IStateStorage.getStateInfoByIdAndState} */
|
|
59
|
+
async getStateInfoByIdAndState(id, state) {
|
|
60
|
+
const { stateContract } = this.getStateContractAndProviderForId(id);
|
|
61
|
+
const rawData = await stateContract.getStateInfoByIdAndState(id, state);
|
|
44
62
|
const stateInfo = {
|
|
45
63
|
id: BigInt(rawData[0]),
|
|
46
64
|
state: BigInt(rawData[1]),
|
|
@@ -54,10 +72,11 @@ class EthStateStorage {
|
|
|
54
72
|
}
|
|
55
73
|
/** {@inheritdoc IStateStorage.publishState} */
|
|
56
74
|
async publishState(proof, signer) {
|
|
57
|
-
const contract = this.stateContract.connect(signer);
|
|
58
75
|
const stateTransitionPubSig = new circuits_1.StateTransitionPubSignals();
|
|
59
76
|
stateTransitionPubSig.pubSignalsUnmarshal(utils_1.byteEncoder.encode(JSON.stringify(proof.pub_signals)));
|
|
60
77
|
const { userId, oldUserState, newUserState, isOldStateGenesis } = stateTransitionPubSig;
|
|
78
|
+
const { stateContract, provider } = this.getStateContractAndProviderForId(userId.bigInt());
|
|
79
|
+
const contract = stateContract.connect(signer);
|
|
61
80
|
const payload = [
|
|
62
81
|
userId.bigInt().toString(),
|
|
63
82
|
oldUserState.bigInt().toString(),
|
|
@@ -70,7 +89,7 @@ class EthStateStorage {
|
|
|
70
89
|
],
|
|
71
90
|
proof.proof.pi_c.slice(0, 2)
|
|
72
91
|
];
|
|
73
|
-
const feeData = await
|
|
92
|
+
const feeData = await provider.getFeeData();
|
|
74
93
|
const maxFeePerGas = exports.defaultEthConnectionConfig.maxFeePerGas
|
|
75
94
|
? BigInt(exports.defaultEthConnectionConfig.maxFeePerGas)
|
|
76
95
|
: feeData.maxFeePerGas;
|
|
@@ -100,7 +119,8 @@ class EthStateStorage {
|
|
|
100
119
|
}
|
|
101
120
|
/** {@inheritdoc IStateStorage.getGISTProof} */
|
|
102
121
|
async getGISTProof(id) {
|
|
103
|
-
const
|
|
122
|
+
const { stateContract } = this.getStateContractAndProviderForId(id);
|
|
123
|
+
const data = await stateContract.getGISTProof(id);
|
|
104
124
|
return {
|
|
105
125
|
root: BigInt(data.root.toString()),
|
|
106
126
|
existence: data.existence,
|
|
@@ -114,7 +134,8 @@ class EthStateStorage {
|
|
|
114
134
|
}
|
|
115
135
|
/** {@inheritdoc IStateStorage.getGISTRootInfo} */
|
|
116
136
|
async getGISTRootInfo(id) {
|
|
117
|
-
const
|
|
137
|
+
const { stateContract } = this.getStateContractAndProviderForId(id);
|
|
138
|
+
const data = await stateContract.getGISTRootInfo(id);
|
|
118
139
|
return {
|
|
119
140
|
root: BigInt(data.root.toString()),
|
|
120
141
|
replacedByRoot: BigInt(data.replacedByRoot.toString()),
|
|
@@ -124,5 +145,29 @@ class EthStateStorage {
|
|
|
124
145
|
replacedAtBlock: BigInt(data.replacedAtBlock.toString())
|
|
125
146
|
};
|
|
126
147
|
}
|
|
148
|
+
getStateContractAndProviderForId(id) {
|
|
149
|
+
const idTyped = js_iden3_core_1.Id.fromBigInt(id);
|
|
150
|
+
if (!Array.isArray(this.ethConfig)) {
|
|
151
|
+
return {
|
|
152
|
+
stateContract: this.stateContract,
|
|
153
|
+
provider: this.provider
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
const chainId = (0, js_iden3_core_1.getChainId)(js_iden3_core_1.DID.blockchainFromId(idTyped), js_iden3_core_1.DID.networkIdFromId(idTyped));
|
|
157
|
+
const config = this.networkByChainId(chainId);
|
|
158
|
+
const provider = new ethers_1.JsonRpcProvider(config.url);
|
|
159
|
+
const stateContract = new ethers_1.Contract(config.contractAddress, State_json_1.default, this.provider);
|
|
160
|
+
return { stateContract, provider };
|
|
161
|
+
}
|
|
162
|
+
networkByChainId(chainId) {
|
|
163
|
+
if (Array.isArray(this.ethConfig)) {
|
|
164
|
+
const network = this.ethConfig.find((c) => c.chainId === chainId);
|
|
165
|
+
if (!network) {
|
|
166
|
+
throw new Error(`chainId "${chainId}" not supported`);
|
|
167
|
+
}
|
|
168
|
+
return network;
|
|
169
|
+
}
|
|
170
|
+
return this.ethConfig;
|
|
171
|
+
}
|
|
127
172
|
}
|
|
128
173
|
exports.EthStateStorage = EthStateStorage;
|
|
@@ -163,8 +163,8 @@ const StandardJSONCredentialsQueryFilter = (query) => {
|
|
|
163
163
|
case 'claimId':
|
|
164
164
|
return acc.concat(new FilterQuery('id', exports.comparatorOptions.$eq, queryValue));
|
|
165
165
|
case 'allowedIssuers': {
|
|
166
|
-
const
|
|
167
|
-
if (
|
|
166
|
+
const queryValueParam = queryValue || ['*'];
|
|
167
|
+
if (queryValueParam.includes('*')) {
|
|
168
168
|
return acc;
|
|
169
169
|
}
|
|
170
170
|
return acc.concat(new FilterQuery('issuer', exports.comparatorOptions.$in, queryValue));
|