@docknetwork/wallet-sdk-wasm 1.5.11 → 1.7.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/generate-docs.js +49 -0
- package/jsdoc.conf.json +29 -6
- package/lib/index.js +8 -1
- package/lib/index.mjs +8 -1
- package/lib/rpc-server.js +10 -1
- package/lib/rpc-server.mjs +10 -1
- package/lib/services/blockchain/cached-did-resolver.js +113 -0
- package/lib/services/blockchain/cached-did-resolver.mjs +109 -0
- package/lib/services/blockchain/index.js +11 -0
- package/lib/services/blockchain/index.mjs +11 -0
- package/lib/services/blockchain/service-rpc.js +16 -0
- package/lib/services/blockchain/service-rpc.mjs +16 -0
- package/lib/services/blockchain/service.js +144 -12
- package/lib/services/blockchain/service.mjs +144 -12
- package/lib/services/credential/bbs-revocation.js +11 -0
- package/lib/services/credential/bbs-revocation.mjs +11 -0
- package/lib/services/credential/config.js +4 -1
- package/lib/services/credential/config.mjs +4 -1
- package/lib/services/credential/index.js +14 -0
- package/lib/services/credential/index.mjs +14 -0
- package/lib/services/credential/pex-helpers.js +20 -0
- package/lib/services/credential/pex-helpers.mjs +20 -1
- package/lib/services/credential/sd-jwt.js +214 -0
- package/lib/services/credential/sd-jwt.mjs +200 -0
- package/lib/services/credential/service-rpc.js +9 -0
- package/lib/services/credential/service-rpc.mjs +9 -0
- package/lib/services/credential/service.js +325 -8
- package/lib/services/credential/service.mjs +326 -9
- package/lib/services/edv/service.js +145 -1
- package/lib/services/edv/service.mjs +145 -1
- package/lib/services/index.js +13 -0
- package/lib/services/index.mjs +13 -0
- package/lib/services/relay-service/service.js +124 -1
- package/lib/services/relay-service/service.mjs +124 -1
- package/lib/services/rpc-service-client.js +0 -3
- package/lib/services/rpc-service-client.mjs +0 -3
- package/lib/services/storage/index.js +19 -2
- package/lib/services/storage/index.mjs +24 -1
- package/lib/services/storage/service-rpc.js +7 -3
- package/lib/services/storage/service-rpc.mjs +7 -3
- package/lib/services/storage/service.js +4 -0
- package/lib/services/storage/service.mjs +4 -0
- package/lib/setup-nodejs.js +8 -1
- package/lib/setup-nodejs.mjs +8 -1
- package/lib/setup-tests.js +8 -1
- package/lib/setup-tests.mjs +8 -1
- package/lib/src/services/blockchain/cached-did-resolver.d.ts +28 -0
- package/lib/src/services/blockchain/cached-did-resolver.d.ts.map +1 -0
- package/lib/src/services/blockchain/cached-did-resolver.test.d.ts +2 -0
- package/lib/src/services/blockchain/cached-did-resolver.test.d.ts.map +1 -0
- package/lib/src/services/blockchain/service.d.ts +115 -17
- package/lib/src/services/blockchain/service.d.ts.map +1 -1
- package/lib/src/services/credential/config.d.ts.map +1 -1
- package/lib/src/services/credential/index.d.ts +3 -0
- package/lib/src/services/credential/index.d.ts.map +1 -1
- package/lib/src/services/credential/pex-helpers.d.ts +13 -1
- package/lib/src/services/credential/pex-helpers.d.ts.map +1 -1
- package/lib/src/services/credential/sd-jwt.test.d.ts +2 -0
- package/lib/src/services/credential/sd-jwt.test.d.ts.map +1 -0
- package/lib/src/services/credential/service.d.ts +274 -4
- package/lib/src/services/credential/service.d.ts.map +1 -1
- package/lib/src/services/edv/service.d.ts +151 -1
- package/lib/src/services/edv/service.d.ts.map +1 -1
- package/lib/src/services/relay-service/service.d.ts +129 -1
- package/lib/src/services/relay-service/service.d.ts.map +1 -1
- package/lib/src/services/rpc-service-client.d.ts +2 -2
- package/lib/src/services/rpc-service-client.d.ts.map +1 -1
- package/lib/src/services/storage/index.d.ts +1 -1
- package/lib/src/services/storage/index.d.ts.map +1 -1
- package/lib/src/services/storage/service-rpc.d.ts +9 -0
- package/lib/src/services/storage/service-rpc.d.ts.map +1 -0
- package/lib/src/services/storage/service.d.ts +1 -0
- package/lib/src/services/storage/service.d.ts.map +1 -1
- package/lib/src/services/util-crypto/service.d.ts +1 -1
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/lib/wallet/rpc-storage-interface.js +13 -3
- package/lib/wallet/rpc-storage-interface.mjs +11 -1
- package/lib/wallet/rpc-storage-wallet.js +10 -0
- package/lib/wallet/rpc-storage-wallet.mjs +10 -0
- package/package.json +13 -8
- package/src/services/blockchain/cached-did-resolver.test.ts +288 -0
- package/src/services/blockchain/cached-did-resolver.ts +126 -0
- package/src/services/blockchain/service-rpc.js +16 -0
- package/src/services/blockchain/service.ts +146 -12
- package/src/services/credential/config.ts +7 -1
- package/src/services/credential/pex-helpers.js +20 -1
- package/src/services/credential/pex-helpers.test.js +114 -0
- package/src/services/credential/sd-jwt.test.ts +718 -0
- package/src/services/credential/sd-jwt.ts +231 -0
- package/src/services/credential/service-rpc.js +9 -0
- package/src/services/credential/service.ts +330 -9
- package/src/services/edv/service.ts +153 -1
- package/src/services/relay-service/service.ts +130 -1
- package/src/services/rpc-service-client.js +0 -3
- package/src/services/storage/index.js +15 -1
- package/src/services/storage/service-rpc.js +7 -3
- package/src/services/storage/service.ts +5 -0
|
@@ -10,8 +10,9 @@ import { blockchainService } from '../blockchain/service.mjs';
|
|
|
10
10
|
import { hasProvingKey, fetchProvingKey, applyEnforceBounds } from './bound-check.mjs';
|
|
11
11
|
import assert from 'assert';
|
|
12
12
|
import { getIsRevoked, getWitnessDetails } from './bbs-revocation.mjs';
|
|
13
|
-
import { getPexRequiredAttributes } from './pex-helpers.mjs';
|
|
13
|
+
import { getPexRequiredAttributes, shouldSkipAttribute } from './pex-helpers.mjs';
|
|
14
14
|
import { didService } from '../dids/service.mjs';
|
|
15
|
+
import { createSDJWTPresentation, isSDJWTCredential, verifySDJWT, credentialToW3C } from './sd-jwt.mjs';
|
|
15
16
|
import '@cosmjs/proto-signing';
|
|
16
17
|
import '@docknetwork/cheqd-blockchain-api';
|
|
17
18
|
import '@docknetwork/cheqd-blockchain-modules';
|
|
@@ -26,6 +27,17 @@ import '@scure/bip39';
|
|
|
26
27
|
import '@scure/bip39/wordlists/english';
|
|
27
28
|
import '../util-crypto/configs.mjs';
|
|
28
29
|
import '@docknetwork/credential-sdk/types';
|
|
30
|
+
import '../blockchain/cached-did-resolver.mjs';
|
|
31
|
+
import '../storage/index.mjs';
|
|
32
|
+
import '../storage/service.mjs';
|
|
33
|
+
import '../storage/service-rpc.mjs';
|
|
34
|
+
import '../rpc-service-client.mjs';
|
|
35
|
+
import '../../rpc-client.mjs';
|
|
36
|
+
import 'json-rpc-2.0';
|
|
37
|
+
import '../../core/crypto.mjs';
|
|
38
|
+
import 'crypto';
|
|
39
|
+
import '../../logger.mjs';
|
|
40
|
+
import '../../rpc-util.mjs';
|
|
29
41
|
import '@docknetwork/crypto-wasm-ts/lib/legosnark';
|
|
30
42
|
import 'base64url';
|
|
31
43
|
import '@astronautlabs/jsonpath';
|
|
@@ -40,23 +52,65 @@ import '@digitalbazaar/x25519-key-agreement-key-2019';
|
|
|
40
52
|
import '@digitalbazaar/ed25519-verification-key-2018';
|
|
41
53
|
import '@digitalbazaar/ed25519-verification-key-2020';
|
|
42
54
|
import '../dids/keypair-utils.mjs';
|
|
55
|
+
import '@sd-jwt/sd-jwt-vc';
|
|
56
|
+
import '@sd-jwt/crypto-nodejs';
|
|
43
57
|
|
|
44
58
|
// @ts-nocheck
|
|
59
|
+
/**
|
|
60
|
+
* PEX (Presentation Exchange) instance for credential filtering
|
|
61
|
+
* @private
|
|
62
|
+
*/
|
|
45
63
|
const pex = new PEX();
|
|
64
|
+
/**
|
|
65
|
+
* Checks if a credential uses BBS+ signature
|
|
66
|
+
* @param {Object} credential - The credential to check
|
|
67
|
+
* @returns {boolean} True if the credential uses BBS+ signature
|
|
68
|
+
* @example
|
|
69
|
+
* const isBBS = isBBSPlusCredential(credential);
|
|
70
|
+
* if (isBBS) {
|
|
71
|
+
* console.log('This credential uses BBS+ signatures');
|
|
72
|
+
* }
|
|
73
|
+
*/
|
|
46
74
|
function isBBSPlusCredential(credential) {
|
|
47
75
|
return ((typeof credential?.proof?.type === 'string' &&
|
|
48
76
|
credential.proof.type.includes('BBS+SignatureDock')) ||
|
|
49
77
|
(Array.isArray(credential['@context']) &&
|
|
50
78
|
credential['@context'].find(context => typeof context === 'string' && context.indexOf('bbs') > -1)));
|
|
51
79
|
}
|
|
80
|
+
/**
|
|
81
|
+
* Checks if a credential uses KVAC (BBDT16) signature
|
|
82
|
+
* @param {Object} credential - The credential to check
|
|
83
|
+
* @returns {boolean} True if the credential uses KVAC signature
|
|
84
|
+
* @example
|
|
85
|
+
* const isKVAC = isKvacCredential(credential);
|
|
86
|
+
*/
|
|
52
87
|
function isKvacCredential(credential) {
|
|
53
88
|
return (typeof credential?.proof?.type === 'string' &&
|
|
54
89
|
credential.proof.type.toLowerCase().includes('bbdt16'));
|
|
55
90
|
}
|
|
91
|
+
/**
|
|
92
|
+
* Checks if a credential is anonymous (BBS+ or KVAC)
|
|
93
|
+
* @param {Object} credential - The credential to check
|
|
94
|
+
* @returns {boolean} True if the credential is anonymous
|
|
95
|
+
* @example
|
|
96
|
+
* if (isAnnonymousCredential(credential)) {
|
|
97
|
+
* console.log('This credential supports selective disclosure');
|
|
98
|
+
* }
|
|
99
|
+
*/
|
|
56
100
|
function isAnnonymousCredential(credential) {
|
|
57
101
|
return isBBSPlusCredential(credential) || isKvacCredential(credential);
|
|
58
102
|
}
|
|
103
|
+
/**
|
|
104
|
+
* Service class for managing verifiable credentials
|
|
105
|
+
* @class
|
|
106
|
+
* @description Provides methods for creating, signing, verifying, and presenting
|
|
107
|
+
* verifiable credentials with support for various signature types
|
|
108
|
+
*/
|
|
59
109
|
class CredentialService {
|
|
110
|
+
/**
|
|
111
|
+
* Creates a new CredentialService instance
|
|
112
|
+
* @constructor
|
|
113
|
+
*/
|
|
60
114
|
constructor() {
|
|
61
115
|
this.name = serviceName;
|
|
62
116
|
}
|
|
@@ -69,8 +123,25 @@ class CredentialService {
|
|
|
69
123
|
CredentialService.prototype.deriveVCFromPresentation,
|
|
70
124
|
CredentialService.prototype.isBBSPlusCredential,
|
|
71
125
|
CredentialService.prototype.isKvacCredential,
|
|
126
|
+
CredentialService.prototype.isSDJWTCredential,
|
|
127
|
+
CredentialService.prototype.credentialToW3C,
|
|
128
|
+
CredentialService.prototype.createSDJWTPresentation,
|
|
72
129
|
CredentialService.prototype.acquireOIDCredential,
|
|
73
130
|
];
|
|
131
|
+
createSDJWTPresentation(params) {
|
|
132
|
+
const { attributesToReveal, credential } = params;
|
|
133
|
+
return createSDJWTPresentation({ attributesToReveal, credential });
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Generates a new verifiable credential template
|
|
137
|
+
* @param {Object} [params={}] - Generation parameters
|
|
138
|
+
* @param {Object} [params.subject] - The credential subject
|
|
139
|
+
* @returns {VerifiableCredential} A new verifiable credential instance
|
|
140
|
+
* @example
|
|
141
|
+
* const credential = credentialService.generateCredential({
|
|
142
|
+
* subject: { id: 'did:example:123', name: 'Alice' }
|
|
143
|
+
* });
|
|
144
|
+
*/
|
|
74
145
|
generateCredential(params = {}) {
|
|
75
146
|
validation.generateCredential(params);
|
|
76
147
|
const { subject } = params;
|
|
@@ -88,6 +159,19 @@ class CredentialService {
|
|
|
88
159
|
}
|
|
89
160
|
return vc;
|
|
90
161
|
}
|
|
162
|
+
/**
|
|
163
|
+
* Signs a verifiable credential
|
|
164
|
+
* @param {Object} params - Signing parameters
|
|
165
|
+
* @param {Object} params.vcJson - The credential JSON to sign
|
|
166
|
+
* @param {Object} params.keyDoc - The key document for signing
|
|
167
|
+
* @returns {Promise<VerifiableCredential>} The signed verifiable credential
|
|
168
|
+
* @throws {Error} If validation fails or signing fails
|
|
169
|
+
* @example
|
|
170
|
+
* const signedCredential = await credentialService.signCredential({
|
|
171
|
+
* vcJson: credentialData,
|
|
172
|
+
* keyDoc: issuerKeyDocument
|
|
173
|
+
* });
|
|
174
|
+
*/
|
|
91
175
|
async signCredential(params) {
|
|
92
176
|
validation.signCredential(params);
|
|
93
177
|
const { vcJson, keyDoc } = params;
|
|
@@ -100,13 +184,38 @@ class CredentialService {
|
|
|
100
184
|
await verifiableCredential.sign(suite);
|
|
101
185
|
return verifiableCredential;
|
|
102
186
|
}
|
|
187
|
+
/**
|
|
188
|
+
* Creates a verifiable presentation from credentials
|
|
189
|
+
* @param {Object} params - Presentation parameters
|
|
190
|
+
* @param {Array<Object>} params.credentials - Array of verifiable credentials to include
|
|
191
|
+
* @param {Object} params.keyDoc - The key document for signing the presentation
|
|
192
|
+
* @param {string} [params.challenge] - Challenge string for the presentation proof
|
|
193
|
+
* @param {string} [params.id] - Presentation identifier
|
|
194
|
+
* @param {string} [params.domain] - Domain for the presentation proof
|
|
195
|
+
* @returns {Promise<Object>} The signed verifiable presentation
|
|
196
|
+
* @throws {Error} If validation fails
|
|
197
|
+
* @example
|
|
198
|
+
* const presentation = await credentialService.createPresentation({
|
|
199
|
+
* credentials: [credential1, credential2],
|
|
200
|
+
* keyDoc: holderKeyDocument,
|
|
201
|
+
* challenge: 'abc123',
|
|
202
|
+
* domain: 'example.com'
|
|
203
|
+
* });
|
|
204
|
+
*/
|
|
103
205
|
async createPresentation(params) {
|
|
104
206
|
validation.createPresentation(params);
|
|
105
207
|
const { credentials, keyDoc, challenge, id, domain } = params;
|
|
106
208
|
const vp = new VerifiablePresentation(id);
|
|
107
209
|
let shouldSkipSigning = false;
|
|
210
|
+
let jwtCredentials = [];
|
|
108
211
|
for (const signedVC of credentials) {
|
|
109
|
-
|
|
212
|
+
if (typeof signedVC === 'string') {
|
|
213
|
+
jwtCredentials.push(signedVC);
|
|
214
|
+
shouldSkipSigning = true;
|
|
215
|
+
}
|
|
216
|
+
else {
|
|
217
|
+
vp.addCredential(signedVC);
|
|
218
|
+
}
|
|
110
219
|
shouldSkipSigning = shouldSkipSigning || isAnnonymousCredential(signedVC);
|
|
111
220
|
}
|
|
112
221
|
if (!shouldSkipSigning) {
|
|
@@ -116,16 +225,54 @@ class CredentialService {
|
|
|
116
225
|
keyPair.signer = keyPair.signer();
|
|
117
226
|
const suite = await getSuiteFromKeyDoc(keyPair);
|
|
118
227
|
if (shouldSkipSigning) {
|
|
119
|
-
|
|
228
|
+
const result = vp.toJSON();
|
|
229
|
+
result.verifiableCredential.push(...jwtCredentials);
|
|
230
|
+
return result;
|
|
120
231
|
}
|
|
121
232
|
return vp.sign(suite, challenge, domain, blockchainService.resolver);
|
|
122
233
|
}
|
|
234
|
+
/**
|
|
235
|
+
* Verifies a verifiable presentation
|
|
236
|
+
* @param {Object} params - Verification parameters
|
|
237
|
+
* @param {Object} params.presentation - The presentation to verify
|
|
238
|
+
* @param {Object} [params.options] - Verification options
|
|
239
|
+
* @returns {Promise<Object>} Verification result with verified status and any errors
|
|
240
|
+
* @example
|
|
241
|
+
* const result = await credentialService.verifyPresentation({
|
|
242
|
+
* presentation: presentationData
|
|
243
|
+
* });
|
|
244
|
+
* console.log('Verified:', result.verified);
|
|
245
|
+
*/
|
|
123
246
|
async verifyPresentation({ presentation, options }) {
|
|
124
247
|
return verifyPresentation(presentation, options);
|
|
125
248
|
}
|
|
249
|
+
/**
|
|
250
|
+
* Verifies a verifiable credential including revocation check
|
|
251
|
+
* @param {Object} params - Verification parameters
|
|
252
|
+
* @param {Object} params.credential - The credential to verify
|
|
253
|
+
* @param {Object} [params.membershipWitness] - Membership witness for revocation check
|
|
254
|
+
* @returns {Promise<Object>} Verification result
|
|
255
|
+
* @returns {boolean} returns.verified - Whether the credential is valid
|
|
256
|
+
* @returns {string} [returns.error] - Error message if verification failed
|
|
257
|
+
* @throws {Error} If validation fails
|
|
258
|
+
* @example
|
|
259
|
+
* const result = await credentialService.verifyCredential({
|
|
260
|
+
* credential: credentialData,
|
|
261
|
+
* membershipWitness: witnessData
|
|
262
|
+
* });
|
|
263
|
+
* if (!result.verified) {
|
|
264
|
+
* console.error('Verification failed:', result.error);
|
|
265
|
+
* }
|
|
266
|
+
*/
|
|
126
267
|
async verifyCredential(params) {
|
|
127
268
|
validation.verifyCredential(params);
|
|
128
|
-
|
|
269
|
+
let { credential, membershipWitness } = params;
|
|
270
|
+
if (credential._sd_jwt) {
|
|
271
|
+
credential = credential?._sd_jwt?.encoded;
|
|
272
|
+
}
|
|
273
|
+
if (typeof credential === 'string' && isSDJWTCredential(credential)) {
|
|
274
|
+
return verifySDJWT(credential);
|
|
275
|
+
}
|
|
129
276
|
const result = await verifyCredential(credential, {
|
|
130
277
|
resolver: blockchainService.resolver,
|
|
131
278
|
revocationApi: { dock: blockchainService.dock },
|
|
@@ -146,24 +293,113 @@ class CredentialService {
|
|
|
146
293
|
}
|
|
147
294
|
return result;
|
|
148
295
|
}
|
|
296
|
+
/**
|
|
297
|
+
* Filters credentials based on a presentation definition
|
|
298
|
+
* @param {Object} params - Filter parameters
|
|
299
|
+
* @param {Array<Object>} params.credentials - Array of credentials to filter
|
|
300
|
+
* @param {Object} params.presentationDefinition - PEX presentation definition
|
|
301
|
+
* @param {string} [params.holderDid] - DID of the credential holder
|
|
302
|
+
* @returns {Object} Filtered credentials matching the presentation definition
|
|
303
|
+
* @example
|
|
304
|
+
* const filtered = credentialService.filterCredentials({
|
|
305
|
+
* credentials: allCredentials,
|
|
306
|
+
* presentationDefinition: definition,
|
|
307
|
+
* holderDid: 'did:example:holder'
|
|
308
|
+
* });
|
|
309
|
+
*/
|
|
149
310
|
filterCredentials(params) {
|
|
150
311
|
const { credentials, presentationDefinition, holderDid } = params;
|
|
151
312
|
const result = pex.selectFrom(presentationDefinition, credentials, holderDid);
|
|
152
313
|
return result;
|
|
153
314
|
}
|
|
315
|
+
/**
|
|
316
|
+
* Evaluates a presentation against a presentation definition
|
|
317
|
+
* @param {Object} params - Evaluation parameters
|
|
318
|
+
* @param {Object} params.presentation - The presentation to evaluate
|
|
319
|
+
* @param {Object} params.presentationDefinition - PEX presentation definition
|
|
320
|
+
* @returns {Object} Evaluation result with validation details
|
|
321
|
+
* @example
|
|
322
|
+
* const evaluation = credentialService.evaluatePresentation({
|
|
323
|
+
* presentation: presentationData,
|
|
324
|
+
* presentationDefinition: definition
|
|
325
|
+
* });
|
|
326
|
+
*/
|
|
154
327
|
evaluatePresentation(params) {
|
|
155
328
|
const { presentation, presentationDefinition } = params;
|
|
156
329
|
const result = pex.evaluatePresentation(presentationDefinition, presentation);
|
|
157
330
|
return result;
|
|
158
331
|
}
|
|
332
|
+
/**
|
|
333
|
+
* Checks if a credential uses BBS+ signature
|
|
334
|
+
* @param {Object} params - Check parameters
|
|
335
|
+
* @param {Object} params.credential - The credential to check
|
|
336
|
+
* @returns {boolean} True if the credential uses BBS+ signature
|
|
337
|
+
*/
|
|
159
338
|
isBBSPlusCredential(params) {
|
|
160
339
|
const { credential } = params;
|
|
161
340
|
return isBBSPlusCredential(credential);
|
|
162
341
|
}
|
|
342
|
+
/**
|
|
343
|
+
* Checks if a credential uses KVAC signature
|
|
344
|
+
* @param {Object} params - Check parameters
|
|
345
|
+
* @param {Object} params.credential - The credential to check
|
|
346
|
+
* @returns {boolean} True if the credential uses KVAC signature
|
|
347
|
+
*/
|
|
163
348
|
isKvacCredential(params) {
|
|
164
349
|
const { credential } = params;
|
|
165
350
|
return isKvacCredential(credential);
|
|
166
351
|
}
|
|
352
|
+
/**
|
|
353
|
+
* Checks if a credential is an SD-JWT (Selective Disclosure JWT) credential
|
|
354
|
+
* @param {Object} params - Check parameters
|
|
355
|
+
* @param {string} params.credential - The JWT string to check
|
|
356
|
+
* @returns {boolean} True if the credential is an SD-JWT credential
|
|
357
|
+
* @example
|
|
358
|
+
* const isSDJWT = credentialService.isSDJWTCredential({
|
|
359
|
+
* credential: 'eyJ0eXAiOiJ2YytzZC1qd3Q...'
|
|
360
|
+
* });
|
|
361
|
+
*/
|
|
362
|
+
isSDJWTCredential(params) {
|
|
363
|
+
const { credential } = params;
|
|
364
|
+
return isSDJWTCredential(credential);
|
|
365
|
+
}
|
|
366
|
+
/**
|
|
367
|
+
* Converts a credential to W3C Verifiable Credential format
|
|
368
|
+
* @description Handles both SD-JWT credentials (needs decoding) and regular W3C credentials (returns as-is)
|
|
369
|
+
* @param {Object} params - Conversion parameters
|
|
370
|
+
* @param {string|Object} params.credential - Either an SD-JWT string or a credential object
|
|
371
|
+
* @returns {Promise<Object>} W3C Verifiable Credential format
|
|
372
|
+
* @throws {Error} If credential cannot be converted to W3C format
|
|
373
|
+
* @example
|
|
374
|
+
* // Convert SD-JWT to W3C format
|
|
375
|
+
* const w3cCredential = await credentialService.credentialToW3C({
|
|
376
|
+
* credential: 'eyJ0eXAiOiJ2YytzZC1qd3Q...'
|
|
377
|
+
* });
|
|
378
|
+
*
|
|
379
|
+
* // Returns W3C credential as-is
|
|
380
|
+
* const w3cCredential = await credentialService.credentialToW3C({
|
|
381
|
+
* credential: { '@context': [...], type: [...], ... }
|
|
382
|
+
* });
|
|
383
|
+
*/
|
|
384
|
+
async credentialToW3C(params) {
|
|
385
|
+
const { credential } = params;
|
|
386
|
+
return credentialToW3C(credential);
|
|
387
|
+
}
|
|
388
|
+
/**
|
|
389
|
+
* Acquires a credential through OpenID for Verifiable Credentials (OID4VC)
|
|
390
|
+
* @param {Object} params - Acquisition parameters
|
|
391
|
+
* @param {string} params.uri - The credential offer URI
|
|
392
|
+
* @param {string} [params.authorizationCode] - Authorization code if required
|
|
393
|
+
* @param {Object} params.holderKeyDocument - Key document for the credential holder
|
|
394
|
+
* @returns {Promise<Object>} Result containing the credential or authorization URL
|
|
395
|
+
* @returns {Object} [returns.credential] - The acquired credential
|
|
396
|
+
* @returns {string} [returns.authorizationURL] - Authorization URL if auth is required
|
|
397
|
+
* @example
|
|
398
|
+
* const result = await credentialService.acquireOIDCredential({
|
|
399
|
+
* uri: 'openid-credential-offer://...',
|
|
400
|
+
* holderKeyDocument: keyDoc
|
|
401
|
+
* });
|
|
402
|
+
*/
|
|
167
403
|
async acquireOIDCredential({ uri, authorizationCode, holderKeyDocument, }) {
|
|
168
404
|
const searchParams = new URL(uri).searchParams;
|
|
169
405
|
new URLSearchParams(searchParams);
|
|
@@ -173,6 +409,8 @@ class CredentialService {
|
|
|
173
409
|
authorizationRequest: {
|
|
174
410
|
redirectUri: 'dock-wallet://credentials/callback',
|
|
175
411
|
clientId: 'dock.wallet',
|
|
412
|
+
// Hack: we need the scope property to avoid 'CredentialOffer format is wrong.' error
|
|
413
|
+
scope: []
|
|
176
414
|
},
|
|
177
415
|
});
|
|
178
416
|
const format = 'ldp_vc';
|
|
@@ -223,6 +461,22 @@ class CredentialService {
|
|
|
223
461
|
console.error(err);
|
|
224
462
|
}
|
|
225
463
|
}
|
|
464
|
+
/**
|
|
465
|
+
* Creates a BBS+ presentation with selective disclosure
|
|
466
|
+
* @param {Object} params - Presentation parameters
|
|
467
|
+
* @param {Array<Object>} params.credentials - Array of credentials with attributes to reveal
|
|
468
|
+
* @param {Object} params.credentials[].credential - The BBS+ credential
|
|
469
|
+
* @param {Array<string>} [params.credentials[].attributesToReveal] - Attributes to reveal
|
|
470
|
+
* @returns {Promise<Object>} The BBS+ presentation
|
|
471
|
+
* @throws {Error} If validation fails
|
|
472
|
+
* @example
|
|
473
|
+
* const presentation = await credentialService.createBBSPresentation({
|
|
474
|
+
* credentials: [{
|
|
475
|
+
* credential: bbsCredential,
|
|
476
|
+
* attributesToReveal: ['name', 'age']
|
|
477
|
+
* }]
|
|
478
|
+
* });
|
|
479
|
+
*/
|
|
226
480
|
async createBBSPresentation(params) {
|
|
227
481
|
validation.createBBSPresentation(params);
|
|
228
482
|
const { credentials } = params;
|
|
@@ -237,6 +491,13 @@ class CredentialService {
|
|
|
237
491
|
}
|
|
238
492
|
return bbsPlusPresentation.createPresentation();
|
|
239
493
|
}
|
|
494
|
+
/**
|
|
495
|
+
* Gets the accumulator ID from a credential's status
|
|
496
|
+
* @param {Object} params - Parameters
|
|
497
|
+
* @param {Object} params.credential - The credential to get accumulator ID from
|
|
498
|
+
* @returns {string|null} The accumulator ID or null if not present
|
|
499
|
+
* @throws {Error} If credential is not provided
|
|
500
|
+
*/
|
|
240
501
|
getAccumulatorId({ credential }) {
|
|
241
502
|
assert(!!credential, `credential is required`);
|
|
242
503
|
if (!credential?.credentialStatus) {
|
|
@@ -244,6 +505,13 @@ class CredentialService {
|
|
|
244
505
|
}
|
|
245
506
|
return credential?.credentialStatus.id;
|
|
246
507
|
}
|
|
508
|
+
/**
|
|
509
|
+
* Gets accumulator data from the blockchain for a credential
|
|
510
|
+
* @param {Object} params - Parameters
|
|
511
|
+
* @param {Object} params.credential - The credential to get accumulator data for
|
|
512
|
+
* @returns {Promise<Object|null>} The accumulator data or null if not found
|
|
513
|
+
* @throws {Error} If credential is not provided
|
|
514
|
+
*/
|
|
247
515
|
async getAccumulatorData({ credential }) {
|
|
248
516
|
assert(!!credential, `credential is required`);
|
|
249
517
|
const accumulatorId = await this.getAccumulatorId({ credential });
|
|
@@ -253,10 +521,15 @@ class CredentialService {
|
|
|
253
521
|
return blockchainService.dock.accumulatorModule.getAccumulator(accumulatorId, false);
|
|
254
522
|
}
|
|
255
523
|
/**
|
|
256
|
-
*
|
|
257
|
-
* The witness is generated by the issuer when the credential is created
|
|
258
|
-
*
|
|
259
|
-
*
|
|
524
|
+
* Updates the membership witness with the latest accumulator state
|
|
525
|
+
* @description The witness is generated by the issuer when the credential is created
|
|
526
|
+
* and is stored in the wallet when the credential is imported. This method updates
|
|
527
|
+
* it with the latest accumulator changes from the blockchain.
|
|
528
|
+
* @param {Object} params - Update parameters
|
|
529
|
+
* @param {Object} params.credential - The credential with revocation status
|
|
530
|
+
* @param {Object} params.membershipWitnessJSON - Current membership witness in JSON format
|
|
531
|
+
* @returns {Promise<Object>} Updated membership witness in JSON format
|
|
532
|
+
* @throws {Error} If updates cannot be fetched or applied
|
|
260
533
|
*/
|
|
261
534
|
async updateMembershipWitness({ credential, membershipWitnessJSON }) {
|
|
262
535
|
const revocationId = credential.credentialStatus.revocationId;
|
|
@@ -293,6 +566,25 @@ class CredentialService {
|
|
|
293
566
|
witness.updateUsingPublicInfoPostBatchUpdate(member, additions, removals, queriedWitnessInfo);
|
|
294
567
|
return witness.toJSON();
|
|
295
568
|
}
|
|
569
|
+
/**
|
|
570
|
+
* Derives verifiable credentials from a presentation with selective disclosure
|
|
571
|
+
* @param {Object} params - Derivation parameters
|
|
572
|
+
* @param {Array<Object>} params.credentials - Array of credential objects
|
|
573
|
+
* @param {Object} params.credentials[].credential - The credential
|
|
574
|
+
* @param {Array<string>} params.credentials[].attributesToReveal - Attributes to reveal
|
|
575
|
+
* @param {Object} [params.credentials[].witness] - Membership witness for revocation
|
|
576
|
+
* @param {Object} [params.options={}] - Additional options for derivation
|
|
577
|
+
* @param {Object} [params.proofRequest] - Proof request with constraints
|
|
578
|
+
* @returns {Promise<Array>} Array of derived credentials
|
|
579
|
+
* @throws {Error} If validation fails
|
|
580
|
+
* @example
|
|
581
|
+
* const derivedCredentials = await credentialService.deriveVCFromPresentation({
|
|
582
|
+
* credentials: [{
|
|
583
|
+
* credential: bbsCredential,
|
|
584
|
+
* attributesToReveal: ['name', 'dateOfBirth']
|
|
585
|
+
* }]
|
|
586
|
+
* });
|
|
587
|
+
*/
|
|
296
588
|
async deriveVCFromPresentation(params) {
|
|
297
589
|
validation.deriveVCFromPresentation(params);
|
|
298
590
|
const { credentials, options = {}, proofRequest } = params;
|
|
@@ -323,7 +615,7 @@ class CredentialService {
|
|
|
323
615
|
const attributesToSkip = descriptorBounds[idx]
|
|
324
616
|
? descriptorBounds[idx].map(bound => bound.attributeName)
|
|
325
617
|
: [];
|
|
326
|
-
const filteredAttributes = attributesToReveal.filter(attribute => !attributesToSkip.includes(attribute));
|
|
618
|
+
const filteredAttributes = attributesToReveal.filter(attribute => !attributesToSkip.includes(attribute) && !shouldSkipAttribute(attribute));
|
|
327
619
|
const _pexRequiredAttributes = pexRequiredAttributes[idx] || [];
|
|
328
620
|
_pexRequiredAttributes.forEach(attr => {
|
|
329
621
|
if (!filteredAttributes.includes(attr)) {
|
|
@@ -346,10 +638,35 @@ class CredentialService {
|
|
|
346
638
|
const credentialsFromPresentation = await presentation.deriveCredentials(options);
|
|
347
639
|
return credentialsFromPresentation;
|
|
348
640
|
}
|
|
641
|
+
/**
|
|
642
|
+
* Test method for range proofs
|
|
643
|
+
* @private
|
|
644
|
+
* @returns {Promise<void>}
|
|
645
|
+
*/
|
|
349
646
|
async testRangeProof() {
|
|
350
647
|
console.log('test');
|
|
351
648
|
}
|
|
352
649
|
}
|
|
650
|
+
/**
|
|
651
|
+
* Singleton instance of the credential service
|
|
652
|
+
* @type {CredentialService}
|
|
653
|
+
* @example
|
|
654
|
+
* import { credentialService } from '@docknetwork/wallet-sdk-wasm/services/credential';
|
|
655
|
+
*
|
|
656
|
+
* // Create and sign a credential
|
|
657
|
+
* const credential = credentialService.generateCredential({
|
|
658
|
+
* subject: { id: 'did:example:123' }
|
|
659
|
+
* });
|
|
660
|
+
* const signed = await credentialService.signCredential({
|
|
661
|
+
* vcJson: credential,
|
|
662
|
+
* keyDoc: issuerKey
|
|
663
|
+
* });
|
|
664
|
+
*
|
|
665
|
+
* // Verify a credential
|
|
666
|
+
* const result = await credentialService.verifyCredential({
|
|
667
|
+
* credential: signedCredential
|
|
668
|
+
* });
|
|
669
|
+
*/
|
|
353
670
|
const credentialService = new CredentialService();
|
|
354
671
|
|
|
355
672
|
export { credentialService, isAnnonymousCredential, isBBSPlusCredential, isKvacCredential };
|