@interop/wallet-core 0.1.1 → 0.3.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 (115) hide show
  1. package/README.md +27 -3
  2. package/dist/display/alignment.d.ts +49 -0
  3. package/dist/display/alignment.d.ts.map +1 -0
  4. package/dist/display/alignment.js +114 -0
  5. package/dist/display/alignment.js.map +1 -0
  6. package/dist/display/credentialName.d.ts +42 -0
  7. package/dist/display/credentialName.d.ts.map +1 -0
  8. package/dist/display/credentialName.js +106 -0
  9. package/dist/display/credentialName.js.map +1 -0
  10. package/dist/display/displayFields.d.ts +55 -0
  11. package/dist/display/displayFields.d.ts.map +1 -0
  12. package/dist/display/displayFields.js +136 -0
  13. package/dist/display/displayFields.js.map +1 -0
  14. package/dist/display/evidence.d.ts +44 -0
  15. package/dist/display/evidence.d.ts.map +1 -0
  16. package/dist/display/evidence.js +65 -0
  17. package/dist/display/evidence.js.map +1 -0
  18. package/dist/display/image.d.ts +18 -0
  19. package/dist/display/image.d.ts.map +1 -0
  20. package/dist/display/image.js +23 -0
  21. package/dist/display/image.js.map +1 -0
  22. package/dist/display/index.d.ts +38 -0
  23. package/dist/display/index.d.ts.map +1 -0
  24. package/dist/display/index.js +32 -0
  25. package/dist/display/index.js.map +1 -0
  26. package/dist/display/issuer.d.ts +97 -0
  27. package/dist/display/issuer.d.ts.map +1 -0
  28. package/dist/display/issuer.js +126 -0
  29. package/dist/display/issuer.js.map +1 -0
  30. package/dist/display/obv3.d.ts +77 -0
  31. package/dist/display/obv3.d.ts.map +1 -0
  32. package/dist/display/obv3.js +127 -0
  33. package/dist/display/obv3.js.map +1 -0
  34. package/dist/display/parse.d.ts +62 -0
  35. package/dist/display/parse.d.ts.map +1 -0
  36. package/dist/display/parse.js +100 -0
  37. package/dist/display/parse.js.map +1 -0
  38. package/dist/display/subject.d.ts +75 -0
  39. package/dist/display/subject.d.ts.map +1 -0
  40. package/dist/display/subject.js +122 -0
  41. package/dist/display/subject.js.map +1 -0
  42. package/dist/display/text.d.ts +42 -0
  43. package/dist/display/text.d.ts.map +1 -0
  44. package/dist/display/text.js +62 -0
  45. package/dist/display/text.js.map +1 -0
  46. package/dist/display/types.d.ts +55 -0
  47. package/dist/display/types.d.ts.map +1 -0
  48. package/dist/display/types.js +41 -0
  49. package/dist/display/types.js.map +1 -0
  50. package/dist/display/validity.d.ts +51 -0
  51. package/dist/display/validity.d.ts.map +1 -0
  52. package/dist/display/validity.js +51 -0
  53. package/dist/display/validity.js.map +1 -0
  54. package/dist/display/verificationView.d.ts +101 -0
  55. package/dist/display/verificationView.d.ts.map +1 -0
  56. package/dist/display/verificationView.js +199 -0
  57. package/dist/display/verificationView.js.map +1 -0
  58. package/dist/identity/agents.d.ts +68 -0
  59. package/dist/identity/agents.d.ts.map +1 -0
  60. package/dist/identity/agents.js +95 -0
  61. package/dist/identity/agents.js.map +1 -0
  62. package/dist/identity/index.d.ts +20 -0
  63. package/dist/identity/index.d.ts.map +1 -0
  64. package/dist/identity/index.js +19 -0
  65. package/dist/identity/index.js.map +1 -0
  66. package/dist/identity/keyResolver.d.ts +30 -0
  67. package/dist/identity/keyResolver.d.ts.map +1 -0
  68. package/dist/identity/keyResolver.js +25 -0
  69. package/dist/identity/keyResolver.js.map +1 -0
  70. package/dist/index.d.ts +14 -2
  71. package/dist/index.d.ts.map +1 -1
  72. package/dist/index.js +14 -2
  73. package/dist/index.js.map +1 -1
  74. package/dist/request/classify.d.ts +112 -0
  75. package/dist/request/classify.d.ts.map +1 -0
  76. package/dist/request/classify.js +210 -0
  77. package/dist/request/classify.js.map +1 -0
  78. package/dist/request/composeVp.d.ts +52 -0
  79. package/dist/request/composeVp.d.ts.map +1 -0
  80. package/dist/request/composeVp.js +177 -0
  81. package/dist/request/composeVp.js.map +1 -0
  82. package/dist/request/exchangeClient.d.ts +165 -0
  83. package/dist/request/exchangeClient.d.ts.map +1 -0
  84. package/dist/request/exchangeClient.js +212 -0
  85. package/dist/request/exchangeClient.js.map +1 -0
  86. package/dist/request/index.d.ts +35 -0
  87. package/dist/request/index.d.ts.map +1 -0
  88. package/dist/request/index.js +35 -0
  89. package/dist/request/index.js.map +1 -0
  90. package/dist/request/interactionUrl.d.ts +53 -0
  91. package/dist/request/interactionUrl.d.ts.map +1 -0
  92. package/dist/request/interactionUrl.js +83 -0
  93. package/dist/request/interactionUrl.js.map +1 -0
  94. package/dist/request/matching.d.ts +69 -0
  95. package/dist/request/matching.d.ts.map +1 -0
  96. package/dist/request/matching.js +183 -0
  97. package/dist/request/matching.js.map +1 -0
  98. package/dist/request/parse.d.ts +68 -0
  99. package/dist/request/parse.d.ts.map +1 -0
  100. package/dist/request/parse.js +114 -0
  101. package/dist/request/parse.js.map +1 -0
  102. package/dist/request/presentationSuite.d.ts +71 -0
  103. package/dist/request/presentationSuite.d.ts.map +1 -0
  104. package/dist/request/presentationSuite.js +139 -0
  105. package/dist/request/presentationSuite.js.map +1 -0
  106. package/dist/request/processRequest.d.ts +48 -0
  107. package/dist/request/processRequest.d.ts.map +1 -0
  108. package/dist/request/processRequest.js +139 -0
  109. package/dist/request/processRequest.js.map +1 -0
  110. package/dist/request/types.d.ts +150 -0
  111. package/dist/request/types.d.ts.map +1 -0
  112. package/dist/request/types.js +2 -0
  113. package/dist/request/types.js.map +1 -0
  114. package/dist/sync/types.d.ts.map +1 -1
  115. package/package.json +31 -3
@@ -0,0 +1,177 @@
1
+ /*!
2
+ * Copyright (c) 2026 Interop Alliance. All rights reserved.
3
+ */
4
+ /**
5
+ * Composes a Verifiable Presentation to send back to a requester. The VP is
6
+ * signed when DID Authentication was requested (proving control of the holder's
7
+ * DID over the request's `challenge`, and `domain` when the verifier sends
8
+ * one), and unsigned otherwise.
9
+ *
10
+ * Merged from DCW's `app/lib/composeVp.ts` and Freewallet's
11
+ * `src/lib/walletRequest/composeVP.ts`. The signer and holder DID are injected
12
+ * as a {@link PresentationSigner} -- each app resolves them from its own key
13
+ * material -- and the optional zcap / appConnect embedding (grants ride inside
14
+ * the VP, added before signing so a DIDAuth proof covers them) is carried over
15
+ * from Freewallet. The DIDAuth guard follows DCW: `challenge` is required,
16
+ * `domain` is optional (a wallet that needs the stricter "domain always
17
+ * present" invariant enforces it in its own wrapper before calling here).
18
+ */
19
+ import * as vc from '@interop/vc';
20
+ import { securityLoader } from '@interop/security-document-loader';
21
+ import { presentationSuiteFor } from './presentationSuite.js';
22
+ /**
23
+ * Shared JSON-LD document loader for presentation and credential signing.
24
+ * Exported so single-VC issuance paths reuse the same context resolution the VP
25
+ * compose path uses.
26
+ */
27
+ export const documentLoader = securityLoader({
28
+ fetchRemoteContexts: true
29
+ }).build();
30
+ /**
31
+ * The default JSON-LD vocabulary base IRI for the embedded-grant term
32
+ * definitions. This IRI is canonicalized into the DIDAuth proof, so it must be
33
+ * byte-stable: the default is Freewallet's value, keeping Freewallet's signed
34
+ * output byte-identical after extraction. A wallet that embeds grants under a
35
+ * different vocabulary passes its own `vocabBaseIri`.
36
+ */
37
+ const DEFAULT_VOCAB_BASE_IRI = 'urn:freewallet:vocab#';
38
+ /** Reads a presentation's `@context` as a mutable array of entries. */
39
+ function contextEntries(presentation) {
40
+ const base = presentation['@context'];
41
+ return Array.isArray(base) ? [...base] : [base];
42
+ }
43
+ /** Writes a presentation's `@context` from an array of entries. */
44
+ function setContext(presentation, entries) {
45
+ ;
46
+ presentation['@context'] = entries;
47
+ }
48
+ /**
49
+ * The bare `zcap` term definition appended to the VP `@context` when grants are
50
+ * embedded. Only the top-level term is defined (mapped to `${vocabBaseIri}zcap`);
51
+ * the zcap sub-contexts are *not* hoisted -- each embedded zcap self-describes
52
+ * via its own `@context`. Defining the term is what lets JSON-LD safe-mode
53
+ * canonicalization include (rather than reject) the grants, so the
54
+ * authentication proof genuinely covers them.
55
+ */
56
+ function zcapTermContext(vocabBaseIri) {
57
+ return {
58
+ '@protected': true,
59
+ zcap: { '@id': `${vocabBaseIri}zcap`, '@container': '@set' }
60
+ };
61
+ }
62
+ /**
63
+ * The `appConnect` term definition appended to the VP `@context` when an App
64
+ * Connect response marker is embedded. The member is a JSON literal
65
+ * (`@type: '@json'`) so its `firstRun` boolean canonicalizes as one opaque
66
+ * value; embedding happens before signing, so the DIDAuth proof covers the
67
+ * marker the same way it covers the grants.
68
+ */
69
+ function appConnectTermContext(vocabBaseIri) {
70
+ return {
71
+ '@protected': true,
72
+ appConnect: { '@id': `${vocabBaseIri}appConnect`, '@type': '@json' }
73
+ };
74
+ }
75
+ /**
76
+ * Embeds the delegated capabilities on the presentation and adds the bare
77
+ * `zcap` term to its `@context`.
78
+ */
79
+ function embedZcaps(presentation, zcaps, vocabBaseIri) {
80
+ if (zcaps.length === 0) {
81
+ return;
82
+ }
83
+ setContext(presentation, [
84
+ ...contextEntries(presentation),
85
+ zcapTermContext(vocabBaseIri)
86
+ ]);
87
+ presentation.zcap = zcaps;
88
+ }
89
+ /**
90
+ * Embeds the App Connect response marker (the wallet-provided `firstRun`
91
+ * signal) on the presentation and adds the `appConnect` term to its `@context`.
92
+ */
93
+ function embedAppConnect(presentation, appConnect, vocabBaseIri) {
94
+ if (!appConnect) {
95
+ return;
96
+ }
97
+ setContext(presentation, [
98
+ ...contextEntries(presentation),
99
+ appConnectTermContext(vocabBaseIri)
100
+ ]);
101
+ presentation.appConnect = appConnect;
102
+ }
103
+ /**
104
+ * Creates a Verifiable Presentation for the requester.
105
+ *
106
+ * @param options {object}
107
+ * @param options.presentationSigner {PresentationSigner} - The authentication
108
+ * signer and the holder DID to name on a signed VP.
109
+ * @param [options.selectedVcs] {IVerifiableCredential[]} - VCs the user chose to
110
+ * share (empty for a DID-Auth-only or zcap-only response).
111
+ * @param [options.challenge] {string} - Required when DID Auth is requested.
112
+ * @param [options.domain] {string} - Signed into the proof when present;
113
+ * optional per the VPR spec.
114
+ * @param options.didAuthRequested {boolean} - Whether to sign the VP.
115
+ * @param [options.cryptosuite] {string} - Negotiated cryptosuite; falls back to
116
+ * the wallet default (Ed25519Signature2020) when absent.
117
+ * @param [options.zcaps] {IZcap[]} - Delegated capabilities to embed as the
118
+ * VP's `zcap` array (before signing, so a DIDAuth proof covers them).
119
+ * @param [options.appConnect] {{ firstRun: boolean }} - App Connect response
120
+ * marker to embed (before signing, like the grants).
121
+ * @param [options.vocabBaseIri] {string} - Vocabulary base IRI for the embedded
122
+ * term definitions; defaults to Freewallet's value.
123
+ * @param [options.documentLoader] {IDocumentLoader} - JSON-LD loader; defaults
124
+ * to the shared security loader.
125
+ * @returns {Promise<IVerifiablePresentation>}
126
+ */
127
+ export async function composeVp({ presentationSigner, selectedVcs = [], challenge, domain, didAuthRequested, cryptosuite, zcaps = [], appConnect, vocabBaseIri = DEFAULT_VOCAB_BASE_IRI, documentLoader: loader = documentLoader }) {
128
+ if (!didAuthRequested && selectedVcs.length === 0 && zcaps.length === 0) {
129
+ throw new Error('A VP requires credentials, capabilities, or a DID Auth request.');
130
+ }
131
+ if (didAuthRequested && !challenge) {
132
+ throw new Error('A "challenge" is required for DID Auth.');
133
+ }
134
+ if (!didAuthRequested) {
135
+ // Return an unsigned VP. verify: false skips per-VC validation (including
136
+ // expiration checks). A zcap-only response rides here: the grants are
137
+ // individually signed and controller-bound, so they need no VP proof.
138
+ const presentation = vc.createPresentation({
139
+ verifiableCredential: selectedVcs.length > 0 ? selectedVcs : undefined,
140
+ verify: false,
141
+ version: 1.0
142
+ });
143
+ embedZcaps(presentation, zcaps, vocabBaseIri);
144
+ embedAppConnect(presentation, appConnect, vocabBaseIri);
145
+ return presentation;
146
+ }
147
+ const { signer, holder } = presentationSigner;
148
+ // Sign with the cryptosuite the verifier requested (via VCALM
149
+ // `acceptedCryptosuites`), falling back to the wallet default. The suite
150
+ // dictates the VC data model version: eddsa-rdfc-2022 proofs require VC 2.0,
151
+ // the default Ed25519Signature2020 proof uses VC 1.0.
152
+ const { suite, version } = presentationSuiteFor({ signer, cryptosuite });
153
+ const presentation = vc.createPresentation({
154
+ holder,
155
+ verifiableCredential: selectedVcs.length > 0 ? selectedVcs : undefined,
156
+ verify: false,
157
+ version
158
+ });
159
+ // Embed the grants (and any App Connect marker) before signing so the
160
+ // authentication proof covers them; the grants additionally self-authenticate
161
+ // via their own delegation proofs and carry their own `@context`.
162
+ embedZcaps(presentation, zcaps, vocabBaseIri);
163
+ embedAppConnect(presentation, appConnect, vocabBaseIri);
164
+ return (await vc.signPresentation({
165
+ presentation,
166
+ challenge,
167
+ ...(domain !== undefined && { domain }),
168
+ documentLoader: loader,
169
+ suite
170
+ }));
171
+ }
172
+ /**
173
+ * @deprecated Use {@link composeVp}. Retained for Freewallet, which imports the
174
+ * `composeVP` spelling.
175
+ */
176
+ export const composeVP = composeVp;
177
+ //# sourceMappingURL=composeVp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"composeVp.js","sourceRoot":"","sources":["../../src/request/composeVp.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,165 @@
1
+ /*!
2
+ * Copyright (c) 2026 Interop Alliance. All rights reserved.
3
+ */
4
+ /**
5
+ * VC API exchange client. A verifier may hand the wallet a CHAPI request whose
6
+ * `VerifiablePresentation` body is empty and whose `protocols.vcapi` names an
7
+ * exchange URL instead: the real Verifiable Presentation Request lives on the
8
+ * verifier's exchange endpoint, and the wallet POSTs its response back there
9
+ * rather than (only) over the CHAPI channel. vcplayground.org's verifier does
10
+ * exactly this whenever it mints an exchange, which is always.
11
+ *
12
+ * Two calls make up the wallet's side of the exchange: `startExchange` (POST an
13
+ * empty body, receive the VPR) and `submitPresentation` (POST the composed VP
14
+ * to the VPR's presentation service endpoint, defaulting to the exchange URL).
15
+ * An issuance exchange runs the same two calls in the other direction.
16
+ *
17
+ * Ported from Freewallet's `src/lib/walletRequest/vcApiExchange.ts`, with the
18
+ * network transport injected ({@link FetchLike}, default `globalThis.fetch`) and
19
+ * DCW's `sendToExchanger` (the whole-`WalletResponse` POST, envelope carrying
20
+ * `zcap`) added alongside `submitPresentation` (VP-only body).
21
+ *
22
+ * @see https://w3c-ccg.github.io/vc-api/#exchange-examples
23
+ */
24
+ import type { CHAPIProtocols, FetchLike, IVerifiablePresentation, IVPRDetails, IZcap, VCAPIExchangeResponse } from './types.js';
25
+ /**
26
+ * The exchange URL a CHAPI request defers to, if any. Present when the verifier
27
+ * or issuer chose an exchange-based protocol, in which case the request's VPR
28
+ * (or store) body is empty and everything of substance lives behind this URL.
29
+ *
30
+ * Two protocol handles carry such a URL: the classic `vcapi` key, and the
31
+ * `interact` key of the newer `chapi.interact()` API (a "meta" protocol whose
32
+ * URL is opaque -- the underlying exchange is negotiated behind it, exactly as
33
+ * with `vcapi`). Both are plain HTTP exchange endpoints the wallet POSTs to, so
34
+ * they are handled identically here; `interact` is preferred when a request
35
+ * carries both.
36
+ *
37
+ * @param options {object}
38
+ * @param [options.protocols] {CHAPIProtocols}
39
+ * @returns {string | undefined}
40
+ */
41
+ export declare function vcApiExchangeUrl({ protocols }: {
42
+ protocols?: CHAPIProtocols;
43
+ }): string | undefined;
44
+ /**
45
+ * Opens the exchange and retrieves the Verifiable Presentation Request the
46
+ * verifier is actually asking for. The wallet begins an exchange by POSTing an
47
+ * empty body; the reply carries the VPR.
48
+ *
49
+ * @param options {object}
50
+ * @param options.exchangeUrl {string}
51
+ * @param [options.fetch] {FetchLike}
52
+ * @returns {Promise<IVPRDetails>}
53
+ */
54
+ export declare function startExchange({ exchangeUrl, fetch }: {
55
+ exchangeUrl: string;
56
+ fetch?: FetchLike;
57
+ }): Promise<IVPRDetails>;
58
+ /**
59
+ * Opens an exchange: the wallet's first message is always an empty JSON body,
60
+ * whether the exchange goes on to request a presentation (a verifier) or to
61
+ * offer one (an issuer).
62
+ *
63
+ * @param options {object}
64
+ * @param options.exchangeUrl {string}
65
+ * @param [options.fetch] {FetchLike}
66
+ * @returns {Promise<VCAPIExchangeResponse>}
67
+ */
68
+ export declare function beginExchange({ exchangeUrl, fetch }: {
69
+ exchangeUrl: string;
70
+ fetch?: FetchLike;
71
+ }): Promise<VCAPIExchangeResponse>;
72
+ /**
73
+ * Delivers the wallet's composed presentation to a verifier's exchange and
74
+ * confirms the exchange finished. The exchange, not the CHAPI channel, is the
75
+ * verifier's system of record, so an unfinished (multi-step) reply is a failed
76
+ * delivery.
77
+ *
78
+ * @param options {object}
79
+ * @param options.request {IVPRDetails} - The VPR the exchange handed back.
80
+ * @param options.exchangeUrl {string}
81
+ * @param options.verifiablePresentation {IVerifiablePresentation}
82
+ * @param [options.fetch] {FetchLike}
83
+ * @returns {Promise<void>}
84
+ */
85
+ export declare function deliverPresentation({ request, exchangeUrl, verifiablePresentation, fetch }: {
86
+ request: IVPRDetails;
87
+ exchangeUrl: string;
88
+ verifiablePresentation: IVerifiablePresentation;
89
+ fetch?: FetchLike;
90
+ }): Promise<void>;
91
+ /**
92
+ * Answers an issuance exchange's holder-binding step: POSTs the wallet's
93
+ * DID-Auth presentation and collects the credentials the issuer hands back in
94
+ * return. A reply carrying yet another `verifiablePresentationRequest` means a
95
+ * further round this wallet does not answer.
96
+ *
97
+ * @param options {object}
98
+ * @param options.request {IVPRDetails} - The VPR the exchange opened with.
99
+ * @param options.exchangeUrl {string}
100
+ * @param options.verifiablePresentation {IVerifiablePresentation} - The signed
101
+ * DID-Auth presentation proving control of the holder DID.
102
+ * @param [options.fetch] {FetchLike}
103
+ * @returns {Promise<IVerifiablePresentation>} The offered presentation.
104
+ */
105
+ export declare function collectIssuedPresentation({ request, exchangeUrl, verifiablePresentation, fetch }: {
106
+ request: IVPRDetails;
107
+ exchangeUrl: string;
108
+ verifiablePresentation: IVerifiablePresentation;
109
+ fetch?: FetchLike;
110
+ }): Promise<IVerifiablePresentation>;
111
+ /**
112
+ * Where to POST the composed presentation: the VPR's unmediated HTTP
113
+ * presentation service, when it names one, else the exchange URL itself (which
114
+ * every exchange accepts, and which is all vcplayground.org's VPR offers).
115
+ *
116
+ * @param options {object}
117
+ * @param options.request {IVPRDetails}
118
+ * @param options.exchangeUrl {string}
119
+ * @returns {string}
120
+ */
121
+ export declare function presentationEndpointFor({ request, exchangeUrl }: {
122
+ request: IVPRDetails;
123
+ exchangeUrl: string;
124
+ }): string;
125
+ /**
126
+ * Delivers the wallet's composed presentation to the exchange and returns the
127
+ * raw reply. The exchange is complete unless the reply carries a further
128
+ * `verifiablePresentationRequest`; the finalize helpers (`deliverPresentation`,
129
+ * `collectIssuedPresentation`) inspect the reply via `assertExchangeComplete`.
130
+ *
131
+ * @param options {object}
132
+ * @param options.request {IVPRDetails} - The VPR the exchange handed back.
133
+ * @param options.exchangeUrl {string}
134
+ * @param options.verifiablePresentation {IVerifiablePresentation}
135
+ * @param [options.fetch] {FetchLike}
136
+ * @returns {Promise<VCAPIExchangeResponse>}
137
+ */
138
+ export declare function submitPresentation({ request, exchangeUrl, verifiablePresentation, fetch }: {
139
+ request: IVPRDetails;
140
+ exchangeUrl: string;
141
+ verifiablePresentation: IVerifiablePresentation;
142
+ fetch?: FetchLike;
143
+ }): Promise<VCAPIExchangeResponse>;
144
+ /**
145
+ * Sends the whole Wallet Response object -- a VP and/or delegated `zcap`s -- to
146
+ * an exchanger endpoint (DCW's response envelope, which threads the grants
147
+ * *beside* the VP rather than embedding them inside it). Returns the parsed JSON
148
+ * reply, or `null` for an empty body. Kept alongside `submitPresentation` (whose
149
+ * envelope carries only the VP) because the two apps POST different shapes.
150
+ *
151
+ * @param options {object}
152
+ * @param options.exchangeUrl {string}
153
+ * @param options.payload {{ verifiablePresentation?, zcap? }}
154
+ * @param [options.fetch] {FetchLike}
155
+ * @returns {Promise<unknown>}
156
+ */
157
+ export declare function sendToExchanger({ exchangeUrl, payload, fetch }: {
158
+ exchangeUrl: string;
159
+ payload: {
160
+ verifiablePresentation?: IVerifiablePresentation;
161
+ zcap?: IZcap[];
162
+ };
163
+ fetch?: FetchLike;
164
+ }): Promise<unknown>;
165
+ //# sourceMappingURL=exchangeClient.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exchangeClient.d.ts","sourceRoot":"","sources":["../../src/request/exchangeClient.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,KAAK,EACV,cAAc,EACd,SAAS,EACT,uBAAuB,EACvB,WAAW,EACX,KAAK,EACL,qBAAqB,EACtB,MAAM,YAAY,CAAA;AAQnB;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,gBAAgB,CAAC,EAC/B,SAAS,EACV,EAAE;IACD,SAAS,CAAC,EAAE,cAAc,CAAA;CAC3B,GAAG,MAAM,GAAG,SAAS,CAGrB;AA6CD;;;;;;;;;GASG;AACH,wBAAsB,aAAa,CAAC,EAClC,WAAW,EACX,KAAwB,EACzB,EAAE;IACD,WAAW,EAAE,MAAM,CAAA;IACnB,KAAK,CAAC,EAAE,SAAS,CAAA;CAClB,GAAG,OAAO,CAAC,WAAW,CAAC,CAYvB;AAED;;;;;;;;;GASG;AACH,wBAAsB,aAAa,CAAC,EAClC,WAAW,EACX,KAAwB,EACzB,EAAE;IACD,WAAW,EAAE,MAAM,CAAA;IACnB,KAAK,CAAC,EAAE,SAAS,CAAA;CAClB,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAEjC;AAwBD;;;;;;;;;;;;GAYG;AACH,wBAAsB,mBAAmB,CAAC,EACxC,OAAO,EACP,WAAW,EACX,sBAAsB,EACtB,KAAwB,EACzB,EAAE;IACD,OAAO,EAAE,WAAW,CAAA;IACpB,WAAW,EAAE,MAAM,CAAA;IACnB,sBAAsB,EAAE,uBAAuB,CAAA;IAC/C,KAAK,CAAC,EAAE,SAAS,CAAA;CAClB,GAAG,OAAO,CAAC,IAAI,CAAC,CAQhB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,yBAAyB,CAAC,EAC9C,OAAO,EACP,WAAW,EACX,sBAAsB,EACtB,KAAwB,EACzB,EAAE;IACD,OAAO,EAAE,WAAW,CAAA;IACpB,WAAW,EAAE,MAAM,CAAA;IACnB,sBAAsB,EAAE,uBAAuB,CAAA;IAC/C,KAAK,CAAC,EAAE,SAAS,CAAA;CAClB,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAcnC;AAED;;;;;;;;;GASG;AACH,wBAAgB,uBAAuB,CAAC,EACtC,OAAO,EACP,WAAW,EACZ,EAAE;IACD,OAAO,EAAE,WAAW,CAAA;IACpB,WAAW,EAAE,MAAM,CAAA;CACpB,GAAG,MAAM,CAOT;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,kBAAkB,CAAC,EACvC,OAAO,EACP,WAAW,EACX,sBAAsB,EACtB,KAAwB,EACzB,EAAE;IACD,OAAO,EAAE,WAAW,CAAA;IACpB,WAAW,EAAE,MAAM,CAAA;IACnB,sBAAsB,EAAE,uBAAuB,CAAA;IAC/C,KAAK,CAAC,EAAE,SAAS,CAAA;CAClB,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAMjC;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,eAAe,CAAC,EACpC,WAAW,EACX,OAAO,EACP,KAAwB,EACzB,EAAE;IACD,WAAW,EAAE,MAAM,CAAA;IACnB,OAAO,EAAE;QACP,sBAAsB,CAAC,EAAE,uBAAuB,CAAA;QAChD,IAAI,CAAC,EAAE,KAAK,EAAE,CAAA;KACf,CAAA;IACD,KAAK,CAAC,EAAE,SAAS,CAAA;CAClB,GAAG,OAAO,CAAC,OAAO,CAAC,CAQnB"}
@@ -0,0 +1,212 @@
1
+ /**
2
+ * The `interact.service` type naming an endpoint that accepts a Verifiable
3
+ * Presentation over plain HTTP POST, with no mediator in between.
4
+ */
5
+ const PRESENTATION_SERVICE_TYPE = 'UnmediatedHttpPresentationService2021';
6
+ /**
7
+ * The exchange URL a CHAPI request defers to, if any. Present when the verifier
8
+ * or issuer chose an exchange-based protocol, in which case the request's VPR
9
+ * (or store) body is empty and everything of substance lives behind this URL.
10
+ *
11
+ * Two protocol handles carry such a URL: the classic `vcapi` key, and the
12
+ * `interact` key of the newer `chapi.interact()` API (a "meta" protocol whose
13
+ * URL is opaque -- the underlying exchange is negotiated behind it, exactly as
14
+ * with `vcapi`). Both are plain HTTP exchange endpoints the wallet POSTs to, so
15
+ * they are handled identically here; `interact` is preferred when a request
16
+ * carries both.
17
+ *
18
+ * @param options {object}
19
+ * @param [options.protocols] {CHAPIProtocols}
20
+ * @returns {string | undefined}
21
+ */
22
+ export function vcApiExchangeUrl({ protocols }) {
23
+ const candidates = [protocols?.interact, protocols?.vcapi];
24
+ return candidates.find(url => typeof url === 'string' && url.length > 0);
25
+ }
26
+ /**
27
+ * POSTs a JSON body to an exchange endpoint and parses the reply. A 2xx with an
28
+ * empty body is normal (a completed exchange), and yields `{}`.
29
+ *
30
+ * @param options {object}
31
+ * @param options.url {string}
32
+ * @param options.body {object}
33
+ * @param options.fetch {FetchLike}
34
+ * @returns {Promise<VCAPIExchangeResponse>}
35
+ */
36
+ async function postToExchange({ url, body, fetch }) {
37
+ const response = await fetch(url, {
38
+ method: 'POST',
39
+ headers: { 'content-type': 'application/json', accept: 'application/json' },
40
+ body: JSON.stringify(body)
41
+ });
42
+ if (!response.ok) {
43
+ throw new Error(`The exchange at ${url} responded ${response.status} ` +
44
+ `${response.statusText}.`);
45
+ }
46
+ const text = await response.text();
47
+ if (!text) {
48
+ return {};
49
+ }
50
+ try {
51
+ return JSON.parse(text);
52
+ }
53
+ catch (err) {
54
+ throw new Error(`The exchange at ${url} returned malformed JSON.`, {
55
+ cause: err
56
+ });
57
+ }
58
+ }
59
+ /**
60
+ * Opens the exchange and retrieves the Verifiable Presentation Request the
61
+ * verifier is actually asking for. The wallet begins an exchange by POSTing an
62
+ * empty body; the reply carries the VPR.
63
+ *
64
+ * @param options {object}
65
+ * @param options.exchangeUrl {string}
66
+ * @param [options.fetch] {FetchLike}
67
+ * @returns {Promise<IVPRDetails>}
68
+ */
69
+ export async function startExchange({ exchangeUrl, fetch = globalThis.fetch }) {
70
+ const { verifiablePresentationRequest } = await beginExchange({
71
+ exchangeUrl,
72
+ fetch
73
+ });
74
+ if (!verifiablePresentationRequest) {
75
+ throw new Error(`The exchange at ${exchangeUrl} did not return a ` +
76
+ 'verifiablePresentationRequest.');
77
+ }
78
+ return verifiablePresentationRequest;
79
+ }
80
+ /**
81
+ * Opens an exchange: the wallet's first message is always an empty JSON body,
82
+ * whether the exchange goes on to request a presentation (a verifier) or to
83
+ * offer one (an issuer).
84
+ *
85
+ * @param options {object}
86
+ * @param options.exchangeUrl {string}
87
+ * @param [options.fetch] {FetchLike}
88
+ * @returns {Promise<VCAPIExchangeResponse>}
89
+ */
90
+ export async function beginExchange({ exchangeUrl, fetch = globalThis.fetch }) {
91
+ return postToExchange({ url: exchangeUrl, body: {}, fetch });
92
+ }
93
+ /**
94
+ * Reply inspection shared by both exchange directions. This wallet answers a
95
+ * single round, so a reply carrying a further `verifiablePresentationRequest` is
96
+ * a multi-step exchange it cannot continue: throw rather than pretend the
97
+ * exchange closed. A reply without one is a completed round and returns
98
+ * normally.
99
+ */
100
+ function assertExchangeComplete({ reply, exchangeUrl }) {
101
+ if (reply.verifiablePresentationRequest) {
102
+ throw new Error(`The exchange at ${exchangeUrl} asked for a further presentation; ` +
103
+ 'multi-step exchanges are not supported.');
104
+ }
105
+ }
106
+ /**
107
+ * Delivers the wallet's composed presentation to a verifier's exchange and
108
+ * confirms the exchange finished. The exchange, not the CHAPI channel, is the
109
+ * verifier's system of record, so an unfinished (multi-step) reply is a failed
110
+ * delivery.
111
+ *
112
+ * @param options {object}
113
+ * @param options.request {IVPRDetails} - The VPR the exchange handed back.
114
+ * @param options.exchangeUrl {string}
115
+ * @param options.verifiablePresentation {IVerifiablePresentation}
116
+ * @param [options.fetch] {FetchLike}
117
+ * @returns {Promise<void>}
118
+ */
119
+ export async function deliverPresentation({ request, exchangeUrl, verifiablePresentation, fetch = globalThis.fetch }) {
120
+ const reply = await submitPresentation({
121
+ request,
122
+ exchangeUrl,
123
+ verifiablePresentation,
124
+ fetch
125
+ });
126
+ assertExchangeComplete({ reply, exchangeUrl });
127
+ }
128
+ /**
129
+ * Answers an issuance exchange's holder-binding step: POSTs the wallet's
130
+ * DID-Auth presentation and collects the credentials the issuer hands back in
131
+ * return. A reply carrying yet another `verifiablePresentationRequest` means a
132
+ * further round this wallet does not answer.
133
+ *
134
+ * @param options {object}
135
+ * @param options.request {IVPRDetails} - The VPR the exchange opened with.
136
+ * @param options.exchangeUrl {string}
137
+ * @param options.verifiablePresentation {IVerifiablePresentation} - The signed
138
+ * DID-Auth presentation proving control of the holder DID.
139
+ * @param [options.fetch] {FetchLike}
140
+ * @returns {Promise<IVerifiablePresentation>} The offered presentation.
141
+ */
142
+ export async function collectIssuedPresentation({ request, exchangeUrl, verifiablePresentation, fetch = globalThis.fetch }) {
143
+ const reply = await submitPresentation({
144
+ request,
145
+ exchangeUrl,
146
+ verifiablePresentation,
147
+ fetch
148
+ });
149
+ if (reply.verifiablePresentation) {
150
+ return reply.verifiablePresentation;
151
+ }
152
+ assertExchangeComplete({ reply, exchangeUrl });
153
+ throw new Error(`The exchange at ${exchangeUrl} offered no verifiablePresentation.`);
154
+ }
155
+ /**
156
+ * Where to POST the composed presentation: the VPR's unmediated HTTP
157
+ * presentation service, when it names one, else the exchange URL itself (which
158
+ * every exchange accepts, and which is all vcplayground.org's VPR offers).
159
+ *
160
+ * @param options {object}
161
+ * @param options.request {IVPRDetails}
162
+ * @param options.exchangeUrl {string}
163
+ * @returns {string}
164
+ */
165
+ export function presentationEndpointFor({ request, exchangeUrl }) {
166
+ const services = request.interact?.service ?? [];
167
+ const unmediated = services.find(({ type, serviceEndpoint }) => type === PRESENTATION_SERVICE_TYPE && !!serviceEndpoint);
168
+ return unmediated?.serviceEndpoint ?? exchangeUrl;
169
+ }
170
+ /**
171
+ * Delivers the wallet's composed presentation to the exchange and returns the
172
+ * raw reply. The exchange is complete unless the reply carries a further
173
+ * `verifiablePresentationRequest`; the finalize helpers (`deliverPresentation`,
174
+ * `collectIssuedPresentation`) inspect the reply via `assertExchangeComplete`.
175
+ *
176
+ * @param options {object}
177
+ * @param options.request {IVPRDetails} - The VPR the exchange handed back.
178
+ * @param options.exchangeUrl {string}
179
+ * @param options.verifiablePresentation {IVerifiablePresentation}
180
+ * @param [options.fetch] {FetchLike}
181
+ * @returns {Promise<VCAPIExchangeResponse>}
182
+ */
183
+ export async function submitPresentation({ request, exchangeUrl, verifiablePresentation, fetch = globalThis.fetch }) {
184
+ return postToExchange({
185
+ url: presentationEndpointFor({ request, exchangeUrl }),
186
+ body: { verifiablePresentation },
187
+ fetch
188
+ });
189
+ }
190
+ /**
191
+ * Sends the whole Wallet Response object -- a VP and/or delegated `zcap`s -- to
192
+ * an exchanger endpoint (DCW's response envelope, which threads the grants
193
+ * *beside* the VP rather than embedding them inside it). Returns the parsed JSON
194
+ * reply, or `null` for an empty body. Kept alongside `submitPresentation` (whose
195
+ * envelope carries only the VP) because the two apps POST different shapes.
196
+ *
197
+ * @param options {object}
198
+ * @param options.exchangeUrl {string}
199
+ * @param options.payload {{ verifiablePresentation?, zcap? }}
200
+ * @param [options.fetch] {FetchLike}
201
+ * @returns {Promise<unknown>}
202
+ */
203
+ export async function sendToExchanger({ exchangeUrl, payload, fetch = globalThis.fetch }) {
204
+ const response = await fetch(exchangeUrl, {
205
+ method: 'POST',
206
+ headers: { 'Content-Type': 'application/json' },
207
+ body: JSON.stringify(payload)
208
+ });
209
+ const text = await response.text();
210
+ return text ? JSON.parse(text) : null;
211
+ }
212
+ //# sourceMappingURL=exchangeClient.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exchangeClient.js","sourceRoot":"","sources":["../../src/request/exchangeClient.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ /*!
2
+ * Copyright (c) 2026 Interop Alliance. All rights reserved.
3
+ */
4
+ /**
5
+ * The `@interop/wallet-core/request` subpath: wallet-request / exchange-protocol
6
+ * handling shared by the Interop wallet apps (DCW and Freewallet).
7
+ *
8
+ * - `types` re-exports the VPR message vocabulary from
9
+ * `@interop/data-integrity-core` and declares the request-local types (CHAPI
10
+ * events, the classified-request profile, and the `PresentationSigner` /
11
+ * `FetchLike` / `RequestProcessors` injection seams).
12
+ * - `parse` / `classify` turn a raw URL, JSON string, or CHAPI event into a
13
+ * typed message and dispatch on what it asks for.
14
+ * - `matching` filters stored credentials against a QueryByExample (both the
15
+ * jsonpath deep matcher and the type/issuer matcher).
16
+ * - `presentationSuite` negotiates the response cryptosuite; `composeVp` builds
17
+ * the (optionally signed, optionally grant-embedding) response VP.
18
+ * - `exchangeClient` is the fetch-injectable VC-API exchange client;
19
+ * `interactionUrl` resolves VCALM `interaction:` URLs.
20
+ * - `processRequest` is the pure request-to-response pipeline, with the
21
+ * app-side side effects injected.
22
+ *
23
+ * The signing / document-loader dependency graph lives entirely behind this
24
+ * subpath; `@interop/wallet-core`'s plaintext consumers never pull it in.
25
+ */
26
+ export * from './types.js';
27
+ export * from './parse.js';
28
+ export * from './classify.js';
29
+ export * from './matching.js';
30
+ export * from './presentationSuite.js';
31
+ export * from './composeVp.js';
32
+ export * from './exchangeClient.js';
33
+ export * from './interactionUrl.js';
34
+ export * from './processRequest.js';
35
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/request/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,cAAc,YAAY,CAAA;AAC1B,cAAc,YAAY,CAAA;AAC1B,cAAc,eAAe,CAAA;AAC7B,cAAc,eAAe,CAAA;AAC7B,cAAc,wBAAwB,CAAA;AACtC,cAAc,gBAAgB,CAAA;AAC9B,cAAc,qBAAqB,CAAA;AACnC,cAAc,qBAAqB,CAAA;AACnC,cAAc,qBAAqB,CAAA"}
@@ -0,0 +1,35 @@
1
+ /*!
2
+ * Copyright (c) 2026 Interop Alliance. All rights reserved.
3
+ */
4
+ /**
5
+ * The `@interop/wallet-core/request` subpath: wallet-request / exchange-protocol
6
+ * handling shared by the Interop wallet apps (DCW and Freewallet).
7
+ *
8
+ * - `types` re-exports the VPR message vocabulary from
9
+ * `@interop/data-integrity-core` and declares the request-local types (CHAPI
10
+ * events, the classified-request profile, and the `PresentationSigner` /
11
+ * `FetchLike` / `RequestProcessors` injection seams).
12
+ * - `parse` / `classify` turn a raw URL, JSON string, or CHAPI event into a
13
+ * typed message and dispatch on what it asks for.
14
+ * - `matching` filters stored credentials against a QueryByExample (both the
15
+ * jsonpath deep matcher and the type/issuer matcher).
16
+ * - `presentationSuite` negotiates the response cryptosuite; `composeVp` builds
17
+ * the (optionally signed, optionally grant-embedding) response VP.
18
+ * - `exchangeClient` is the fetch-injectable VC-API exchange client;
19
+ * `interactionUrl` resolves VCALM `interaction:` URLs.
20
+ * - `processRequest` is the pure request-to-response pipeline, with the
21
+ * app-side side effects injected.
22
+ *
23
+ * The signing / document-loader dependency graph lives entirely behind this
24
+ * subpath; `@interop/wallet-core`'s plaintext consumers never pull it in.
25
+ */
26
+ export * from './types.js';
27
+ export * from './parse.js';
28
+ export * from './classify.js';
29
+ export * from './matching.js';
30
+ export * from './presentationSuite.js';
31
+ export * from './composeVp.js';
32
+ export * from './exchangeClient.js';
33
+ export * from './interactionUrl.js';
34
+ export * from './processRequest.js';
35
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/request/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,cAAc,YAAY,CAAA;AAC1B,cAAc,YAAY,CAAA;AAC1B,cAAc,eAAe,CAAA;AAC7B,cAAc,eAAe,CAAA;AAC7B,cAAc,wBAAwB,CAAA;AACtC,cAAc,gBAAgB,CAAA;AAC9B,cAAc,qBAAqB,CAAA;AACnC,cAAc,qBAAqB,CAAA;AACnC,cAAc,qBAAqB,CAAA"}