@sphereon/ssi-sdk.siopv2-oid4vp-op-auth 0.34.1-feature.SSISDK.45.94 → 0.34.1-feature.SSISDK.46.40

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.
@@ -1,333 +1,322 @@
1
- // import { PresentationDefinitionWithLocation, PresentationExchange } from '@sphereon/did-auth-siop'
2
- // import { SelectResults, Status, SubmissionRequirementMatch } from '@sphereon/pex'
3
- //import { Format } from '@sphereon/pex-models'
4
- // import {
5
- // //isManagedIdentifierDidResult,
6
- // isOID4VCIssuerIdentifier,
7
- // ManagedIdentifierOptsOrResult,
8
- // ManagedIdentifierResult,
9
- // } from '@sphereon/ssi-sdk-ext.identifier-resolution'
10
- // import { defaultHasher,
11
- // // ProofOptions
12
- // } from '@sphereon/ssi-sdk.core'
13
- //import { UniqueDigitalCredential, verifiableCredentialForRoleFilter } from '@sphereon/ssi-sdk.credential-store'
14
- //import { CredentialRole, FindDigitalCredentialArgs } from '@sphereon/ssi-sdk.data-store'
1
+ import { PresentationDefinitionWithLocation, PresentationExchange } from '@sphereon/did-auth-siop'
2
+ import { SelectResults, Status, SubmissionRequirementMatch } from '@sphereon/pex'
3
+ import { Format } from '@sphereon/pex-models'
15
4
  import {
16
- //CompactJWT,
17
- HasherSync,
18
- //IProof, OriginalVerifiableCredential
19
- } from '@sphereon/ssi-types'
5
+ isManagedIdentifierDidResult,
6
+ isOID4VCIssuerIdentifier,
7
+ ManagedIdentifierOptsOrResult,
8
+ ManagedIdentifierResult,
9
+ } from '@sphereon/ssi-sdk-ext.identifier-resolution'
10
+ import { defaultHasher, ProofOptions } from '@sphereon/ssi-sdk.core'
11
+ import { UniqueDigitalCredential, verifiableCredentialForRoleFilter } from '@sphereon/ssi-sdk.credential-store'
12
+ import { CredentialRole, FindDigitalCredentialArgs } from '@sphereon/ssi-sdk.data-store'
13
+ import { CompactJWT, HasherSync, IProof, OriginalVerifiableCredential } from '@sphereon/ssi-types'
20
14
  import {
21
- //DEFAULT_JWT_PROOF_TYPE,
22
- //IGetPresentationExchangeArgs,
15
+ DEFAULT_JWT_PROOF_TYPE,
16
+ IGetPresentationExchangeArgs,
23
17
  IOID4VPArgs,
24
- //VerifiableCredentialsWithDefinition,
25
- //VerifiablePresentationWithDefinition,
18
+ VerifiableCredentialsWithDefinition,
19
+ VerifiablePresentationWithDefinition,
26
20
  } from '../types'
27
- //import { createOID4VPPresentationSignCallback } from './functions'
21
+ import { createOID4VPPresentationSignCallback } from './functions'
28
22
  import { OpSession } from './OpSession'
29
23
 
30
- // FIXME SSISDK-44 add support for DCQL presentations
31
-
32
24
  export class OID4VP {
33
- //private readonly session: OpSession
34
- // private readonly allIdentifiers: string[]
35
- // private readonly hasher?: HasherSync
25
+ private readonly session: OpSession
26
+ private readonly allIdentifiers: string[]
27
+ private readonly hasher?: HasherSync
36
28
 
37
29
  private constructor(args: IOID4VPArgs) {
38
- // const { session,
39
- // // allIdentifiers, hasher = defaultHasher
40
- // } = args
30
+ const { session, allIdentifiers, hasher = defaultHasher } = args
41
31
 
42
- //this.session = session
43
- // this.allIdentifiers = allIdentifiers ?? []
44
- // this.hasher = hasher
32
+ this.session = session
33
+ this.allIdentifiers = allIdentifiers ?? []
34
+ this.hasher = hasher
45
35
  }
46
36
 
47
37
  public static async init(session: OpSession, allIdentifiers: string[], hasher?: HasherSync): Promise<OID4VP> {
48
38
  return new OID4VP({ session, allIdentifiers: allIdentifiers ?? (await session.getSupportedDIDs()), hasher })
49
39
  }
50
40
 
51
- // public async getPresentationDefinitions(): Promise<PresentationDefinitionWithLocation[] | undefined> {
52
- // const definitions = await this.session.getPresentationDefinitions()
53
- // if (definitions) {
54
- // PresentationExchange.assertValidPresentationDefinitionWithLocations(definitions)
55
- // }
56
- // return definitions
57
- // }
41
+ public async getPresentationDefinitions(): Promise<PresentationDefinitionWithLocation[] | undefined> {
42
+ const definitions = await this.session.getPresentationDefinitions()
43
+ if (definitions) {
44
+ PresentationExchange.assertValidPresentationDefinitionWithLocations(definitions)
45
+ }
46
+ return definitions
47
+ }
48
+
49
+ private getPresentationExchange(args: IGetPresentationExchangeArgs): PresentationExchange {
50
+ const { verifiableCredentials, allIdentifiers, hasher } = args
51
+
52
+ return new PresentationExchange({
53
+ allDIDs: allIdentifiers ?? this.allIdentifiers,
54
+ allVerifiableCredentials: verifiableCredentials,
55
+ hasher: hasher ?? this.hasher,
56
+ })
57
+ }
58
+
59
+ public async createVerifiablePresentations(
60
+ credentialRole: CredentialRole,
61
+ credentialsWithDefinitions: VerifiableCredentialsWithDefinition[],
62
+ opts?: {
63
+ forceNoCredentialsInVP?: boolean // Allow to create a VP without credentials, like EBSI is using it. Defaults to false
64
+ restrictToFormats?: Format
65
+ restrictToDIDMethods?: string[]
66
+ proofOpts?: ProofOptions
67
+ idOpts?: ManagedIdentifierOptsOrResult
68
+ skipDidResolution?: boolean
69
+ holderDID?: string
70
+ subjectIsHolder?: boolean
71
+ hasher?: HasherSync
72
+ applyFilter?: boolean
73
+ },
74
+ ): Promise<VerifiablePresentationWithDefinition[]> {
75
+ return await Promise.all(credentialsWithDefinitions.map((cred) => this.createVerifiablePresentation(credentialRole, cred, opts)))
76
+ }
77
+
78
+ public async createVerifiablePresentation(
79
+ credentialRole: CredentialRole,
80
+ selectedVerifiableCredentials: VerifiableCredentialsWithDefinition,
81
+ opts?: {
82
+ forceNoCredentialsInVP?: boolean // Allow to create a VP without credentials, like EBSI is using it. Defaults to false
83
+ restrictToFormats?: Format
84
+ restrictToDIDMethods?: string[]
85
+ proofOpts?: ProofOptions
86
+ idOpts?: ManagedIdentifierOptsOrResult
87
+ skipDidResolution?: boolean
88
+ holder?: string
89
+ subjectIsHolder?: boolean
90
+ applyFilter?: boolean
91
+ hasher?: HasherSync
92
+ },
93
+ ): Promise<VerifiablePresentationWithDefinition> {
94
+ const { subjectIsHolder, holder, forceNoCredentialsInVP = false } = { ...opts }
95
+ if (subjectIsHolder && holder) {
96
+ throw Error('Cannot both have subject is holder and a holderDID value at the same time (programming error)')
97
+ }
98
+ if (forceNoCredentialsInVP) {
99
+ selectedVerifiableCredentials.credentials = []
100
+ } else if (!selectedVerifiableCredentials?.credentials || selectedVerifiableCredentials.credentials.length === 0) {
101
+ throw Error('No verifiable verifiableCredentials provided for presentation definition')
102
+ }
103
+
104
+ const proofOptions: ProofOptions = {
105
+ ...opts?.proofOpts,
106
+ challenge: opts?.proofOpts?.nonce ?? opts?.proofOpts?.challenge ?? this.session.nonce,
107
+ domain: opts?.proofOpts?.domain ?? (await this.session.getRedirectUri()),
108
+ }
58
109
 
59
- // private getPresentationExchange(args: IGetPresentationExchangeArgs): PresentationExchange {
60
- // const { verifiableCredentials, allIdentifiers, hasher } = args
61
- //
62
- // return new PresentationExchange({
63
- // allDIDs: allIdentifiers ?? this.allIdentifiers,
64
- // allVerifiableCredentials: verifiableCredentials,
65
- // hasher: hasher ?? this.hasher,
66
- // })
67
- // }
110
+ let idOpts = opts?.idOpts
111
+ if (!idOpts) {
112
+ if (opts?.subjectIsHolder) {
113
+ if (forceNoCredentialsInVP) {
114
+ return Promise.reject(
115
+ Error(
116
+ `Cannot have subject is holder, when force no credentials is being used, as we could never determine the holder then. Please provide holderDID`,
117
+ ),
118
+ )
119
+ }
120
+ const firstUniqueDC = selectedVerifiableCredentials.credentials[0]
121
+ // const firstVC = firstUniqueDC.uniformVerifiableCredential!
122
+ if (typeof firstUniqueDC !== 'object' || !('digitalCredential' in firstUniqueDC)) {
123
+ return Promise.reject(Error('If no opts provided, credentials should be of type UniqueDigitalCredential'))
124
+ }
68
125
 
69
- // public async createVerifiablePresentations(
70
- // credentialRole: CredentialRole,
71
- // credentialsWithDefinitions: VerifiableCredentialsWithDefinition[],
72
- // opts?: {
73
- // forceNoCredentialsInVP?: boolean // Allow to create a VP without credentials, like EBSI is using it. Defaults to false
74
- // restrictToFormats?: Format
75
- // restrictToDIDMethods?: string[]
76
- // proofOpts?: ProofOptions
77
- // idOpts?: ManagedIdentifierOptsOrResult
78
- // skipDidResolution?: boolean
79
- // holderDID?: string
80
- // subjectIsHolder?: boolean
81
- // hasher?: HasherSync
82
- // applyFilter?: boolean
83
- // },
84
- // ): Promise<VerifiablePresentationWithDefinition[]> {
85
- // return await Promise.all(credentialsWithDefinitions.map((cred) => this.createVerifiablePresentation(credentialRole, cred, opts)))
86
- // }
126
+ idOpts = isOID4VCIssuerIdentifier(firstUniqueDC.digitalCredential.kmsKeyRef)
127
+ ? await this.session.context.agent.identifierManagedGetByIssuer({
128
+ identifier: firstUniqueDC.digitalCredential.kmsKeyRef,
129
+ })
130
+ : await this.session.context.agent.identifierManagedGetByKid({
131
+ identifier: firstUniqueDC.digitalCredential.kmsKeyRef,
132
+ kmsKeyRef: firstUniqueDC.digitalCredential.kmsKeyRef,
133
+ })
87
134
 
88
- // public async createVerifiablePresentation(
89
- // credentialRole: CredentialRole,
90
- // selectedVerifiableCredentials: VerifiableCredentialsWithDefinition,
91
- // opts?: {
92
- // forceNoCredentialsInVP?: boolean // Allow to create a VP without credentials, like EBSI is using it. Defaults to false
93
- // restrictToFormats?: Format
94
- // restrictToDIDMethods?: string[]
95
- // proofOpts?: ProofOptions
96
- // idOpts?: ManagedIdentifierOptsOrResult
97
- // skipDidResolution?: boolean
98
- // holder?: string
99
- // subjectIsHolder?: boolean
100
- // applyFilter?: boolean
101
- // hasher?: HasherSync
102
- // },
103
- // ): Promise<VerifiablePresentationWithDefinition> {
104
- // const { subjectIsHolder, holder, forceNoCredentialsInVP = false } = { ...opts }
105
- // if (subjectIsHolder && holder) {
106
- // throw Error('Cannot both have subject is holder and a holderDID value at the same time (programming error)')
107
- // }
108
- // if (forceNoCredentialsInVP) {
109
- // selectedVerifiableCredentials.credentials = []
110
- // } else if (!selectedVerifiableCredentials?.credentials || selectedVerifiableCredentials.credentials.length === 0) {
111
- // throw Error('No verifiable verifiableCredentials provided for presentation definition')
112
- // }
113
- //
114
- // // const proofOptions: ProofOptions = {
115
- // // ...opts?.proofOpts,
116
- // // challenge: opts?.proofOpts?.nonce ?? opts?.proofOpts?.challenge ?? this.session.nonce,
117
- // // domain: opts?.proofOpts?.domain ?? (await this.session.getRedirectUri()),
118
- // // }
119
- //
120
- // let idOpts = opts?.idOpts
121
- // if (!idOpts) {
122
- // if (opts?.subjectIsHolder) {
123
- // if (forceNoCredentialsInVP) {
124
- // return Promise.reject(
125
- // Error(
126
- // `Cannot have subject is holder, when force no credentials is being used, as we could never determine the holder then. Please provide holderDID`,
127
- // ),
128
- // )
129
- // }
130
- // const firstUniqueDC = selectedVerifiableCredentials.credentials[0]
131
- // // const firstVC = firstUniqueDC.uniformVerifiableCredential!
132
- // if (typeof firstUniqueDC !== 'object' || !('digitalCredential' in firstUniqueDC)) {
133
- // return Promise.reject(Error('If no opts provided, credentials should be of type UniqueDigitalCredential'))
134
- // }
135
- //
136
- // idOpts = isOID4VCIssuerIdentifier(firstUniqueDC.digitalCredential.kmsKeyRef)
137
- // ? await this.session.context.agent.identifierManagedGetByIssuer({
138
- // identifier: firstUniqueDC.digitalCredential.kmsKeyRef,
139
- // })
140
- // : await this.session.context.agent.identifierManagedGetByKid({
141
- // identifier: firstUniqueDC.digitalCredential.kmsKeyRef,
142
- // kmsKeyRef: firstUniqueDC.digitalCredential.kmsKeyRef,
143
- // })
144
- //
145
- // /*
146
- // const holder = CredentialMapper.isSdJwtDecodedCredential(firstVC)
147
- // ? firstVC.decodedPayload.cnf?.jwk
148
- // ? //TODO SDK-19: convert the JWK to hex and search for the appropriate key and associated DID
149
- // //doesn't apply to did:jwk only, as you can represent any DID key as a JWK. So whenever you encounter a JWK it doesn't mean it had to come from a did:jwk in the system. It just can always be represented as a did:jwk
150
- // `did:jwk:${encodeJoseBlob(firstVC.decodedPayload.cnf?.jwk)}#0`
151
- // : firstVC.decodedPayload.sub
152
- // : Array.isArray(firstVC.credentialSubject)
153
- // ? firstVC.credentialSubject[0].id
154
- // : firstVC.credentialSubject.id
155
- // if (holder) {
156
- // idOpts = { identifier: holder }
157
- // }
158
- // */
159
- // } else if (opts?.holder) {
160
- // idOpts = { identifier: opts.holder }
161
- // }
162
- // }
163
- //
164
- // // We are making sure to filter, in case the user submitted all verifiableCredentials in the wallet/agent. We also make sure to get original formats back
165
- // const vcs = forceNoCredentialsInVP
166
- // ? selectedVerifiableCredentials
167
- // : opts?.applyFilter
168
- // ? await this.filterCredentials(credentialRole, selectedVerifiableCredentials.dcqlQuery, {
169
- // restrictToFormats: opts?.restrictToFormats,
170
- // restrictToDIDMethods: opts?.restrictToDIDMethods,
171
- // filterOpts: {
172
- // verifiableCredentials: selectedVerifiableCredentials.credentials,
173
- // },
174
- // })
175
- // : {
176
- // definition: selectedVerifiableCredentials.dcqlQuery,
177
- // credentials: selectedVerifiableCredentials.credentials,
178
- // }
179
- //
180
- // if (!idOpts) {
181
- // return Promise.reject(Error(`No identifier options present at this point`))
182
- // }
183
- //
184
- // // const signCallback = await createOID4VPPresentationSignCallback({
185
- // // presentationSignCallback: this.session.options.presentationSignCallback,
186
- // // idOpts,
187
- // // context: this.session.context,
188
- // // domain: proofOptions.domain,
189
- // // challenge: proofOptions.challenge,
190
- // // format: opts?.restrictToFormats ?? selectedVerifiableCredentials.dcqlQuery.dcqlQuery.format,
191
- // // skipDidResolution: opts?.skipDidResolution ?? false,
192
- // // })
193
- // const identifier: ManagedIdentifierResult = await this.session.context.agent.identifierManagedGet(idOpts)
194
- // const verifiableCredentials = vcs.credentials.map((credential) =>
195
- // typeof credential === 'object' && 'digitalCredential' in credential ? credential.originalVerifiableCredential! : credential,
196
- // )
197
- // // const presentationResult = await this.getPresentationExchange({
198
- // // verifiableCredentials: verifiableCredentials,
199
- // // allIdentifiers: this.allIdentifiers,
200
- // // hasher: opts?.hasher,
201
- // // }).createVerifiablePresentation(vcs.dcqlQuery.dcqlQuery, verifiableCredentials, signCallback, {
202
- // // proofOptions,
203
- // // // fixme: Update to newer siop-vp to not require dids here. But when Veramo is creating the VP it's still looking at this field to pass into didManagerGet
204
- // // ...(identifier && isManagedIdentifierDidResult(identifier) && { holderDID: identifier.did }),
205
- // // })
206
- //
207
- // const verifiablePresentations = presentationResult.verifiablePresentations.map((verifiablePresentation) =>
208
- // typeof verifiablePresentation !== 'string' &&
209
- // 'proof' in verifiablePresentation &&
210
- // 'jwt' in verifiablePresentation.proof &&
211
- // verifiablePresentation.proof.jwt
212
- // ? verifiablePresentation.proof.jwt
213
- // : verifiablePresentation,
214
- // )
215
- //
216
- // return {
217
- // ...presentationResult,
218
- // verifiablePresentations,
219
- // verifiableCredentials: verifiableCredentials,
220
- // dcqlQuery: selectedVerifiableCredentials.dcqlQuery,
221
- // idOpts,
222
- // }
223
- // }
135
+ /*
136
+ const holder = CredentialMapper.isSdJwtDecodedCredential(firstVC)
137
+ ? firstVC.decodedPayload.cnf?.jwk
138
+ ? //TODO SDK-19: convert the JWK to hex and search for the appropriate key and associated DID
139
+ //doesn't apply to did:jwk only, as you can represent any DID key as a JWK. So whenever you encounter a JWK it doesn't mean it had to come from a did:jwk in the system. It just can always be represented as a did:jwk
140
+ `did:jwk:${encodeJoseBlob(firstVC.decodedPayload.cnf?.jwk)}#0`
141
+ : firstVC.decodedPayload.sub
142
+ : Array.isArray(firstVC.credentialSubject)
143
+ ? firstVC.credentialSubject[0].id
144
+ : firstVC.credentialSubject.id
145
+ if (holder) {
146
+ idOpts = { identifier: holder }
147
+ }
148
+ */
149
+ } else if (opts?.holder) {
150
+ idOpts = { identifier: opts.holder }
151
+ }
152
+ }
224
153
 
225
- // public async filterCredentialsAgainstAllDefinitions(
226
- // credentialRole: CredentialRole,
227
- // opts?: {
228
- // filterOpts?: {
229
- // verifiableCredentials?: UniqueDigitalCredential[]
230
- // filter?: FindDigitalCredentialArgs
231
- // }
232
- // holderDIDs?: string[]
233
- // restrictToFormats?: Format
234
- // restrictToDIDMethods?: string[]
235
- // },
236
- // ): Promise<VerifiableCredentialsWithDefinition[]> {
237
- // const defs = await this.getPresentationDefinitions()
238
- // const result: VerifiableCredentialsWithDefinition[] = []
239
- // if (defs) {
240
- // for (const definition of defs) {
241
- // result.push(await this.filterCredentials(credentialRole, definition, opts))
242
- // }
243
- // }
244
- // return result
245
- // }
154
+ // We are making sure to filter, in case the user submitted all verifiableCredentials in the wallet/agent. We also make sure to get original formats back
155
+ const vcs = forceNoCredentialsInVP
156
+ ? selectedVerifiableCredentials
157
+ : opts?.applyFilter
158
+ ? await this.filterCredentials(credentialRole, selectedVerifiableCredentials.definition, {
159
+ restrictToFormats: opts?.restrictToFormats,
160
+ restrictToDIDMethods: opts?.restrictToDIDMethods,
161
+ filterOpts: {
162
+ verifiableCredentials: selectedVerifiableCredentials.credentials,
163
+ },
164
+ })
165
+ : {
166
+ definition: selectedVerifiableCredentials.definition,
167
+ credentials: selectedVerifiableCredentials.credentials,
168
+ }
246
169
 
247
- // public async filterCredentials(
248
- // credentialRole: CredentialRole,
249
- // presentationDefinition: PresentationDefinitionWithLocation,
250
- // opts?: {
251
- // filterOpts?: { verifiableCredentials?: (UniqueDigitalCredential | OriginalVerifiableCredential)[]; filter?: FindDigitalCredentialArgs }
252
- // holderDIDs?: string[]
253
- // restrictToFormats?: Format
254
- // restrictToDIDMethods?: string[]
255
- // },
256
- // ): Promise<VerifiableCredentialsWithDefinition> {
257
- // const udcMap = new Map<OriginalVerifiableCredential, UniqueDigitalCredential | OriginalVerifiableCredential>()
258
- // opts?.filterOpts?.verifiableCredentials?.forEach((credential) => {
259
- // if (typeof credential === 'object' && 'digitalCredential' in credential) {
260
- // udcMap.set(credential.originalVerifiableCredential!, credential)
261
- // } else {
262
- // udcMap.set(credential, credential)
263
- // }
264
- // })
265
- //
266
- // const credentials = (
267
- // await this.filterCredentialsWithSelectionStatus(credentialRole, presentationDefinition, {
268
- // ...opts,
269
- // filterOpts: {
270
- // verifiableCredentials: opts?.filterOpts?.verifiableCredentials?.map((credential) => {
271
- // if (typeof credential === 'object' && 'digitalCredential' in credential) {
272
- // return credential.originalVerifiableCredential!
273
- // } else {
274
- // return credential
275
- // }
276
- // }),
277
- // },
278
- // })
279
- // ).verifiableCredential
280
- //
281
- // return {
282
- // dcqlQuery: presentationDefinition,
283
- // credentials: credentials?.map((vc) => udcMap.get(vc)!) ?? [],
284
- // }
285
- // }
170
+ if (!idOpts) {
171
+ return Promise.reject(Error(`No identifier options present at this point`))
172
+ }
286
173
 
287
- // public async filterCredentialsWithSelectionStatus(
288
- // credentialRole: CredentialRole,
289
- // presentationDefinition: PresentationDefinitionWithLocation,
290
- // opts?: {
291
- // filterOpts?: { verifiableCredentials?: OriginalVerifiableCredential[]; filter?: FindDigitalCredentialArgs }
292
- // holderDIDs?: string[]
293
- // restrictToFormats?: Format
294
- // restrictToDIDMethods?: string[]
295
- // },
296
- // ): Promise<SelectResults> {
297
- // const selectionResults: SelectResults = await this.getPresentationExchange({
298
- // verifiableCredentials: await this.getCredentials(credentialRole, opts?.filterOpts),
299
- // }).selectVerifiableCredentialsForSubmission(presentationDefinition.definition, opts)
300
- // if (selectionResults.errors && selectionResults.errors.length > 0) {
301
- // throw Error(JSON.stringify(selectionResults.errors))
302
- // } else if (selectionResults.areRequiredCredentialsPresent === Status.ERROR) {
303
- // throw Error(`Not all required credentials are available to satisfy the relying party's request`)
304
- // }
305
- //
306
- // const matches: SubmissionRequirementMatch[] | undefined = selectionResults.matches
307
- // if (!matches || matches.length === 0 || !selectionResults.verifiableCredential || selectionResults.verifiableCredential.length === 0) {
308
- // throw Error(JSON.stringify(selectionResults.errors))
309
- // }
310
- // return selectionResults
311
- // }
312
- //
313
- // private async getCredentials(
314
- // credentialRole: CredentialRole,
315
- // filterOpts?: {
316
- // verifiableCredentials?: OriginalVerifiableCredential[]
317
- // filter?: FindDigitalCredentialArgs
318
- // },
319
- // ): Promise<OriginalVerifiableCredential[]> {
320
- // if (filterOpts?.verifiableCredentials && filterOpts.verifiableCredentials.length > 0) {
321
- // return filterOpts.verifiableCredentials
322
- // }
323
- //
324
- // const filter = verifiableCredentialForRoleFilter(credentialRole, filterOpts?.filter)
325
- // const uniqueCredentials = await this.session.context.agent.crsGetUniqueCredentials({ filter })
326
- // return uniqueCredentials.map((uniqueVC: UniqueDigitalCredential) => {
327
- // const vc = uniqueVC.uniformVerifiableCredential!
328
- // const proof = Array.isArray(vc.proof) ? vc.proof : [vc.proof]
329
- // const jwtProof = proof.find((p: IProof) => p?.type === DEFAULT_JWT_PROOF_TYPE)
330
- // return jwtProof ? (jwtProof.jwt as CompactJWT) : vc
331
- // })
332
- // }
174
+ const signCallback = await createOID4VPPresentationSignCallback({
175
+ presentationSignCallback: this.session.options.presentationSignCallback,
176
+ idOpts,
177
+ context: this.session.context,
178
+ domain: proofOptions.domain,
179
+ challenge: proofOptions.challenge,
180
+ format: opts?.restrictToFormats ?? selectedVerifiableCredentials.definition.definition.format,
181
+ skipDidResolution: opts?.skipDidResolution ?? false,
182
+ })
183
+ const identifier: ManagedIdentifierResult = await this.session.context.agent.identifierManagedGet(idOpts)
184
+ const verifiableCredentials = vcs.credentials.map((credential) =>
185
+ typeof credential === 'object' && 'digitalCredential' in credential ? credential.originalVerifiableCredential! : credential,
186
+ )
187
+ const presentationResult = await this.getPresentationExchange({
188
+ verifiableCredentials: verifiableCredentials,
189
+ allIdentifiers: this.allIdentifiers,
190
+ hasher: opts?.hasher,
191
+ }).createVerifiablePresentation(vcs.definition.definition, verifiableCredentials, signCallback, {
192
+ proofOptions,
193
+ // fixme: Update to newer siop-vp to not require dids here. But when Veramo is creating the VP it's still looking at this field to pass into didManagerGet
194
+ ...(identifier && isManagedIdentifierDidResult(identifier) && { holderDID: identifier.did }),
195
+ })
196
+
197
+ const verifiablePresentations = presentationResult.verifiablePresentations.map((verifiablePresentation) =>
198
+ typeof verifiablePresentation !== 'string' &&
199
+ 'proof' in verifiablePresentation &&
200
+ 'jwt' in verifiablePresentation.proof &&
201
+ verifiablePresentation.proof.jwt
202
+ ? verifiablePresentation.proof.jwt
203
+ : verifiablePresentation,
204
+ )
205
+
206
+ return {
207
+ ...presentationResult,
208
+ verifiablePresentations,
209
+ verifiableCredentials: verifiableCredentials,
210
+ definition: selectedVerifiableCredentials.definition,
211
+ idOpts,
212
+ }
213
+ }
214
+
215
+ public async filterCredentialsAgainstAllDefinitions(
216
+ credentialRole: CredentialRole,
217
+ opts?: {
218
+ filterOpts?: {
219
+ verifiableCredentials?: UniqueDigitalCredential[]
220
+ filter?: FindDigitalCredentialArgs
221
+ }
222
+ holderDIDs?: string[]
223
+ restrictToFormats?: Format
224
+ restrictToDIDMethods?: string[]
225
+ },
226
+ ): Promise<VerifiableCredentialsWithDefinition[]> {
227
+ const defs = await this.getPresentationDefinitions()
228
+ const result: VerifiableCredentialsWithDefinition[] = []
229
+ if (defs) {
230
+ for (const definition of defs) {
231
+ result.push(await this.filterCredentials(credentialRole, definition, opts))
232
+ }
233
+ }
234
+ return result
235
+ }
236
+
237
+ public async filterCredentials(
238
+ credentialRole: CredentialRole,
239
+ presentationDefinition: PresentationDefinitionWithLocation,
240
+ opts?: {
241
+ filterOpts?: { verifiableCredentials?: (UniqueDigitalCredential | OriginalVerifiableCredential)[]; filter?: FindDigitalCredentialArgs }
242
+ holderDIDs?: string[]
243
+ restrictToFormats?: Format
244
+ restrictToDIDMethods?: string[]
245
+ },
246
+ ): Promise<VerifiableCredentialsWithDefinition> {
247
+ const udcMap = new Map<OriginalVerifiableCredential, UniqueDigitalCredential | OriginalVerifiableCredential>()
248
+ opts?.filterOpts?.verifiableCredentials?.forEach((credential) => {
249
+ if (typeof credential === 'object' && 'digitalCredential' in credential) {
250
+ udcMap.set(credential.originalVerifiableCredential!, credential)
251
+ } else {
252
+ udcMap.set(credential, credential)
253
+ }
254
+ })
255
+
256
+ const credentials = (
257
+ await this.filterCredentialsWithSelectionStatus(credentialRole, presentationDefinition, {
258
+ ...opts,
259
+ filterOpts: {
260
+ verifiableCredentials: opts?.filterOpts?.verifiableCredentials?.map((credential) => {
261
+ if (typeof credential === 'object' && 'digitalCredential' in credential) {
262
+ return credential.originalVerifiableCredential!
263
+ } else {
264
+ return credential
265
+ }
266
+ }),
267
+ },
268
+ })
269
+ ).verifiableCredential
270
+ return {
271
+ definition: presentationDefinition,
272
+ credentials: credentials?.map((vc) => udcMap.get(vc)!) ?? [],
273
+ }
274
+ }
275
+
276
+ public async filterCredentialsWithSelectionStatus(
277
+ credentialRole: CredentialRole,
278
+ presentationDefinition: PresentationDefinitionWithLocation,
279
+ opts?: {
280
+ filterOpts?: { verifiableCredentials?: OriginalVerifiableCredential[]; filter?: FindDigitalCredentialArgs }
281
+ holderDIDs?: string[]
282
+ restrictToFormats?: Format
283
+ restrictToDIDMethods?: string[]
284
+ },
285
+ ): Promise<SelectResults> {
286
+ const selectionResults: SelectResults = await this.getPresentationExchange({
287
+ verifiableCredentials: await this.getCredentials(credentialRole, opts?.filterOpts),
288
+ }).selectVerifiableCredentialsForSubmission(presentationDefinition.definition, opts)
289
+ if (selectionResults.errors && selectionResults.errors.length > 0) {
290
+ throw Error(JSON.stringify(selectionResults.errors))
291
+ } else if (selectionResults.areRequiredCredentialsPresent === Status.ERROR) {
292
+ throw Error(`Not all required credentials are available to satisfy the relying party's request`)
293
+ }
294
+
295
+ const matches: SubmissionRequirementMatch[] | undefined = selectionResults.matches
296
+ if (!matches || matches.length === 0 || !selectionResults.verifiableCredential || selectionResults.verifiableCredential.length === 0) {
297
+ throw Error(JSON.stringify(selectionResults.errors))
298
+ }
299
+ return selectionResults
300
+ }
301
+
302
+ private async getCredentials(
303
+ credentialRole: CredentialRole,
304
+ filterOpts?: {
305
+ verifiableCredentials?: OriginalVerifiableCredential[]
306
+ filter?: FindDigitalCredentialArgs
307
+ },
308
+ ): Promise<OriginalVerifiableCredential[]> {
309
+ if (filterOpts?.verifiableCredentials && filterOpts.verifiableCredentials.length > 0) {
310
+ return filterOpts.verifiableCredentials
311
+ }
312
+
313
+ const filter = verifiableCredentialForRoleFilter(credentialRole, filterOpts?.filter)
314
+ const uniqueCredentials = await this.session.context.agent.crsGetUniqueCredentials({ filter })
315
+ return uniqueCredentials.map((uniqueVC: UniqueDigitalCredential) => {
316
+ const vc = uniqueVC.uniformVerifiableCredential!
317
+ const proof = Array.isArray(vc.proof) ? vc.proof : [vc.proof]
318
+ const jwtProof = proof.find((p: IProof) => p?.type === DEFAULT_JWT_PROOF_TYPE)
319
+ return jwtProof ? (jwtProof.jwt as CompactJWT) : vc
320
+ })
321
+ }
333
322
  }