@pagopa/io-react-native-wallet 0.28.1 → 0.28.2

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.
Files changed (80) hide show
  1. package/lib/commonjs/credential/issuance/04-complete-user-authorization.js +5 -3
  2. package/lib/commonjs/credential/issuance/04-complete-user-authorization.js.map +1 -1
  3. package/lib/commonjs/credential/presentation/01-start-flow.js +6 -7
  4. package/lib/commonjs/credential/presentation/01-start-flow.js.map +1 -1
  5. package/lib/commonjs/credential/presentation/02-evaluate-rp-trust.js +4 -2
  6. package/lib/commonjs/credential/presentation/02-evaluate-rp-trust.js.map +1 -1
  7. package/lib/commonjs/credential/presentation/03-get-request-object.js +2 -2
  8. package/lib/commonjs/credential/presentation/03-get-request-object.js.map +1 -1
  9. package/lib/commonjs/credential/presentation/05-verify-request-object.js +11 -4
  10. package/lib/commonjs/credential/presentation/05-verify-request-object.js.map +1 -1
  11. package/lib/commonjs/credential/presentation/07-evaluate-dcql-query.js +19 -10
  12. package/lib/commonjs/credential/presentation/07-evaluate-dcql-query.js.map +1 -1
  13. package/lib/commonjs/credential/presentation/07-evaluate-input-descriptor.js +10 -3
  14. package/lib/commonjs/credential/presentation/07-evaluate-input-descriptor.js.map +1 -1
  15. package/lib/commonjs/credential/presentation/08-send-authorization-response.js +4 -4
  16. package/lib/commonjs/credential/presentation/08-send-authorization-response.js.map +1 -1
  17. package/lib/commonjs/credential/presentation/README.md +88 -2
  18. package/lib/commonjs/credential/presentation/errors.js +5 -6
  19. package/lib/commonjs/credential/presentation/errors.js.map +1 -1
  20. package/lib/commonjs/credential/presentation/index.js +27 -2
  21. package/lib/commonjs/credential/presentation/index.js.map +1 -1
  22. package/lib/commonjs/credential/presentation/types.js +1 -1
  23. package/lib/commonjs/credential/presentation/types.js.map +1 -1
  24. package/lib/module/credential/issuance/04-complete-user-authorization.js +5 -3
  25. package/lib/module/credential/issuance/04-complete-user-authorization.js.map +1 -1
  26. package/lib/module/credential/presentation/01-start-flow.js +6 -7
  27. package/lib/module/credential/presentation/01-start-flow.js.map +1 -1
  28. package/lib/module/credential/presentation/02-evaluate-rp-trust.js +4 -2
  29. package/lib/module/credential/presentation/02-evaluate-rp-trust.js.map +1 -1
  30. package/lib/module/credential/presentation/03-get-request-object.js +2 -2
  31. package/lib/module/credential/presentation/03-get-request-object.js.map +1 -1
  32. package/lib/module/credential/presentation/05-verify-request-object.js +11 -4
  33. package/lib/module/credential/presentation/05-verify-request-object.js.map +1 -1
  34. package/lib/module/credential/presentation/07-evaluate-dcql-query.js +20 -10
  35. package/lib/module/credential/presentation/07-evaluate-dcql-query.js.map +1 -1
  36. package/lib/module/credential/presentation/07-evaluate-input-descriptor.js +8 -1
  37. package/lib/module/credential/presentation/07-evaluate-input-descriptor.js.map +1 -1
  38. package/lib/module/credential/presentation/08-send-authorization-response.js +4 -4
  39. package/lib/module/credential/presentation/08-send-authorization-response.js.map +1 -1
  40. package/lib/module/credential/presentation/README.md +88 -2
  41. package/lib/module/credential/presentation/errors.js +5 -6
  42. package/lib/module/credential/presentation/errors.js.map +1 -1
  43. package/lib/module/credential/presentation/index.js +4 -3
  44. package/lib/module/credential/presentation/index.js.map +1 -1
  45. package/lib/module/credential/presentation/types.js +1 -1
  46. package/lib/module/credential/presentation/types.js.map +1 -1
  47. package/lib/typescript/credential/issuance/04-complete-user-authorization.d.ts +2 -2
  48. package/lib/typescript/credential/issuance/04-complete-user-authorization.d.ts.map +1 -1
  49. package/lib/typescript/credential/presentation/01-start-flow.d.ts +1 -6
  50. package/lib/typescript/credential/presentation/01-start-flow.d.ts.map +1 -1
  51. package/lib/typescript/credential/presentation/02-evaluate-rp-trust.d.ts +1 -0
  52. package/lib/typescript/credential/presentation/02-evaluate-rp-trust.d.ts.map +1 -1
  53. package/lib/typescript/credential/presentation/03-get-request-object.d.ts +1 -2
  54. package/lib/typescript/credential/presentation/03-get-request-object.d.ts.map +1 -1
  55. package/lib/typescript/credential/presentation/05-verify-request-object.d.ts +4 -2
  56. package/lib/typescript/credential/presentation/05-verify-request-object.d.ts.map +1 -1
  57. package/lib/typescript/credential/presentation/07-evaluate-dcql-query.d.ts +13 -5
  58. package/lib/typescript/credential/presentation/07-evaluate-dcql-query.d.ts.map +1 -1
  59. package/lib/typescript/credential/presentation/07-evaluate-input-descriptor.d.ts +7 -2
  60. package/lib/typescript/credential/presentation/07-evaluate-input-descriptor.d.ts.map +1 -1
  61. package/lib/typescript/credential/presentation/08-send-authorization-response.d.ts +3 -3
  62. package/lib/typescript/credential/presentation/08-send-authorization-response.d.ts.map +1 -1
  63. package/lib/typescript/credential/presentation/errors.d.ts +3 -4
  64. package/lib/typescript/credential/presentation/errors.d.ts.map +1 -1
  65. package/lib/typescript/credential/presentation/index.d.ts +5 -4
  66. package/lib/typescript/credential/presentation/index.d.ts.map +1 -1
  67. package/lib/typescript/credential/presentation/types.d.ts +3 -3
  68. package/package.json +3 -3
  69. package/src/credential/issuance/04-complete-user-authorization.ts +6 -3
  70. package/src/credential/presentation/01-start-flow.ts +10 -13
  71. package/src/credential/presentation/02-evaluate-rp-trust.ts +3 -2
  72. package/src/credential/presentation/03-get-request-object.ts +2 -3
  73. package/src/credential/presentation/05-verify-request-object.ts +17 -6
  74. package/src/credential/presentation/07-evaluate-dcql-query.ts +25 -17
  75. package/src/credential/presentation/07-evaluate-input-descriptor.ts +32 -30
  76. package/src/credential/presentation/08-send-authorization-response.ts +9 -7
  77. package/src/credential/presentation/README.md +88 -2
  78. package/src/credential/presentation/errors.ts +6 -6
  79. package/src/credential/presentation/index.ts +22 -4
  80. package/src/credential/presentation/types.ts +1 -1
@@ -10,6 +10,7 @@ export type EvaluateRelyingPartyTrust = (
10
10
  }
11
11
  ) => Promise<{
12
12
  rpConf: RelyingPartyEntityConfiguration["payload"]["metadata"];
13
+ subject: string;
13
14
  }>;
14
15
 
15
16
  /**
@@ -25,9 +26,9 @@ export const evaluateRelyingPartyTrust: EvaluateRelyingPartyTrust = async (
25
26
  { appFetch = fetch } = {}
26
27
  ) => {
27
28
  const {
28
- payload: { metadata: rpConf },
29
+ payload: { metadata: rpConf, sub },
29
30
  } = await getRelyingPartyEntityConfiguration(rpUrl, {
30
31
  appFetch,
31
32
  });
32
- return { rpConf };
33
+ return { rpConf, subject: sub };
33
34
  };
@@ -4,9 +4,8 @@ import { RequestObjectWalletCapabilities } from "./types";
4
4
 
5
5
  export type GetRequestObject = (
6
6
  requestUri: Out<StartFlow>["requestUri"],
7
- context: {
7
+ context?: {
8
8
  appFetch?: GlobalFetch["fetch"];
9
- walletInstanceAttestation: string;
10
9
  walletCapabilities?: RequestObjectWalletCapabilities;
11
10
  }
12
11
  ) => Promise<{ requestObjectEncodedJwt: string }>;
@@ -23,7 +22,7 @@ export type GetRequestObject = (
23
22
  */
24
23
  export const getRequestObject: GetRequestObject = async (
25
24
  requestUri,
26
- { appFetch = fetch, walletCapabilities }
25
+ { appFetch = fetch, walletCapabilities } = {}
27
26
  ) => {
28
27
  if (walletCapabilities) {
29
28
  // Validate external input
@@ -8,8 +8,9 @@ export type VerifyRequestObject = (
8
8
  requestObjectEncodedJwt: string,
9
9
  context: {
10
10
  clientId: string;
11
- // jwkKeys: Out<FetchJwks>["keys"];
12
- rpConf: RelyingPartyEntityConfiguration["payload"];
11
+ rpConf: RelyingPartyEntityConfiguration["payload"]["metadata"];
12
+ rpSubject: string;
13
+ state?: string;
13
14
  }
14
15
  ) => Promise<{ requestObject: RequestObject }>;
15
16
 
@@ -17,16 +18,16 @@ export type VerifyRequestObject = (
17
18
  * Function to verify the Request Object's signature and the client ID.
18
19
  * @param requestObjectEncodedJwt The Request Object in JWT format
19
20
  * @param context.clientId The client ID to verify
20
- * @param context.jwkKeys The set of keys to verify the signature
21
21
  * @param context.rpConf The Entity Configuration of the Relying Party
22
+ * @param context.state Optional state
22
23
  * @returns The verified Request Object
23
24
  */
24
25
  export const verifyRequestObject: VerifyRequestObject = async (
25
26
  requestObjectEncodedJwt,
26
- { clientId, rpConf }
27
+ { clientId, rpConf, rpSubject, state }
27
28
  ) => {
28
29
  const requestObjectJwt = decodeJwt(requestObjectEncodedJwt);
29
- const { keys } = getJwksFromConfig(rpConf.metadata);
30
+ const { keys } = getJwksFromConfig(rpConf);
30
31
 
31
32
  // Verify token signature to ensure the request object is authentic
32
33
  const pubKey = keys?.find(
@@ -42,11 +43,21 @@ export const verifyRequestObject: VerifyRequestObject = async (
42
43
 
43
44
  const requestObject = RequestObject.parse(requestObjectJwt.payload);
44
45
 
45
- if (!(clientId === requestObject.client_id && clientId === rpConf.sub)) {
46
+ const isClientIdMatch =
47
+ clientId === requestObject.client_id && clientId === rpSubject;
48
+
49
+ if (!isClientIdMatch) {
46
50
  throw new UnverifiedEntityError(
47
51
  "Client ID does not match Request Object or Entity Configuration"
48
52
  );
49
53
  }
50
54
 
55
+ const isStateMatch =
56
+ state && requestObject.state ? state === requestObject.state : true;
57
+
58
+ if (!isStateMatch) {
59
+ throw new UnverifiedEntityError("State does not match Request Object");
60
+ }
61
+
51
62
  return { requestObject };
52
63
  };
@@ -6,23 +6,32 @@ import {
6
6
  } from "dcql";
7
7
  import { isValiError } from "valibot";
8
8
  import { decode, prepareVpToken } from "../../sd-jwt";
9
- import type { Disclosure, DisclosureWithEncoded } from "../../sd-jwt/types";
9
+ import type { Disclosure } from "../../sd-jwt/types";
10
10
  import { ValidationFailed } from "../../utils/errors";
11
11
  import { createCryptoContextFor } from "../../utils/crypto";
12
12
  import type { RemotePresentation } from "./types";
13
13
 
14
- type EvaluateDcqlQuery = (
14
+ /**
15
+ * The purpose for the credential request by the RP.
16
+ */
17
+ type CredentialPurpose = {
18
+ required: boolean;
19
+ description?: string;
20
+ };
21
+
22
+ export type EvaluateDcqlQuery = (
15
23
  credentialsSdJwt: [string /* keyTag */, string /* credential */][],
16
24
  query: DcqlQuery.Input
17
25
  ) => {
18
26
  id: string;
27
+ vct: string;
19
28
  credential: string;
20
29
  keyTag: string;
21
- requiredDisclosures: DisclosureWithEncoded[];
22
- isOptional?: boolean;
30
+ requiredDisclosures: Disclosure[];
31
+ purposes: CredentialPurpose[];
23
32
  }[];
24
33
 
25
- type PrepareRemotePresentations = (
34
+ export type PrepareRemotePresentations = (
26
35
  credentials: {
27
36
  id: string;
28
37
  credential: string;
@@ -90,7 +99,6 @@ export const evaluateDcqlQuery: EvaluateDcqlQuery = (
90
99
  if (!queryResult.canBeSatisfied) {
91
100
  throw new Error("No credential can satisfy the provided DCQL query");
92
101
  }
93
-
94
102
  // Build an object vct:credentialJwt to map matched credentials to their JWT
95
103
  const credentialsSdJwtByVct = credentials.reduce(
96
104
  (acc, c, i) => ({ ...acc, [c.vct]: credentialsSdJwt[i]! }),
@@ -103,24 +111,24 @@ export const evaluateDcqlQuery: EvaluateDcqlQuery = (
103
111
  }
104
112
  const { vct, claims } = match.output;
105
113
 
106
- // Find a matching credential set to see whether the credential is optional
107
- // If no credential set is found, then the credential is required by default
108
- // NOTE: This is an extra, it might not be necessary
109
- const credentialSet = queryResult.credential_sets?.find((set) =>
110
- set.matching_options?.flat().includes(vct)
111
- );
112
- const isOptional = credentialSet ? !credentialSet.required : false;
114
+ const purposes = queryResult.credential_sets
115
+ ?.filter((set) => set.matching_options?.flat().includes(id))
116
+ ?.map<CredentialPurpose>((credentialSet) => ({
117
+ description: credentialSet.purpose?.toString(),
118
+ required: Boolean(credentialSet.required),
119
+ }));
113
120
 
114
121
  const [keyTag, credential] = credentialsSdJwtByVct[vct]!;
115
- const requiredDisclosures = Object.values(
116
- claims
117
- ) as DisclosureWithEncoded[];
122
+ const requiredDisclosures = Object.values(claims) as Disclosure[];
118
123
  return {
119
124
  id,
125
+ vct,
120
126
  keyTag,
121
127
  credential,
122
- isOptional,
123
128
  requiredDisclosures,
129
+ // When it is a match but no credential_sets are found, the credential is required by default
130
+ // See https://openid.net/specs/openid-4-verifiable-presentations-1_0-24.html#section-6.3.1.2-2.1
131
+ purposes: purposes ?? [{ required: true }],
124
132
  };
125
133
  });
126
134
  } catch (error) {
@@ -33,7 +33,10 @@ export type EvaluateInputDescriptors = (
33
33
  }[]
34
34
  >;
35
35
 
36
- export type PrepareRemotePresentations = (
36
+ /**
37
+ * @deprecated Use `prepareRemotePresentations` from DCQL
38
+ */
39
+ export type PrepareLegacyRemotePresentations = (
37
40
  credentialAndDescriptors: {
38
41
  requestedClaims: string[];
39
42
  inputDescriptor: InputDescriptor;
@@ -352,6 +355,8 @@ export const evaluateInputDescriptors: EvaluateInputDescriptors = async (
352
355
  * - Validates the credential format.
353
356
  * - Generates a verifiable presentation token (vpToken) using the provided nonce and client identifier.
354
357
  *
358
+ * @deprecated Use `prepareRemotePresentations` from DCQL
359
+ *
355
360
  * @param credentialAndDescriptors - An array containing objects with requested claims,
356
361
  * input descriptor, credential, and keyTag.
357
362
  * @param nonce - A unique nonce for the verifiable presentation token.
@@ -359,33 +364,30 @@ export const evaluateInputDescriptors: EvaluateInputDescriptors = async (
359
364
  * @returns A promise that resolves to an array of RemotePresentation objects.
360
365
  * @throws {CredentialNotFoundError} When the credential format is unsupported.
361
366
  */
362
- export const prepareRemotePresentations: PrepareRemotePresentations = async (
363
- credentialAndDescriptors,
364
- nonce,
365
- client_id
366
- ) => {
367
- return Promise.all(
368
- credentialAndDescriptors.map(async (item) => {
369
- const descriptor = item.inputDescriptor;
370
-
371
- if (descriptor.format?.["vc+sd-jwt"]) {
372
- const { vp_token } = await prepareVpToken(nonce, client_id, [
373
- item.credential,
374
- item.requestedClaims,
375
- createCryptoContextFor(item.keyTag),
376
- ]);
377
-
378
- return {
379
- requestedClaims: item.requestedClaims,
380
- inputDescriptor: descriptor,
381
- vpToken: vp_token,
382
- format: "vc+sd-jwt",
383
- };
384
- }
367
+ export const prepareLegacyRemotePresentations: PrepareLegacyRemotePresentations =
368
+ async (credentialAndDescriptors, nonce, client_id) => {
369
+ return Promise.all(
370
+ credentialAndDescriptors.map(async (item) => {
371
+ const descriptor = item.inputDescriptor;
372
+
373
+ if (descriptor.format?.["vc+sd-jwt"]) {
374
+ const { vp_token } = await prepareVpToken(nonce, client_id, [
375
+ item.credential,
376
+ item.requestedClaims,
377
+ createCryptoContextFor(item.keyTag),
378
+ ]);
379
+
380
+ return {
381
+ requestedClaims: item.requestedClaims,
382
+ inputDescriptor: descriptor,
383
+ vpToken: vp_token,
384
+ format: "vc+sd-jwt",
385
+ };
386
+ }
385
387
 
386
- throw new CredentialNotFoundError(
387
- `${descriptor.format} format is not supported.`
388
- );
389
- })
390
- );
391
- };
388
+ throw new CredentialNotFoundError(
389
+ `${descriptor.format} format is not supported.`
390
+ );
391
+ })
392
+ );
393
+ };
@@ -60,7 +60,7 @@ export const choosePublicKeyToEncrypt = (
60
60
  */
61
61
  export const buildDirectPostJwtBody = async (
62
62
  requestObject: Out<VerifyRequestObject>["requestObject"],
63
- rpConf: RelyingPartyEntityConfiguration["payload"],
63
+ rpConf: RelyingPartyEntityConfiguration["payload"]["metadata"],
64
64
  payload: DirectAuthorizationBodyPayload | LegacyDirectAuthorizationBodyPayload
65
65
  ): Promise<string> => {
66
66
  type Jwe = ConstructorParameters<typeof EncryptJwe>[1];
@@ -70,19 +70,21 @@ export const buildDirectPostJwtBody = async (
70
70
  state: requestObject.state,
71
71
  ...payload,
72
72
  });
73
-
74
73
  // Choose a suitable public key for encryption
75
- const { keys } = getJwksFromConfig(rpConf.metadata);
74
+ const { keys } = getJwksFromConfig(rpConf);
76
75
  const encPublicJwk = choosePublicKeyToEncrypt(keys);
77
76
 
78
77
  // Encrypt the authorization payload
79
78
  const {
80
79
  authorization_encrypted_response_alg,
81
80
  authorization_encrypted_response_enc,
82
- } = rpConf.metadata.openid_credential_verifier;
81
+ } = rpConf.openid_credential_verifier;
82
+
83
+ const defaultAlg: Jwe["alg"] =
84
+ encPublicJwk.kty === "EC" ? "ECDH-ES" : "RSA-OAEP-256";
83
85
 
84
86
  const encryptedResponse = await new EncryptJwe(authzResponsePayload, {
85
- alg: (authorization_encrypted_response_alg as Jwe["alg"]) || "RSA-OAEP-256",
87
+ alg: (authorization_encrypted_response_alg as Jwe["alg"]) || defaultAlg,
86
88
  enc:
87
89
  (authorization_encrypted_response_enc as Jwe["enc"]) || "A256CBC-HS512",
88
90
  kid: encPublicJwk.kid,
@@ -106,7 +108,7 @@ export type SendLegacyAuthorizationResponse = (
106
108
  requestObject: Out<VerifyRequestObject>["requestObject"],
107
109
  presentationDefinitionId: string,
108
110
  remotePresentations: LegacyRemotePresentation[],
109
- rpConf: RelyingPartyEntityConfiguration["payload"],
111
+ rpConf: RelyingPartyEntityConfiguration["payload"]["metadata"],
110
112
  context?: {
111
113
  appFetch?: GlobalFetch["fetch"];
112
114
  }
@@ -183,7 +185,7 @@ export const sendLegacyAuthorizationResponse: SendLegacyAuthorizationResponse =
183
185
  export type SendAuthorizationResponse = (
184
186
  requestObject: Out<VerifyRequestObject>["requestObject"],
185
187
  remotePresentations: RemotePresentation[],
186
- rpConf: RelyingPartyEntityConfiguration["payload"],
188
+ rpConf: RelyingPartyEntityConfiguration["payload"]["metadata"],
187
189
  context?: {
188
190
  appFetch?: GlobalFetch["fetch"];
189
191
  }
@@ -1,3 +1,89 @@
1
- # Credential presentation
1
+ # Credential Presentation
2
2
 
3
- Currently this flow is outdated.
3
+ This flow is used for remote presentation, allowing a user with a valid Wallet Instance to remotely present credentials to a Relying Party (Verifier). The presentation flow adheres to the [IT Wallet 0.9.x specification](https://italia.github.io/eid-wallet-it-docs/v0.9.3/en/relying-party-solution.html).
4
+
5
+ The Relying Party provides the Wallet with a Request Object that contains the requested credentials and claims. The Wallet validates the Request Object and asks the user for consent. Then the Wallet creates an encrypted Authorization Response that contains the Verifiable Presentation with the requested data (`vp_token`) and sends it to the Relying Party.
6
+
7
+ ## Sequence Diagram
8
+
9
+ ```mermaid
10
+ sequenceDiagram
11
+ autonumber
12
+ participant I as User (Wallet Instance)
13
+ participant O as Relying Party (Verifier)
14
+
15
+ O->>+I: QR-CODE: Authorization Request (`request_uri`)
16
+ I->>+O: GET: Verifier's Entity Configuration
17
+ O->>+I: Respond with metadata (including public keys)
18
+ I->>+O: GET: Request Object, resolved from the `request_uri`
19
+ O->>+I: Respond with the Request Object
20
+ I->>+O: POST: VP token encrypted response
21
+ O->>+I: Redirect: Authorization Response
22
+ ```
23
+
24
+
25
+ ## Examples
26
+
27
+ <details>
28
+ <summary>Remote Presentation flow</summary>
29
+
30
+ **Note:** To successfully complete a remote presentation, the Wallet Instance must be in a valid state with a valid Wallet Instance Attestation.
31
+
32
+ ```ts
33
+ // Retrieve and scan the qr-code, decode it and get its parameters
34
+ const qrCodeParams = decodeQrCode(qrCode)
35
+
36
+ // Start the issuance flow
37
+ const {
38
+ requestUri,
39
+ clientId,
40
+ requestUriMethod,
41
+ state
42
+ } = Credential.Presentation.startFlowFromQR(qrCodeParams);
43
+
44
+ // Get the Relying Party's Entity Configuration and evaluate trust
45
+ const { rpConf } = await Credential.Presentation.evaluateRelyingPartyTrust(clientId);
46
+
47
+ // Get the Request Object from the RP
48
+ const { requestObjectEncodedJwt } =
49
+ await Credential.Presentation.getRequestObject(requestUri);
50
+
51
+ // Validate the Request Object
52
+ const { requestObject } = await Credential.Presentation.verifyRequestObject(
53
+ requestObjectEncodedJwt,
54
+ { clientId, rpConf }
55
+ );
56
+
57
+ // All the credentials that might be requested by the Relying Party
58
+ const credentialsSdJwt = [
59
+ ["credential1_keytag", "eyJraWQiOiItRl82VWdhOG4zVmVnalkyVTdZVUhLMXpMb2FELU5QVGM2M1JNSVNuTGF3IiwidHlwIjoidmMrc2Qtand0IiwiYWxnIjoiRVMyNTYifQ.eyJfc2"],
60
+ ["credential2_keytag", "eyJ0eXAiOiJ2YytzZC1qd3QiLCJhbGciOiJFUzI1NiIsImtpZCI6Ii1GXzZVZ2E4bjNWZWdqWTJVN1lVSEsxekxvYUQtTlBUYzYzUk1JU25MYXcifQ.ew0KIC"]
61
+ ];
62
+
63
+ const result = Credential.Presentation.evaluateDcqlQuery(
64
+ credentialsSdJwt,
65
+ requestObject.dcql_query as DcqlQuery
66
+ );
67
+
68
+ const credentialsToPresent = result.map(
69
+ ({ requiredDisclosures, ...rest }) => ({
70
+ ...rest,
71
+ requestedClaims: requiredDisclosures.map(([, claimName]) => claimName),
72
+ })
73
+ );
74
+
75
+ const remotePresentations =
76
+ await Credential.Presentation.prepareRemotePresentations(
77
+ credentialsToPresent,
78
+ requestObject.nonce,
79
+ requestObject.client_id
80
+ );
81
+
82
+ const authResponse = await Credential.Presentation.sendAuthorizationResponse(
83
+ requestObject,
84
+ remotePresentations,
85
+ rpConf
86
+ );
87
+ ```
88
+
89
+ </details>
@@ -47,12 +47,12 @@ export class NoSuitableKeysFoundInEntityConfiguration extends IoWalletError {
47
47
  export class InvalidQRCodeError extends IoWalletError {
48
48
  code = "ERR_INVALID_QR_CODE";
49
49
 
50
- /**
51
- * @param detail A description of why the QR code is considered invalid.
52
- */
53
- constructor(detail: string) {
54
- const message = `QR code is not valid: ${detail}.`;
55
- super(message);
50
+ /** Detailed reason for the QR code validation failure. */
51
+ reason: string;
52
+
53
+ constructor(reason: string) {
54
+ super("Invalid QR code");
55
+ this.reason = reason;
56
56
  }
57
57
  }
58
58
 
@@ -17,12 +17,22 @@ import {
17
17
  type FetchPresentationDefinition,
18
18
  } from "./06-fetch-presentation-definition";
19
19
  import {
20
- evaluateInputDescriptorForSdJwt4VC,
21
- type EvaluateInputDescriptorSdJwt4VC,
20
+ evaluateInputDescriptors,
21
+ prepareLegacyRemotePresentations,
22
+ type EvaluateInputDescriptors,
23
+ type PrepareLegacyRemotePresentations,
22
24
  } from "./07-evaluate-input-descriptor";
25
+ import {
26
+ evaluateDcqlQuery,
27
+ prepareRemotePresentations,
28
+ type EvaluateDcqlQuery,
29
+ type PrepareRemotePresentations,
30
+ } from "./07-evaluate-dcql-query";
23
31
  import {
24
32
  sendAuthorizationResponse,
25
33
  type SendAuthorizationResponse,
34
+ sendLegacyAuthorizationResponse,
35
+ type SendLegacyAuthorizationResponse,
26
36
  } from "./08-send-authorization-response";
27
37
  import * as Errors from "./errors";
28
38
 
@@ -33,8 +43,12 @@ export {
33
43
  getJwksFromConfig,
34
44
  verifyRequestObject,
35
45
  fetchPresentDefinition,
36
- evaluateInputDescriptorForSdJwt4VC,
46
+ evaluateInputDescriptors,
47
+ evaluateDcqlQuery,
48
+ prepareLegacyRemotePresentations,
49
+ prepareRemotePresentations,
37
50
  sendAuthorizationResponse,
51
+ sendLegacyAuthorizationResponse,
38
52
  Errors,
39
53
  };
40
54
  export type {
@@ -44,6 +58,10 @@ export type {
44
58
  FetchJwks,
45
59
  VerifyRequestObject,
46
60
  FetchPresentationDefinition,
47
- EvaluateInputDescriptorSdJwt4VC,
61
+ EvaluateInputDescriptors,
62
+ EvaluateDcqlQuery,
63
+ PrepareLegacyRemotePresentations,
64
+ PrepareRemotePresentations,
48
65
  SendAuthorizationResponse,
66
+ SendLegacyAuthorizationResponse,
49
67
  };
@@ -94,7 +94,7 @@ export const RequestObject = z.object({
94
94
  iss: z.string(),
95
95
  iat: UnixTime,
96
96
  exp: UnixTime,
97
- state: z.string(),
97
+ state: z.string().optional(),
98
98
  nonce: z.string(),
99
99
  response_uri: z.string(),
100
100
  response_uri_method: z.string().optional(),