@dwn-protocol/id-sdk 0.2.5 → 0.2.6
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/package.json +2 -3
- package/src/agent/app-data-store.ts +0 -365
- package/src/agent/did-manager.ts +0 -393
- package/src/agent/dwn-manager.ts +0 -548
- package/src/agent/identity-manager.ts +0 -165
- package/src/agent/index.ts +0 -19
- package/src/agent/json-rpc.ts +0 -107
- package/src/agent/key-manager.ts +0 -302
- package/src/agent/kms-local.ts +0 -412
- package/src/agent/outbox.ts +0 -128
- package/src/agent/rpc-client.ts +0 -223
- package/src/agent/store-managed-did.ts +0 -295
- package/src/agent/store-managed-identity.ts +0 -243
- package/src/agent/store-managed-key.ts +0 -754
- package/src/agent/sync-manager.ts +0 -631
- package/src/agent/test-managed-agent.ts +0 -299
- package/src/agent/types/agent.ts +0 -145
- package/src/agent/types/managed-key.ts +0 -442
- package/src/agent/utils.ts +0 -190
- package/src/common/convert.ts +0 -424
- package/src/common/index.ts +0 -9
- package/src/common/multicodec.ts +0 -176
- package/src/common/object.ts +0 -43
- package/src/common/stores.ts +0 -125
- package/src/common/stream-node.ts +0 -381
- package/src/common/stream.ts +0 -406
- package/src/common/type-utils.ts +0 -117
- package/src/common/types.ts +0 -48
- package/src/credentials/credential-bbs.ts +0 -419
- package/src/credentials/credential.ts +0 -324
- package/src/credentials/index.ts +0 -5
- package/src/credentials/presentation.ts +0 -182
- package/src/credentials/status-list.ts +0 -365
- package/src/credentials/utils.ts +0 -58
- package/src/credentials/validators.ts +0 -52
- package/src/crypto/algorithms-api/aes/base.ts +0 -49
- package/src/crypto/algorithms-api/aes/ctr.ts +0 -51
- package/src/crypto/algorithms-api/aes/index.ts +0 -2
- package/src/crypto/algorithms-api/crypto-algorithm.ts +0 -127
- package/src/crypto/algorithms-api/crypto-key.ts +0 -56
- package/src/crypto/algorithms-api/ec/base.ts +0 -39
- package/src/crypto/algorithms-api/ec/ecdh.ts +0 -53
- package/src/crypto/algorithms-api/ec/ecdsa.ts +0 -37
- package/src/crypto/algorithms-api/ec/eddsa.ts +0 -30
- package/src/crypto/algorithms-api/ec/index.ts +0 -4
- package/src/crypto/algorithms-api/errors.ts +0 -29
- package/src/crypto/algorithms-api/index.ts +0 -6
- package/src/crypto/algorithms-api/pbkdf/index.ts +0 -1
- package/src/crypto/algorithms-api/pbkdf/pbkdf2.ts +0 -91
- package/src/crypto/crypto-algorithms/aes-ctr.ts +0 -70
- package/src/crypto/crypto-algorithms/bbs.ts +0 -110
- package/src/crypto/crypto-algorithms/ecdh.ts +0 -115
- package/src/crypto/crypto-algorithms/ecdsa.ts +0 -111
- package/src/crypto/crypto-algorithms/eddsa.ts +0 -110
- package/src/crypto/crypto-algorithms/index.ts +0 -6
- package/src/crypto/crypto-algorithms/pbkdf2.ts +0 -54
- package/src/crypto/crypto-primitives/aes-ctr.ts +0 -131
- package/src/crypto/crypto-primitives/aes-gcm.ts +0 -138
- package/src/crypto/crypto-primitives/bbs.ts +0 -183
- package/src/crypto/crypto-primitives/concat-kdf.ts +0 -207
- package/src/crypto/crypto-primitives/ed25519.ts +0 -201
- package/src/crypto/crypto-primitives/index.ts +0 -10
- package/src/crypto/crypto-primitives/pbkdf2.ts +0 -78
- package/src/crypto/crypto-primitives/secp256k1.ts +0 -322
- package/src/crypto/crypto-primitives/x25519.ts +0 -101
- package/src/crypto/crypto-primitives/xchacha20-poly1305.ts +0 -46
- package/src/crypto/crypto-primitives/xchacha20.ts +0 -34
- package/src/crypto/index.ts +0 -8
- package/src/crypto/jose.ts +0 -948
- package/src/crypto/types/crypto-key.ts +0 -4
- package/src/crypto/types/iddwn-crypto.ts +0 -119
- package/src/crypto/utils.ts +0 -200
- package/src/did-api.ts +0 -72
- package/src/dids/dht.ts +0 -412
- package/src/dids/did-dht.ts +0 -436
- package/src/dids/did-ion.ts +0 -613
- package/src/dids/did-key.ts +0 -791
- package/src/dids/did-resolver.ts +0 -107
- package/src/dids/index.ts +0 -9
- package/src/dids/resolver-cache-level.ts +0 -82
- package/src/dids/resolver-cache-noop.ts +0 -25
- package/src/dids/types.ts +0 -278
- package/src/dids/utils.ts +0 -129
- package/src/dwn-api.ts +0 -584
- package/src/iddwn.ts +0 -241
- package/src/identity-agent/index.ts +0 -270
- package/src/index.ts +0 -26
- package/src/interfaces/metadata.ts +0 -163
- package/src/interfaces/queue.ts +0 -108
- package/src/interfaces/services.ts +0 -122
- package/src/interfaces/transactions.ts +0 -220
- package/src/protocol.ts +0 -68
- package/src/proxy-agent/index.ts +0 -255
- package/src/record.ts +0 -521
- package/src/service-options.ts +0 -62
- package/src/typings/decentralized-identity__ion-pow-sdk.d.ts +0 -7
- package/src/user-agent/index.ts +0 -295
- package/src/utils.ts +0 -29
- package/src/vc-api.ts +0 -505
package/src/vc-api.ts
DELETED
|
@@ -1,505 +0,0 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
2
|
-
import type { IDAgent, IDManagedAgent } from './agent/index.js';
|
|
3
|
-
import type { DwnApi } from './dwn-api.js';
|
|
4
|
-
import type { DecodedVcJwt, Signer } from './credentials/credential.js';
|
|
5
|
-
import type { DecodedVpJwt, JwtHeaderParams } from './credentials/presentation.js';
|
|
6
|
-
import type { JwtDecodedVerifiablePresentation, PresentationSubmission } from '@sphereon/ssi-types';
|
|
7
|
-
import type { EvaluationResults, PresentationResult, Validated as PexValidated } from '@sphereon/pex';
|
|
8
|
-
import type { PresentationDefinitionV2 } from './credentials/presentation.js';
|
|
9
|
-
import type { VcDataModel } from './credentials/credential.js';
|
|
10
|
-
import type {
|
|
11
|
-
BbsSignOptions,
|
|
12
|
-
BbsDeriveProofOptions,
|
|
13
|
-
BbsCredentialCreateOptions,
|
|
14
|
-
BbsSignedCredentialBundle,
|
|
15
|
-
BbsDerivedCredential,
|
|
16
|
-
BbsVerifiableCredential,
|
|
17
|
-
} from './credentials/credential-bbs.js';
|
|
18
|
-
import type { BbsKeyPair } from './crypto/crypto-primitives/bbs.js';
|
|
19
|
-
import { Convert } from './common/index.js';
|
|
20
|
-
import { Ed25519, Bbs } from './crypto/index.js';
|
|
21
|
-
import { createJwt, decodeJwt, SignOptions, VerifiableCredential } from './credentials/credential.js';
|
|
22
|
-
import { BbsCredential } from './credentials/credential-bbs.js';
|
|
23
|
-
import { PresentationExchange } from './credentials/presentation.js';
|
|
24
|
-
import { StatusListManager, StatusPurpose } from './credentials/status-list.js';
|
|
25
|
-
import { v4 as uuidv4 } from 'uuid';
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* The VC API is used to issue, present and verify VCs
|
|
29
|
-
*
|
|
30
|
-
* @beta
|
|
31
|
-
*/
|
|
32
|
-
export class VcApi {
|
|
33
|
-
private agent: IDAgent;
|
|
34
|
-
private connectedDid: string;
|
|
35
|
-
private statusListManager?: StatusListManager;
|
|
36
|
-
private vcServiceUrl?: string;
|
|
37
|
-
|
|
38
|
-
constructor(options: {
|
|
39
|
-
agent: IDAgent,
|
|
40
|
-
connectedDid: string,
|
|
41
|
-
dwnApi?: DwnApi, // For SDK-native revocation
|
|
42
|
-
vcServiceUrl?: string, // For service-based revocation
|
|
43
|
-
}) {
|
|
44
|
-
this.agent = options.agent;
|
|
45
|
-
this.connectedDid = options.connectedDid;
|
|
46
|
-
if (options.dwnApi) {
|
|
47
|
-
this.statusListManager = new StatusListManager({
|
|
48
|
-
agent: options.agent,
|
|
49
|
-
connectedDid: options.connectedDid,
|
|
50
|
-
dwnApi: options.dwnApi
|
|
51
|
-
});
|
|
52
|
-
}
|
|
53
|
-
this.vcServiceUrl = options.vcServiceUrl;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
async createCredential(
|
|
57
|
-
issuer: string,
|
|
58
|
-
subject: string,
|
|
59
|
-
data: any,
|
|
60
|
-
type?: string,
|
|
61
|
-
): Promise<VerifiableCredential> {
|
|
62
|
-
const vc = VerifiableCredential.create({
|
|
63
|
-
issuer,
|
|
64
|
-
subject,
|
|
65
|
-
data,
|
|
66
|
-
type,
|
|
67
|
-
});
|
|
68
|
-
return vc;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
async signCredential(
|
|
72
|
-
vc: VerifiableCredential,
|
|
73
|
-
signOptions: SignOptions
|
|
74
|
-
): Promise<any> {
|
|
75
|
-
return await vc.sign(signOptions);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
async createJWT(
|
|
79
|
-
payload: any,
|
|
80
|
-
signOptions: SignOptions
|
|
81
|
-
): Promise<any> {
|
|
82
|
-
return await createJwt(payload, signOptions);
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
async decodeJWT(
|
|
86
|
-
jwt: string
|
|
87
|
-
): Promise<DecodedVcJwt> {
|
|
88
|
-
return decodeJwt(jwt);
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
async parseJWT(
|
|
92
|
-
jwt: string
|
|
93
|
-
): Promise<VerifiableCredential> {
|
|
94
|
-
return await VerifiableCredential.parseJwt(jwt);
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
async verifyJWT(
|
|
98
|
-
jwt: string
|
|
99
|
-
): Promise<boolean> {
|
|
100
|
-
try {
|
|
101
|
-
VerifiableCredential.verify(jwt);
|
|
102
|
-
return true;
|
|
103
|
-
} catch(e) {
|
|
104
|
-
console.log('verifyJWT error', e);
|
|
105
|
-
return false;
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
async createPresentation(
|
|
110
|
-
vcJwts: string[],
|
|
111
|
-
presentationDefinition: PresentationDefinitionV2
|
|
112
|
-
): Promise<PresentationResult> {
|
|
113
|
-
return PresentationExchange.createPresentationFromCredentials(vcJwts, presentationDefinition);
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
async satisfiesPresentation(
|
|
117
|
-
vcJwts: string[],
|
|
118
|
-
presentationDefinition: PresentationDefinitionV2
|
|
119
|
-
): Promise<boolean> {
|
|
120
|
-
try {
|
|
121
|
-
PresentationExchange.validateDefinition(presentationDefinition);
|
|
122
|
-
PresentationExchange.satisfiesPresentationDefinition(vcJwts, presentationDefinition);
|
|
123
|
-
return true;
|
|
124
|
-
} catch (err) {
|
|
125
|
-
return false;
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
async decodePresentation(
|
|
130
|
-
jwt: string
|
|
131
|
-
): Promise<DecodedVpJwt> {
|
|
132
|
-
const [encodedHeader, encodedPayload, encodedSignature] = jwt.split('.');
|
|
133
|
-
return {
|
|
134
|
-
header : Convert.base64Url(encodedHeader).toObject() as JwtHeaderParams,
|
|
135
|
-
payload : Convert.base64Url(encodedPayload).toObject() as JwtDecodedVerifiablePresentation,
|
|
136
|
-
signature : encodedSignature
|
|
137
|
-
};
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
async evaluatePresentation(
|
|
141
|
-
presentationDefinition: PresentationDefinitionV2,
|
|
142
|
-
presentationResult: any,
|
|
143
|
-
): Promise<EvaluationResults> {
|
|
144
|
-
return PresentationExchange.evaluatePresentation(presentationDefinition, presentationResult.presentation );
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
async validateSubmission(
|
|
148
|
-
presentationSubmission: PresentationSubmission,
|
|
149
|
-
): Promise<any> {
|
|
150
|
-
return PresentationExchange.validateSubmission(presentationSubmission);
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
EdDsaSigner(
|
|
154
|
-
privateKey: Uint8Array
|
|
155
|
-
): Signer {
|
|
156
|
-
return async (data: Uint8Array): Promise<Uint8Array> => {
|
|
157
|
-
const signature = await Ed25519.sign({ data, key: privateKey});
|
|
158
|
-
return signature;
|
|
159
|
-
};
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
/**
|
|
163
|
-
* Create a revocable credential with status list support
|
|
164
|
-
*
|
|
165
|
-
* @param options - Options for creating a revocable credential
|
|
166
|
-
* @returns Credential with status list information
|
|
167
|
-
*/
|
|
168
|
-
async createRevocableCredential(options: {
|
|
169
|
-
issuer: string;
|
|
170
|
-
subject: string;
|
|
171
|
-
data: any;
|
|
172
|
-
type?: string;
|
|
173
|
-
revocable?: boolean;
|
|
174
|
-
suspendable?: boolean;
|
|
175
|
-
signOptions: SignOptions;
|
|
176
|
-
}): Promise<{
|
|
177
|
-
credential: VerifiableCredential;
|
|
178
|
-
credentialJwt: string;
|
|
179
|
-
statusListCredential?: VerifiableCredential;
|
|
180
|
-
statusListJwt?: string;
|
|
181
|
-
statusListRecordId?: string;
|
|
182
|
-
credentialStatus?: any;
|
|
183
|
-
}> {
|
|
184
|
-
if (!this.statusListManager) {
|
|
185
|
-
throw new Error('StatusListManager not available. Provide dwnApi in VcApi constructor.');
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
const { issuer, subject, data, type, revocable, suspendable, signOptions } = options;
|
|
189
|
-
|
|
190
|
-
// Create base credential
|
|
191
|
-
const credential = await this.createCredential(issuer, subject, data, type);
|
|
192
|
-
|
|
193
|
-
// If revocable or suspendable, create or get status list
|
|
194
|
-
if (revocable || suspendable) {
|
|
195
|
-
const statusPurpose: StatusPurpose = revocable ? 'revocation' : 'suspension';
|
|
196
|
-
|
|
197
|
-
// Create a new status list (in production, you might want to reuse existing ones)
|
|
198
|
-
const { statusListCredential, statusListJwt, record } = await this.statusListManager.createStatusList({
|
|
199
|
-
issuer: issuer,
|
|
200
|
-
statusPurpose: statusPurpose,
|
|
201
|
-
signOptions: signOptions
|
|
202
|
-
});
|
|
203
|
-
|
|
204
|
-
// Generate a random index for this credential in the status list
|
|
205
|
-
// In production, you'd want to track this index properly
|
|
206
|
-
const statusListIndex = Math.floor(Math.random() * 100000); // Simplified - should be tracked
|
|
207
|
-
|
|
208
|
-
// Add credentialStatus to the credential
|
|
209
|
-
this.statusListManager.addCredentialStatus(
|
|
210
|
-
credential,
|
|
211
|
-
statusListCredential.vcDataModel.id!,
|
|
212
|
-
statusListIndex,
|
|
213
|
-
statusPurpose
|
|
214
|
-
);
|
|
215
|
-
|
|
216
|
-
// Sign the credential with status
|
|
217
|
-
const credentialJwt = await credential.sign(signOptions);
|
|
218
|
-
|
|
219
|
-
return {
|
|
220
|
-
credential,
|
|
221
|
-
credentialJwt,
|
|
222
|
-
statusListCredential,
|
|
223
|
-
statusListJwt,
|
|
224
|
-
statusListRecordId: record.id,
|
|
225
|
-
credentialStatus: credential.vcDataModel.credentialStatus
|
|
226
|
-
};
|
|
227
|
-
} else {
|
|
228
|
-
// Regular non-revocable credential
|
|
229
|
-
const credentialJwt = await credential.sign(signOptions);
|
|
230
|
-
return {
|
|
231
|
-
credential,
|
|
232
|
-
credentialJwt
|
|
233
|
-
};
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
/**
|
|
238
|
-
* Revoke a credential (SDK-native or via VC Service)
|
|
239
|
-
*
|
|
240
|
-
* @param options - Options for revoking the credential
|
|
241
|
-
* @returns Revocation result
|
|
242
|
-
*/
|
|
243
|
-
async revokeCredential(options: {
|
|
244
|
-
credentialId: string;
|
|
245
|
-
statusListRecordId?: string; // For SDK-native
|
|
246
|
-
statusListIndex?: number; // For SDK-native
|
|
247
|
-
useService?: boolean; // Use VC Service API instead
|
|
248
|
-
signOptions?: SignOptions; // Required for SDK-native
|
|
249
|
-
}): Promise<any> {
|
|
250
|
-
if (options.useService && this.vcServiceUrl) {
|
|
251
|
-
// Call VC Service API
|
|
252
|
-
return await this.revokeViaService(options.credentialId);
|
|
253
|
-
} else if (this.statusListManager && options.statusListRecordId && options.statusListIndex !== undefined && options.signOptions) {
|
|
254
|
-
// Use SDK-native revocation
|
|
255
|
-
return await this.statusListManager.revokeCredential({
|
|
256
|
-
credentialId: options.credentialId,
|
|
257
|
-
statusListRecordId: options.statusListRecordId,
|
|
258
|
-
statusListIndex: options.statusListIndex,
|
|
259
|
-
signOptions: options.signOptions
|
|
260
|
-
});
|
|
261
|
-
} else {
|
|
262
|
-
throw new Error('Either useService=true with vcServiceUrl, or statusListRecordId, statusListIndex, and signOptions must be provided for SDK-native revocation');
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
/**
|
|
267
|
-
* Suspend a credential (SDK-native or via VC Service)
|
|
268
|
-
*
|
|
269
|
-
* @param options - Options for suspending the credential
|
|
270
|
-
* @returns Suspension result
|
|
271
|
-
*/
|
|
272
|
-
async suspendCredential(options: {
|
|
273
|
-
credentialId: string;
|
|
274
|
-
statusListRecordId?: string; // For SDK-native
|
|
275
|
-
statusListIndex?: number; // For SDK-native
|
|
276
|
-
useService?: boolean; // Use VC Service API instead
|
|
277
|
-
signOptions?: SignOptions; // Required for SDK-native
|
|
278
|
-
}): Promise<any> {
|
|
279
|
-
if (options.useService && this.vcServiceUrl) {
|
|
280
|
-
// Call VC Service API (suspension via service)
|
|
281
|
-
return await this.suspendViaService(options.credentialId);
|
|
282
|
-
} else if (this.statusListManager && options.statusListRecordId && options.statusListIndex !== undefined && options.signOptions) {
|
|
283
|
-
// Use SDK-native suspension
|
|
284
|
-
return await this.statusListManager.suspendCredential({
|
|
285
|
-
credentialId: options.credentialId,
|
|
286
|
-
statusListRecordId: options.statusListRecordId,
|
|
287
|
-
statusListIndex: options.statusListIndex,
|
|
288
|
-
signOptions: options.signOptions
|
|
289
|
-
});
|
|
290
|
-
} else {
|
|
291
|
-
throw new Error('Either useService=true with vcServiceUrl, or statusListRecordId, statusListIndex, and signOptions must be provided for SDK-native suspension');
|
|
292
|
-
}
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
/**
|
|
296
|
-
* Check credential status
|
|
297
|
-
*
|
|
298
|
-
* @param options - Options for checking status
|
|
299
|
-
* @returns Status information
|
|
300
|
-
*/
|
|
301
|
-
async checkCredentialStatus(options: {
|
|
302
|
-
credentialId: string;
|
|
303
|
-
statusListCredentialId?: string;
|
|
304
|
-
statusListIndex?: number;
|
|
305
|
-
statusListRecordId?: string;
|
|
306
|
-
useService?: boolean;
|
|
307
|
-
}): Promise<{ revoked: boolean, suspended: boolean }> {
|
|
308
|
-
if (options.useService && this.vcServiceUrl) {
|
|
309
|
-
return await this.checkStatusViaService(options.credentialId);
|
|
310
|
-
} else if (options.statusListCredentialId && options.statusListIndex !== undefined && this.statusListManager) {
|
|
311
|
-
return await this.statusListManager.checkStatus({
|
|
312
|
-
statusListCredentialId: options.statusListCredentialId,
|
|
313
|
-
statusListIndex: options.statusListIndex,
|
|
314
|
-
statusListRecordId: options.statusListRecordId
|
|
315
|
-
});
|
|
316
|
-
} else {
|
|
317
|
-
throw new Error('Either useService=true with vcServiceUrl, or statusListCredentialId and statusListIndex must be provided');
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
/**
|
|
322
|
-
* Revoke via VC Service API
|
|
323
|
-
*/
|
|
324
|
-
private async revokeViaService(credentialId: string): Promise<any> {
|
|
325
|
-
if (!this.vcServiceUrl) {
|
|
326
|
-
throw new Error('vcServiceUrl not configured');
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
const response = await fetch(`${this.vcServiceUrl}/v1/credentials/${credentialId}/status`, {
|
|
330
|
-
method: 'PUT',
|
|
331
|
-
headers: { 'Content-Type': 'application/json' },
|
|
332
|
-
body: JSON.stringify({ revoked: true })
|
|
333
|
-
});
|
|
334
|
-
|
|
335
|
-
if (!response.ok) {
|
|
336
|
-
throw new Error(`VC Service API error: ${response.status} ${response.statusText}`);
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
return await response.json();
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
/**
|
|
343
|
-
* Suspend via VC Service API
|
|
344
|
-
*/
|
|
345
|
-
private async suspendViaService(credentialId: string): Promise<any> {
|
|
346
|
-
if (!this.vcServiceUrl) {
|
|
347
|
-
throw new Error('vcServiceUrl not configured');
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
const response = await fetch(`${this.vcServiceUrl}/v1/credentials/${credentialId}/status`, {
|
|
351
|
-
method: 'PUT',
|
|
352
|
-
headers: { 'Content-Type': 'application/json' },
|
|
353
|
-
body: JSON.stringify({ suspended: true })
|
|
354
|
-
});
|
|
355
|
-
|
|
356
|
-
if (!response.ok) {
|
|
357
|
-
throw new Error(`VC Service API error: ${response.status} ${response.statusText}`);
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
return await response.json();
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
/**
|
|
364
|
-
* Check status via VC Service API
|
|
365
|
-
*/
|
|
366
|
-
private async checkStatusViaService(credentialId: string): Promise<{ revoked: boolean, suspended: boolean }> {
|
|
367
|
-
if (!this.vcServiceUrl) {
|
|
368
|
-
throw new Error('vcServiceUrl not configured');
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
const response = await fetch(`${this.vcServiceUrl}/v1/credentials/${credentialId}/status`);
|
|
372
|
-
|
|
373
|
-
if (!response.ok) {
|
|
374
|
-
throw new Error(`VC Service API error: ${response.status} ${response.statusText}`);
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
return await response.json();
|
|
378
|
-
}
|
|
379
|
-
|
|
380
|
-
/**
|
|
381
|
-
* Helper to get signer options from agent
|
|
382
|
-
* This is a convenience method that can be used to get signer options
|
|
383
|
-
*/
|
|
384
|
-
async getSignerOptions(issuerDid: string, subjectDid: string): Promise<SignOptions> {
|
|
385
|
-
// Check if agent is IDManagedAgent (has didManager and dwnManager)
|
|
386
|
-
if (!('didManager' in this.agent) || !('dwnManager' in this.agent)) {
|
|
387
|
-
throw new Error('Agent must be an IDManagedAgent to get signer options');
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
const managedAgent = this.agent as IDManagedAgent;
|
|
391
|
-
|
|
392
|
-
// Get signing key ID from agent
|
|
393
|
-
const signingKeyId = await managedAgent.didManager.getDefaultSigningKey({ did: issuerDid });
|
|
394
|
-
|
|
395
|
-
if (!signingKeyId) {
|
|
396
|
-
throw new Error(`No signing key found for DID: ${issuerDid}`);
|
|
397
|
-
}
|
|
398
|
-
|
|
399
|
-
// Get the signer from agent
|
|
400
|
-
const signer = await managedAgent.dwnManager.getSigner(issuerDid);
|
|
401
|
-
|
|
402
|
-
return {
|
|
403
|
-
kid: signingKeyId,
|
|
404
|
-
issuerDid: issuerDid,
|
|
405
|
-
subjectDid: subjectDid,
|
|
406
|
-
signer: signer.sign
|
|
407
|
-
};
|
|
408
|
-
}
|
|
409
|
-
|
|
410
|
-
// ──────────────────────────────────────────────────────
|
|
411
|
-
// BBS+ Selective Disclosure Methods
|
|
412
|
-
// ──────────────────────────────────────────────────────
|
|
413
|
-
|
|
414
|
-
/**
|
|
415
|
-
* Generates a BLS12-381 G2 key pair for BBS+ signature operations.
|
|
416
|
-
*
|
|
417
|
-
* @returns A key pair with 96-byte publicKey and 32-byte secretKey.
|
|
418
|
-
*/
|
|
419
|
-
async generateBbsKeyPair(): Promise<BbsKeyPair> {
|
|
420
|
-
return Bbs.generateKeyPair();
|
|
421
|
-
}
|
|
422
|
-
|
|
423
|
-
/**
|
|
424
|
-
* Creates a Verifiable Credential data model prepared for BBS+ signing.
|
|
425
|
-
* Each attribute in `data` will become a separately-signable BBS+ message.
|
|
426
|
-
*/
|
|
427
|
-
async createBbsCredential(
|
|
428
|
-
options: BbsCredentialCreateOptions
|
|
429
|
-
): Promise<VcDataModel> {
|
|
430
|
-
return BbsCredential.create(options);
|
|
431
|
-
}
|
|
432
|
-
|
|
433
|
-
/**
|
|
434
|
-
* Signs a credential with BBS+ producing a Data Integrity proof.
|
|
435
|
-
* The credential subject attributes are signed as individual BBS+ messages,
|
|
436
|
-
* enabling per-attribute selective disclosure.
|
|
437
|
-
*
|
|
438
|
-
* @param vc - The VC data model to sign.
|
|
439
|
-
* @param signOptions - BBS+ signing options including the key pair.
|
|
440
|
-
* @returns A bundle containing the signed credential, attribute key order, and signature.
|
|
441
|
-
*/
|
|
442
|
-
async signBbsCredential(
|
|
443
|
-
vc: VcDataModel,
|
|
444
|
-
signOptions: BbsSignOptions
|
|
445
|
-
): Promise<BbsSignedCredentialBundle> {
|
|
446
|
-
return BbsCredential.sign(vc, signOptions);
|
|
447
|
-
}
|
|
448
|
-
|
|
449
|
-
/**
|
|
450
|
-
* Verifies a full BBS+ signed credential against the issuer's public key.
|
|
451
|
-
*
|
|
452
|
-
* @param credential - The BBS+ signed credential.
|
|
453
|
-
* @param issuerPublicKey - The issuer's 96-byte BLS12-381 G2 public key.
|
|
454
|
-
*/
|
|
455
|
-
async verifyBbsCredential(
|
|
456
|
-
credential: BbsVerifiableCredential,
|
|
457
|
-
issuerPublicKey: Uint8Array
|
|
458
|
-
): Promise<boolean> {
|
|
459
|
-
return BbsCredential.verify(credential, issuerPublicKey);
|
|
460
|
-
}
|
|
461
|
-
|
|
462
|
-
/**
|
|
463
|
-
* Derives a zero-knowledge selective disclosure proof from a BBS+ signed
|
|
464
|
-
* credential. The result contains only the chosen attributes and a proof
|
|
465
|
-
* that the holder possesses a valid signature over the full attribute set.
|
|
466
|
-
*
|
|
467
|
-
* @param bundle - The signed credential bundle (from signBbsCredential).
|
|
468
|
-
* @param options - Which attributes to reveal and a session nonce.
|
|
469
|
-
*/
|
|
470
|
-
async deriveBbsSelectiveProof(
|
|
471
|
-
bundle: BbsSignedCredentialBundle,
|
|
472
|
-
options: BbsDeriveProofOptions
|
|
473
|
-
): Promise<BbsDerivedCredential> {
|
|
474
|
-
return BbsCredential.deriveProof(bundle, options);
|
|
475
|
-
}
|
|
476
|
-
|
|
477
|
-
/**
|
|
478
|
-
* Verifies a BBS+ selective disclosure proof. The verifier only sees the
|
|
479
|
-
* disclosed attributes but can cryptographically confirm they originate
|
|
480
|
-
* from a valid credential signed by the issuer.
|
|
481
|
-
*
|
|
482
|
-
* @param credential - The derived credential with selective disclosure proof.
|
|
483
|
-
* @param issuerPublicKey - The issuer's 96-byte BLS12-381 G2 public key.
|
|
484
|
-
*/
|
|
485
|
-
async verifyBbsSelectiveProof(
|
|
486
|
-
credential: BbsVerifiableCredential,
|
|
487
|
-
issuerPublicKey: Uint8Array
|
|
488
|
-
): Promise<boolean> {
|
|
489
|
-
return BbsCredential.verifyProof(credential, issuerPublicKey);
|
|
490
|
-
}
|
|
491
|
-
|
|
492
|
-
/**
|
|
493
|
-
* Resolves the BBS+ public key from an issuer's DID document.
|
|
494
|
-
*
|
|
495
|
-
* @param issuerDid - The issuer's DID.
|
|
496
|
-
* @param kid - Optional key ID to match a specific verification method.
|
|
497
|
-
*/
|
|
498
|
-
async resolveIssuerBbsPublicKey(
|
|
499
|
-
issuerDid: string,
|
|
500
|
-
kid?: string
|
|
501
|
-
): Promise<Uint8Array | null> {
|
|
502
|
-
return BbsCredential.resolveIssuerPublicKey(issuerDid, kid);
|
|
503
|
-
}
|
|
504
|
-
|
|
505
|
-
}
|