@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.
@@ -0,0 +1,84 @@
1
+ import { UniqueDigitalCredential } from '@sphereon/ssi-sdk.credential-store'
2
+ import { Loggers, OriginalVerifiableCredential, WrappedVerifiableCredential } from '@sphereon/ssi-types'
3
+ import type { PresentationPayload } from '@veramo/core'
4
+ import { W3CVerifiableCredential } from '@veramo/core/src/types/vc-data-model'
5
+ import { LOGGER_NAMESPACE, RequiredContext } from '../types'
6
+
7
+ const logger = Loggers.DEFAULT.get(LOGGER_NAMESPACE)
8
+
9
+ /**
10
+ * Extracts the original credential from various wrapper types
11
+ */
12
+ function extractOriginalCredential(
13
+ credential: UniqueDigitalCredential | WrappedVerifiableCredential | OriginalVerifiableCredential,
14
+ ): OriginalVerifiableCredential {
15
+ if (typeof credential === 'string') {
16
+ return credential
17
+ }
18
+
19
+ if ('digitalCredential' in credential) {
20
+ const udc = credential as UniqueDigitalCredential
21
+ if (udc.originalVerifiableCredential) {
22
+ return udc.originalVerifiableCredential
23
+ }
24
+ return udc.uniformVerifiableCredential as OriginalVerifiableCredential
25
+ }
26
+
27
+ if ('original' in credential) {
28
+ return credential.original
29
+ }
30
+
31
+ return credential as OriginalVerifiableCredential
32
+ }
33
+
34
+ /**
35
+ * Creates a Verifiable Presentation for LinkedVP publishing
36
+ * Contains multiple credentials in a single JWT VP
37
+ * No nonce or audience since this is for publishing, not responding to verification
38
+ */
39
+ export async function createLinkedVPPresentation(
40
+ holderDid: string,
41
+ credentials: UniqueDigitalCredential[],
42
+ agent: RequiredContext['agent'],
43
+ ): Promise<string | Record<string, any>> {
44
+ if (credentials.length === 0) {
45
+ return Promise.reject(Error('Cannot create LinkedVP presentation with zero credentials'))
46
+ }
47
+
48
+ logger.debug(`Creating LinkedVP presentation for ${holderDid} with ${credentials.length} credentials`)
49
+
50
+ const identifier = await agent.identifierManagedGet({ identifier: holderDid })
51
+
52
+ // Extract and prepare credentials
53
+ const verifiableCredentials = credentials.map((credential) => {
54
+ const original = extractOriginalCredential(credential)
55
+ // Keep as-is if string (JWT), otherwise convert to object
56
+ return typeof original === 'string' ? original : original
57
+ })
58
+
59
+ // Create VP structure
60
+ const vpObject: PresentationPayload = {
61
+ '@context': ['https://www.w3.org/2018/credentials/v1'],
62
+ type: ['VerifiablePresentation'],
63
+ holder: holderDid,
64
+ verifiableCredential: verifiableCredentials as W3CVerifiableCredential[],
65
+ }
66
+
67
+ // Create and sign the VP as JWT
68
+ const result = await agent.createVerifiablePresentation({
69
+ presentation: vpObject,
70
+ proofFormat: 'jwt',
71
+ keyRef: identifier.kmsKeyRef || identifier.kid,
72
+ })
73
+
74
+ // Extract JWT from result
75
+ if (typeof result === 'string') {
76
+ return result
77
+ }
78
+
79
+ if (result.proof && 'jws' in result.proof) {
80
+ return result.proof.jws
81
+ }
82
+
83
+ return Promise.reject(Error('Failed to create JWT VP - no JWT in result'))
84
+ }
@@ -0,0 +1,85 @@
1
+ import { IIdentifierResolution } from '@sphereon/ssi-sdk-ext.identifier-resolution'
2
+ import { ICredentialStore } from '@sphereon/ssi-sdk.credential-store'
3
+ import { VcdmCredentialPlugin } from '@sphereon/ssi-sdk.credential-vcdm'
4
+ import { IAgentContext, IPluginMethodMap } from '@veramo/core'
5
+ import { IKeyManager } from '@veramo/core/src/types/IKeyManager'
6
+
7
+ export const LOGGER_NAMESPACE = 'sphereon:linked-vp'
8
+
9
+ export type LinkedVPPresentation = string | Record<string, any>
10
+
11
+ export interface ILinkedVPManager extends IPluginMethodMap {
12
+ /**
13
+ * Publish a credential as a LinkedVP by adding it to the holder's DID Document
14
+ * @param args - Publication arguments including credential ID and scope configuration
15
+ * @param context - Agent context
16
+ */
17
+ lvpPublishCredential(args: PublishCredentialArgs, context: RequiredContext): Promise<LinkedVPEntry>
18
+
19
+ /**
20
+ * Unpublish a credential by removing its LinkedVP entry from the DID Document
21
+ * @param args - Unpublish arguments
22
+ * @param context - Agent context
23
+ */
24
+ lvpUnpublishCredential(args: UnpublishCredentialArgs, context: RequiredContext): Promise<boolean>
25
+
26
+ /**
27
+ * Check if a LinkedVP entry exists by linkedVpId
28
+ * @param args - Query arguments
29
+ * @param context - Agent context
30
+ */
31
+ lvpHasEntry(args: HasLinkedVPEntryArgs, context: RequiredContext): Promise<boolean>
32
+
33
+ /**
34
+ * Get LinkedVP service entries for a DID to be added to a DID Document
35
+ * This is useful when generating DID Documents with toDidDocument
36
+ * @param args - Query arguments for the DID
37
+ * @param context - Agent context
38
+ */
39
+ lvpGetServiceEntries(args: GetServiceEntriesArgs, context: RequiredContext): Promise<Array<LinkedVPServiceEntry>>
40
+
41
+ /**
42
+ * Generate and return a Verifiable Presentation for a published LinkedVP
43
+ * This is the main endpoint handler for GET /linked-vp/{linkedVpId}
44
+ * @param args - Generation arguments
45
+ * @param context - Agent context
46
+ */
47
+ lvpGeneratePresentation(args: GeneratePresentationArgs, context: RequiredContext): Promise<LinkedVPPresentation>
48
+ }
49
+
50
+ export type PublishCredentialArgs = {
51
+ digitalCredentialId: string
52
+ linkedVpId?: string // Optional: if not provided, will be auto-generated
53
+ }
54
+
55
+ export type UnpublishCredentialArgs = {
56
+ linkedVpId: string
57
+ }
58
+
59
+ export type HasLinkedVPEntryArgs = {
60
+ linkedVpId: string
61
+ }
62
+
63
+ export type GetServiceEntriesArgs = {
64
+ tenantId?: string
65
+ }
66
+
67
+ export type GeneratePresentationArgs = {
68
+ linkedVpId: string
69
+ }
70
+
71
+ export type LinkedVPEntry = {
72
+ id: string
73
+ linkedVpId: string
74
+ tenantId?: string
75
+ linkedVpFrom?: Date
76
+ createdAt: Date
77
+ }
78
+
79
+ export type LinkedVPServiceEntry = {
80
+ id: string
81
+ type: 'LinkedVerifiablePresentation'
82
+ serviceEndpoint: string
83
+ }
84
+
85
+ export type RequiredContext = IAgentContext<IIdentifierResolution & ICredentialStore & IKeyManager & VcdmCredentialPlugin>
@@ -0,0 +1 @@
1
+ export * from './ILinkedVPManager'