@learncard/openid4vc-plugin 0.0.1

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 (90) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +592 -0
  3. package/dist/dcql/adapt.d.ts +80 -0
  4. package/dist/dcql/adapt.d.ts.map +1 -0
  5. package/dist/dcql/build.d.ts +122 -0
  6. package/dist/dcql/build.d.ts.map +1 -0
  7. package/dist/dcql/compose.d.ts +78 -0
  8. package/dist/dcql/compose.d.ts.map +1 -0
  9. package/dist/dcql/index.d.ts +18 -0
  10. package/dist/dcql/index.d.ts.map +1 -0
  11. package/dist/dcql/parse.d.ts +16 -0
  12. package/dist/dcql/parse.d.ts.map +1 -0
  13. package/dist/dcql/respond.d.ts +115 -0
  14. package/dist/dcql/respond.d.ts.map +1 -0
  15. package/dist/dcql/select.d.ts +63 -0
  16. package/dist/dcql/select.d.ts.map +1 -0
  17. package/dist/dcql/types.d.ts +93 -0
  18. package/dist/dcql/types.d.ts.map +1 -0
  19. package/dist/index.d.ts +8 -0
  20. package/dist/index.d.ts.map +1 -0
  21. package/dist/index.js +7 -0
  22. package/dist/offer/index.d.ts +4 -0
  23. package/dist/offer/index.d.ts.map +1 -0
  24. package/dist/offer/normalize.d.ts +15 -0
  25. package/dist/offer/normalize.d.ts.map +1 -0
  26. package/dist/offer/parse.d.ts +24 -0
  27. package/dist/offer/parse.d.ts.map +1 -0
  28. package/dist/offer/types.d.ts +92 -0
  29. package/dist/offer/types.d.ts.map +1 -0
  30. package/dist/openid4vc-plugin.cjs.development.js +27402 -0
  31. package/dist/openid4vc-plugin.cjs.development.js.map +7 -0
  32. package/dist/openid4vc-plugin.cjs.production.min.js +146 -0
  33. package/dist/openid4vc-plugin.cjs.production.min.js.map +7 -0
  34. package/dist/openid4vc-plugin.esm.js +27396 -0
  35. package/dist/openid4vc-plugin.esm.js.map +7 -0
  36. package/dist/plugin.d.ts +12 -0
  37. package/dist/plugin.d.ts.map +1 -0
  38. package/dist/siop/index.d.ts +11 -0
  39. package/dist/siop/index.d.ts.map +1 -0
  40. package/dist/siop/sign.d.ts +92 -0
  41. package/dist/siop/sign.d.ts.map +1 -0
  42. package/dist/types.d.ts +359 -0
  43. package/dist/types.d.ts.map +1 -0
  44. package/dist/vci/accept.d.ts +24 -0
  45. package/dist/vci/accept.d.ts.map +1 -0
  46. package/dist/vci/auth-code.d.ts +148 -0
  47. package/dist/vci/auth-code.d.ts.map +1 -0
  48. package/dist/vci/decode.d.ts +65 -0
  49. package/dist/vci/decode.d.ts.map +1 -0
  50. package/dist/vci/errors.d.ts +22 -0
  51. package/dist/vci/errors.d.ts.map +1 -0
  52. package/dist/vci/index.d.ts +12 -0
  53. package/dist/vci/index.d.ts.map +1 -0
  54. package/dist/vci/metadata.d.ts +25 -0
  55. package/dist/vci/metadata.d.ts.map +1 -0
  56. package/dist/vci/pkce.d.ts +85 -0
  57. package/dist/vci/pkce.d.ts.map +1 -0
  58. package/dist/vci/proof.d.ts +43 -0
  59. package/dist/vci/proof.d.ts.map +1 -0
  60. package/dist/vci/request.d.ts +48 -0
  61. package/dist/vci/request.d.ts.map +1 -0
  62. package/dist/vci/store.d.ts +89 -0
  63. package/dist/vci/store.d.ts.map +1 -0
  64. package/dist/vci/token.d.ts +16 -0
  65. package/dist/vci/token.d.ts.map +1 -0
  66. package/dist/vci/types.d.ts +156 -0
  67. package/dist/vci/types.d.ts.map +1 -0
  68. package/dist/vp/client-id-prefix.d.ts +115 -0
  69. package/dist/vp/client-id-prefix.d.ts.map +1 -0
  70. package/dist/vp/encrypt.d.ts +221 -0
  71. package/dist/vp/encrypt.d.ts.map +1 -0
  72. package/dist/vp/index.d.ts +27 -0
  73. package/dist/vp/index.d.ts.map +1 -0
  74. package/dist/vp/parse.d.ts +60 -0
  75. package/dist/vp/parse.d.ts.map +1 -0
  76. package/dist/vp/pex.d.ts +83 -0
  77. package/dist/vp/pex.d.ts.map +1 -0
  78. package/dist/vp/present.d.ts +126 -0
  79. package/dist/vp/present.d.ts.map +1 -0
  80. package/dist/vp/request-object.d.ts +99 -0
  81. package/dist/vp/request-object.d.ts.map +1 -0
  82. package/dist/vp/select.d.ts +137 -0
  83. package/dist/vp/select.d.ts.map +1 -0
  84. package/dist/vp/sign.d.ts +125 -0
  85. package/dist/vp/sign.d.ts.map +1 -0
  86. package/dist/vp/submit.d.ts +175 -0
  87. package/dist/vp/submit.d.ts.map +1 -0
  88. package/dist/vp/types.d.ts +255 -0
  89. package/dist/vp/types.d.ts.map +1 -0
  90. package/package.json +52 -0
@@ -0,0 +1,175 @@
1
+ import { PresentationSubmission } from './select';
2
+ import { VpToken } from './sign';
3
+ import { type JarmClientMetadata } from './encrypt';
4
+ import type { ProofJwtSigner } from '../vci/types';
5
+ /**
6
+ * Slice 7c / 7d — **direct_post + direct_post.jwt transport**.
7
+ *
8
+ * POST a signed `vp_token` (and, for PEX, a `presentation_submission`)
9
+ * to the verifier's `response_uri` per OID4VP §8. Pure transport —
10
+ * no signing, no PEX/DCQL evaluation, no request-object parsing.
11
+ *
12
+ * Two response modes are supported:
13
+ *
14
+ * - **`direct_post`** (§8.2) — form fields go on the wire as
15
+ * cleartext (`vp_token`, `presentation_submission`, `state`,
16
+ * `id_token` directly URL-encoded). What every walt.id-class
17
+ * verifier accepts today.
18
+ *
19
+ * - **`direct_post.jwt`** (§8.3) — the same fields are packed into
20
+ * a JSON payload, optionally signed by the wallet, then encrypted
21
+ * to the verifier's published encryption key. The single resulting
22
+ * compact JOSE string goes on the wire as one form field named
23
+ * `response`. What EUDI / EU pilot deployments require for
24
+ * production. Encryption is delegated to `./encrypt.ts`; this
25
+ * module just dispatches.
26
+ *
27
+ * ## PEX vs DCQL submissions
28
+ *
29
+ * OID4VP defines two distinct response shapes:
30
+ *
31
+ * - **PEX** (Draft 22 and earlier, still used by every walt.id-class
32
+ * verifier in the wild) → fields `vp_token` + `presentation_submission`.
33
+ * `vp_token` is a single signed VP; `presentation_submission`
34
+ * carries the descriptor_map that routes inner credentials.
35
+ *
36
+ * - **DCQL** (OID4VP 1.0 §6.4) → field `vp_token` only, valued
37
+ * as a JSON-encoded object whose keys are `credential_query_id`
38
+ * strings and whose values are signed presentations. NO
39
+ * `presentation_submission` field — the keying carries the routing
40
+ * implicitly. Callers using the DCQL pipeline (`dcql/respond.ts`)
41
+ * pass `submission: undefined` (or omit it) so this transport
42
+ * leaves the field off the response body.
43
+ *
44
+ * Both query-language splits work in either response mode. JARM
45
+ * just wraps the same payload in a JOSE blob.
46
+ *
47
+ * ## Encoding (cleartext mode)
48
+ *
49
+ * OID4VP requires `application/x-www-form-urlencoded`, even though
50
+ * `vp_token` and `presentation_submission` are structured values.
51
+ * Stringification rules:
52
+ *
53
+ * - `vp_token` as a `string` (jwt_vp_json compact JWS) → used verbatim.
54
+ * - `vp_token` as an object (ldp_vp signed VP, OR a DCQL vp_token
55
+ * object keyed by credential_query_id) → `JSON.stringify`.
56
+ * - `presentation_submission` → always `JSON.stringify` when present.
57
+ * - `state` → echoed verbatim if present.
58
+ *
59
+ * ## Encoding (JARM mode)
60
+ *
61
+ * Single form field: `response=<JOSE blob>`. Same form-urlencoded
62
+ * content type so verifier servers don't need protocol-aware framing
63
+ * — the JOSE blob is just one parameter value.
64
+ *
65
+ * ## Response handling
66
+ *
67
+ * Spec-compliant verifiers respond 200 OK with either an empty body
68
+ * (success) or `{ "redirect_uri": "…" }` (wallet is asked to deep-link
69
+ * back). We parse both shapes and surface anything else through
70
+ * `SubmitResponse.body` unchanged so callers can debug vendor-specific
71
+ * returns (e.g. walt.id's `{ success: true }`).
72
+ *
73
+ * HTTP-level failures become typed `VpSubmitError`s so UIs can render
74
+ * "connection issue" vs "verifier rejected the VP" correctly.
75
+ */
76
+ export interface SubmitPresentationOptions {
77
+ /**
78
+ * The `response_uri` from the verifier's Authorization Request. We
79
+ * POST here, form-encoded, per OID4VP §8.
80
+ */
81
+ responseUri: string;
82
+ /**
83
+ * Signed VP token. Three shapes are accepted:
84
+ * - PEX `jwt_vp_json` → compact JWS string
85
+ * - PEX `ldp_vp` → signed VP JSON object
86
+ * - DCQL response → JSON object keyed by `credential_query_id`,
87
+ * values are per-query signed presentations
88
+ */
89
+ vpToken: VpToken;
90
+ /**
91
+ * DIF PEX v2 Presentation Submission. Required for PEX flows;
92
+ * MUST be omitted (or `undefined`) for DCQL flows — DCQL's
93
+ * vp_token keying provides the routing implicitly. See the
94
+ * module-level docstring for the full PEX-vs-DCQL split.
95
+ */
96
+ submission?: PresentationSubmission;
97
+ /**
98
+ * SIOPv2 ID token (Slice 8). Required when the verifier asked for
99
+ * `response_type=vp_token id_token` or `response_type=id_token`;
100
+ * must be omitted otherwise. Encoded as the `id_token` form field
101
+ * alongside `vp_token`.
102
+ */
103
+ idToken?: string;
104
+ /**
105
+ * The verifier's `state` parameter (if present in the Auth
106
+ * Request). Echoed back so the verifier can correlate the
107
+ * response with the pending session. Omitted when absent.
108
+ */
109
+ state?: string;
110
+ /**
111
+ * Verifier's `response_mode` from the Authorization Request.
112
+ * Defaults to `direct_post` (cleartext). Set to `direct_post.jwt`
113
+ * to send a JARM (encrypted, optionally signed) response. Any
114
+ * other value is treated as cleartext for forward-compat — the
115
+ * caller can detect and reject unsupported modes upstream rather
116
+ * than have the transport silently downgrade.
117
+ */
118
+ responseMode?: string;
119
+ /**
120
+ * Verifier's `client_metadata` from the Authorization Request.
121
+ * Required when `responseMode === 'direct_post.jwt'` (carries
122
+ * the JWE algorithms + verifier's encryption JWKS). Ignored in
123
+ * cleartext mode.
124
+ */
125
+ clientMetadata?: JarmClientMetadata;
126
+ /**
127
+ * Verifier's `nonce` from the Authorization Request. Required
128
+ * when `responseMode === 'direct_post.jwt'` (used as the JWE
129
+ * `apv` ECDH-ES KDF input per OID4VP §8.3 ¶6). Ignored in
130
+ * cleartext mode.
131
+ */
132
+ nonce?: string;
133
+ /**
134
+ * Wallet signer — same shape as VCI proof-of-possession + outer
135
+ * VP signing. Required when JARM is in use AND the verifier
136
+ * declared `authorization_signed_response_alg` (the wallet must
137
+ * sign the response object before encrypting). Ignored otherwise.
138
+ */
139
+ signer?: ProofJwtSigner;
140
+ /** Override fetch — defaults to `globalThis.fetch`. */
141
+ fetchImpl?: typeof fetch;
142
+ }
143
+ /**
144
+ * Shape of a successful `direct_post` response. `redirectUri` is
145
+ * populated when the verifier requested wallet redirect (OID4VP §8.2).
146
+ */
147
+ export interface SubmitPresentationResult {
148
+ /** HTTP status (always 2xx for successful submissions; otherwise we throw). */
149
+ status: number;
150
+ /**
151
+ * Redirect URI the wallet should deep-link to. Present when the
152
+ * verifier wants the wallet to bounce the user back (e.g. to an
153
+ * in-browser "success" page).
154
+ */
155
+ redirectUri?: string;
156
+ /**
157
+ * Raw parsed body. `object` when the verifier returned JSON,
158
+ * `string` for plain text, `undefined` for empty. Preserved so
159
+ * callers can debug vendor-specific fields.
160
+ */
161
+ body: unknown;
162
+ }
163
+ export type VpSubmitErrorCode = 'invalid_input' | 'no_fetch' | 'network_error' | 'server_error' | 'jarm_encrypt_failed';
164
+ export declare class VpSubmitError extends Error {
165
+ readonly code: VpSubmitErrorCode;
166
+ readonly status?: number;
167
+ readonly body?: unknown;
168
+ constructor(code: VpSubmitErrorCode, message: string, extra?: {
169
+ status?: number;
170
+ body?: unknown;
171
+ cause?: unknown;
172
+ });
173
+ }
174
+ export declare const submitPresentation: (options: SubmitPresentationOptions) => Promise<SubmitPresentationResult>;
175
+ //# sourceMappingURL=submit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"submit.d.ts","sourceRoot":"","sources":["../../src/vp/submit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,UAAU,CAAC;AAClD,OAAO,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AACjC,OAAO,EAGH,KAAK,kBAAkB,EAE1B,MAAM,WAAW,CAAC;AACnB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAEnD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsEG;AAMH,MAAM,WAAW,yBAAyB;IACtC;;;OAGG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB;;;;;;OAMG;IACH,OAAO,EAAE,OAAO,CAAC;IAEjB;;;;;OAKG;IACH,UAAU,CAAC,EAAE,sBAAsB,CAAC;IAEpC;;;;;OAKG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;;;;;;OAOG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;;;;OAKG;IACH,cAAc,CAAC,EAAE,kBAAkB,CAAC;IAEpC;;;;;OAKG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;;;;OAKG;IACH,MAAM,CAAC,EAAE,cAAc,CAAC;IAExB,uDAAuD;IACvD,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;CAC5B;AAED;;;GAGG;AACH,MAAM,WAAW,wBAAwB;IACrC,+EAA+E;IAC/E,MAAM,EAAE,MAAM,CAAC;IAEf;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;;;OAIG;IACH,IAAI,EAAE,OAAO,CAAC;CACjB;AAMD,MAAM,MAAM,iBAAiB,GACvB,eAAe,GACf,UAAU,GACV,eAAe,GACf,cAAc,GACd,qBAAqB,CAAC;AAE5B,qBAAa,aAAc,SAAQ,KAAK;IACpC,QAAQ,CAAC,IAAI,EAAE,iBAAiB,CAAC;IACjC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;gBAGpB,IAAI,EAAE,iBAAiB,EACvB,OAAO,EAAE,MAAM,EACf,KAAK,GAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAO;CAWvE;AAMD,eAAO,MAAM,kBAAkB,YAClB,yBAAyB,KACnC,OAAO,CAAC,wBAAwB,CAwFlC,CAAC"}
@@ -0,0 +1,255 @@
1
+ /**
2
+ * OpenID for Verifiable Presentations (OID4VP) Authorization Request types
3
+ * plus the DIF Presentation Exchange v2.0 subset the plugin consumes.
4
+ *
5
+ * Spec references:
6
+ * - OpenID4VP Draft 22: https://openid.net/specs/openid-4-verifiable-presentations-1_0.html
7
+ * - DIF PEX v2.0: https://identity.foundation/presentation-exchange/spec/v2.0.0/
8
+ *
9
+ * We target Draft 22 (`response_uri`) but tolerate legacy `redirect_uri`
10
+ * when the caller used an older verifier implementation.
11
+ */
12
+ /**
13
+ * Stable error codes surfaced to UI layers. Every parse failure maps to
14
+ * exactly one of these so UI can localize copy without string-matching
15
+ * `Error.message`.
16
+ */
17
+ export type VpErrorCode = 'invalid_uri' | 'invalid_json' | 'missing_client_id' | 'missing_nonce' | 'missing_response_type' | 'unsupported_response_type' | 'missing_response_target' | 'missing_presentation_definition' | 'invalid_presentation_definition' | 'both_definition_and_uri' | 'request_object_not_supported' | 'presentation_definition_fetch_failed'
18
+ /**
19
+ * The Authorization Request carried a `dcql_query` that wasn't a
20
+ * JSON object, failed `DcqlQuery.parse` (structure), or failed
21
+ * `DcqlQuery.validate` (content). Distinct from
22
+ * `invalid_presentation_definition` so UI can localize the two
23
+ * separately; the underlying `dcql` library error rides along on
24
+ * `Error.cause` for debug.
25
+ */
26
+ | 'invalid_dcql_query'
27
+ /**
28
+ * The Authorization Request carried BOTH `presentation_definition`
29
+ * (or `..._uri`) AND `dcql_query`. OID4VP 1.0 §5.3 forbids this:
30
+ * the verifier picks ONE query language per request. Without this
31
+ * guard we'd silently route on whichever one we happened to read
32
+ * first, which would mask verifier-side bugs.
33
+ */
34
+ | 'both_pex_and_dcql';
35
+ /**
36
+ * Thrown by the parser/resolver and by PEX selection helpers. The `code`
37
+ * field is the stable contract; `message` and `cause` are diagnostic.
38
+ */
39
+ export declare class VpError extends Error {
40
+ readonly code: VpErrorCode;
41
+ constructor(code: VpErrorCode, message: string, options?: {
42
+ cause?: unknown;
43
+ });
44
+ }
45
+ /**
46
+ * Result of parsing an OID4VP Authorization Request URI.
47
+ *
48
+ * - `by_value` — every parameter was inline in the URI; the request is
49
+ * fully resolved and ready for PEX matching (Slice 6c+).
50
+ * - `by_reference_request_uri` — the verifier delegated the full request
51
+ * to a signed JWT fetched from `request_uri`; deferred to Slice 7.
52
+ * - `by_reference_request_jwt` — the request was embedded inline as a
53
+ * signed JWS via the `request` parameter; deferred to Slice 7.
54
+ *
55
+ * The `by_reference_*` variants intentionally don't attempt to decode
56
+ * the JWS — signature verification requires trust anchors (x5c chain,
57
+ * registered client metadata, did:web resolution) that belong in Slice 7.
58
+ */
59
+ export type ParsedAuthorizationRequest = {
60
+ kind: 'by_value';
61
+ request: AuthorizationRequest;
62
+ } | {
63
+ kind: 'by_reference_request_uri';
64
+ requestUri: string;
65
+ rawParams: URLSearchParams;
66
+ } | {
67
+ kind: 'by_reference_request_jwt';
68
+ jwt: string;
69
+ rawParams: URLSearchParams;
70
+ };
71
+ /**
72
+ * Canonical Authorization Request shape the plugin operates on. Values
73
+ * come from either the inline URI params or the decoded signed Request
74
+ * Object (Slice 7). Field names match the OID4VP spec so they round-trip
75
+ * cleanly back into the `direct_post` response.
76
+ */
77
+ export interface AuthorizationRequest {
78
+ /**
79
+ * Verifier identifier. Shape depends on `client_id_scheme`:
80
+ * - `did` → a DID URL
81
+ * - `x509_san_dns` / `x509_san_uri` → a hostname/URL backed by the
82
+ * signing cert's SAN
83
+ * - `redirect_uri` → the verifier's response_uri host
84
+ * - `pre-registered` → an opaque string registered out-of-band
85
+ */
86
+ client_id: string;
87
+ client_id_scheme?: string;
88
+ /**
89
+ * Space-separated list — typically `vp_token` alone, or
90
+ * `vp_token id_token` for SIOPv2 + VP combined.
91
+ */
92
+ response_type: string;
93
+ /**
94
+ * `direct_post` — POST the VP token to `response_uri` as a form body.
95
+ * `direct_post.jwt` — same, but the body is a JWE.
96
+ * `fragment` / `query` — legacy browser-redirect modes.
97
+ *
98
+ * When omitted for a `vp_token` response_type, the spec's default is
99
+ * `fragment`, but every real-world wallet assumes `direct_post`.
100
+ */
101
+ response_mode?: string;
102
+ /**
103
+ * Draft 22+: destination for the VP token when `response_mode` is
104
+ * `direct_post*`. Mutually exclusive with legacy `redirect_uri` for
105
+ * direct-post flows, though older verifiers may still send
106
+ * `redirect_uri` here.
107
+ */
108
+ response_uri?: string;
109
+ /**
110
+ * Legacy (Draft ≤ 17): combined redirect + response destination.
111
+ * Still used by some verifiers in the wild. The resolver surfaces
112
+ * whichever one arrived under `response_uri` for consistency.
113
+ */
114
+ redirect_uri?: string;
115
+ nonce: string;
116
+ state?: string;
117
+ /**
118
+ * Inline DIF PEX v2 Presentation Definition. Mutually exclusive
119
+ * with `dcql_query` per OID4VP 1.0 §5.3 — a verifier expresses
120
+ * its credential ask in EITHER PEX OR DCQL, never both.
121
+ *
122
+ * Exactly one of `presentation_definition` /
123
+ * `presentation_definition_uri` / `dcql_query` /
124
+ * `scope` (with a well-known scope→PD mapping) is expected.
125
+ *
126
+ * The plugin auto-routes on whichever is present; PEX is the legacy
127
+ * path (every pre-1.0 verifier), DCQL is the OID4VP 1.0+ path.
128
+ */
129
+ presentation_definition?: PresentationDefinition;
130
+ /**
131
+ * URL returning the inline `presentation_definition` JSON. Resolved
132
+ * by {@link resolvePresentationDefinitionByReference}.
133
+ */
134
+ presentation_definition_uri?: string;
135
+ /**
136
+ * **OID4VP 1.0 §6** Digital Credentials Query Language query.
137
+ *
138
+ * Mutually exclusive with `presentation_definition` —
139
+ * verifiers using DCQL set this and omit PEX, and vice versa.
140
+ * Coexistence is at the plugin level (we accept either),
141
+ * NOT at the wire level (a single auth request never carries both).
142
+ *
143
+ * Stored as a parsed-and-validated value of the `dcql` library's
144
+ * `DcqlQuery` type so downstream selector code can run
145
+ * `DcqlQuery.query(...)` without re-parsing. The plugin's
146
+ * resolver (in `./parse.ts`) calls `DcqlQuery.parse(rawJson)`
147
+ * before populating this field — by the time it lands here, it's
148
+ * already been structurally + semantically validated.
149
+ *
150
+ * Unlike `presentation_definition_uri`, DCQL is **always inline**;
151
+ * the spec doesn't define a `dcql_query_uri` mechanism.
152
+ */
153
+ dcql_query?: import('../dcql/types').DcqlQuery;
154
+ /**
155
+ * Verifier metadata (supported formats, response-encryption JWKS,
156
+ * etc.). Consumed by Slice 7 when building the direct_post.jwt
157
+ * response.
158
+ */
159
+ client_metadata?: Record<string, unknown>;
160
+ /** URL variant of {@link client_metadata}. */
161
+ client_metadata_uri?: string;
162
+ /**
163
+ * Space-separated OAuth scopes. Mainly used by SIOPv2 (`openid`) and
164
+ * by verifiers that pre-register scope→presentation_definition
165
+ * mappings. Passed through verbatim for Slice 8.
166
+ */
167
+ scope?: string;
168
+ /**
169
+ * Any additional parameters the verifier included. Kept so callers
170
+ * writing to the direct_post response can echo `state`, custom
171
+ * extensions, etc. without losing fidelity.
172
+ */
173
+ extra?: Record<string, string>;
174
+ }
175
+ /**
176
+ * DIF PEX v2 Presentation Definition. The minimum fields the plugin
177
+ * inspects for matching; forward-compatible extensions are preserved in
178
+ * `extra` so they can round-trip into the Presentation Submission.
179
+ */
180
+ export interface PresentationDefinition {
181
+ id: string;
182
+ name?: string;
183
+ purpose?: string;
184
+ format?: Record<string, ClaimFormatDesignation>;
185
+ submission_requirements?: SubmissionRequirement[];
186
+ input_descriptors: InputDescriptor[];
187
+ }
188
+ export interface InputDescriptor {
189
+ id: string;
190
+ name?: string;
191
+ purpose?: string;
192
+ group?: string[];
193
+ format?: Record<string, ClaimFormatDesignation>;
194
+ constraints: Constraints;
195
+ }
196
+ export interface Constraints {
197
+ /**
198
+ * `required` — wallet MUST strip every field not listed in `fields[]`
199
+ * before presenting (selective disclosure).
200
+ * `preferred` — wallet SHOULD, but isn't required to.
201
+ *
202
+ * Slice 6 ignores limit_disclosure for VC 1.1 JSON-LD / JWT-VC since
203
+ * neither format supports field-level redaction cleanly. SD-JWT-VC
204
+ * support lives in a separate plugin.
205
+ */
206
+ limit_disclosure?: 'required' | 'preferred';
207
+ fields?: Field[];
208
+ }
209
+ export interface Field {
210
+ /**
211
+ * JSONPath expressions evaluated (in order) against each candidate VC.
212
+ * The first path that yields a non-empty match wins; that match is
213
+ * then tested against `filter` (when present).
214
+ */
215
+ path: string[];
216
+ id?: string;
217
+ name?: string;
218
+ purpose?: string;
219
+ /**
220
+ * JSON Schema (Draft 7 subset) applied to the resolved value. Slice 6
221
+ * supports `type`, `const`, `enum`, `pattern`, `contains`, plus the
222
+ * numeric/string bound keywords — which covers every filter seen in
223
+ * the PEX test vectors and real verifier payloads we've inspected.
224
+ */
225
+ filter?: Record<string, unknown>;
226
+ /**
227
+ * When `true`, the field doesn't need to match for the input
228
+ * descriptor to be satisfied. Useful for "nice-to-have" claims.
229
+ */
230
+ optional?: boolean;
231
+ /**
232
+ * `required` — the VC must literally contain the claim (default).
233
+ * `preferred` — the wallet should supply the claim if available, but
234
+ * may substitute a predicate proof (ZKP). We treat
235
+ * both as `required` until a ZKP-capable backend lands.
236
+ */
237
+ predicate?: 'required' | 'preferred';
238
+ }
239
+ export interface SubmissionRequirement {
240
+ name?: string;
241
+ purpose?: string;
242
+ rule: 'all' | 'pick';
243
+ count?: number;
244
+ min?: number;
245
+ max?: number;
246
+ /** Reference to an `input_descriptor.group` value. */
247
+ from?: string;
248
+ /** Nested submission requirements for composite rules. */
249
+ from_nested?: SubmissionRequirement[];
250
+ }
251
+ export interface ClaimFormatDesignation {
252
+ alg?: string[];
253
+ proof_type?: string[];
254
+ }
255
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/vp/types.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,52 @@
1
+ {
2
+ "name": "@learncard/openid4vc-plugin",
3
+ "version": "0.0.1",
4
+ "description": "OpenID for Verifiable Credentials (OID4VCI + OID4VP + SIOPv2) holder support for LearnCard",
5
+ "main": "./dist/index.js",
6
+ "module": "./dist/openid4vc-plugin.esm.js",
7
+ "files": [
8
+ "dist"
9
+ ],
10
+ "author": "Learning Economy Foundation (www.learningeconomy.io)",
11
+ "license": "MIT",
12
+ "homepage": "https://github.com/learningeconomy/LearnCard/tree/main/packages/plugins/openid4vc/README.md",
13
+ "repository": {
14
+ "type": "git",
15
+ "url": "https://github.com/learningeconomy/LearnCard"
16
+ },
17
+ "bugs": {
18
+ "url": "https://github.com/learningeconomy/LearnCard/issues"
19
+ },
20
+ "devDependencies": {
21
+ "@types/jest": "^29.2.2",
22
+ "@types/node": "^17.0.31",
23
+ "aqu": "0.4.3",
24
+ "esbuild": "^0.27.1",
25
+ "esbuild-jest": "^0.5.0",
26
+ "esbuild-plugin-copy": "^1.3.0",
27
+ "jest": "^29.3.0",
28
+ "shx": "^0.3.4",
29
+ "ts-jest": "^29.0.3",
30
+ "tsx": "^4.20.6",
31
+ "@learncard/types": "5.15.0"
32
+ },
33
+ "types": "./dist/index.d.ts",
34
+ "dependencies": {
35
+ "@peculiar/x509": "^1.12.0",
36
+ "dcql": "^3.0.0",
37
+ "jose": "^5.9.6",
38
+ "safe-regex": "^2.1.1",
39
+ "@learncard/core": "9.4.18",
40
+ "@learncard/didkit-plugin": "^1.8.9",
41
+ "@learncard/vc-plugin": "^1.4.14"
42
+ },
43
+ "sideEffects": false,
44
+ "scripts": {
45
+ "build": "node ./scripts/build.mjs && shx cp ./scripts/mixedEntypoint.js ./dist/index.js && tsc --p tsconfig.json",
46
+ "test": "jest --passWithNoTests",
47
+ "test:watch": "jest --watch",
48
+ "test:coverage": "jest --silent --ci --coverage --coverageReporters=\"text\" --coverageReporters=\"text-summary\"",
49
+ "try-offer": "tsx ./scripts/try-offer.ts",
50
+ "try-verify": "tsx ./scripts/try-verify.ts"
51
+ }
52
+ }