@0xpolygonid/js-sdk 1.6.1 → 1.7.1
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/README.md +3 -1
- package/dist/browser/esm/index.js +837 -494
- package/dist/browser/esm/index.js.map +1 -1
- package/dist/browser/umd/index.js +885 -536
- package/dist/browser/umd/index.js.map +1 -1
- package/dist/node/cjs/circuits/comparer.js +21 -3
- package/dist/node/cjs/circuits/linked-multi-query.js +1 -1
- package/dist/node/cjs/credentials/credential-wallet.js +20 -2
- package/dist/node/cjs/credentials/index.js +1 -0
- package/dist/node/cjs/credentials/rhs.js +28 -15
- package/dist/node/cjs/credentials/status/credential-status-publisher.js +84 -0
- package/dist/node/cjs/credentials/utils.js +14 -1
- package/dist/node/cjs/iden3comm/constants.js +2 -0
- package/dist/node/cjs/iden3comm/handlers/fetch.js +2 -2
- package/dist/node/cjs/iden3comm/handlers/index.js +1 -0
- package/dist/node/cjs/iden3comm/handlers/refresh.js +76 -0
- package/dist/node/cjs/identity/identity-wallet.js +57 -26
- package/dist/node/cjs/storage/blockchain/abi/CredentialStatusResolver.json +1 -1
- package/dist/node/cjs/storage/blockchain/index.js +1 -0
- package/dist/node/cjs/storage/blockchain/onchain-revocation.js +45 -5
- package/dist/node/cjs/verifiable/constants.js +10 -1
- package/dist/node/esm/circuits/comparer.js +21 -3
- package/dist/node/esm/circuits/linked-multi-query.js +1 -1
- package/dist/node/esm/credentials/credential-wallet.js +21 -3
- package/dist/node/esm/credentials/index.js +1 -0
- package/dist/node/esm/credentials/rhs.js +26 -14
- package/dist/node/esm/credentials/status/credential-status-publisher.js +78 -0
- package/dist/node/esm/credentials/utils.js +12 -0
- package/dist/node/esm/iden3comm/constants.js +2 -0
- package/dist/node/esm/iden3comm/handlers/fetch.js +2 -2
- package/dist/node/esm/iden3comm/handlers/index.js +1 -0
- package/dist/node/esm/iden3comm/handlers/refresh.js +72 -0
- package/dist/node/esm/identity/identity-wallet.js +52 -21
- package/dist/node/esm/storage/blockchain/abi/CredentialStatusResolver.json +1 -1
- package/dist/node/esm/storage/blockchain/index.js +1 -0
- package/dist/node/esm/storage/blockchain/onchain-revocation.js +45 -5
- package/dist/node/esm/verifiable/constants.js +9 -0
- package/dist/types/credentials/credential-wallet.d.ts +5 -1
- package/dist/types/credentials/index.d.ts +1 -0
- package/dist/types/credentials/rhs.d.ts +11 -0
- package/dist/types/credentials/status/credential-status-publisher.d.ts +70 -0
- package/dist/types/credentials/utils.d.ts +2 -0
- package/dist/types/iden3comm/constants.d.ts +1 -0
- package/dist/types/iden3comm/handlers/fetch.d.ts +2 -2
- package/dist/types/iden3comm/handlers/index.d.ts +1 -0
- package/dist/types/iden3comm/handlers/refresh.d.ts +56 -0
- package/dist/types/iden3comm/types/packer.d.ts +2 -1
- package/dist/types/iden3comm/types/protocol/credentials.d.ts +15 -0
- package/dist/types/identity/identity-wallet.d.ts +42 -13
- package/dist/types/storage/blockchain/index.d.ts +1 -0
- package/dist/types/storage/blockchain/onchain-revocation.d.ts +7 -3
- package/dist/types/verifiable/constants.d.ts +8 -0
- package/dist/types/verifiable/credential.d.ts +2 -1
- package/dist/types/verifiable/proof.d.ts +10 -1
- package/package.json +1 -1
|
@@ -53,12 +53,30 @@ exports.QueryOperators = {
|
|
|
53
53
|
};
|
|
54
54
|
const allOperations = Object.values(exports.QueryOperators);
|
|
55
55
|
exports.availableTypesOperators = new Map([
|
|
56
|
-
[XSDNS.Boolean, [exports.QueryOperators.$eq, exports.QueryOperators.$ne]],
|
|
56
|
+
[XSDNS.Boolean, [exports.QueryOperators.$eq, exports.QueryOperators.$ne, exports.QueryOperators.$sd]],
|
|
57
57
|
[XSDNS.Integer, allOperations],
|
|
58
58
|
[XSDNS.NonNegativeInteger, allOperations],
|
|
59
59
|
[XSDNS.PositiveInteger, allOperations],
|
|
60
|
-
[
|
|
61
|
-
|
|
60
|
+
[
|
|
61
|
+
XSDNS.Double,
|
|
62
|
+
[
|
|
63
|
+
exports.QueryOperators.$eq,
|
|
64
|
+
exports.QueryOperators.$ne,
|
|
65
|
+
exports.QueryOperators.$in,
|
|
66
|
+
exports.QueryOperators.$nin,
|
|
67
|
+
exports.QueryOperators.$sd
|
|
68
|
+
]
|
|
69
|
+
],
|
|
70
|
+
[
|
|
71
|
+
XSDNS.String,
|
|
72
|
+
[
|
|
73
|
+
exports.QueryOperators.$eq,
|
|
74
|
+
exports.QueryOperators.$ne,
|
|
75
|
+
exports.QueryOperators.$in,
|
|
76
|
+
exports.QueryOperators.$nin,
|
|
77
|
+
exports.QueryOperators.$sd
|
|
78
|
+
]
|
|
79
|
+
],
|
|
62
80
|
[XSDNS.DateTime, allOperations]
|
|
63
81
|
]);
|
|
64
82
|
/**
|
|
@@ -28,7 +28,7 @@ class LinkedMultiQueryInputs extends common_1.BaseConfig {
|
|
|
28
28
|
if (!this.query[i]) {
|
|
29
29
|
enabled.push(0);
|
|
30
30
|
claimPathNotExists.push(0);
|
|
31
|
-
claimPathMtp.push(
|
|
31
|
+
claimPathMtp.push(new Array(this.getMTLevelsClaim()).fill('0'));
|
|
32
32
|
claimPathMtpNoAux.push('0');
|
|
33
33
|
claimPathMtpAuxHi.push('0');
|
|
34
34
|
claimPathMtpAuxHv.push('0');
|
|
@@ -76,6 +76,7 @@ class CredentialWallet {
|
|
|
76
76
|
cr['@context'] = context;
|
|
77
77
|
cr.type = credentialType;
|
|
78
78
|
cr.expirationDate = expirationDate ? new Date(expirationDate * 1000).toISOString() : undefined;
|
|
79
|
+
cr.refreshService = request.refreshService;
|
|
79
80
|
cr.issuanceDate = new Date().toISOString();
|
|
80
81
|
cr.credentialSubject = credentialSubject;
|
|
81
82
|
cr.issuer = issuer.string();
|
|
@@ -83,7 +84,7 @@ class CredentialWallet {
|
|
|
83
84
|
id: request.credentialSchema,
|
|
84
85
|
type: verifiable_1.VerifiableConstants.JSON_SCHEMA_VALIDATOR
|
|
85
86
|
};
|
|
86
|
-
cr.credentialStatus = this.buildCredentialStatus(request);
|
|
87
|
+
cr.credentialStatus = this.buildCredentialStatus(request, issuer);
|
|
87
88
|
return cr;
|
|
88
89
|
};
|
|
89
90
|
// if no credential status resolvers are provided
|
|
@@ -149,7 +150,7 @@ class CredentialWallet {
|
|
|
149
150
|
* @param {CredentialRequest} request
|
|
150
151
|
* @returns `CredentialStatus`
|
|
151
152
|
*/
|
|
152
|
-
buildCredentialStatus(request) {
|
|
153
|
+
buildCredentialStatus(request, issuer) {
|
|
153
154
|
const credentialStatus = {
|
|
154
155
|
id: request.revocationOpts.id,
|
|
155
156
|
type: request.revocationOpts.type,
|
|
@@ -168,6 +169,23 @@ class CredentialWallet {
|
|
|
168
169
|
? `${credentialStatus.id.replace(/\/$/, '')}/node?state=${request.revocationOpts.issuerState}`
|
|
169
170
|
: `${credentialStatus.id.replace(/\/$/, '')}`
|
|
170
171
|
};
|
|
172
|
+
case verifiable_1.CredentialStatusType.Iden3OnchainSparseMerkleTreeProof2023: {
|
|
173
|
+
const issuerId = js_iden3_core_1.DID.idFromDID(issuer);
|
|
174
|
+
const chainId = (0, js_iden3_core_1.getChainId)(js_iden3_core_1.DID.blockchainFromId(issuerId), js_iden3_core_1.DID.networkIdFromId(issuerId));
|
|
175
|
+
const searchParams = [
|
|
176
|
+
['revocationNonce', request.revocationOpts.nonce?.toString() || ''],
|
|
177
|
+
['contractAddress', `${chainId}:${request.revocationOpts.id}`],
|
|
178
|
+
['state', request.revocationOpts.issuerState || '']
|
|
179
|
+
]
|
|
180
|
+
.filter(([, value]) => Boolean(value))
|
|
181
|
+
.map(([key, value]) => `${key}=${value}`)
|
|
182
|
+
.join('&');
|
|
183
|
+
return {
|
|
184
|
+
...credentialStatus,
|
|
185
|
+
// `[did]:[methodid]:[chain]:[network]:[id]/credentialStatus?(revocationNonce=value)&[contractAddress=[chainID]:[contractAddress]]&(state=issuerState)`
|
|
186
|
+
id: `${issuer.string()}/credentialStatus?${searchParams}`
|
|
187
|
+
};
|
|
188
|
+
}
|
|
171
189
|
default:
|
|
172
190
|
return credentialStatus;
|
|
173
191
|
}
|
|
@@ -19,6 +19,7 @@ __exportStar(require("./status/reverse-sparse-merkle-tree"), exports);
|
|
|
19
19
|
__exportStar(require("./status/sparse-merkle-tree"), exports);
|
|
20
20
|
__exportStar(require("./status/resolver"), exports);
|
|
21
21
|
__exportStar(require("./status/agent-revocation"), exports);
|
|
22
|
+
__exportStar(require("./status/credential-status-publisher"), exports);
|
|
22
23
|
__exportStar(require("./status/utils"), exports);
|
|
23
24
|
__exportStar(require("./credential-wallet"), exports);
|
|
24
25
|
__exportStar(require("./rhs"), exports);
|
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.pushHashesToRHS = void 0;
|
|
3
|
+
exports.getNodesRepresentation = exports.pushHashesToRHS = void 0;
|
|
4
4
|
const js_merkletree_1 = require("@iden3/js-merkletree");
|
|
5
5
|
const js_merkletree_2 = require("@iden3/js-merkletree");
|
|
6
6
|
const js_merkletree_3 = require("@iden3/js-merkletree");
|
|
7
7
|
const reverse_sparse_merkle_tree_1 = require("./status/reverse-sparse-merkle-tree");
|
|
8
|
+
const credential_status_publisher_1 = require("./status/credential-status-publisher");
|
|
9
|
+
const verifiable_1 = require("../verifiable");
|
|
8
10
|
/**
|
|
9
11
|
* Pushes identity state information to a reverse hash service.
|
|
10
12
|
*
|
|
11
13
|
* A reverse hash service (RHS) is a centralized or decentralized service for storing publicly available data about identity.
|
|
12
14
|
* Such data are identity state and state of revocation tree and roots tree root tree.
|
|
13
15
|
*
|
|
16
|
+
* @deprecated Use `pushHashesToReverseHashService` instead.
|
|
14
17
|
* @param {Hash} state - current state of identity
|
|
15
18
|
* @param {TreesModel} trees - current trees of identity (claims, revocation, rootOfRoots )
|
|
16
19
|
* @param {string} rhsUrl - URL of service
|
|
@@ -18,6 +21,24 @@ const reverse_sparse_merkle_tree_1 = require("./status/reverse-sparse-merkle-tre
|
|
|
18
21
|
* @returns void
|
|
19
22
|
*/
|
|
20
23
|
async function pushHashesToRHS(state, trees, rhsUrl, revokedNonces) {
|
|
24
|
+
const nodes = await getNodesRepresentation(revokedNonces, trees, state);
|
|
25
|
+
const publisher = new credential_status_publisher_1.Iden3SmtRhsCredentialStatusPublisher();
|
|
26
|
+
await publisher.publish({
|
|
27
|
+
nodes,
|
|
28
|
+
credentialStatusType: verifiable_1.CredentialStatusType.Iden3ReverseSparseMerkleTreeProof,
|
|
29
|
+
rhsUrl: rhsUrl
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
exports.pushHashesToRHS = pushHashesToRHS;
|
|
33
|
+
/**
|
|
34
|
+
* Retrieves the representation of nodes for generating a proof.
|
|
35
|
+
*
|
|
36
|
+
* @param revokedNonces - An array of revoked nonces.
|
|
37
|
+
* @param trees - The TreesModel object containing the necessary trees.
|
|
38
|
+
* @param state - The hash of the state.
|
|
39
|
+
* @returns A Promise that resolves to an array of ProofNode objects.
|
|
40
|
+
*/
|
|
41
|
+
async function getNodesRepresentation(revokedNonces, trees, state) {
|
|
21
42
|
const nb = new NodesBuilder();
|
|
22
43
|
if (revokedNonces) {
|
|
23
44
|
await addRevocationNode(nb, trees, revokedNonces);
|
|
@@ -31,17 +52,9 @@ async function pushHashesToRHS(state, trees, rhsUrl, revokedNonces) {
|
|
|
31
52
|
await trees.rootsTree.root()
|
|
32
53
|
]));
|
|
33
54
|
}
|
|
34
|
-
|
|
35
|
-
await saveNodes(nb.nodes, rhsUrl);
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
exports.pushHashesToRHS = pushHashesToRHS;
|
|
39
|
-
async function saveNodes(nodes, nodeUrl) {
|
|
40
|
-
const nodesJSON = nodes.map((n) => n.toJSON());
|
|
41
|
-
const resp = await fetch(nodeUrl + '/node', { method: 'post', body: JSON.stringify(nodesJSON) });
|
|
42
|
-
const status = resp.status;
|
|
43
|
-
return status === 200;
|
|
55
|
+
return nb.nodes;
|
|
44
56
|
}
|
|
57
|
+
exports.getNodesRepresentation = getNodesRepresentation;
|
|
45
58
|
async function addRoRNode(nb, trees) {
|
|
46
59
|
const currentRootsTree = trees.rootsTree;
|
|
47
60
|
const claimsTree = trees.claimsTree;
|
|
@@ -66,8 +79,8 @@ class NodesBuilder {
|
|
|
66
79
|
}
|
|
67
80
|
async addKey(tree, nodeKey) {
|
|
68
81
|
const { value: nodeValue, siblings } = await tree.get(nodeKey);
|
|
69
|
-
const nodeKeyHash =
|
|
70
|
-
const nodeValueHash =
|
|
82
|
+
const nodeKeyHash = js_merkletree_1.Hash.fromBigInt(nodeKey);
|
|
83
|
+
const nodeValueHash = js_merkletree_1.Hash.fromBigInt(nodeValue);
|
|
71
84
|
const node = new js_merkletree_1.NodeLeaf(nodeKeyHash, nodeValueHash);
|
|
72
85
|
const newNodes = await buildNodesUp(siblings, node);
|
|
73
86
|
for (const n of newNodes) {
|
|
@@ -97,7 +110,7 @@ async function buildNodesUp(siblings, node) {
|
|
|
97
110
|
nodes[index] = new reverse_sparse_merkle_tree_1.ProofNode();
|
|
98
111
|
}
|
|
99
112
|
nodes[sl].hash = prevHash;
|
|
100
|
-
const hashOfOne =
|
|
113
|
+
const hashOfOne = js_merkletree_1.Hash.fromBigInt(BigInt(1));
|
|
101
114
|
nodes[sl].children = [node.entry[0], node.entry[1], hashOfOne];
|
|
102
115
|
const pathKey = node.entry[0];
|
|
103
116
|
for (let i = sl - 1; i >= 0; i--) {
|
|
@@ -111,7 +124,7 @@ async function buildNodesUp(siblings, node) {
|
|
|
111
124
|
nodes[i].children[0] = prevHash;
|
|
112
125
|
nodes[i].children[1] = siblings[i];
|
|
113
126
|
}
|
|
114
|
-
nodes[i].hash =
|
|
127
|
+
nodes[i].hash = (0, js_merkletree_3.hashElems)([nodes[i].children[0].bigInt(), nodes[i].children[1].bigInt()]);
|
|
115
128
|
prevHash = nodes[i].hash;
|
|
116
129
|
}
|
|
117
130
|
return nodes;
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Iden3SmtRhsCredentialStatusPublisher = exports.Iden3OnchainSmtCredentialStatusPublisher = exports.CredentialStatusPublisherRegistry = void 0;
|
|
4
|
+
const verifiable_1 = require("../../verifiable");
|
|
5
|
+
/**
|
|
6
|
+
* Registry for managing credential status publishers.
|
|
7
|
+
*/
|
|
8
|
+
class CredentialStatusPublisherRegistry {
|
|
9
|
+
constructor() {
|
|
10
|
+
this._publishers = new Map();
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Registers one or more credential status publishers for a given type.
|
|
14
|
+
* @param type - The credential status type.
|
|
15
|
+
* @param publisher - One or more credential status publishers.
|
|
16
|
+
*/
|
|
17
|
+
register(type, ...publisher) {
|
|
18
|
+
const publishers = this._publishers.get(type) ?? [];
|
|
19
|
+
publishers.push(...publisher);
|
|
20
|
+
this._publishers.set(type, publishers);
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Retrieves the credential status publishers for a given type.
|
|
24
|
+
* @param type - The credential status type.
|
|
25
|
+
* @returns An array of credential status publishers or undefined if none are registered for the given type.
|
|
26
|
+
*/
|
|
27
|
+
get(type) {
|
|
28
|
+
return this._publishers.get(type);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
exports.CredentialStatusPublisherRegistry = CredentialStatusPublisherRegistry;
|
|
32
|
+
/**
|
|
33
|
+
* Implementation of the ICredentialStatusPublisher interface for publishing on-chain credential status.
|
|
34
|
+
*/
|
|
35
|
+
class Iden3OnchainSmtCredentialStatusPublisher {
|
|
36
|
+
constructor(_storage) {
|
|
37
|
+
this._storage = _storage;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Publishes the credential status to the blockchain.
|
|
41
|
+
* @param params - The parameters for publishing the credential status.
|
|
42
|
+
*/
|
|
43
|
+
async publish(params) {
|
|
44
|
+
if (![verifiable_1.CredentialStatusType.Iden3OnchainSparseMerkleTreeProof2023].includes(params.credentialStatusType)) {
|
|
45
|
+
throw new Error(`On-chain publishing is not supported for credential status type ${params.credentialStatusType}`);
|
|
46
|
+
}
|
|
47
|
+
const nodesBigInts = params.nodes.map((n) => n.children.map((c) => c.bigInt()));
|
|
48
|
+
const txPromise = this._storage.saveNodes(nodesBigInts);
|
|
49
|
+
if (params.onChain?.txCallback) {
|
|
50
|
+
const cb = params.onChain?.txCallback;
|
|
51
|
+
txPromise.then((receipt) => cb(receipt));
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
await txPromise;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
exports.Iden3OnchainSmtCredentialStatusPublisher = Iden3OnchainSmtCredentialStatusPublisher;
|
|
58
|
+
/**
|
|
59
|
+
* Implementation of the ICredentialStatusPublisher interface for publishing off-chain credential status.
|
|
60
|
+
*/
|
|
61
|
+
class Iden3SmtRhsCredentialStatusPublisher {
|
|
62
|
+
/**
|
|
63
|
+
* Publishes the credential status to a specified node URL.
|
|
64
|
+
* @param params - The parameters for publishing the credential status.
|
|
65
|
+
* @param params.nodes - The proof nodes to be published.
|
|
66
|
+
* @param params.rhsUrl - The URL of the node to publish the credential status to.
|
|
67
|
+
* @returns A promise that resolves when the credential status is successfully published.
|
|
68
|
+
* @throws An error if the publishing fails.
|
|
69
|
+
*/
|
|
70
|
+
async publish(params) {
|
|
71
|
+
if (![verifiable_1.CredentialStatusType.Iden3ReverseSparseMerkleTreeProof].includes(params.credentialStatusType)) {
|
|
72
|
+
throw new Error(`On-chain publishing is not supported for credential status type ${params.credentialStatusType}`);
|
|
73
|
+
}
|
|
74
|
+
const nodesJSON = params.nodes.map((n) => n.toJSON());
|
|
75
|
+
const resp = await fetch(params.rhsUrl + '/node', {
|
|
76
|
+
method: 'post',
|
|
77
|
+
body: JSON.stringify(nodesJSON)
|
|
78
|
+
});
|
|
79
|
+
if (resp.status !== 200) {
|
|
80
|
+
throw new Error(`Failed to publish credential status. Status: ${resp.status}`);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
exports.Iden3SmtRhsCredentialStatusPublisher = Iden3SmtRhsCredentialStatusPublisher;
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getUserDIDFromCredential = void 0;
|
|
3
|
+
exports.getKMSIdByAuthCredential = exports.getUserDIDFromCredential = void 0;
|
|
4
4
|
const js_iden3_core_1 = require("@iden3/js-iden3-core");
|
|
5
|
+
const js_crypto_1 = require("@iden3/js-crypto");
|
|
6
|
+
const kms_1 = require("../kms");
|
|
5
7
|
/**
|
|
6
8
|
* Retrieves the user DID from a given credential.
|
|
7
9
|
* If the credential does not have a credentialSubject.id property, the issuer DID is returned.
|
|
@@ -21,3 +23,14 @@ const getUserDIDFromCredential = (issuerDID, credential) => {
|
|
|
21
23
|
return js_iden3_core_1.DID.parse(credential.credentialSubject.id);
|
|
22
24
|
};
|
|
23
25
|
exports.getUserDIDFromCredential = getUserDIDFromCredential;
|
|
26
|
+
const getKMSIdByAuthCredential = (credential) => {
|
|
27
|
+
if (!credential.type.includes('AuthBJJCredential')) {
|
|
28
|
+
throw new Error("can't sign with not AuthBJJCredential credential");
|
|
29
|
+
}
|
|
30
|
+
const x = credential.credentialSubject['x'];
|
|
31
|
+
const y = credential.credentialSubject['y'];
|
|
32
|
+
const pb = new js_crypto_1.PublicKey([BigInt(x), BigInt(y)]);
|
|
33
|
+
const kp = (0, kms_1.keyPath)(kms_1.KmsKeyType.BabyJubJub, pb.hex());
|
|
34
|
+
return { type: kms_1.KmsKeyType.BabyJubJub, id: kp };
|
|
35
|
+
};
|
|
36
|
+
exports.getKMSIdByAuthCredential = getKMSIdByAuthCredential;
|
|
@@ -18,6 +18,8 @@ exports.PROTOCOL_MESSAGE_TYPE = Object.freeze({
|
|
|
18
18
|
CREDENTIAL_OFFER_MESSAGE_TYPE: IDEN3_PROTOCOL + 'credentials/1.0/offer',
|
|
19
19
|
// CredentialIssuanceResponseMessageType is type for message with a credential issuance
|
|
20
20
|
CREDENTIAL_ISSUANCE_RESPONSE_MESSAGE_TYPE: IDEN3_PROTOCOL + 'credentials/1.0/issuance-response',
|
|
21
|
+
// CredentialRefreshMessageType is type for message with a credential issuance
|
|
22
|
+
CREDENTIAL_REFRESH_MESSAGE_TYPE: IDEN3_PROTOCOL + 'credentials/1.0/refresh',
|
|
21
23
|
// DeviceRegistrationRequestMessageType defines device registration request type of the communication protocol
|
|
22
24
|
DEVICE_REGISTRATION_REQUEST_MESSAGE_TYPE: IDEN3_PROTOCOL + 'devices/1.0/registration',
|
|
23
25
|
// MessageFetMessageFetchRequestMessageType defines message fetch request type of the communication protocol.
|
|
@@ -42,7 +42,7 @@ const js_iden3_core_1 = require("@iden3/js-iden3-core");
|
|
|
42
42
|
*/
|
|
43
43
|
class FetchHandler {
|
|
44
44
|
/**
|
|
45
|
-
* Creates an instance of
|
|
45
|
+
* Creates an instance of FetchHandler.
|
|
46
46
|
* @param {IPackageManager} _packerMgr - package manager to unpack message envelope
|
|
47
47
|
*/
|
|
48
48
|
constructor(_packerMgr) {
|
|
@@ -55,7 +55,7 @@ class FetchHandler {
|
|
|
55
55
|
* offer: Uint8Array; offer - raw offer message
|
|
56
56
|
* opts
|
|
57
57
|
* }) options how to fetch credential
|
|
58
|
-
* @returns `Promise<W3CCredential>`
|
|
58
|
+
* @returns `Promise<W3CCredential[]>`
|
|
59
59
|
*/
|
|
60
60
|
async handleCredentialOffer(offer, opts) {
|
|
61
61
|
if (!opts) {
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RefreshHandler = void 0;
|
|
4
|
+
const constants_1 = require("../constants");
|
|
5
|
+
const constants_2 = require("../constants");
|
|
6
|
+
const verifiable_1 = require("../../verifiable");
|
|
7
|
+
const utils_1 = require("../../utils");
|
|
8
|
+
const js_jwz_1 = require("@iden3/js-jwz");
|
|
9
|
+
const js_iden3_core_1 = require("@iden3/js-iden3-core");
|
|
10
|
+
const circuits_1 = require("../../circuits");
|
|
11
|
+
const crypto_1 = require("crypto");
|
|
12
|
+
/**
|
|
13
|
+
*
|
|
14
|
+
* Allows to refresh credential from refresh service and return refreshed credential
|
|
15
|
+
*
|
|
16
|
+
* @public
|
|
17
|
+
|
|
18
|
+
* @class RefreshHandler
|
|
19
|
+
* @implements implements RefreshHandler interface
|
|
20
|
+
*/
|
|
21
|
+
class RefreshHandler {
|
|
22
|
+
/**
|
|
23
|
+
* Creates an instance of RefreshHandler.
|
|
24
|
+
* @param {RefreshHandlerOptions} _options - refresh handler options
|
|
25
|
+
*/
|
|
26
|
+
constructor(_options) {
|
|
27
|
+
this._options = _options;
|
|
28
|
+
}
|
|
29
|
+
async refreshCredential(credential, opts) {
|
|
30
|
+
if (!credential.refreshService) {
|
|
31
|
+
throw new Error('refreshService not specified for W3CCredential');
|
|
32
|
+
}
|
|
33
|
+
if (credential.refreshService.type !== verifiable_1.RefreshServiceType.Iden3RefreshService2023) {
|
|
34
|
+
throw new Error(`refresh service type ${credential.refreshService.type} is not supported`);
|
|
35
|
+
}
|
|
36
|
+
const otherIdentifier = credential.credentialSubject.id;
|
|
37
|
+
if (!otherIdentifier) {
|
|
38
|
+
throw new Error('self credentials do not support refresh');
|
|
39
|
+
}
|
|
40
|
+
const senderDID = js_iden3_core_1.DID.parse(otherIdentifier);
|
|
41
|
+
const zkpParams = {
|
|
42
|
+
senderDID,
|
|
43
|
+
provingMethodAlg: new js_jwz_1.ProvingMethodAlg(js_jwz_1.proving.provingMethodGroth16AuthV2Instance.methodAlg.alg, circuits_1.CircuitId.AuthV2)
|
|
44
|
+
};
|
|
45
|
+
const refreshMsg = {
|
|
46
|
+
id: (0, crypto_1.randomUUID)(),
|
|
47
|
+
typ: constants_1.MediaType.ZKPMessage,
|
|
48
|
+
type: constants_2.PROTOCOL_MESSAGE_TYPE.CREDENTIAL_REFRESH_MESSAGE_TYPE,
|
|
49
|
+
thid: (0, crypto_1.randomUUID)(),
|
|
50
|
+
body: {
|
|
51
|
+
id: otherIdentifier,
|
|
52
|
+
reason: opts?.reason ?? 'credential is expired'
|
|
53
|
+
},
|
|
54
|
+
from: otherIdentifier,
|
|
55
|
+
to: credential.issuer
|
|
56
|
+
};
|
|
57
|
+
const msgBytes = utils_1.byteEncoder.encode(JSON.stringify(refreshMsg));
|
|
58
|
+
const jwzToken = await this._options.packageManager.pack(constants_1.MediaType.ZKPMessage, msgBytes, zkpParams);
|
|
59
|
+
const resp = await fetch(credential.refreshService.id, {
|
|
60
|
+
method: 'post',
|
|
61
|
+
headers: {
|
|
62
|
+
'Content-Type': 'application/json'
|
|
63
|
+
},
|
|
64
|
+
body: jwzToken
|
|
65
|
+
});
|
|
66
|
+
if (resp.status !== 200) {
|
|
67
|
+
throw new Error(`could not refresh W3C credential, return status ${resp.status}`);
|
|
68
|
+
}
|
|
69
|
+
const respBody = await resp.json();
|
|
70
|
+
if (!respBody.body?.credential) {
|
|
71
|
+
throw new Error('no credential in CredentialIssuanceMessage response');
|
|
72
|
+
}
|
|
73
|
+
return verifiable_1.W3CCredential.fromJSON(respBody.body.credential);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
exports.RefreshHandler = RefreshHandler;
|
|
@@ -31,11 +31,11 @@ const js_merkletree_1 = require("@iden3/js-merkletree");
|
|
|
31
31
|
const common_1 = require("./common");
|
|
32
32
|
const uuid = __importStar(require("uuid"));
|
|
33
33
|
const schema_processor_1 = require("../schema-processor");
|
|
34
|
-
const
|
|
35
|
-
const provider_helpers_1 = require("../kms/provider-helpers");
|
|
34
|
+
const storage_1 = require("../storage");
|
|
36
35
|
const verifiable_1 = require("../verifiable");
|
|
37
36
|
const credentials_1 = require("../credentials");
|
|
38
37
|
const utils_1 = require("../utils");
|
|
38
|
+
const credential_status_publisher_1 = require("../credentials/status/credential-status-publisher");
|
|
39
39
|
/**
|
|
40
40
|
* @public
|
|
41
41
|
* Wallet instance to manage the digital identity based on iden3 protocol
|
|
@@ -56,10 +56,19 @@ class IdentityWallet {
|
|
|
56
56
|
* @param {ICredentialWallet} _credentialWallet - credential wallet instance to quickly access credential CRUD functionality
|
|
57
57
|
* @public
|
|
58
58
|
*/
|
|
59
|
-
constructor(_kms, _storage, _credentialWallet) {
|
|
59
|
+
constructor(_kms, _storage, _credentialWallet, _opts) {
|
|
60
60
|
this._kms = _kms;
|
|
61
61
|
this._storage = _storage;
|
|
62
62
|
this._credentialWallet = _credentialWallet;
|
|
63
|
+
this._opts = _opts;
|
|
64
|
+
if (!_opts?.credentialStatusPublisherRegistry) {
|
|
65
|
+
this._credentialStatusPublisherRegistry = new credential_status_publisher_1.CredentialStatusPublisherRegistry();
|
|
66
|
+
this._credentialStatusPublisherRegistry.register(verifiable_1.CredentialStatusType.Iden3ReverseSparseMerkleTreeProof, new credential_status_publisher_1.Iden3SmtRhsCredentialStatusPublisher());
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
this._credentialStatusPublisherRegistry = this._opts
|
|
70
|
+
?.credentialStatusPublisherRegistry;
|
|
71
|
+
}
|
|
63
72
|
}
|
|
64
73
|
/**
|
|
65
74
|
* {@inheritDoc IIdentityWallet.createIdentity}
|
|
@@ -78,8 +87,8 @@ class IdentityWallet {
|
|
|
78
87
|
const authClaim = js_iden3_core_1.Claim.newClaim(schemaHash, js_iden3_core_1.ClaimOptions.withIndexDataInts(pubKey.p[0], pubKey.p[1]), js_iden3_core_1.ClaimOptions.withRevocationNonce(BigInt(0)));
|
|
79
88
|
const revNonce = opts.revocationOpts.nonce ?? 0;
|
|
80
89
|
authClaim.setRevocationNonce(BigInt(revNonce));
|
|
81
|
-
await this._storage.mt.addToMerkleTree(tmpIdentifier,
|
|
82
|
-
const claimsTree = await this._storage.mt.getMerkleTreeByIdentifierAndType(tmpIdentifier,
|
|
90
|
+
await this._storage.mt.addToMerkleTree(tmpIdentifier, storage_1.MerkleTreeType.Claims, authClaim.hiHv().hi, authClaim.hiHv().hv);
|
|
91
|
+
const claimsTree = await this._storage.mt.getMerkleTreeByIdentifierAndType(tmpIdentifier, storage_1.MerkleTreeType.Claims);
|
|
83
92
|
const currentState = (0, js_merkletree_1.hashElems)([
|
|
84
93
|
(await claimsTree.root()).bigInt(),
|
|
85
94
|
js_merkletree_1.ZERO_HASH.bigInt(),
|
|
@@ -133,9 +142,10 @@ class IdentityWallet {
|
|
|
133
142
|
coreClaim: authClaim
|
|
134
143
|
});
|
|
135
144
|
credential.proof = [mtpProof];
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
145
|
+
await this.publishRevocationInfoByCredentialStatusType(did, opts.revocationOpts.type, {
|
|
146
|
+
rhsUrl: opts.revocationOpts.id,
|
|
147
|
+
onChain: opts.revocationOpts.onChain
|
|
148
|
+
});
|
|
139
149
|
await this._storage.identity.saveIdentity({
|
|
140
150
|
did: did.string(),
|
|
141
151
|
state: currentState,
|
|
@@ -197,10 +207,11 @@ class IdentityWallet {
|
|
|
197
207
|
}
|
|
198
208
|
/** {@inheritDoc IIdentityWallet.getDIDTreeModel} */
|
|
199
209
|
async getDIDTreeModel(did) {
|
|
200
|
-
const
|
|
201
|
-
const
|
|
202
|
-
const
|
|
203
|
-
const
|
|
210
|
+
const didStr = did.string();
|
|
211
|
+
const claimsTree = await this._storage.mt.getMerkleTreeByIdentifierAndType(didStr, storage_1.MerkleTreeType.Claims);
|
|
212
|
+
const revocationTree = await this._storage.mt.getMerkleTreeByIdentifierAndType(didStr, storage_1.MerkleTreeType.Revocations);
|
|
213
|
+
const rootsTree = await this._storage.mt.getMerkleTreeByIdentifierAndType(didStr, storage_1.MerkleTreeType.Roots);
|
|
214
|
+
const state = (0, js_merkletree_1.hashElems)([
|
|
204
215
|
(await claimsTree.root()).bigInt(),
|
|
205
216
|
(await revocationTree.root()).bigInt(),
|
|
206
217
|
(await rootsTree.root()).bigInt()
|
|
@@ -217,7 +228,7 @@ class IdentityWallet {
|
|
|
217
228
|
const coreClaim = await this.getCoreClaimFromCredential(credential);
|
|
218
229
|
// todo: Parser.parseClaim
|
|
219
230
|
const treesModel = await this.getDIDTreeModel(did);
|
|
220
|
-
const claimsTree = await this._storage.mt.getMerkleTreeByIdentifierAndType(did.string(),
|
|
231
|
+
const claimsTree = await this._storage.mt.getMerkleTreeByIdentifierAndType(did.string(), storage_1.MerkleTreeType.Claims);
|
|
221
232
|
const claimsRoot = await treesModel.claimsTree.root();
|
|
222
233
|
const rootOfRoots = await treesModel.rootsTree.root();
|
|
223
234
|
const revocationRoot = await treesModel.revocationTree.root();
|
|
@@ -237,7 +248,7 @@ class IdentityWallet {
|
|
|
237
248
|
const coreClaim = await this.getCoreClaimFromCredential(credential);
|
|
238
249
|
const revNonce = coreClaim.getRevocationNonce();
|
|
239
250
|
const treesModel = await this.getDIDTreeModel(did);
|
|
240
|
-
const revocationTree = await this._storage.mt.getMerkleTreeByIdentifierAndType(did.string(),
|
|
251
|
+
const revocationTree = await this._storage.mt.getMerkleTreeByIdentifierAndType(did.string(), storage_1.MerkleTreeType.Revocations);
|
|
241
252
|
const claimsRoot = await treesModel.claimsTree.root();
|
|
242
253
|
const rootOfRoots = await treesModel.rootsTree.root();
|
|
243
254
|
const revocationRoot = await treesModel.revocationTree.root();
|
|
@@ -254,14 +265,14 @@ class IdentityWallet {
|
|
|
254
265
|
}
|
|
255
266
|
/** {@inheritDoc IIdentityWallet.sign} */
|
|
256
267
|
async sign(message, credential) {
|
|
257
|
-
const keyKMSId =
|
|
268
|
+
const keyKMSId = (0, credentials_1.getKMSIdByAuthCredential)(credential);
|
|
258
269
|
const payload = js_crypto_1.poseidon.hashBytes(message);
|
|
259
270
|
const signature = await this._kms.sign(keyKMSId, js_iden3_core_1.BytesHelper.intToBytes(payload));
|
|
260
271
|
return js_crypto_1.Signature.newFromCompressed(signature);
|
|
261
272
|
}
|
|
262
273
|
/** {@inheritDoc IIdentityWallet.signChallenge} */
|
|
263
274
|
async signChallenge(challenge, credential) {
|
|
264
|
-
const keyKMSId =
|
|
275
|
+
const keyKMSId = (0, credentials_1.getKMSIdByAuthCredential)(credential);
|
|
265
276
|
const signature = await this._kms.sign(keyKMSId, js_iden3_core_1.BytesHelper.intToBytes(challenge));
|
|
266
277
|
return js_crypto_1.Signature.newFromCompressed(signature);
|
|
267
278
|
}
|
|
@@ -358,11 +369,11 @@ class IdentityWallet {
|
|
|
358
369
|
if (!coreClaim) {
|
|
359
370
|
throw new Error('credential must have coreClaim representation in the signature proof');
|
|
360
371
|
}
|
|
361
|
-
await this._storage.mt.addToMerkleTree(issuerDID.string(),
|
|
372
|
+
await this._storage.mt.addToMerkleTree(issuerDID.string(), storage_1.MerkleTreeType.Claims, coreClaim.hIndex(), coreClaim.hValue());
|
|
362
373
|
}
|
|
363
374
|
const newIssuerTreeState = await this.getDIDTreeModel(issuerDID);
|
|
364
375
|
const claimTreeRoot = await newIssuerTreeState.claimsTree.root();
|
|
365
|
-
await this._storage.mt.addToMerkleTree(issuerDID.string(),
|
|
376
|
+
await this._storage.mt.addToMerkleTree(issuerDID.string(), storage_1.MerkleTreeType.Roots, claimTreeRoot.bigInt(), BigInt(0));
|
|
366
377
|
const newIssuerTreeStateWithROR = await this.getDIDTreeModel(issuerDID);
|
|
367
378
|
claimsRoot = await newIssuerTreeStateWithROR.claimsTree.root();
|
|
368
379
|
rootOfRoots = await newIssuerTreeStateWithROR.rootsTree.root();
|
|
@@ -429,15 +440,35 @@ class IdentityWallet {
|
|
|
429
440
|
rootsTree: treeState.rootsTree
|
|
430
441
|
}, rhsURL, revokedNonces);
|
|
431
442
|
}
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
443
|
+
/** {@inheritDoc IIdentityWallet.publishRevocationInfoByCredentialStatusType} */
|
|
444
|
+
async publishRevocationInfoByCredentialStatusType(issuerDID, credentialStatusType, opts) {
|
|
445
|
+
const rhsPublishers = this._credentialStatusPublisherRegistry.get(credentialStatusType);
|
|
446
|
+
if (!rhsPublishers) {
|
|
447
|
+
throw new Error(`there is no registered publisher to save hash is not registered for ${credentialStatusType} is not registered`);
|
|
448
|
+
}
|
|
449
|
+
let nodes = [];
|
|
450
|
+
if (opts?.treeModel) {
|
|
451
|
+
nodes = await (0, credentials_1.getNodesRepresentation)(opts.revokedNonces, {
|
|
452
|
+
revocationTree: opts.treeModel.revocationTree,
|
|
453
|
+
claimsTree: opts.treeModel.claimsTree,
|
|
454
|
+
state: opts.treeModel.state,
|
|
455
|
+
rootsTree: opts.treeModel.rootsTree
|
|
456
|
+
}, opts.treeModel.state);
|
|
457
|
+
}
|
|
458
|
+
else {
|
|
459
|
+
const treeState = await this.getDIDTreeModel(issuerDID);
|
|
460
|
+
nodes = await (0, credentials_1.getNodesRepresentation)(opts?.revokedNonces, {
|
|
461
|
+
revocationTree: treeState.revocationTree,
|
|
462
|
+
claimsTree: treeState.claimsTree,
|
|
463
|
+
state: treeState.state,
|
|
464
|
+
rootsTree: treeState.rootsTree
|
|
465
|
+
}, treeState.state);
|
|
466
|
+
}
|
|
467
|
+
if (!nodes.length) {
|
|
468
|
+
return;
|
|
435
469
|
}
|
|
436
|
-
const
|
|
437
|
-
|
|
438
|
-
const pb = new js_crypto_1.PublicKey([BigInt(x), BigInt(y)]);
|
|
439
|
-
const kp = (0, provider_helpers_1.keyPath)(kms_1.KmsKeyType.BabyJubJub, pb.hex());
|
|
440
|
-
return { type: kms_1.KmsKeyType.BabyJubJub, id: kp };
|
|
470
|
+
const rhsPublishersTask = rhsPublishers.map((publisher) => publisher.publish({ nodes, ...opts, credentialStatusType, issuerDID }));
|
|
471
|
+
await Promise.all(rhsPublishersTask);
|
|
441
472
|
}
|
|
442
473
|
async getCoreClaimFromCredential(credential) {
|
|
443
474
|
const coreClaimFromSigProof = credential.getCoreClaimFromProof(verifiable_1.ProofType.BJJSignature);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
[{ "inputs": [{ "internalType": "uint256", "name": "id", "type": "uint256" }, { "internalType": "uint64", "name": "nonce", "type": "uint64" }], "name": "getRevocationStatus", "outputs": [{ "components": [{ "components": [{ "internalType": "uint256", "name": "state", "type": "uint256" }, { "internalType": "uint256", "name": "claimsTreeRoot", "type": "uint256" }, { "internalType": "uint256", "name": "revocationTreeRoot", "type": "uint256" }, { "internalType": "uint256", "name": "rootOfRoots", "type": "uint256" }], "internalType": "
|
|
1
|
+
[{ "inputs": [], "name": "MAX_SMT_DEPTH", "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "uint256", "name": "key", "type": "uint256" }], "name": "getNode", "outputs": [{ "internalType": "uint256[]", "name": "", "type": "uint256[]" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "uint256", "name": "id", "type": "uint256" }, { "internalType": "uint64", "name": "nonce", "type": "uint64" }], "name": "getRevocationStatus", "outputs": [{ "components": [{ "components": [{ "internalType": "uint256", "name": "state", "type": "uint256" }, { "internalType": "uint256", "name": "claimsTreeRoot", "type": "uint256" }, { "internalType": "uint256", "name": "revocationTreeRoot", "type": "uint256" }, { "internalType": "uint256", "name": "rootOfRoots", "type": "uint256" }], "internalType": "struct IOnchainCredentialStatusResolver.IdentityStateRoots", "name": "issuer", "type": "tuple" }, { "components": [{ "internalType": "uint256", "name": "root", "type": "uint256" }, { "internalType": "bool", "name": "existence", "type": "bool" }, { "internalType": "uint256[]", "name": "siblings", "type": "uint256[]" }, { "internalType": "uint256", "name": "index", "type": "uint256" }, { "internalType": "uint256", "name": "value", "type": "uint256" }, { "internalType": "bool", "name": "auxExistence", "type": "bool" }, { "internalType": "uint256", "name": "auxIndex", "type": "uint256" }, { "internalType": "uint256", "name": "auxValue", "type": "uint256" }], "internalType": "struct IOnchainCredentialStatusResolver.Proof", "name": "mtp", "type": "tuple" }], "internalType": "struct IOnchainCredentialStatusResolver.CredentialStatus", "name": "", "type": "tuple" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "uint256", "name": "id", "type": "uint256" }, { "internalType": "uint256", "name": "state", "type": "uint256" }, { "internalType": "uint64", "name": "nonce", "type": "uint64" }], "name": "getRevocationStatusByIdAndState", "outputs": [{ "components": [{ "components": [{ "internalType": "uint256", "name": "state", "type": "uint256" }, { "internalType": "uint256", "name": "claimsTreeRoot", "type": "uint256" }, { "internalType": "uint256", "name": "revocationTreeRoot", "type": "uint256" }, { "internalType": "uint256", "name": "rootOfRoots", "type": "uint256" }], "internalType": "struct IOnchainCredentialStatusResolver.IdentityStateRoots", "name": "issuer", "type": "tuple" }, { "components": [{ "internalType": "uint256", "name": "root", "type": "uint256" }, { "internalType": "bool", "name": "existence", "type": "bool" }, { "internalType": "uint256[]", "name": "siblings", "type": "uint256[]" }, { "internalType": "uint256", "name": "index", "type": "uint256" }, { "internalType": "uint256", "name": "value", "type": "uint256" }, { "internalType": "bool", "name": "auxExistence", "type": "bool" }, { "internalType": "uint256", "name": "auxIndex", "type": "uint256" }, { "internalType": "uint256", "name": "auxValue", "type": "uint256" }], "internalType": "struct IOnchainCredentialStatusResolver.Proof", "name": "mtp", "type": "tuple" }], "internalType": "struct IOnchainCredentialStatusResolver.CredentialStatus", "name": "", "type": "tuple" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "owner", "outputs": [{ "internalType": "address", "name": "", "type": "address" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "uint256[][]", "name": "nodes", "type": "uint256[][]" }], "name": "saveNodes", "outputs": [], "stateMutability": "nonpayable", "type": "function" }]
|
|
@@ -16,3 +16,4 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
17
|
__exportStar(require("./state"), exports);
|
|
18
18
|
__exportStar(require("./onchain-zkp-verifier"), exports);
|
|
19
|
+
__exportStar(require("./onchain-revocation"), exports);
|