@pagopa/io-react-native-wallet 1.3.0 → 1.4.0

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 (100) hide show
  1. package/lib/commonjs/credential/issuance/06-obtain-credential.js +8 -2
  2. package/lib/commonjs/credential/issuance/06-obtain-credential.js.map +1 -1
  3. package/lib/commonjs/credential/issuance/07-verify-and-parse-credential.js +147 -3
  4. package/lib/commonjs/credential/issuance/07-verify-and-parse-credential.js.map +1 -1
  5. package/lib/commonjs/credential/issuance/const.js +1 -1
  6. package/lib/commonjs/credential/issuance/const.js.map +1 -1
  7. package/lib/commonjs/credential/issuance/types.js +1 -1
  8. package/lib/commonjs/credential/issuance/types.js.map +1 -1
  9. package/lib/commonjs/credential/presentation/03-get-request-object.js +7 -25
  10. package/lib/commonjs/credential/presentation/03-get-request-object.js.map +1 -1
  11. package/lib/commonjs/credential/presentation/07-evaluate-input-descriptor.js +1 -1
  12. package/lib/commonjs/credential/presentation/07-evaluate-input-descriptor.js.map +1 -1
  13. package/lib/commonjs/credential/presentation/08-send-authorization-response.js +52 -12
  14. package/lib/commonjs/credential/presentation/08-send-authorization-response.js.map +1 -1
  15. package/lib/commonjs/credential/presentation/README.md +1 -3
  16. package/lib/commonjs/credential/presentation/index.js +6 -0
  17. package/lib/commonjs/credential/presentation/index.js.map +1 -1
  18. package/lib/commonjs/credential/presentation/types.js +19 -1
  19. package/lib/commonjs/credential/presentation/types.js.map +1 -1
  20. package/lib/commonjs/entity/openid-connect/issuer/types.js +10 -7
  21. package/lib/commonjs/entity/openid-connect/issuer/types.js.map +1 -1
  22. package/lib/commonjs/entity/trust/types.js +1 -1
  23. package/lib/commonjs/entity/trust/types.js.map +1 -1
  24. package/lib/commonjs/mdoc/converters.js +26 -0
  25. package/lib/commonjs/mdoc/converters.js.map +1 -0
  26. package/lib/commonjs/mdoc/index.js +28 -0
  27. package/lib/commonjs/mdoc/index.js.map +1 -0
  28. package/lib/commonjs/utils/string.js +13 -1
  29. package/lib/commonjs/utils/string.js.map +1 -1
  30. package/lib/module/credential/issuance/06-obtain-credential.js +8 -2
  31. package/lib/module/credential/issuance/06-obtain-credential.js.map +1 -1
  32. package/lib/module/credential/issuance/07-verify-and-parse-credential.js +147 -3
  33. package/lib/module/credential/issuance/07-verify-and-parse-credential.js.map +1 -1
  34. package/lib/module/credential/issuance/const.js +1 -1
  35. package/lib/module/credential/issuance/const.js.map +1 -1
  36. package/lib/module/credential/issuance/types.js +1 -1
  37. package/lib/module/credential/issuance/types.js.map +1 -1
  38. package/lib/module/credential/presentation/03-get-request-object.js +7 -24
  39. package/lib/module/credential/presentation/03-get-request-object.js.map +1 -1
  40. package/lib/module/credential/presentation/07-evaluate-input-descriptor.js +1 -1
  41. package/lib/module/credential/presentation/07-evaluate-input-descriptor.js.map +1 -1
  42. package/lib/module/credential/presentation/08-send-authorization-response.js +51 -11
  43. package/lib/module/credential/presentation/08-send-authorization-response.js.map +1 -1
  44. package/lib/module/credential/presentation/README.md +1 -3
  45. package/lib/module/credential/presentation/index.js +2 -2
  46. package/lib/module/credential/presentation/index.js.map +1 -1
  47. package/lib/module/credential/presentation/types.js +18 -0
  48. package/lib/module/credential/presentation/types.js.map +1 -1
  49. package/lib/module/entity/openid-connect/issuer/types.js +7 -6
  50. package/lib/module/entity/openid-connect/issuer/types.js.map +1 -1
  51. package/lib/module/entity/trust/types.js +1 -1
  52. package/lib/module/entity/trust/types.js.map +1 -1
  53. package/lib/module/mdoc/converters.js +20 -0
  54. package/lib/module/mdoc/converters.js.map +1 -0
  55. package/lib/module/mdoc/index.js +21 -0
  56. package/lib/module/mdoc/index.js.map +1 -0
  57. package/lib/module/utils/string.js +12 -0
  58. package/lib/module/utils/string.js.map +1 -1
  59. package/lib/typescript/credential/issuance/06-obtain-credential.d.ts.map +1 -1
  60. package/lib/typescript/credential/issuance/07-verify-and-parse-credential.d.ts.map +1 -1
  61. package/lib/typescript/credential/issuance/const.d.ts +1 -1
  62. package/lib/typescript/credential/issuance/const.d.ts.map +1 -1
  63. package/lib/typescript/credential/issuance/types.d.ts +7 -7
  64. package/lib/typescript/credential/presentation/03-get-request-object.d.ts +2 -8
  65. package/lib/typescript/credential/presentation/03-get-request-object.d.ts.map +1 -1
  66. package/lib/typescript/credential/presentation/07-evaluate-input-descriptor.d.ts.map +1 -1
  67. package/lib/typescript/credential/presentation/08-send-authorization-response.d.ts +23 -7
  68. package/lib/typescript/credential/presentation/08-send-authorization-response.d.ts.map +1 -1
  69. package/lib/typescript/credential/presentation/index.d.ts +3 -3
  70. package/lib/typescript/credential/presentation/index.d.ts.map +1 -1
  71. package/lib/typescript/credential/presentation/types.d.ts +26 -0
  72. package/lib/typescript/credential/presentation/types.d.ts.map +1 -1
  73. package/lib/typescript/entity/openid-connect/issuer/types.d.ts +177 -41
  74. package/lib/typescript/entity/openid-connect/issuer/types.d.ts.map +1 -1
  75. package/lib/typescript/entity/trust/index.d.ts +2 -2
  76. package/lib/typescript/entity/trust/types.d.ts +22 -22
  77. package/lib/typescript/mdoc/converters.d.ts +8 -0
  78. package/lib/typescript/mdoc/converters.d.ts.map +1 -0
  79. package/lib/typescript/mdoc/index.d.ts +6 -0
  80. package/lib/typescript/mdoc/index.d.ts.map +1 -0
  81. package/lib/typescript/sd-jwt/index.d.ts +4 -4
  82. package/lib/typescript/sd-jwt/types.d.ts +5 -5
  83. package/lib/typescript/utils/string.d.ts +7 -0
  84. package/lib/typescript/utils/string.d.ts.map +1 -1
  85. package/package.json +3 -1
  86. package/src/credential/issuance/06-obtain-credential.ts +14 -5
  87. package/src/credential/issuance/07-verify-and-parse-credential.ts +201 -1
  88. package/src/credential/issuance/const.ts +1 -1
  89. package/src/credential/issuance/types.ts +1 -1
  90. package/src/credential/presentation/03-get-request-object.ts +4 -29
  91. package/src/credential/presentation/07-evaluate-input-descriptor.ts +2 -5
  92. package/src/credential/presentation/08-send-authorization-response.ts +70 -22
  93. package/src/credential/presentation/README.md +1 -3
  94. package/src/credential/presentation/index.ts +4 -0
  95. package/src/credential/presentation/types.ts +26 -0
  96. package/src/entity/openid-connect/issuer/types.ts +18 -10
  97. package/src/entity/trust/types.ts +1 -1
  98. package/src/mdoc/converters.ts +26 -0
  99. package/src/mdoc/index.ts +28 -0
  100. package/src/utils/string.ts +12 -0
@@ -1,19 +1,10 @@
1
- import uuid from "react-native-uuid";
2
- import {
3
- sha256ToBase64,
4
- type CryptoContext,
5
- } from "@pagopa/io-react-native-jwt";
6
-
7
- import { createDPopToken } from "../../utils/dpop";
8
1
  import { hasStatusOrThrow, type Out } from "../../utils/misc";
9
2
  import type { StartFlow } from "./01-start-flow";
10
3
 
11
4
  export type GetRequestObject = (
12
5
  requestUri: Out<StartFlow>["requestUri"],
13
- context: {
14
- wiaCryptoContext: CryptoContext;
6
+ context?: {
15
7
  appFetch?: GlobalFetch["fetch"];
16
- walletInstanceAttestation: string;
17
8
  }
18
9
  ) => Promise<{ requestObjectEncodedJwt: string }>;
19
10
 
@@ -21,33 +12,17 @@ export type GetRequestObject = (
21
12
  * Obtain the Request Object for RP authentication
22
13
  * @see https://italia.github.io/eudi-wallet-it-docs/versione-corrente/en/relying-party-solution.html
23
14
  *
24
- * @param requestUri The url for the Relying Party to connect with
25
- * @param rpConf The Relying Party's configuration
26
- * @param context.wiaCryptoContext The context to access the key associated with the Wallet Instance Attestation
27
- * @param context.walletInstanceAttestation The Wallet Instance Attestation token
15
+ * @param requestUri The request uri of the Relying Party
28
16
  * @param context.appFetch (optional) fetch api implementation. Default: built-in fetch
29
17
  * @returns The Request Object that describes the presentation
30
18
  */
31
19
  export const getRequestObject: GetRequestObject = async (
32
20
  requestUri,
33
- { wiaCryptoContext, appFetch = fetch, walletInstanceAttestation }
21
+ context = {}
34
22
  ) => {
35
- const signedWalletInstanceDPoP = await createDPopToken(
36
- {
37
- jti: `${uuid.v4()}`,
38
- htm: "GET",
39
- htu: requestUri,
40
- ath: await sha256ToBase64(walletInstanceAttestation),
41
- },
42
- wiaCryptoContext
43
- );
44
-
23
+ const { appFetch = fetch } = context;
45
24
  const requestObjectEncodedJwt = await appFetch(requestUri, {
46
25
  method: "GET",
47
- headers: {
48
- Authorization: `DPoP ${walletInstanceAttestation}`,
49
- DPoP: signedWalletInstanceDPoP,
50
- },
51
26
  })
52
27
  .then(hasStatusOrThrow(200))
53
28
  .then((res) => res.text());
@@ -189,11 +189,8 @@ export const evaluateInputDescriptorForSdJwt4VC: EvaluateInputDescriptorSdJwt4VC
189
189
  requiredClaimNames.includes(disclosure.decoded[INDEX_CLAIM_NAME])
190
190
  );
191
191
 
192
- const optionalDisclosures = disclosures.filter(
193
- (disclosure) =>
194
- optionalClaimNames.includes(disclosure.decoded[INDEX_CLAIM_NAME]) ||
195
- (isNotLimitDisclosure &&
196
- !requiredClaimNames.includes(disclosure.decoded[INDEX_CLAIM_NAME]))
192
+ const optionalDisclosures = disclosures.filter((disclosure) =>
193
+ optionalClaimNames.includes(disclosure.decoded[INDEX_CLAIM_NAME])
197
194
  );
198
195
 
199
196
  const isNotLimitDisclosure = !(
@@ -9,7 +9,12 @@ import type { VerifyRequestObjectSignature } from "./05-verify-request-object";
9
9
  import { NoSuitableKeysFoundInEntityConfiguration } from "./errors";
10
10
  import { hasStatusOrThrow, type Out } from "../../utils/misc";
11
11
  import { disclose } from "../../sd-jwt";
12
- import { PresentationDefinition, type Presentation } from "./types";
12
+ import {
13
+ DirectAuthorizationBodyPayload,
14
+ ErrorResponse,
15
+ PresentationDefinition,
16
+ type Presentation,
17
+ } from "./types";
13
18
  import * as z from "zod";
14
19
  import type { JWK } from "../../utils/jwk";
15
20
 
@@ -125,19 +130,20 @@ export const prepareVpToken = async (
125
130
  * Builds a URL-encoded form body for a direct POST response without encryption.
126
131
  *
127
132
  * @param requestObject - Contains state, nonce, and other relevant info.
128
- * @param vpToken - The signed VP token to include.
129
- * @param presentationSubmission - Object mapping credential disclosures.
133
+ * @param payload - Object that contains either the VP token to encrypt and the stringified mapping of the credential disclosures or the error code
130
134
  * @returns A URL-encoded string suitable for an `application/x-www-form-urlencoded` POST body.
131
135
  */
132
136
  export const buildDirectPostBody = async (
133
137
  requestObject: Out<VerifyRequestObjectSignature>["requestObject"],
134
- vpToken: string,
135
- presentationSubmission: Record<string, unknown>
138
+ payload: DirectAuthorizationBodyPayload
136
139
  ): Promise<string> => {
137
140
  const formUrlEncodedBody = new URLSearchParams({
138
141
  state: requestObject.state,
139
- presentation_submission: JSON.stringify(presentationSubmission),
140
- vp_token: vpToken,
142
+ ...Object.fromEntries(
143
+ Object.entries(payload).map(([key, value]) => {
144
+ return [key, typeof value === "object" ? JSON.stringify(value) : value];
145
+ })
146
+ ),
141
147
  });
142
148
 
143
149
  return formUrlEncodedBody.toString();
@@ -148,22 +154,19 @@ export const buildDirectPostBody = async (
148
154
  *
149
155
  * @param jwkKeys - Array of JWKs from the Relying Party for encryption.
150
156
  * @param requestObject - Contains state, nonce, and other relevant info.
151
- * @param vpToken - The signed VP token to encrypt.
152
- * @param presentationSubmission - Object mapping credential disclosures.
157
+ * @param payload - Object that contains either the VP token to encrypt and the mapping of the credential disclosures or the error code
153
158
  * @returns A URL-encoded string for an `application/x-www-form-urlencoded` POST body,
154
159
  * where `response` contains the encrypted JWE.
155
160
  */
156
161
  export const buildDirectPostJwtBody = async (
157
162
  jwkKeys: Out<FetchJwks>["keys"],
158
163
  requestObject: Out<VerifyRequestObjectSignature>["requestObject"],
159
- vpToken: string,
160
- presentationSubmission: Record<string, unknown>
164
+ payload: DirectAuthorizationBodyPayload
161
165
  ): Promise<string> => {
162
166
  // Prepare the authorization response payload to be encrypted
163
167
  const authzResponsePayload = JSON.stringify({
164
168
  state: requestObject.state,
165
- presentation_submission: presentationSubmission,
166
- vp_token: vpToken,
169
+ ...payload,
167
170
  });
168
171
 
169
172
  // Choose a suitable RSA public key for encryption
@@ -233,17 +236,14 @@ export const sendAuthorizationResponse: SendAuthorizationResponse = async (
233
236
  // 2. Choose the appropriate request body builder based on response mode
234
237
  const requestBody =
235
238
  requestObject.response_mode === "direct_post.jwt"
236
- ? await buildDirectPostJwtBody(
237
- jwkKeys,
238
- requestObject,
239
+ ? await buildDirectPostJwtBody(jwkKeys, requestObject, {
239
240
  vp_token,
240
- presentation_submission
241
- )
242
- : await buildDirectPostBody(
243
- requestObject,
241
+ presentation_submission,
242
+ })
243
+ : await buildDirectPostBody(requestObject, {
244
244
  vp_token,
245
- presentation_submission
246
- );
245
+ presentation_submission: presentation_submission,
246
+ });
247
247
 
248
248
  // 3. Send the authorization response via HTTP POST and validate the response
249
249
  return await appFetch(requestObject.response_uri, {
@@ -257,3 +257,51 @@ export const sendAuthorizationResponse: SendAuthorizationResponse = async (
257
257
  .then((res) => res.json())
258
258
  .then(AuthorizationResponse.parse);
259
259
  };
260
+
261
+ /**
262
+ * Type definition for the function that sends the authorization response
263
+ * to the Relying Party, completing the presentation flow.
264
+ */
265
+ export type SendAuthorizationErrorResponse = (
266
+ requestObject: Out<VerifyRequestObjectSignature>["requestObject"],
267
+ error: ErrorResponse,
268
+ jwkKeys: Out<FetchJwks>["keys"],
269
+ context?: {
270
+ appFetch?: GlobalFetch["fetch"];
271
+ }
272
+ ) => Promise<AuthorizationResponse>;
273
+
274
+ /**
275
+ * Sends the authorization error response to the Relying Party (RP) using the specified `response_mode`.
276
+ * This function completes the presentation flow in an OpenID 4 Verifiable Presentations scenario.
277
+ *
278
+ * @param requestObject - The request details, including presentation requirements.
279
+ * @param error - The response error value
280
+ * @param jwkKeys - Array of JWKs from the Relying Party for optional encryption.
281
+ * @param context - Contains optional custom fetch implementation.
282
+ * @returns Parsed and validated authorization response from the Relying Party.
283
+ */
284
+ export const sendAuthorizationErrorResponse: SendAuthorizationErrorResponse =
285
+ async (
286
+ requestObject,
287
+ error,
288
+ jwkKeys,
289
+ { appFetch = fetch } = {}
290
+ ): Promise<AuthorizationResponse> => {
291
+ // 2. Choose the appropriate request body builder based on response mode
292
+ const requestBody =
293
+ requestObject.response_mode === "direct_post.jwt"
294
+ ? await buildDirectPostJwtBody(jwkKeys, requestObject, { error })
295
+ : await buildDirectPostBody(requestObject, { error });
296
+ // 3. Send the authorization error response via HTTP POST and validate the response
297
+ return await appFetch(requestObject.response_uri, {
298
+ method: "POST",
299
+ headers: {
300
+ "Content-Type": "application/x-www-form-urlencoded",
301
+ },
302
+ body: requestBody,
303
+ })
304
+ .then(hasStatusOrThrow(200))
305
+ .then((res) => res.json())
306
+ .then(AuthorizationResponse.parse);
307
+ };
@@ -62,9 +62,7 @@ const { rpConf } = await Credential.Presentation.evaluateRelyingPartyTrust(clien
62
62
 
63
63
  const { requestObjectEncodedJwt } =
64
64
  await Credential.Presentation.getRequestObject(requestURI, {
65
- wiaCryptoContext: wiaCryptoContext,
66
- appFetch: appFetch,
67
- walletInstanceAttestation: walletInstanceAttestation,
65
+ appFetch: appFetch
68
66
  });
69
67
 
70
68
  // Retrieve RP JWK
@@ -27,6 +27,8 @@ import {
27
27
  import {
28
28
  sendAuthorizationResponse,
29
29
  type SendAuthorizationResponse,
30
+ sendAuthorizationErrorResponse,
31
+ type SendAuthorizationErrorResponse,
30
32
  } from "./08-send-authorization-response";
31
33
  import * as Errors from "./errors";
32
34
 
@@ -40,6 +42,7 @@ export {
40
42
  fetchPresentDefinition,
41
43
  evaluateInputDescriptorForSdJwt4VC,
42
44
  sendAuthorizationResponse,
45
+ sendAuthorizationErrorResponse,
43
46
  Errors,
44
47
  };
45
48
  export type {
@@ -51,4 +54,5 @@ export type {
51
54
  FetchPresentationDefinition,
52
55
  EvaluateInputDescriptorSdJwt4VC,
53
56
  SendAuthorizationResponse,
57
+ SendAuthorizationErrorResponse,
54
58
  };
@@ -90,3 +90,29 @@ export const RequestObject = z.object({
90
90
  scope: z.string().optional(),
91
91
  presentation_definition: PresentationDefinition.optional(),
92
92
  });
93
+
94
+ /**
95
+ * This type models the possible error responses the OpenID4VP protocol allows for a presentation of a credential.
96
+ * See https://openid.github.io/OpenID4VP/openid-4-verifiable-presentations-wg-draft.html#name-error-response for more information.
97
+ */
98
+ export type ErrorResponse = z.infer<typeof ErrorResponse>;
99
+ export const ErrorResponse = z.enum([
100
+ "invalid_scope",
101
+ "invalid_request",
102
+ "invalid_client",
103
+ "access_denied",
104
+ ]);
105
+
106
+ /**
107
+ * Type that defines the possible payload formats accepted by {@link buildDirectPostJwtBody} and {@link buildDirectPostBody}
108
+ */
109
+ export type DirectAuthorizationBodyPayload = z.infer<
110
+ typeof DirectAuthorizationBodyPayload
111
+ >;
112
+ export const DirectAuthorizationBodyPayload = z.union([
113
+ z.object({
114
+ vp_token: z.string(),
115
+ presentation_submission: z.record(z.string(), z.unknown()),
116
+ }),
117
+ z.object({ error: ErrorResponse }),
118
+ ]);
@@ -24,14 +24,17 @@ export const CredentialClaimDisplay = z.object({
24
24
 
25
25
  export const CredentialFormat = z.union([
26
26
  z.literal("vc+sd-jwt"),
27
- z.literal("example+sd-jwt"),
27
+ z.literal("mso_mdoc"),
28
28
  ]);
29
- const CredentialSdJwtClaims = z.record(
30
- z.object({
31
- mandatory: z.boolean(),
32
- display: z.array(CredentialClaimDisplay),
33
- })
34
- );
29
+
30
+ export type CredentialClaim = z.infer<typeof CredentialClaim>;
31
+ export const CredentialClaim = z.object({
32
+ mandatory: z.boolean(),
33
+ display: z.array(CredentialClaimDisplay),
34
+ });
35
+
36
+ export type CredentialSdJwtClaims = z.infer<typeof CredentialSdJwtClaims>;
37
+ export const CredentialSdJwtClaims = z.record(CredentialClaim);
35
38
 
36
39
  export type CredentialConfigurationSupported = z.infer<
37
40
  typeof CredentialConfigurationSupported
@@ -39,12 +42,17 @@ export type CredentialConfigurationSupported = z.infer<
39
42
  export const CredentialConfigurationSupported = z.record(
40
43
  z.object({
41
44
  cryptographic_suites_supported: z.array(z.string()),
42
- vct: z.string(),
43
- scope: z.string(),
45
+ vct: z.string().optional(),
46
+ scope: z.string().optional(),
44
47
  cryptographic_binding_methods_supported: z.array(z.string()),
45
48
  display: z.array(CredentialDisplay),
46
49
  format: CredentialFormat,
47
- claims: CredentialSdJwtClaims,
50
+ claims: z
51
+ .union([
52
+ CredentialSdJwtClaims,
53
+ z.record(z.string(), CredentialSdJwtClaims),
54
+ ])
55
+ .optional(),
48
56
  })
49
57
  );
50
58
 
@@ -70,7 +70,7 @@ const IssuanceErrorSupported = z.object({
70
70
  // Metadata for a credentia which is supported by a Issuer
71
71
  type SupportedCredentialMetadata = z.infer<typeof SupportedCredentialMetadata>;
72
72
  const SupportedCredentialMetadata = z.object({
73
- format: z.union([z.literal("vc+sd-jwt"), z.literal("vc+mdoc-cbor")]),
73
+ format: z.union([z.literal("vc+sd-jwt"), z.literal("mso_mdoc")]),
74
74
  scope: z.string(),
75
75
  display: z.array(CredentialDisplayMetadata),
76
76
  claims: ClaimsMetadata.optional(), // TODO [SIW-1268]: should not be optional
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Extracts the date value of a given elementIdentifier from an MDOC object.
3
+ * Searches through the issuerSigned namespaces and attempts to parse the value as a Date.
4
+ * The expected date format is "DD-MM-YYYY".
5
+ * Returns the Date object if found, otherwise returns null.
6
+ */
7
+ export function extractElementValueAsDate(elementValue: string): Date | null {
8
+ if (typeof elementValue === "string") {
9
+ const dateParts = elementValue.split("-");
10
+ if (dateParts.length === 3) {
11
+ const [day, month, year] = dateParts.map((part) => Number(part));
12
+ if (
13
+ day !== undefined &&
14
+ month !== undefined &&
15
+ year !== undefined &&
16
+ !isNaN(day) &&
17
+ !isNaN(month) &&
18
+ !isNaN(year)
19
+ ) {
20
+ return new Date(year, month - 1, day); // Month is zero-based in JS Date
21
+ }
22
+ }
23
+ }
24
+
25
+ return null; // Return null if no matching element is found or it's not a valid date
26
+ }
@@ -0,0 +1,28 @@
1
+ import { CBOR } from "@pagopa/io-react-native-cbor";
2
+ import type { JWK } from "../utils/jwk";
3
+
4
+ export const verify = async (
5
+ token: string,
6
+ publicKey: JWK | JWK[]
7
+ ): Promise<{ mDoc: CBOR.MDOC }> => {
8
+ // get decoded data
9
+ const documents = await CBOR.decodeDocuments(token);
10
+ if (!documents || documents.documents.length === 0) {
11
+ throw new Error("Invalid mDoc");
12
+ }
13
+ const mDoc = documents.documents[0];
14
+ if (!mDoc) {
15
+ throw new Error("Invalid mDoc");
16
+ }
17
+
18
+ const sigKey = Array.isArray(publicKey)
19
+ ? publicKey.find((k) => k.use === "sig")
20
+ : publicKey;
21
+ sigKey;
22
+
23
+ //await COSE.verify(mDoc.issuerSigned.issuerAuth, sigKey as PublicKey);
24
+
25
+ return {
26
+ mDoc,
27
+ };
28
+ };
@@ -1,3 +1,5 @@
1
+ import { Buffer } from "buffer";
2
+
1
3
  /**
2
4
  * Randomly obfuscates characters in a string by replacing them with a specified character.
3
5
  *
@@ -43,3 +45,13 @@ export const obfuscateString = (
43
45
 
44
46
  return chars.join("");
45
47
  };
48
+
49
+ /**
50
+ * Converts a hexadecimal byte string to a Base64 URL-encoded string.
51
+ *
52
+ * @param byteString - The input string in hexadecimal format.
53
+ * @returns The Base64 URL-encoded string.
54
+ */
55
+ export const byteStringToBase64Url = (byteString: string): string => {
56
+ return Buffer.from(byteString, "hex").toString("base64");
57
+ };