@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,148 @@
1
+ /**
2
+ * Slice 4 — **OID4VCI authorization_code flow**.
3
+ *
4
+ * The authorization code grant is the second issuance path in
5
+ * OID4VCI Draft 13 (§5 / §6.1). Unlike `pre-authorized_code`, it
6
+ * requires a user-agent redirect to the authorization server, where
7
+ * the user consents, and then a callback back to the wallet with a
8
+ * one-time `code`. PKCE (Slice 4's companion module
9
+ * {@link ./pkce.ts}) protects the exchange.
10
+ *
11
+ * Because the plugin runs headless — it cannot itself launch a
12
+ * browser — we split the flow into two halves:
13
+ *
14
+ * 1. **begin** — resolve issuer + AS metadata, generate PKCE, build
15
+ * the authorization URL, return it along with the opaque
16
+ * `flowHandle` the wallet persists until the redirect fires.
17
+ * 2. **complete** — take the `code` that arrived on the redirect
18
+ * plus the stored `flowHandle`, exchange for an access token,
19
+ * then run the normal `/credential` request + proof-of-possession
20
+ * to get the actual VC.
21
+ *
22
+ * The plugin's public API (`beginCredentialOfferAuthCode` /
23
+ * `completeCredentialOfferAuthCode`) wraps these with LearnCard
24
+ * session plumbing.
25
+ */
26
+ import { CredentialOffer } from '../offer/types';
27
+ import { PkcePair } from './pkce';
28
+ import { AcceptedCredentialResult, AuthorizationServerMetadata, CredentialIssuerMetadata, ProofJwtSigner, TokenResponse } from './types';
29
+ /** Grant-type URN used for the authorization_code flow on /token. */
30
+ export declare const AUTHORIZATION_CODE_GRANT = "authorization_code";
31
+ export interface BeginAuthCodeFlowOptions {
32
+ offer: CredentialOffer;
33
+ /**
34
+ * URL the wallet wants the AS to redirect back to after user
35
+ * consent. Must match whatever the wallet registered with the
36
+ * AS out-of-band (or, for clients using an ephemeral redirect
37
+ * like `http://127.0.0.1:<random>/cb`, whatever the wallet spins
38
+ * up at runtime).
39
+ */
40
+ redirectUri: string;
41
+ /** OAuth 2.0 client identifier. Required for auth_code flows. */
42
+ clientId: string;
43
+ /**
44
+ * Subset of `credential_configuration_ids` from the offer to
45
+ * actually request. Defaults to all of them. Validated before
46
+ * the network hits the AS so typos don't cost a real `code` round
47
+ * trip.
48
+ */
49
+ configurationIds?: string[];
50
+ /**
51
+ * OAuth 2.0 `scope`. Optional — the plugin prefers
52
+ * `authorization_details` (Draft 13 §5.1.1) when it can. Pass
53
+ * `scope` if the AS mandates it.
54
+ */
55
+ scope?: string;
56
+ /** Override fetch — defaults to `globalThis.fetch`. */
57
+ fetchImpl?: typeof fetch;
58
+ }
59
+ /**
60
+ * Result of `begin`. The wallet:
61
+ * - Opens `authorizationUrl` in a user-agent.
62
+ * - Persists `flowHandle` until the redirect delivers a `code`.
63
+ * - Calls `complete` with the received `code` + the stored handle.
64
+ */
65
+ export interface BeginAuthCodeFlowResult {
66
+ authorizationUrl: string;
67
+ /**
68
+ * Opaque handle — JSON-serializable so the wallet can round-trip
69
+ * it through storage / postMessage / deep-link state. Carries
70
+ * everything `complete` needs: PKCE verifier, AS token endpoint,
71
+ * issuer metadata pointers, expected state.
72
+ */
73
+ flowHandle: AuthCodeFlowHandle;
74
+ }
75
+ export interface AuthCodeFlowHandle {
76
+ version: 1;
77
+ issuer: string;
78
+ tokenEndpoint: string;
79
+ credentialEndpoint: string;
80
+ configurationIds: string[];
81
+ redirectUri: string;
82
+ clientId: string;
83
+ state: string;
84
+ pkceVerifier: string;
85
+ pkceMethod: 'S256';
86
+ credentialConfigurations: Record<string, unknown>;
87
+ }
88
+ export interface CompleteAuthCodeFlowOptions {
89
+ flowHandle: AuthCodeFlowHandle;
90
+ /** Code delivered on the redirect callback. */
91
+ code: string;
92
+ /** State delivered on the redirect callback — must match the handle. */
93
+ state?: string;
94
+ /**
95
+ * Holder signer for the proof-of-possession JWT. Plugin wires
96
+ * its Ed25519 default; HSM-backed hosts inject their own.
97
+ */
98
+ signer: ProofJwtSigner;
99
+ fetchImpl?: typeof fetch;
100
+ }
101
+ /**
102
+ * Phase 1 of the auth_code flow. Pure preparation — the only network
103
+ * hits are metadata lookups; no codes are exchanged yet.
104
+ */
105
+ export declare const beginAuthCodeFlow: (options: BeginAuthCodeFlowOptions) => Promise<BeginAuthCodeFlowResult>;
106
+ /**
107
+ * Phase 2 — wallet has the `code` back from the redirect. Exchange
108
+ * for an access token, fetch the VC(s), return them.
109
+ *
110
+ * Reuses `requestCredential` and `buildProofJwt` from the pre-auth
111
+ * pipeline — only the token exchange differs.
112
+ */
113
+ export declare const completeAuthCodeFlow: (options: CompleteAuthCodeFlowOptions) => Promise<AcceptedCredentialResult>;
114
+ /**
115
+ * Build the authorization-endpoint URL a wallet opens in a user-agent
116
+ * to kick off the OAuth dance.
117
+ *
118
+ * Includes PKCE (S256), per-config `authorization_details` scoped to
119
+ * `openid_credential` (Draft 13 §5.1.1), and optional issuer_state so
120
+ * the AS can correlate the request with the original offer.
121
+ */
122
+ export declare const buildAuthorizationUrl: (args: {
123
+ authorizationEndpoint: string;
124
+ clientId: string;
125
+ redirectUri: string;
126
+ configurationIds: string[];
127
+ scope?: string;
128
+ pkce: PkcePair;
129
+ state: string;
130
+ issuerState?: string;
131
+ }) => string;
132
+ /**
133
+ * POST to the AS token endpoint with `grant_type=authorization_code`
134
+ * + PKCE verifier. Returns the canonical {@link TokenResponse}.
135
+ *
136
+ * Error handling mirrors {@link ./token.ts:exchangePreAuthorizedCode}
137
+ * so the plugin's error surface is consistent across grant types.
138
+ */
139
+ export declare const exchangeAuthorizationCode: (args: {
140
+ tokenEndpoint: string;
141
+ code: string;
142
+ codeVerifier: string;
143
+ clientId: string;
144
+ redirectUri: string;
145
+ fetchImpl?: typeof fetch;
146
+ }) => Promise<TokenResponse>;
147
+ export type { CredentialIssuerMetadata, AuthorizationServerMetadata };
148
+ //# sourceMappingURL=auth-code.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-code.d.ts","sourceRoot":"","sources":["../../src/vci/auth-code.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAMjD,OAAO,EAEH,QAAQ,EACX,MAAM,QAAQ,CAAC;AAGhB,OAAO,EACH,wBAAwB,EACxB,2BAA2B,EAC3B,wBAAwB,EAExB,cAAc,EACd,aAAa,EAChB,MAAM,SAAS,CAAC;AAOjB,qEAAqE;AACrE,eAAO,MAAM,wBAAwB,uBAAuB,CAAC;AAE7D,MAAM,WAAW,wBAAwB;IACrC,KAAK,EAAE,eAAe,CAAC;IAEvB;;;;;;OAMG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB,iEAAiE;IACjE,QAAQ,EAAE,MAAM,CAAC;IAEjB;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAE5B;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,uDAAuD;IACvD,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;CAC5B;AAED;;;;;GAKG;AACH,MAAM,WAAW,uBAAuB;IACpC,gBAAgB,EAAE,MAAM,CAAC;IAEzB;;;;;OAKG;IACH,UAAU,EAAE,kBAAkB,CAAC;CAClC;AAED,MAAM,WAAW,kBAAkB;IAC/B,OAAO,EAAE,CAAC,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,CAAC;IACtB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IAGnB,wBAAwB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACrD;AAED,MAAM,WAAW,2BAA2B;IACxC,UAAU,EAAE,kBAAkB,CAAC;IAE/B,+CAA+C;IAC/C,IAAI,EAAE,MAAM,CAAC;IAEb,wEAAwE;IACxE,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;;OAGG;IACH,MAAM,EAAE,cAAc,CAAC;IAEvB,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;CAC5B;AAMD;;;GAGG;AACH,eAAO,MAAM,iBAAiB,YACjB,wBAAwB,KAClC,OAAO,CAAC,uBAAuB,CA8EjC,CAAC;AAMF;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,YACpB,2BAA2B,KACrC,OAAO,CAAC,wBAAwB,CAiClC,CAAC;AAMF;;;;;;;GAOG;AACH,eAAO,MAAM,qBAAqB,SAAU;IACxC,qBAAqB,EAAE,MAAM,CAAC;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,QAAQ,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;CACxB,KAAG,MAuBH,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,yBAAyB,SAAgB;IAClD,aAAa,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;CAC5B,KAAG,OAAO,CAAC,aAAa,CAoExB,CAAC;AA8LF,YAAY,EAAE,wBAAwB,EAAE,2BAA2B,EAAE,CAAC"}
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Normalized representation of an issued credential, suitable for handing
3
+ * to the LearnCard store plane.
4
+ *
5
+ * Fields:
6
+ * - `vc` — W3C VC JSON-LD object (what the wallet UI renders / validates).
7
+ * - `rawFormat` — the format id the issuer returned it in (e.g. `jwt_vc_json`).
8
+ * - `jwt` — original compact JWS, preserved only for jwt-based formats so
9
+ * downstream verification can re-check the signature without re-fetching.
10
+ */
11
+ export interface NormalizedCredential {
12
+ vc: W3CVerifiableCredential;
13
+ rawFormat: string;
14
+ jwt?: string;
15
+ }
16
+ /**
17
+ * W3C VC Data Model shape. Only the fields we actually touch are typed —
18
+ * everything else passes through as `unknown` so issuer-specific extensions
19
+ * aren't clobbered.
20
+ */
21
+ export interface W3CVerifiableCredential {
22
+ '@context': unknown;
23
+ type: string[] | string;
24
+ id?: string;
25
+ issuer?: string | {
26
+ id?: string;
27
+ [k: string]: unknown;
28
+ };
29
+ issuanceDate?: string;
30
+ expirationDate?: string;
31
+ validFrom?: string;
32
+ validUntil?: string;
33
+ credentialSubject?: {
34
+ id?: string;
35
+ [k: string]: unknown;
36
+ } | Array<{
37
+ id?: string;
38
+ [k: string]: unknown;
39
+ }>;
40
+ credentialStatus?: unknown;
41
+ credentialSchema?: unknown;
42
+ proof?: unknown;
43
+ [k: string]: unknown;
44
+ }
45
+ /**
46
+ * Decode a credential returned from the issuer into the wallet's native
47
+ * W3C VC shape.
48
+ *
49
+ * Supports:
50
+ * - `jwt_vc_json` (and the draft-11 alias `jwt_vc`): compact JWS per VCDM
51
+ * §6.3.1. Mapped claims: `iss` → `issuer`, `sub` → `credentialSubject.id`,
52
+ * `jti` → `id`, `nbf`/`iat` → `issuanceDate`, `exp` → `expirationDate`.
53
+ * The raw JWT is preserved in `jwt` so the store can re-verify later.
54
+ * - `ldp_vc`: the credential is already a JSON-LD VC object — pass through.
55
+ *
56
+ * Unknown formats throw `unsupported_format` so callers can decide whether
57
+ * to fail the batch or skip the entry.
58
+ *
59
+ * NOTE: This function deliberately does NOT verify the JWT signature. The
60
+ * issuer is trusted to return a valid credential for the pre-authorized
61
+ * code flow; downstream verification (via `learnCard.invoke.verifyCredential`)
62
+ * will re-check against the proof when the user views the credential.
63
+ */
64
+ export declare const normalizeIssuedCredential: (credential: unknown, format: string) => NormalizedCredential;
65
+ //# sourceMappingURL=decode.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decode.d.ts","sourceRoot":"","sources":["../../src/vci/decode.ts"],"names":[],"mappings":"AAIA;;;;;;;;;GASG;AACH,MAAM,WAAW,oBAAoB;IACjC,EAAE,EAAE,uBAAuB,CAAC;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;GAIG;AACH,MAAM,WAAW,uBAAuB;IACpC,UAAU,EAAE,OAAO,CAAC;IACpB,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC;IACxB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,GAAG;QAAE,EAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAC;IACxD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iBAAiB,CAAC,EAAE;QAAE,EAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,GAAG,KAAK,CAAC;QAAE,EAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAC,CAAC;IACzG,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,yBAAyB,eACtB,OAAO,UACX,MAAM,KACf,oBAsBF,CAAC"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Stable, machine-readable error codes for the VCI (Verifiable Credential
3
+ * Issuance) flow. UI can map `code` → friendly copy without string-matching
4
+ * on the `message`.
5
+ */
6
+ export type VciErrorCode = 'metadata_fetch_failed' | 'metadata_invalid' | 'metadata_issuer_mismatch' | 'token_request_failed' | 'token_response_invalid' | 'proof_signing_failed' | 'credential_request_failed' | 'credential_response_invalid' | 'unsupported_grant' | 'unsupported_format' | 'tx_code_required' | 'nonce_required' | 'store_failed' | 'index_failed' | 'store_plane_missing' | 'index_plane_missing';
7
+ /**
8
+ * Thrown by any VCI helper when a flow step fails. Carries the originating
9
+ * HTTP status (when available) and the raw server body, so higher-level
10
+ * code can surface it for logs without re-parsing.
11
+ */
12
+ export declare class VciError extends Error {
13
+ readonly code: VciErrorCode;
14
+ readonly status?: number;
15
+ readonly body?: unknown;
16
+ constructor(code: VciErrorCode, message: string, opts?: {
17
+ status?: number;
18
+ body?: unknown;
19
+ cause?: unknown;
20
+ });
21
+ }
22
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/vci/errors.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,MAAM,YAAY,GAClB,uBAAuB,GACvB,kBAAkB,GAClB,0BAA0B,GAC1B,sBAAsB,GACtB,wBAAwB,GACxB,sBAAsB,GACtB,2BAA2B,GAC3B,6BAA6B,GAC7B,mBAAmB,GACnB,oBAAoB,GACpB,kBAAkB,GAClB,gBAAgB,GAChB,cAAc,GACd,cAAc,GACd,qBAAqB,GACrB,qBAAqB,CAAC;AAE5B;;;;GAIG;AACH,qBAAa,QAAS,SAAQ,KAAK;IAC/B,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAC5B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;gBAGpB,IAAI,EAAE,YAAY,EAClB,OAAO,EAAE,MAAM,EACf,IAAI,GAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAO;CActE"}
@@ -0,0 +1,12 @@
1
+ export * from './types';
2
+ export * from './errors';
3
+ export * from './metadata';
4
+ export * from './token';
5
+ export * from './proof';
6
+ export * from './request';
7
+ export * from './accept';
8
+ export * from './decode';
9
+ export * from './store';
10
+ export * from './pkce';
11
+ export * from './auth-code';
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/vci/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,UAAU,CAAC;AACzB,cAAc,YAAY,CAAC;AAC3B,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AACxB,cAAc,WAAW,CAAC;AAC1B,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,SAAS,CAAC;AACxB,cAAc,QAAQ,CAAC;AACvB,cAAc,aAAa,CAAC"}
@@ -0,0 +1,25 @@
1
+ import { AuthorizationServerMetadata, CredentialIssuerMetadata } from './types';
2
+ /**
3
+ * Fetch and validate the Credential Issuer Metadata for a given issuer URL.
4
+ *
5
+ * @throws {VciError} with code `metadata_fetch_failed` for network / HTTP
6
+ * errors, `metadata_invalid` for shape issues, and `metadata_issuer_mismatch`
7
+ * when the returned `credential_issuer` doesn't match the requested one.
8
+ */
9
+ export declare const fetchCredentialIssuerMetadata: (credentialIssuer: string, fetchImpl?: typeof fetch) => Promise<CredentialIssuerMetadata>;
10
+ /**
11
+ * Fetch and validate Authorization Server metadata. Tries the
12
+ * OAuth 2.0 well-known path first and falls back to the OpenID Connect one.
13
+ */
14
+ export declare const fetchAuthorizationServerMetadata: (authServer: string, fetchImpl?: typeof fetch) => Promise<AuthorizationServerMetadata>;
15
+ /**
16
+ * Resolve the authorization server metadata that should be used for a given
17
+ * credential offer / issuer metadata pair.
18
+ *
19
+ * Preference order:
20
+ * 1. `authorization_server` explicitly named on the pre-authorized grant.
21
+ * 2. First entry of `issuerMetadata.authorization_servers`.
22
+ * 3. The issuer itself (many small deployments are their own AS).
23
+ */
24
+ export declare const resolveAuthorizationServer: (issuerMetadata: CredentialIssuerMetadata, grantAuthServer?: string) => string;
25
+ //# sourceMappingURL=metadata.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metadata.d.ts","sourceRoot":"","sources":["../../src/vci/metadata.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,2BAA2B,EAC3B,wBAAwB,EAC3B,MAAM,SAAS,CAAC;AAOjB;;;;;;GAMG;AACH,eAAO,MAAM,6BAA6B,qBACpB,MAAM,cACb,OAAO,KAAK,KACxB,OAAO,CAAC,wBAAwB,CA2ClC,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,gCAAgC,eAC7B,MAAM,cACP,OAAO,KAAK,KACxB,OAAO,CAAC,2BAA2B,CA2DrC,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,0BAA0B,mBACnB,wBAAwB,oBACtB,MAAM,KACzB,MAYF,CAAC"}
@@ -0,0 +1,85 @@
1
+ /**
2
+ * Slice 4 — **PKCE (Proof Key for Code Exchange, RFC 7636)**.
3
+ *
4
+ * The authorization-code flow in OID4VCI is vulnerable to authorization
5
+ * code interception attacks unless the wallet proves possession of a
6
+ * secret at token-exchange time. PKCE is the standard mitigation:
7
+ *
8
+ * 1. Wallet generates a high-entropy `code_verifier`.
9
+ * 2. Wallet derives `code_challenge = BASE64URL(SHA-256(verifier))`.
10
+ * 3. Wallet sends `code_challenge` + `code_challenge_method=S256`
11
+ * on the authorization request.
12
+ * 4. Wallet sends the original `code_verifier` on the token request.
13
+ * 5. AS compares the hashed verifier with the stored challenge.
14
+ *
15
+ * We only implement the `S256` method \u2014 `plain` is spec-allowed but
16
+ * provides no security benefit, and OpenID4VCI \u00a76.2 mandates `S256`
17
+ * when PKCE is used.
18
+ *
19
+ * Cross-platform: uses the Web Crypto API (`crypto.getRandomValues` +
20
+ * `crypto.subtle.digest`) which is available natively in browsers and
21
+ * in Node \u2265 18. Async because `subtle.digest` is async by spec.
22
+ */
23
+ /**
24
+ * PKCE code challenge method. OID4VCI permits only `S256`; we pin the
25
+ * literal type so callers get compile-time noise if they try `plain`.
26
+ */
27
+ export type PkceCodeChallengeMethod = 'S256';
28
+ export interface PkcePair {
29
+ /**
30
+ * High-entropy secret kept by the wallet. Sent verbatim on the
31
+ * token request to prove possession of the original challenge.
32
+ */
33
+ verifier: string;
34
+ /**
35
+ * `BASE64URL(SHA-256(verifier))`. Sent on the authorization
36
+ * request (along with `code_challenge_method`) so the AS can
37
+ * later check the verifier matches.
38
+ */
39
+ challenge: string;
40
+ method: PkceCodeChallengeMethod;
41
+ }
42
+ export interface GeneratePkceOptions {
43
+ /**
44
+ * Byte length of the random verifier source. The spec allows
45
+ * 43–128 *characters* of base64url-encoded entropy; our default
46
+ * of 32 bytes encodes to ~43 base64url chars, matching the
47
+ * minimum. Bump this if your threat model demands more.
48
+ */
49
+ byteLength?: number;
50
+ }
51
+ export type PkceErrorCode = 'invalid_verifier' | 'unsupported_method';
52
+ export declare class PkceError extends Error {
53
+ readonly code: PkceErrorCode;
54
+ constructor(code: PkceErrorCode, message: string);
55
+ }
56
+ /**
57
+ * Generate a fresh PKCE verifier + S256 challenge.
58
+ *
59
+ * The verifier is produced by base64url-encoding `byteLength` bytes of
60
+ * Web Crypto random output — which satisfies RFC 7636 §4.1's
61
+ * "unreserved characters only" requirement without extra normalization.
62
+ */
63
+ export declare const generatePkcePair: (options?: GeneratePkceOptions) => Promise<PkcePair>;
64
+ /**
65
+ * Derive the S256 challenge for a given verifier. Separated from
66
+ * {@link generatePkcePair} so callers that round-trip a verifier
67
+ * through a redirect (the common case — wallet stores verifier,
68
+ * extracts it later at token-exchange time) can re-derive the
69
+ * challenge for assertions and logs.
70
+ *
71
+ * Async because Web Crypto's `subtle.digest` is async by spec.
72
+ */
73
+ export declare const computeS256Challenge: (verifier: string) => Promise<string>;
74
+ /**
75
+ * Verify a challenge matches a given verifier. Used by the
76
+ * authorization server, not the wallet — but we expose it so the
77
+ * in-process test server can validate challenges the same way real
78
+ * ASes do.
79
+ */
80
+ export declare const verifyPkce: (args: {
81
+ verifier: string;
82
+ challenge: string;
83
+ method?: PkceCodeChallengeMethod;
84
+ }) => Promise<boolean>;
85
+ //# sourceMappingURL=pkce.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pkce.d.ts","sourceRoot":"","sources":["../../src/vci/pkce.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAMH;;;GAGG;AACH,MAAM,MAAM,uBAAuB,GAAG,MAAM,CAAC;AAE7C,MAAM,WAAW,QAAQ;IACrB;;;OAGG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;;;OAIG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB,MAAM,EAAE,uBAAuB,CAAC;CACnC;AAED,MAAM,WAAW,mBAAmB;IAChC;;;;;OAKG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB;AAMD,MAAM,MAAM,aAAa,GAAG,kBAAkB,GAAG,oBAAoB,CAAC;AAEtE,qBAAa,SAAU,SAAQ,KAAK;IAChC,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;gBACjB,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM;CAKnD;AAMD;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,aAChB,mBAAmB,KAC7B,OAAO,CAAC,QAAQ,CAalB,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,oBAAoB,aAAoB,MAAM,KAAG,OAAO,CAAC,MAAM,CAW3E,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,UAAU,SAAgB;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,uBAAuB,CAAC;CACpC,KAAG,OAAO,CAAC,OAAO,CAOlB,CAAC"}
@@ -0,0 +1,43 @@
1
+ import { JWKWithPrivateKey } from '@learncard/types';
2
+ import { ProofJwtSigner } from './types';
3
+ /**
4
+ * The `typ` value required by OID4VCI Draft 13 §7.2.1.1 for JWT
5
+ * proof-of-possession signatures.
6
+ */
7
+ export declare const OID4VCI_PROOF_TYP = "openid4vci-proof+jwt";
8
+ /**
9
+ * Build an OID4VCI proof-of-possession JWT per Draft 13 §7.2.1.1.
10
+ *
11
+ * Header fields set by this function:
12
+ * - `alg` — from signer
13
+ * - `kid` — from signer (MUST point to a verification method the issuer can resolve)
14
+ * - `typ` — `openid4vci-proof+jwt` (per spec)
15
+ *
16
+ * Payload fields set by this function:
17
+ * - `aud` — the credential issuer identifier
18
+ * - `iat` — current unix time
19
+ * - `nonce` — the `c_nonce` returned by the token endpoint (REQUIRED when the issuer supplied one)
20
+ * - `iss` — only when `clientId` is provided (pre-auth anonymous flows omit it)
21
+ *
22
+ * The signer contract is deliberately narrow so tests can exercise this
23
+ * function without any real crypto.
24
+ */
25
+ export declare const buildProofJwt: (args: {
26
+ signer: ProofJwtSigner;
27
+ audience: string;
28
+ nonce?: string;
29
+ clientId?: string;
30
+ /** Override `iat` for deterministic tests. */
31
+ now?: () => number;
32
+ }) => Promise<string>;
33
+ /**
34
+ * Default {@link ProofJwtSigner} implementation backed by a LearnCard
35
+ * Ed25519 keypair and `jose`. Host plugins that use a different key type
36
+ * or an HSM should construct their own signer.
37
+ */
38
+ export declare const createJoseEd25519Signer: (args: {
39
+ keypair: JWKWithPrivateKey;
40
+ /** Verification method URL, e.g. `did:key:z6M...#z6M...`. */
41
+ kid: string;
42
+ }) => Promise<ProofJwtSigner>;
43
+ //# sourceMappingURL=proof.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"proof.d.ts","sourceRoot":"","sources":["../../src/vci/proof.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAErD,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAGzC;;;GAGG;AACH,eAAO,MAAM,iBAAiB,yBAAyB,CAAC;AAExD;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,aAAa,SAAgB;IACtC,MAAM,EAAE,cAAc,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,8CAA8C;IAC9C,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACtB,KAAG,OAAO,CAAC,MAAM,CA+BjB,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,uBAAuB,SAAgB;IAChD,OAAO,EAAE,iBAAiB,CAAC;IAC3B,6DAA6D;IAC7D,GAAG,EAAE,MAAM,CAAC;CACf,KAAG,OAAO,CAAC,cAAc,CAqBzB,CAAC"}
@@ -0,0 +1,48 @@
1
+ import { CredentialResponseBody } from './types';
2
+ /**
3
+ * POST a credential request to the issuer's credential endpoint and
4
+ * validate the response. Synchronous issuance only — deferred
5
+ * (`transaction_id`) and batch (`credentials` array) responses are passed
6
+ * through for higher-level handling.
7
+ *
8
+ * Draft 13 §7.2 distinguishes two mutually-exclusive ways to identify the
9
+ * credential being requested:
10
+ *
11
+ * 1. `credential_identifier` — supplied by the issuer in the token
12
+ * response's `authorization_details[].credential_identifiers`. Only
13
+ * use this when the token endpoint explicitly returned one.
14
+ * 2. `format` + format-specific fields (e.g. `credential_definition`
15
+ * for `jwt_vc_json` / `ldp_vc`). The default path for pre-authorized
16
+ * flows where the offer carries `credential_configuration_ids` but
17
+ * the token response carries no `authorization_details`.
18
+ *
19
+ * Callers pick the path by setting either `credentialIdentifier` OR
20
+ * `format` (+ relevant `extra` fields).
21
+ */
22
+ export declare const requestCredential: (args: {
23
+ credentialEndpoint: string;
24
+ accessToken: string;
25
+ tokenType?: string;
26
+ /**
27
+ * Opaque identifier from the token response's `authorization_details`.
28
+ * When set, `format` and any format-specific `extra` fields MUST NOT
29
+ * be sent (spec §7.2).
30
+ */
31
+ credentialIdentifier?: string;
32
+ /**
33
+ * Credential format id (`jwt_vc_json`, `ldp_vc`, …). Required unless
34
+ * `credentialIdentifier` is supplied.
35
+ */
36
+ format?: string;
37
+ /** Proof-of-possession JWT built by {@link buildProofJwt}. */
38
+ proofJwt: string;
39
+ /**
40
+ * Format-specific body fields. For `jwt_vc_json` this is typically
41
+ * `{ credential_definition: { type: [...] } }` copied from the issuer
42
+ * metadata's advertised configuration. Ignored when
43
+ * `credentialIdentifier` is set.
44
+ */
45
+ extra?: Record<string, unknown>;
46
+ fetchImpl?: typeof fetch;
47
+ }) => Promise<CredentialResponseBody>;
48
+ //# sourceMappingURL=request.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request.d.ts","sourceRoot":"","sources":["../../src/vci/request.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAkB,MAAM,SAAS,CAAC;AAGjE;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,iBAAiB,SAAgB;IAC1C,kBAAkB,EAAE,MAAM,CAAC;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,8DAA8D;IAC9D,QAAQ,EAAE,MAAM,CAAC;IACjB;;;;;OAKG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;CAC5B,KAAG,OAAO,CAAC,sBAAsB,CAkGjC,CAAC"}
@@ -0,0 +1,89 @@
1
+ import { LearnCard } from '@learncard/core';
2
+ import { W3CVerifiableCredential } from './decode';
3
+ import { AcceptedCredentialResult } from './types';
4
+ import { VciError } from './errors';
5
+ /**
6
+ * Name of the plugin we look for on the `store` and `index` planes by
7
+ * default. Matches the LearnCloud plugin's declared `name`.
8
+ */
9
+ export declare const DEFAULT_STORE_PLUGIN = "LearnCloud";
10
+ /** Shape of the record passed to `learnCard.index.<plugin>.add(record)`. */
11
+ export interface IndexRecord {
12
+ id: string;
13
+ uri: string;
14
+ category: string;
15
+ title?: string;
16
+ imgUrl?: string;
17
+ boostUri?: string;
18
+ /** Index record schema version, matches existing wallet writes. */
19
+ __v: 1;
20
+ }
21
+ export interface StoreAcceptedCredentialsOptions {
22
+ /**
23
+ * Name of the plugin implementing the `store` + `index` planes. Defaults
24
+ * to `LearnCloud`. Overridable for future `SQLite` / local-only backends.
25
+ */
26
+ storage?: string;
27
+ /**
28
+ * When true (default), uploads the credential with `uploadEncrypted` so
29
+ * only the holder can read it back. When false or when the chosen store
30
+ * plugin doesn't implement `uploadEncrypted`, falls back to `upload`.
31
+ */
32
+ encrypt?: boolean;
33
+ /**
34
+ * Override or compute the category placed on the index record. Defaults
35
+ * to a simple VC-type heuristic.
36
+ */
37
+ category?: string | ((vc: W3CVerifiableCredential, index: number) => string);
38
+ /** Optional title (display name) on the index record. */
39
+ title?: string | ((vc: W3CVerifiableCredential, index: number) => string | undefined);
40
+ /** Optional image URL on the index record. */
41
+ imgUrl?: string | ((vc: W3CVerifiableCredential, index: number) => string | undefined);
42
+ /**
43
+ * Low-level escape hatches so consumers can swap the underlying backend
44
+ * (e.g. tests, SQLite, a custom in-memory mock). If supplied these take
45
+ * precedence over the `storage` / `encrypt` defaults.
46
+ */
47
+ upload?: (credential: W3CVerifiableCredential) => Promise<string>;
48
+ addToIndex?: (record: IndexRecord) => Promise<unknown>;
49
+ /** Custom id generator. Defaults to crypto.randomUUID() with a fallback. */
50
+ makeId?: () => string;
51
+ }
52
+ /** Per-credential outcome of `storeAcceptedCredentials`. */
53
+ export interface StoredCredentialEntry {
54
+ /** URI returned by the store plane, e.g. `lc:network:...`. */
55
+ uri: string;
56
+ /** Id used in the index record. */
57
+ recordId: string;
58
+ /** Normalized W3C VC — what the store actually saw. */
59
+ vc: W3CVerifiableCredential;
60
+ /** Credential configuration id from the offer that produced this credential. */
61
+ configurationId: string;
62
+ /** Format id the issuer used (`jwt_vc_json`, `ldp_vc`, …). */
63
+ format: string;
64
+ }
65
+ export interface StoreAcceptedCredentialsResult {
66
+ stored: StoredCredentialEntry[];
67
+ /**
68
+ * Per-credential failures — storage of one credential failing should not
69
+ * abort the batch, so we surface partial success.
70
+ */
71
+ failures: Array<{
72
+ configurationId: string;
73
+ format: string;
74
+ error: VciError;
75
+ }>;
76
+ }
77
+ /**
78
+ * Persist a batch of credentials returned by {@link acceptCredentialOffer}
79
+ * into the host LearnCard's store + index planes.
80
+ *
81
+ * Each credential is normalized (JWT → W3C VC), uploaded to the store plane
82
+ * to get a URI, then indexed so it appears in the wallet UI.
83
+ *
84
+ * Errors are caught per-credential so a single failure doesn't abort the
85
+ * rest of the batch. Callers should inspect `failures` to decide whether
86
+ * to surface a partial-success toast or retry.
87
+ */
88
+ export declare const storeAcceptedCredentials: (learnCard: LearnCard<any, any, any>, accepted: AcceptedCredentialResult, options?: StoreAcceptedCredentialsOptions) => Promise<StoreAcceptedCredentialsResult>;
89
+ //# sourceMappingURL=store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/vci/store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,OAAO,EAEH,uBAAuB,EAE1B,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,wBAAwB,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEpC;;;GAGG;AACH,eAAO,MAAM,oBAAoB,eAAe,CAAC;AAEjD,4EAA4E;AAC5E,MAAM,WAAW,WAAW;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mEAAmE;IACnE,GAAG,EAAE,CAAC,CAAC;CACV;AAED,MAAM,WAAW,+BAA+B;IAC5C;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,EAAE,EAAE,uBAAuB,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC,CAAC;IAC7E,yDAAyD;IACzD,KAAK,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,EAAE,EAAE,uBAAuB,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC,CAAC;IACtF,8CAA8C;IAC9C,MAAM,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,EAAE,EAAE,uBAAuB,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC,CAAC;IACvF;;;;OAIG;IACH,MAAM,CAAC,EAAE,CAAC,UAAU,EAAE,uBAAuB,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAClE,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACvD,4EAA4E;IAC5E,MAAM,CAAC,EAAE,MAAM,MAAM,CAAC;CACzB;AAED,4DAA4D;AAC5D,MAAM,WAAW,qBAAqB;IAClC,8DAA8D;IAC9D,GAAG,EAAE,MAAM,CAAC;IACZ,mCAAmC;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,uDAAuD;IACvD,EAAE,EAAE,uBAAuB,CAAC;IAC5B,gFAAgF;IAChF,eAAe,EAAE,MAAM,CAAC;IACxB,8DAA8D;IAC9D,MAAM,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,8BAA8B;IAC3C,MAAM,EAAE,qBAAqB,EAAE,CAAC;IAChC;;;OAGG;IACH,QAAQ,EAAE,KAAK,CAAC;QACZ,eAAe,EAAE,MAAM,CAAC;QACxB,MAAM,EAAE,MAAM,CAAC;QACf,KAAK,EAAE,QAAQ,CAAC;KACnB,CAAC,CAAC;CACN;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,wBAAwB,cACtB,SAAS,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,YACzB,wBAAwB,YACzB,+BAA+B,KACzC,OAAO,CAAC,8BAA8B,CA+DxC,CAAC"}
@@ -0,0 +1,16 @@
1
+ import { TokenResponse } from './types';
2
+ /**
3
+ * Exchange a pre-authorized code for an access token.
4
+ *
5
+ * Per OID4VCI Draft 13 §6.1, the request is a standard OAuth 2.0 token
6
+ * request with `grant_type = urn:ietf:params:oauth:grant-type:pre-authorized_code`
7
+ * and optional `tx_code` when the offer required one.
8
+ */
9
+ export declare const exchangePreAuthorizedCode: (args: {
10
+ tokenEndpoint: string;
11
+ preAuthorizedCode: string;
12
+ txCode?: string;
13
+ clientId?: string;
14
+ fetchImpl?: typeof fetch;
15
+ }) => Promise<TokenResponse>;
16
+ //# sourceMappingURL=token.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token.d.ts","sourceRoot":"","sources":["../../src/vci/token.ts"],"names":[],"mappings":"AACA,OAAO,EAAkB,aAAa,EAAE,MAAM,SAAS,CAAC;AAGxD;;;;;;GAMG;AACH,eAAO,MAAM,yBAAyB,SAAgB;IAClD,aAAa,EAAE,MAAM,CAAC;IACtB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;CAC5B,KAAG,OAAO,CAAC,aAAa,CAmExB,CAAC"}