@sphereon/ssi-sdk.linked-vp 0.34.1-feature.SSISDK.82.linkedVP.325

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js ADDED
@@ -0,0 +1,442 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
3
+
4
+ // plugin.schema.json
5
+ var plugin_schema_default = {
6
+ ILinkedVPManager: {
7
+ components: {
8
+ schemas: {
9
+ GeneratePresentationArgs: {
10
+ type: "object",
11
+ properties: {
12
+ linkedVpId: {
13
+ type: "string"
14
+ }
15
+ },
16
+ required: [
17
+ "linkedVpId"
18
+ ],
19
+ additionalProperties: false
20
+ },
21
+ LinkedVPPresentation: {
22
+ anyOf: [
23
+ {
24
+ type: "string"
25
+ },
26
+ {
27
+ $ref: "#/components/schemas/Record<string,any>"
28
+ }
29
+ ]
30
+ },
31
+ "Record<string,any>": {
32
+ type: "object"
33
+ },
34
+ GetServiceEntriesArgs: {
35
+ type: "object",
36
+ properties: {
37
+ tenantId: {
38
+ type: "string"
39
+ }
40
+ },
41
+ additionalProperties: false
42
+ },
43
+ LinkedVPServiceEntry: {
44
+ type: "object",
45
+ properties: {
46
+ id: {
47
+ type: "string"
48
+ },
49
+ type: {
50
+ type: "string",
51
+ const: "LinkedVerifiablePresentation"
52
+ },
53
+ serviceEndpoint: {
54
+ type: "string"
55
+ }
56
+ },
57
+ required: [
58
+ "id",
59
+ "type",
60
+ "serviceEndpoint"
61
+ ],
62
+ additionalProperties: false
63
+ },
64
+ HasLinkedVPEntryArgs: {
65
+ type: "object",
66
+ properties: {
67
+ linkedVpId: {
68
+ type: "string"
69
+ }
70
+ },
71
+ required: [
72
+ "linkedVpId"
73
+ ],
74
+ additionalProperties: false
75
+ },
76
+ PublishCredentialArgs: {
77
+ type: "object",
78
+ properties: {
79
+ digitalCredentialId: {
80
+ type: "string"
81
+ },
82
+ linkedVpId: {
83
+ type: "string"
84
+ },
85
+ tenantId: {
86
+ type: "string"
87
+ }
88
+ },
89
+ required: [
90
+ "digitalCredentialId"
91
+ ],
92
+ additionalProperties: false
93
+ },
94
+ LinkedVPEntry: {
95
+ type: "object",
96
+ properties: {
97
+ id: {
98
+ type: "string"
99
+ },
100
+ linkedVpId: {
101
+ type: "string"
102
+ },
103
+ tenantId: {
104
+ type: "string"
105
+ },
106
+ linkedVpFrom: {
107
+ type: "string",
108
+ format: "date-time"
109
+ },
110
+ createdAt: {
111
+ type: "string",
112
+ format: "date-time"
113
+ }
114
+ },
115
+ required: [
116
+ "id",
117
+ "linkedVpId",
118
+ "createdAt"
119
+ ],
120
+ additionalProperties: false
121
+ },
122
+ UnpublishCredentialArgs: {
123
+ type: "object",
124
+ properties: {
125
+ linkedVpId: {
126
+ type: "string"
127
+ }
128
+ },
129
+ required: [
130
+ "linkedVpId"
131
+ ],
132
+ additionalProperties: false
133
+ }
134
+ },
135
+ methods: {
136
+ lvpGeneratePresentation: {
137
+ description: "Generate and return a Verifiable Presentation for a published LinkedVP This is the main endpoint handler for GET /linked-vp/",
138
+ arguments: {
139
+ $ref: "#/components/schemas/GeneratePresentationArgs"
140
+ },
141
+ returnType: {
142
+ $ref: "#/components/schemas/LinkedVPPresentation"
143
+ }
144
+ },
145
+ lvpGetServiceEntries: {
146
+ description: "Get LinkedVP service entries for a DID to be added to a DID Document This is useful when generating DID Documents with toDidDocument",
147
+ arguments: {
148
+ $ref: "#/components/schemas/GetServiceEntriesArgs"
149
+ },
150
+ returnType: {
151
+ type: "array",
152
+ items: {
153
+ $ref: "#/components/schemas/LinkedVPServiceEntry"
154
+ }
155
+ }
156
+ },
157
+ lvpHasEntry: {
158
+ description: "Check if a LinkedVP entry exists by linkedVpId",
159
+ arguments: {
160
+ $ref: "#/components/schemas/HasLinkedVPEntryArgs"
161
+ },
162
+ returnType: {
163
+ type: "boolean"
164
+ }
165
+ },
166
+ lvpPublishCredential: {
167
+ description: "Publish a credential as a LinkedVP by adding it to the holder's DID Document",
168
+ arguments: {
169
+ $ref: "#/components/schemas/PublishCredentialArgs"
170
+ },
171
+ returnType: {
172
+ $ref: "#/components/schemas/LinkedVPEntry"
173
+ }
174
+ },
175
+ lvpUnpublishCredential: {
176
+ description: "Unpublish a credential by removing its LinkedVP entry from the DID Document",
177
+ arguments: {
178
+ $ref: "#/components/schemas/UnpublishCredentialArgs"
179
+ },
180
+ returnType: {
181
+ type: "boolean"
182
+ }
183
+ }
184
+ }
185
+ }
186
+ }
187
+ };
188
+
189
+ // src/agent/LinkedVPManager.ts
190
+ import { IsNull, Not } from "typeorm";
191
+
192
+ // src/services/LinkedVPService.ts
193
+ import { Loggers } from "@sphereon/ssi-types";
194
+
195
+ // src/types/ILinkedVPManager.ts
196
+ var LOGGER_NAMESPACE = "sphereon:linked-vp";
197
+
198
+ // src/services/LinkedVPService.ts
199
+ var logger = Loggers.DEFAULT.get(LOGGER_NAMESPACE);
200
+ function extractOriginalCredential(credential) {
201
+ if (typeof credential === "string") {
202
+ return credential;
203
+ }
204
+ if ("digitalCredential" in credential) {
205
+ const udc = credential;
206
+ if (udc.originalVerifiableCredential) {
207
+ return udc.originalVerifiableCredential;
208
+ }
209
+ return udc.uniformVerifiableCredential;
210
+ }
211
+ if ("original" in credential) {
212
+ return credential.original;
213
+ }
214
+ return credential;
215
+ }
216
+ __name(extractOriginalCredential, "extractOriginalCredential");
217
+ async function createLinkedVPPresentation(holderDid, credentials, agent) {
218
+ if (credentials.length === 0) {
219
+ return Promise.reject(Error("Cannot create LinkedVP presentation with zero credentials"));
220
+ }
221
+ logger.debug(`Creating LinkedVP presentation for ${holderDid} with ${credentials.length} credentials`);
222
+ const identifier = await agent.identifierManagedGet({
223
+ identifier: holderDid
224
+ });
225
+ const verifiableCredentials = credentials.map((credential) => {
226
+ const original = extractOriginalCredential(credential);
227
+ return typeof original === "string" ? original : original;
228
+ });
229
+ const vpObject = {
230
+ "@context": [
231
+ "https://www.w3.org/2018/credentials/v1"
232
+ ],
233
+ type: [
234
+ "VerifiablePresentation"
235
+ ],
236
+ holder: holderDid,
237
+ verifiableCredential: verifiableCredentials
238
+ };
239
+ const result = await agent.createVerifiablePresentation({
240
+ presentation: vpObject,
241
+ proofFormat: "jwt",
242
+ keyRef: identifier.kmsKeyRef || identifier.kid
243
+ });
244
+ if (typeof result === "string") {
245
+ return result;
246
+ }
247
+ if (result.proof && "jws" in result.proof) {
248
+ return result.proof.jws;
249
+ }
250
+ return Promise.reject(Error("Failed to create JWT VP - no JWT in result"));
251
+ }
252
+ __name(createLinkedVPPresentation, "createLinkedVPPresentation");
253
+
254
+ // src/agent/LinkedVPManager.ts
255
+ var linkedVPManagerMethods = [
256
+ "lvpPublishCredential",
257
+ "lvpUnpublishCredential",
258
+ "lvpHasEntry",
259
+ "lvpGetServiceEntries",
260
+ "lvpGeneratePresentation"
261
+ ];
262
+ var LinkedVPManager = class {
263
+ static {
264
+ __name(this, "LinkedVPManager");
265
+ }
266
+ schema = plugin_schema_default.ILinkedVPManager;
267
+ methods = {
268
+ lvpPublishCredential: this.lvpPublishCredential.bind(this),
269
+ lvpUnpublishCredential: this.lvpUnpublishCredential.bind(this),
270
+ lvpHasEntry: this.lvpHasEntry.bind(this),
271
+ lvpGetServiceEntries: this.lvpGetServiceEntries.bind(this),
272
+ lvpGeneratePresentation: this.lvpGeneratePresentation.bind(this)
273
+ };
274
+ holderDids;
275
+ constructor(options) {
276
+ this.holderDids = options.holderDids;
277
+ }
278
+ async lvpPublishCredential(args, context) {
279
+ const { digitalCredentialId } = args;
280
+ const credential = await context.agent.crsGetCredential({
281
+ id: digitalCredentialId
282
+ });
283
+ if (credential.linkedVpId) {
284
+ return Promise.reject(new Error(`Credential ${digitalCredentialId} is already published with linkedVpId ${credential.linkedVpId}`));
285
+ }
286
+ const linkedVpId = this.buildLinkedVpId(args.linkedVpId, credential.tenantId);
287
+ await this.ensureLinkedVpIdUnique(linkedVpId, context, credential.tenantId);
288
+ const publishedAt = /* @__PURE__ */ new Date();
289
+ await context.agent.crsUpdateCredential({
290
+ id: digitalCredentialId,
291
+ linkedVpId,
292
+ linkedVpFrom: publishedAt
293
+ });
294
+ return {
295
+ id: credential.id,
296
+ linkedVpId,
297
+ tenantId: credential.tenantId,
298
+ linkedVpFrom: publishedAt,
299
+ createdAt: credential.createdAt
300
+ };
301
+ }
302
+ async lvpUnpublishCredential(args, context) {
303
+ const { linkedVpId } = args;
304
+ const credentials = await context.agent.crsGetCredentials({
305
+ filter: [
306
+ {
307
+ linkedVpId
308
+ }
309
+ ]
310
+ });
311
+ if (credentials.length === 0) {
312
+ return Promise.reject(Error(`No credential found with linkedVpId ${linkedVpId}`));
313
+ }
314
+ const credential = credentials[0];
315
+ await context.agent.crsUpdateCredential({
316
+ id: credential.id,
317
+ linkedVpId: void 0,
318
+ linkedVpFrom: void 0
319
+ });
320
+ return true;
321
+ }
322
+ async lvpHasEntry(args, context) {
323
+ const { linkedVpId } = args;
324
+ try {
325
+ const credentials = await context.agent.crsGetCredentials({
326
+ filter: [
327
+ {
328
+ linkedVpId
329
+ }
330
+ ]
331
+ });
332
+ return credentials.length > 0;
333
+ } catch (error) {
334
+ return false;
335
+ }
336
+ }
337
+ async lvpGetServiceEntries(args, context) {
338
+ const { tenantId } = args;
339
+ const filter = {
340
+ linkedVpId: Not(IsNull())
341
+ };
342
+ if (tenantId) {
343
+ filter.tenantId = tenantId;
344
+ }
345
+ const credentials = await context.agent.crsGetCredentials({
346
+ filter: [
347
+ filter
348
+ ]
349
+ });
350
+ return credentials.filter((cred) => cred.linkedVpId !== void 0 && cred.linkedVpId !== null).map((cred) => {
351
+ const holderDidForEntry = this.getHolderDid(cred.tenantId);
352
+ return this.credentialToServiceEntry(cred, holderDidForEntry);
353
+ });
354
+ }
355
+ async lvpGeneratePresentation(args, context) {
356
+ const { linkedVpId } = args;
357
+ const tenantId = this.parseTenantFromLinkedVpId(linkedVpId);
358
+ const holderDid = this.getHolderDid(tenantId);
359
+ const uniqueCredentials = await context.agent.crsGetUniqueCredentials({
360
+ filter: [
361
+ {
362
+ linkedVpId: args.linkedVpId,
363
+ ...tenantId && {
364
+ tenantId
365
+ }
366
+ }
367
+ ]
368
+ });
369
+ if (uniqueCredentials.length === 0) {
370
+ return Promise.reject(Error(`No published credentials found for linkedVpId ${linkedVpId}`));
371
+ }
372
+ return createLinkedVPPresentation(holderDid, uniqueCredentials, context.agent);
373
+ }
374
+ getHolderDid(tenantId) {
375
+ const holderDid = this.holderDids[tenantId ?? "default"];
376
+ if (!holderDid) {
377
+ throw Error(`No holder did supplied for tenant ${tenantId ?? "default"}`);
378
+ }
379
+ return holderDid;
380
+ }
381
+ parseTenantFromLinkedVpId(linkedVpId) {
382
+ const idx = linkedVpId.lastIndexOf("@");
383
+ return idx === -1 ? void 0 : linkedVpId.substring(idx + 1);
384
+ }
385
+ generateLinkedVpId() {
386
+ return `lvp-${Date.now()}-${Math.random().toString(36).substring(2, 15)}`;
387
+ }
388
+ async ensureLinkedVpIdUnique(linkedVpId, context, tenantId) {
389
+ const credentials = await context.agent.crsGetCredentials({
390
+ filter: [
391
+ {
392
+ linkedVpId,
393
+ ...tenantId && {
394
+ tenantId
395
+ }
396
+ }
397
+ ]
398
+ });
399
+ if (credentials.length > 0) {
400
+ throw new Error(`LinkedVP ID ${linkedVpId} already exists${tenantId ? ` for tenant ${tenantId}` : ""}`);
401
+ }
402
+ }
403
+ buildLinkedVpId(linkedVpId, tenantId) {
404
+ let finalLinkedVpId = linkedVpId || this.generateLinkedVpId();
405
+ if (tenantId && tenantId !== "" && !finalLinkedVpId.includes("@")) {
406
+ finalLinkedVpId = `${finalLinkedVpId}@${tenantId}`;
407
+ }
408
+ return finalLinkedVpId;
409
+ }
410
+ getBaseUrlFromDid(holderDid) {
411
+ if (!holderDid.startsWith("did:web:")) {
412
+ throw new Error(`Invalid DID: ${holderDid}, must be did:web`);
413
+ }
414
+ const withoutPrefix = holderDid.replace("did:web:", "");
415
+ const parts = withoutPrefix.split(":");
416
+ const domain = parts.shift();
417
+ const path = parts.join("/");
418
+ return path ? `https://${domain}/${path}` : `https://${domain}`;
419
+ }
420
+ buildServiceEndpoint(holderDid, linkedVpId) {
421
+ const baseUrl = this.getBaseUrlFromDid(holderDid);
422
+ const cleanBaseUrl = baseUrl.endsWith("/") ? baseUrl.slice(0, -1) : baseUrl;
423
+ return `${cleanBaseUrl}/linked-vp/${linkedVpId}`;
424
+ }
425
+ credentialToServiceEntry(credential, holderDid) {
426
+ if (!credential.linkedVpId) {
427
+ throw new Error(`Credential ${credential.id} does not have a linkedVpId`);
428
+ }
429
+ return {
430
+ id: `${holderDid}#${credential.linkedVpId}`,
431
+ type: "LinkedVerifiablePresentation",
432
+ serviceEndpoint: this.buildServiceEndpoint(holderDid, credential.linkedVpId)
433
+ };
434
+ }
435
+ };
436
+ export {
437
+ LOGGER_NAMESPACE,
438
+ LinkedVPManager,
439
+ linkedVPManagerMethods,
440
+ plugin_schema_default as schema
441
+ };
442
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../plugin.schema.json","../src/agent/LinkedVPManager.ts","../src/services/LinkedVPService.ts","../src/types/ILinkedVPManager.ts"],"sourcesContent":["{\n \"ILinkedVPManager\": {\n \"components\": {\n \"schemas\": {\n \"GeneratePresentationArgs\": {\n \"type\": \"object\",\n \"properties\": {\n \"linkedVpId\": {\n \"type\": \"string\"\n }\n },\n \"required\": [\n \"linkedVpId\"\n ],\n \"additionalProperties\": false\n },\n \"LinkedVPPresentation\": {\n \"anyOf\": [\n {\n \"type\": \"string\"\n },\n {\n \"$ref\": \"#/components/schemas/Record<string,any>\"\n }\n ]\n },\n \"Record<string,any>\": {\n \"type\": \"object\"\n },\n \"GetServiceEntriesArgs\": {\n \"type\": \"object\",\n \"properties\": {\n \"tenantId\": {\n \"type\": \"string\"\n }\n },\n \"additionalProperties\": false\n },\n \"LinkedVPServiceEntry\": {\n \"type\": \"object\",\n \"properties\": {\n \"id\": {\n \"type\": \"string\"\n },\n \"type\": {\n \"type\": \"string\",\n \"const\": \"LinkedVerifiablePresentation\"\n },\n \"serviceEndpoint\": {\n \"type\": \"string\"\n }\n },\n \"required\": [\n \"id\",\n \"type\",\n \"serviceEndpoint\"\n ],\n \"additionalProperties\": false\n },\n \"HasLinkedVPEntryArgs\": {\n \"type\": \"object\",\n \"properties\": {\n \"linkedVpId\": {\n \"type\": \"string\"\n }\n },\n \"required\": [\n \"linkedVpId\"\n ],\n \"additionalProperties\": false\n },\n \"PublishCredentialArgs\": {\n \"type\": \"object\",\n \"properties\": {\n \"digitalCredentialId\": {\n \"type\": \"string\"\n },\n \"linkedVpId\": {\n \"type\": \"string\"\n },\n \"tenantId\": {\n \"type\": \"string\"\n }\n },\n \"required\": [\n \"digitalCredentialId\"\n ],\n \"additionalProperties\": false\n },\n \"LinkedVPEntry\": {\n \"type\": \"object\",\n \"properties\": {\n \"id\": {\n \"type\": \"string\"\n },\n \"linkedVpId\": {\n \"type\": \"string\"\n },\n \"tenantId\": {\n \"type\": \"string\"\n },\n \"linkedVpFrom\": {\n \"type\": \"string\",\n \"format\": \"date-time\"\n },\n \"createdAt\": {\n \"type\": \"string\",\n \"format\": \"date-time\"\n }\n },\n \"required\": [\n \"id\",\n \"linkedVpId\",\n \"createdAt\"\n ],\n \"additionalProperties\": false\n },\n \"UnpublishCredentialArgs\": {\n \"type\": \"object\",\n \"properties\": {\n \"linkedVpId\": {\n \"type\": \"string\"\n }\n },\n \"required\": [\n \"linkedVpId\"\n ],\n \"additionalProperties\": false\n }\n },\n \"methods\": {\n \"lvpGeneratePresentation\": {\n \"description\": \"Generate and return a Verifiable Presentation for a published LinkedVP This is the main endpoint handler for GET /linked-vp/\",\n \"arguments\": {\n \"$ref\": \"#/components/schemas/GeneratePresentationArgs\"\n },\n \"returnType\": {\n \"$ref\": \"#/components/schemas/LinkedVPPresentation\"\n }\n },\n \"lvpGetServiceEntries\": {\n \"description\": \"Get LinkedVP service entries for a DID to be added to a DID Document This is useful when generating DID Documents with toDidDocument\",\n \"arguments\": {\n \"$ref\": \"#/components/schemas/GetServiceEntriesArgs\"\n },\n \"returnType\": {\n \"type\": \"array\",\n \"items\": {\n \"$ref\": \"#/components/schemas/LinkedVPServiceEntry\"\n }\n }\n },\n \"lvpHasEntry\": {\n \"description\": \"Check if a LinkedVP entry exists by linkedVpId\",\n \"arguments\": {\n \"$ref\": \"#/components/schemas/HasLinkedVPEntryArgs\"\n },\n \"returnType\": {\n \"type\": \"boolean\"\n }\n },\n \"lvpPublishCredential\": {\n \"description\": \"Publish a credential as a LinkedVP by adding it to the holder's DID Document\",\n \"arguments\": {\n \"$ref\": \"#/components/schemas/PublishCredentialArgs\"\n },\n \"returnType\": {\n \"$ref\": \"#/components/schemas/LinkedVPEntry\"\n }\n },\n \"lvpUnpublishCredential\": {\n \"description\": \"Unpublish a credential by removing its LinkedVP entry from the DID Document\",\n \"arguments\": {\n \"$ref\": \"#/components/schemas/UnpublishCredentialArgs\"\n },\n \"returnType\": {\n \"type\": \"boolean\"\n }\n }\n }\n }\n }\n}","import { DigitalCredential } from '@sphereon/ssi-sdk.data-store-types'\nimport { IAgentPlugin } from '@veramo/core'\nimport { IsNull, Not } from 'typeorm'\nimport { schema } from '../index'\nimport { createLinkedVPPresentation } from '../services/LinkedVPService'\nimport {\n GeneratePresentationArgs,\n GetServiceEntriesArgs,\n HasLinkedVPEntryArgs,\n ILinkedVPManager,\n LinkedVPEntry,\n LinkedVPPresentation,\n LinkedVPServiceEntry,\n PublishCredentialArgs,\n RequiredContext,\n UnpublishCredentialArgs,\n} from '../types'\n\n// Exposing the methods here for any REST implementation\nexport const linkedVPManagerMethods: Array<string> = [\n 'lvpPublishCredential',\n 'lvpUnpublishCredential',\n 'lvpHasEntry',\n 'lvpGetServiceEntries',\n 'lvpGeneratePresentation',\n]\n\n/**\n * {@inheritDoc ILinkedVPManager}\n */\nexport class LinkedVPManager implements IAgentPlugin {\n readonly schema = schema.ILinkedVPManager\n readonly methods: ILinkedVPManager = {\n lvpPublishCredential: this.lvpPublishCredential.bind(this),\n lvpUnpublishCredential: this.lvpUnpublishCredential.bind(this),\n lvpHasEntry: this.lvpHasEntry.bind(this),\n lvpGetServiceEntries: this.lvpGetServiceEntries.bind(this),\n lvpGeneratePresentation: this.lvpGeneratePresentation.bind(this),\n }\n\n private readonly holderDids: Record<string, string>\n\n constructor(options: { holderDids: Record<string, string> }) {\n this.holderDids = options.holderDids\n }\n\n private async lvpPublishCredential(args: PublishCredentialArgs, context: RequiredContext): Promise<LinkedVPEntry> {\n const { digitalCredentialId } = args\n\n const credential: DigitalCredential = await context.agent.crsGetCredential({ id: digitalCredentialId })\n\n if (credential.linkedVpId) {\n return Promise.reject(new Error(`Credential ${digitalCredentialId} is already published with linkedVpId ${credential.linkedVpId}`))\n }\n\n const linkedVpId = this.buildLinkedVpId(args.linkedVpId, credential.tenantId)\n\n await this.ensureLinkedVpIdUnique(linkedVpId, context, credential.tenantId)\n\n const publishedAt = new Date()\n await context.agent.crsUpdateCredential({\n id: digitalCredentialId,\n linkedVpId,\n linkedVpFrom: publishedAt,\n })\n\n return {\n id: credential.id,\n linkedVpId,\n tenantId: credential.tenantId,\n linkedVpFrom: publishedAt,\n createdAt: credential.createdAt,\n }\n }\n\n private async lvpUnpublishCredential(args: UnpublishCredentialArgs, context: RequiredContext): Promise<boolean> {\n const { linkedVpId } = args\n\n // Find credential by linkedVpId and tenantId\n const credentials = await context.agent.crsGetCredentials({\n filter: [{ linkedVpId }],\n })\n if (credentials.length === 0) {\n return Promise.reject(Error(`No credential found with linkedVpId ${linkedVpId}`))\n }\n\n const credential = credentials[0]\n await context.agent.crsUpdateCredential({\n id: credential.id,\n linkedVpId: undefined,\n linkedVpFrom: undefined,\n })\n\n return true\n }\n\n private async lvpHasEntry(args: HasLinkedVPEntryArgs, context: RequiredContext): Promise<boolean> {\n const { linkedVpId } = args\n\n try {\n const credentials = await context.agent.crsGetCredentials({\n filter: [{ linkedVpId }],\n })\n return credentials.length > 0\n } catch (error) {\n return false\n }\n }\n\n private async lvpGetServiceEntries(args: GetServiceEntriesArgs, context: RequiredContext): Promise<Array<LinkedVPServiceEntry>> {\n const { tenantId } = args\n\n // Get all published credentials (credentials with linkedVpId set)\n const filter: any = { linkedVpId: Not(IsNull()) }\n if (tenantId) {\n filter.tenantId = tenantId\n }\n\n const credentials = await context.agent.crsGetCredentials({\n filter: [filter],\n })\n\n return credentials\n .filter((cred) => cred.linkedVpId !== undefined && cred.linkedVpId !== null)\n .map((cred) => {\n const holderDidForEntry = this.getHolderDid(cred.tenantId)\n return this.credentialToServiceEntry(cred, holderDidForEntry)\n })\n }\n\n private async lvpGeneratePresentation(args: GeneratePresentationArgs, context: RequiredContext): Promise<LinkedVPPresentation> {\n const { linkedVpId } = args\n const tenantId = this.parseTenantFromLinkedVpId(linkedVpId)\n const holderDid = this.getHolderDid(tenantId)\n\n const uniqueCredentials = await context.agent.crsGetUniqueCredentials({\n filter: [\n {\n linkedVpId: args.linkedVpId,\n ...(tenantId && { tenantId }),\n },\n ],\n })\n if (uniqueCredentials.length === 0) {\n return Promise.reject(Error(`No published credentials found for linkedVpId ${linkedVpId}`))\n }\n\n // Generate the Verifiable Presentation with all published credentials\n return createLinkedVPPresentation(holderDid, uniqueCredentials, context.agent)\n }\n\n private getHolderDid(tenantId: string | undefined) {\n const holderDid = this.holderDids[tenantId ?? 'default']\n if (!holderDid) {\n throw Error(`No holder did supplied for tenant ${tenantId ?? 'default'}`)\n }\n return holderDid\n }\n\n private parseTenantFromLinkedVpId(linkedVpId: string): string | undefined {\n const idx = linkedVpId.lastIndexOf('@')\n return idx === -1 ? undefined : linkedVpId.substring(idx + 1)\n }\n\n private generateLinkedVpId(): string {\n return `lvp-${Date.now()}-${Math.random().toString(36).substring(2, 15)}`\n }\n\n private async ensureLinkedVpIdUnique(linkedVpId: string, context: RequiredContext, tenantId?: string): Promise<void> {\n const credentials = await context.agent.crsGetCredentials({\n filter: [{ linkedVpId, ...(tenantId && { tenantId }) }],\n })\n\n if (credentials.length > 0) {\n throw new Error(`LinkedVP ID ${linkedVpId} already exists${tenantId ? ` for tenant ${tenantId}` : ''}`)\n }\n }\n\n private buildLinkedVpId(linkedVpId: string | undefined, tenantId: string | undefined) {\n let finalLinkedVpId = linkedVpId || this.generateLinkedVpId()\n\n // Append tenantId if provided and not already present\n if (tenantId && tenantId !== '' && !finalLinkedVpId.includes('@')) {\n finalLinkedVpId = `${finalLinkedVpId}@${tenantId}`\n }\n return finalLinkedVpId\n }\n\n private getBaseUrlFromDid(holderDid: string): string {\n if (!holderDid.startsWith('did:web:')) {\n throw new Error(`Invalid DID: ${holderDid}, must be did:web`)\n }\n\n const withoutPrefix = holderDid.replace('did:web:', '') // example.com:tenants:tenant1\n const parts = withoutPrefix.split(':')\n const domain = parts.shift()! // example.com\n const path = parts.join('/') // tenants/tenant1\n\n return path\n ? `https://${domain}/${path}` // https://example.com/tenants/tenant1\n : `https://${domain}` // https://example.com\n }\n\n private buildServiceEndpoint(holderDid: string, linkedVpId: string): string {\n const baseUrl = this.getBaseUrlFromDid(holderDid)\n const cleanBaseUrl = baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl\n return `${cleanBaseUrl}/linked-vp/${linkedVpId}`\n }\n\n private credentialToServiceEntry(credential: DigitalCredential, holderDid: string): LinkedVPServiceEntry {\n if (!credential.linkedVpId) {\n throw new Error(`Credential ${credential.id} does not have a linkedVpId`)\n }\n\n return {\n id: `${holderDid}#${credential.linkedVpId}`,\n type: 'LinkedVerifiablePresentation',\n serviceEndpoint: this.buildServiceEndpoint(holderDid, credential.linkedVpId),\n }\n }\n}\n","import { UniqueDigitalCredential } from '@sphereon/ssi-sdk.credential-store'\nimport { Loggers, OriginalVerifiableCredential, WrappedVerifiableCredential } from '@sphereon/ssi-types'\nimport type { PresentationPayload } from '@veramo/core'\nimport { W3CVerifiableCredential } from '@veramo/core/src/types/vc-data-model'\nimport { LOGGER_NAMESPACE, RequiredContext } from '../types'\n\nconst logger = Loggers.DEFAULT.get(LOGGER_NAMESPACE)\n\n/**\n * Extracts the original credential from various wrapper types\n */\nfunction extractOriginalCredential(\n credential: UniqueDigitalCredential | WrappedVerifiableCredential | OriginalVerifiableCredential,\n): OriginalVerifiableCredential {\n if (typeof credential === 'string') {\n return credential\n }\n\n if ('digitalCredential' in credential) {\n const udc = credential as UniqueDigitalCredential\n if (udc.originalVerifiableCredential) {\n return udc.originalVerifiableCredential\n }\n return udc.uniformVerifiableCredential as OriginalVerifiableCredential\n }\n\n if ('original' in credential) {\n return credential.original\n }\n\n return credential as OriginalVerifiableCredential\n}\n\n/**\n * Creates a Verifiable Presentation for LinkedVP publishing\n * Contains multiple credentials in a single JWT VP\n * No nonce or audience since this is for publishing, not responding to verification\n */\nexport async function createLinkedVPPresentation(\n holderDid: string,\n credentials: UniqueDigitalCredential[],\n agent: RequiredContext['agent'],\n): Promise<string | Record<string, any>> {\n if (credentials.length === 0) {\n return Promise.reject(Error('Cannot create LinkedVP presentation with zero credentials'))\n }\n\n logger.debug(`Creating LinkedVP presentation for ${holderDid} with ${credentials.length} credentials`)\n\n const identifier = await agent.identifierManagedGet({ identifier: holderDid })\n\n // Extract and prepare credentials\n const verifiableCredentials = credentials.map((credential) => {\n const original = extractOriginalCredential(credential)\n // Keep as-is if string (JWT), otherwise convert to object\n return typeof original === 'string' ? original : original\n })\n\n // Create VP structure\n const vpObject: PresentationPayload = {\n '@context': ['https://www.w3.org/2018/credentials/v1'],\n type: ['VerifiablePresentation'],\n holder: holderDid,\n verifiableCredential: verifiableCredentials as W3CVerifiableCredential[],\n }\n\n // Create and sign the VP as JWT\n const result = await agent.createVerifiablePresentation({\n presentation: vpObject,\n proofFormat: 'jwt',\n keyRef: identifier.kmsKeyRef || identifier.kid,\n })\n\n // Extract JWT from result\n if (typeof result === 'string') {\n return result\n }\n\n if (result.proof && 'jws' in result.proof) {\n return result.proof.jws\n }\n\n return Promise.reject(Error('Failed to create JWT VP - no JWT in result'))\n}\n","import { IIdentifierResolution } from '@sphereon/ssi-sdk-ext.identifier-resolution'\nimport { ICredentialStore } from '@sphereon/ssi-sdk.credential-store'\nimport { VcdmCredentialPlugin } from '@sphereon/ssi-sdk.credential-vcdm'\nimport { IAgentContext, IPluginMethodMap } from '@veramo/core'\nimport { IKeyManager } from '@veramo/core/src/types/IKeyManager'\n\nexport const LOGGER_NAMESPACE = 'sphereon:linked-vp'\n\nexport type LinkedVPPresentation = string | Record<string, any>\n\nexport interface ILinkedVPManager extends IPluginMethodMap {\n /**\n * Publish a credential as a LinkedVP by adding it to the holder's DID Document\n * @param args - Publication arguments including credential ID and scope configuration\n * @param context - Agent context\n */\n lvpPublishCredential(args: PublishCredentialArgs, context: RequiredContext): Promise<LinkedVPEntry>\n\n /**\n * Unpublish a credential by removing its LinkedVP entry from the DID Document\n * @param args - Unpublish arguments\n * @param context - Agent context\n */\n lvpUnpublishCredential(args: UnpublishCredentialArgs, context: RequiredContext): Promise<boolean>\n\n /**\n * Check if a LinkedVP entry exists by linkedVpId\n * @param args - Query arguments\n * @param context - Agent context\n */\n lvpHasEntry(args: HasLinkedVPEntryArgs, context: RequiredContext): Promise<boolean>\n\n /**\n * Get LinkedVP service entries for a DID to be added to a DID Document\n * This is useful when generating DID Documents with toDidDocument\n * @param args - Query arguments for the DID\n * @param context - Agent context\n */\n lvpGetServiceEntries(args: GetServiceEntriesArgs, context: RequiredContext): Promise<Array<LinkedVPServiceEntry>>\n\n /**\n * Generate and return a Verifiable Presentation for a published LinkedVP\n * This is the main endpoint handler for GET /linked-vp/{linkedVpId}\n * @param args - Generation arguments\n * @param context - Agent context\n */\n lvpGeneratePresentation(args: GeneratePresentationArgs, context: RequiredContext): Promise<LinkedVPPresentation>\n}\n\nexport type PublishCredentialArgs = {\n digitalCredentialId: string\n linkedVpId?: string // Optional: if not provided, will be auto-generated\n}\n\nexport type UnpublishCredentialArgs = {\n linkedVpId: string\n}\n\nexport type HasLinkedVPEntryArgs = {\n linkedVpId: string\n}\n\nexport type GetServiceEntriesArgs = {\n tenantId?: string\n}\n\nexport type GeneratePresentationArgs = {\n linkedVpId: string\n}\n\nexport type LinkedVPEntry = {\n id: string\n linkedVpId: string\n tenantId?: string\n linkedVpFrom?: Date\n createdAt: Date\n}\n\nexport type LinkedVPServiceEntry = {\n id: string\n type: 'LinkedVerifiablePresentation'\n serviceEndpoint: string\n}\n\nexport type RequiredContext = IAgentContext<IIdentifierResolution & ICredentialStore & IKeyManager & VcdmCredentialPlugin>\n"],"mappings":"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","names":["IsNull","Not","Loggers","LOGGER_NAMESPACE","logger","Loggers","DEFAULT","get","LOGGER_NAMESPACE","extractOriginalCredential","credential","udc","originalVerifiableCredential","uniformVerifiableCredential","original","createLinkedVPPresentation","holderDid","credentials","agent","length","Promise","reject","Error","debug","identifier","identifierManagedGet","verifiableCredentials","map","vpObject","type","holder","verifiableCredential","result","createVerifiablePresentation","presentation","proofFormat","keyRef","kmsKeyRef","kid","proof","jws","linkedVPManagerMethods","LinkedVPManager","schema","ILinkedVPManager","methods","lvpPublishCredential","bind","lvpUnpublishCredential","lvpHasEntry","lvpGetServiceEntries","lvpGeneratePresentation","holderDids","options","args","context","digitalCredentialId","credential","agent","crsGetCredential","id","linkedVpId","Promise","reject","Error","buildLinkedVpId","tenantId","ensureLinkedVpIdUnique","publishedAt","Date","crsUpdateCredential","linkedVpFrom","createdAt","credentials","crsGetCredentials","filter","length","undefined","error","Not","IsNull","cred","map","holderDidForEntry","getHolderDid","credentialToServiceEntry","parseTenantFromLinkedVpId","holderDid","uniqueCredentials","crsGetUniqueCredentials","createLinkedVPPresentation","idx","lastIndexOf","substring","generateLinkedVpId","now","Math","random","toString","finalLinkedVpId","includes","getBaseUrlFromDid","startsWith","withoutPrefix","replace","parts","split","domain","shift","path","join","buildServiceEndpoint","baseUrl","cleanBaseUrl","endsWith","slice","type","serviceEndpoint"]}
package/package.json ADDED
@@ -0,0 +1,80 @@
1
+ {
2
+ "name": "@sphereon/ssi-sdk.linked-vp",
3
+ "version": "0.34.1-feature.SSISDK.82.linkedVP.325+9de5d4ff",
4
+ "source": "src/index.ts",
5
+ "type": "module",
6
+ "main": "./dist/index.cjs",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ "react-native": "./dist/index.js",
11
+ "import": {
12
+ "types": "./dist/index.d.ts",
13
+ "import": "./dist/index.js"
14
+ },
15
+ "require": {
16
+ "types": "./dist/index.d.cts",
17
+ "require": "./dist/index.cjs"
18
+ }
19
+ },
20
+ "veramo": {
21
+ "pluginInterfaces": {
22
+ "ILinkedVPManager": "./src/types/ILinkedVPManager.ts"
23
+ }
24
+ },
25
+ "scripts": {
26
+ "build": "tsup --config ../../tsup.config.ts --tsconfig ../../tsconfig.tsup.json",
27
+ "generate-plugin-schema": "tsx ../../packages/dev/bin/sphereon.js dev generate-plugin-schema"
28
+ },
29
+ "dependencies": {
30
+ "@sphereon/ssi-sdk-ext.identifier-resolution": "0.34.1-feature.SSISDK.82.linkedVP.325+9de5d4ff",
31
+ "@sphereon/ssi-sdk.credential-store": "0.34.1-feature.SSISDK.82.linkedVP.325+9de5d4ff",
32
+ "@sphereon/ssi-sdk.credential-vcdm": "0.34.1-feature.SSISDK.82.linkedVP.325+9de5d4ff",
33
+ "@sphereon/ssi-sdk.data-store": "0.34.1-feature.SSISDK.82.linkedVP.325+9de5d4ff",
34
+ "@sphereon/ssi-sdk.data-store-types": "0.34.1-feature.SSISDK.82.linkedVP.325+9de5d4ff",
35
+ "@sphereon/ssi-types": "0.34.1-feature.SSISDK.82.linkedVP.325+9de5d4ff",
36
+ "@veramo/utils": "4.2.0",
37
+ "cross-fetch": "^4.1.0",
38
+ "dcql": "1.0.1",
39
+ "pkijs": "^3.2.4",
40
+ "typeorm": "0.3.20",
41
+ "uint8arrays": "3.1.1"
42
+ },
43
+ "devDependencies": {
44
+ "@sphereon/ssi-sdk-ext.key-manager": "0.34.1-feature.SSISDK.82.linkedVP.325+9de5d4ff",
45
+ "@sphereon/ssi-sdk-ext.kms-local": "0.34.1-feature.SSISDK.82.linkedVP.325+9de5d4ff",
46
+ "@sphereon/ssi-sdk.agent-config": "0.34.1-feature.SSISDK.82.linkedVP.325+9de5d4ff",
47
+ "@sphereon/ssi-sdk.credential-vcdm1-jwt-provider": "0.34.1-feature.SSISDK.82.linkedVP.325+9de5d4ff",
48
+ "@veramo/data-store": "4.2.0",
49
+ "@veramo/did-manager": "4.2.0",
50
+ "@veramo/did-provider-web": "4.2.0",
51
+ "@veramo/did-resolver": "4.2.0",
52
+ "@veramo/key-manager": "4.2.0",
53
+ "@veramo/remote-client": "4.2.0",
54
+ "@veramo/remote-server": "4.2.0",
55
+ "did-resolver": "^4.1.0",
56
+ "web-did-resolver": "^2.0.30"
57
+ },
58
+ "files": [
59
+ "dist",
60
+ "src",
61
+ "README.md",
62
+ "plugin.schema.json",
63
+ "LICENSE"
64
+ ],
65
+ "private": false,
66
+ "publishConfig": {
67
+ "access": "public"
68
+ },
69
+ "repository": "git@github.com:Sphereon-Opensource/SSI-SDK.git",
70
+ "author": "Sphereon <dev@sphereon.com>",
71
+ "license": "Apache-2.0",
72
+ "keywords": [
73
+ "Sphereon",
74
+ "SSI",
75
+ "Veramo",
76
+ "Presentation Defintion Manager",
77
+ "PD Manager"
78
+ ],
79
+ "gitHead": "9de5d4ff0d17685351d63a9685ec853f6add2d6c"
80
+ }