@interop/wallet-core 0.1.1 → 0.2.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 (103) hide show
  1. package/README.md +18 -2
  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/index.d.ts +11 -2
  59. package/dist/index.d.ts.map +1 -1
  60. package/dist/index.js +11 -2
  61. package/dist/index.js.map +1 -1
  62. package/dist/request/classify.d.ts +112 -0
  63. package/dist/request/classify.d.ts.map +1 -0
  64. package/dist/request/classify.js +210 -0
  65. package/dist/request/classify.js.map +1 -0
  66. package/dist/request/composeVp.d.ts +52 -0
  67. package/dist/request/composeVp.d.ts.map +1 -0
  68. package/dist/request/composeVp.js +177 -0
  69. package/dist/request/composeVp.js.map +1 -0
  70. package/dist/request/exchangeClient.d.ts +165 -0
  71. package/dist/request/exchangeClient.d.ts.map +1 -0
  72. package/dist/request/exchangeClient.js +212 -0
  73. package/dist/request/exchangeClient.js.map +1 -0
  74. package/dist/request/index.d.ts +35 -0
  75. package/dist/request/index.d.ts.map +1 -0
  76. package/dist/request/index.js +35 -0
  77. package/dist/request/index.js.map +1 -0
  78. package/dist/request/interactionUrl.d.ts +53 -0
  79. package/dist/request/interactionUrl.d.ts.map +1 -0
  80. package/dist/request/interactionUrl.js +83 -0
  81. package/dist/request/interactionUrl.js.map +1 -0
  82. package/dist/request/matching.d.ts +69 -0
  83. package/dist/request/matching.d.ts.map +1 -0
  84. package/dist/request/matching.js +183 -0
  85. package/dist/request/matching.js.map +1 -0
  86. package/dist/request/parse.d.ts +68 -0
  87. package/dist/request/parse.d.ts.map +1 -0
  88. package/dist/request/parse.js +114 -0
  89. package/dist/request/parse.js.map +1 -0
  90. package/dist/request/presentationSuite.d.ts +71 -0
  91. package/dist/request/presentationSuite.d.ts.map +1 -0
  92. package/dist/request/presentationSuite.js +139 -0
  93. package/dist/request/presentationSuite.js.map +1 -0
  94. package/dist/request/processRequest.d.ts +48 -0
  95. package/dist/request/processRequest.d.ts.map +1 -0
  96. package/dist/request/processRequest.js +139 -0
  97. package/dist/request/processRequest.js.map +1 -0
  98. package/dist/request/types.d.ts +150 -0
  99. package/dist/request/types.d.ts.map +1 -0
  100. package/dist/request/types.js +2 -0
  101. package/dist/request/types.js.map +1 -0
  102. package/dist/sync/types.d.ts.map +1 -1
  103. package/package.json +21 -2
@@ -0,0 +1,183 @@
1
+ /*!
2
+ * Copyright (c) 2026 Interop Alliance. All rights reserved.
3
+ */
4
+ /**
5
+ * QueryByExample matching: which stored credentials satisfy a verifier's
6
+ * `QueryByExample` request. Two independent algorithms ship here because the two
7
+ * apps genuinely differ, and each wallet matches only its own local store (no
8
+ * cross-replica agreement is required):
9
+ *
10
+ * - `credentialMatchesVprExampleQuery` / `filterCredentialsByExample` -- DCW's
11
+ * jsonpath-plus deep matcher, which walks the example object and matches any
12
+ * nested field (arrays, nested objects, literals) against the credential.
13
+ * - `vcMatchesFor` / `hasTypedExample` / `requestsCredentialType` --
14
+ * Freewallet's type-and-issuer matcher, which constrains only on the
15
+ * example's `type` (and, when pinned, `issuer`).
16
+ *
17
+ * Both operate on plain `IVerifiableCredential`s; each app maps its own record
18
+ * type down to the credential before calling. Ported from DCW's
19
+ * `app/lib/credentialMatching.ts` and Freewallet's
20
+ * `src/lib/walletRequest/vcMatches.ts`.
21
+ */
22
+ import { JSONPath } from 'jsonpath-plus';
23
+ import { credentialQueriesOf } from './classify.js';
24
+ import { issuerId, typeArray } from '@interop/data-integrity-core/guards';
25
+ // The loose-field normalizers are owned by data-integrity-core; re-export them
26
+ // here so a matching consumer imports one module.
27
+ export { issuerId, typeArray } from '@interop/data-integrity-core/guards';
28
+ /**
29
+ * Whether a credential matches a QueryByExample `example` object, by the DCW
30
+ * deep-matching algorithm: every key of the example is resolved as a JSONPath
31
+ * against the credential and compared. Array example values require the
32
+ * credential to contain (at least) every listed value; object example values
33
+ * recurse; literal example values compare by strict equality. An empty example
34
+ * matches any credential.
35
+ *
36
+ * @param vprExample {Record<string, unknown>} - The QueryByExample `example`.
37
+ * @param credential {IVerifiableCredential} - The stored credential to test.
38
+ * @param [credentialPath] {string} - JSONPath root into the credential
39
+ * (defaults to `$`); used internally when recursing into nested objects.
40
+ * @returns {boolean}
41
+ */
42
+ export function credentialMatchesVprExampleQuery(vprExample, credential, credentialPath = '$') {
43
+ const matches = [];
44
+ for (const [vprExampleKey, vprExampleValue] of Object.entries(vprExample)) {
45
+ const nextPath = extendPath(credentialPath, vprExampleKey);
46
+ // The result is always dumped into a single-element array.
47
+ const [credentialScope] = JSONPath({ path: nextPath, json: credential });
48
+ if (Array.isArray(vprExampleValue)) {
49
+ // Array query values require that the matching credential contains at
50
+ // least every value specified. This assumes each element is a literal.
51
+ if (!Array.isArray(credentialScope)) {
52
+ return false;
53
+ }
54
+ if (credentialScope.length < vprExampleValue.length) {
55
+ return false;
56
+ }
57
+ matches.push(vprExampleValue.every(exVal => credentialScope.includes(exVal)));
58
+ }
59
+ else if (typeof vprExampleValue === 'object' &&
60
+ vprExampleValue !== null) {
61
+ // Object query values recurse, to handle nested queries.
62
+ matches.push(credentialMatchesVprExampleQuery(vprExampleValue, credential, nextPath));
63
+ }
64
+ else {
65
+ // Literal query values compare directly.
66
+ matches.push(credentialScope === vprExampleValue);
67
+ }
68
+ }
69
+ return matches.every(m => m);
70
+ }
71
+ /**
72
+ * Extends a JSONPath by a literal key, escaping any JSONPath-reserved
73
+ * characters in the key (jsonpath-plus escapes a reserved char by prefixing it
74
+ * with a backtick).
75
+ */
76
+ function extendPath(path, extension) {
77
+ const reserved = /[$@*()[\].:?]/g;
78
+ if (reserved.test(extension)) {
79
+ extension = extension.replace(reserved, match => '`' + match);
80
+ }
81
+ return `${path}.${extension}`;
82
+ }
83
+ /**
84
+ * Filters credentials to those matching a `QueryByExample`, using the deep
85
+ * matcher. Each of the query's `credentialQuery` details contributes its
86
+ * `example`; a credential is included when it matches any of them. A malformed
87
+ * query with no example matches nothing.
88
+ *
89
+ * @param credentials {IVerifiableCredential[]}
90
+ * @param query {IQueryByExample}
91
+ * @returns {IVerifiableCredential[]}
92
+ */
93
+ export function filterCredentialsByExample(credentials, query) {
94
+ const examples = credentialQueriesOf(query)
95
+ .map(({ example }) => example)
96
+ .filter((example) => !!example);
97
+ if (examples.length === 0) {
98
+ // Malformed request: no example to match against.
99
+ return [];
100
+ }
101
+ return credentials.filter(credential => examples.some(example => credentialMatchesVprExampleQuery(example, credential)));
102
+ }
103
+ /**
104
+ * Whether a credential matches a single QueryByExample `example` by the
105
+ * type-and-issuer algorithm: every type listed in `example.type` must appear in
106
+ * the credential's `type`, and -- when the example pins an `issuer` -- the
107
+ * credential's issuer must equal it.
108
+ *
109
+ * @param options {object}
110
+ * @param options.credential {IVerifiableCredential}
111
+ * @param options.example {ICredentialQuery['example']}
112
+ * @returns {boolean}
113
+ */
114
+ function matchesExample({ credential, example }) {
115
+ const wantedTypes = typeArray(example.type);
116
+ const credentialTypes = typeArray(credential.type);
117
+ const typesMatch = wantedTypes.every(type => credentialTypes.includes(type));
118
+ if (!typesMatch) {
119
+ return false;
120
+ }
121
+ const wantedIssuer = issuerId(example.issuer);
122
+ if (wantedIssuer) {
123
+ return issuerId(credential.issuer) === wantedIssuer;
124
+ }
125
+ return true;
126
+ }
127
+ /**
128
+ * The credentials matching any of the given QueryByExample queries by the
129
+ * type-and-issuer algorithm. Only queries whose `example` carries a `type`
130
+ * constrain the result; a query with no example type matches nothing here (the
131
+ * caller keeps its list-all behavior when *no* query specifies a type).
132
+ *
133
+ * @param options {object}
134
+ * @param options.credentials {IVerifiableCredential[]}
135
+ * @param options.queries {IQueryByExample[]}
136
+ * @returns {IVerifiableCredential[]}
137
+ */
138
+ export function vcMatchesFor({ credentials, queries }) {
139
+ const examples = typedExamplesOf(queries);
140
+ if (examples.length === 0) {
141
+ return [];
142
+ }
143
+ return credentials.filter(credential => examples.some(example => matchesExample({ credential, example })));
144
+ }
145
+ /**
146
+ * The example credential shapes pinned by a query set: every `credentialQuery`
147
+ * detail carrying an example `type`. Only these constrain the share list.
148
+ *
149
+ * @param queries {IQueryByExample[]}
150
+ * @returns {Array<ICredentialQuery['example']>}
151
+ */
152
+ function typedExamplesOf(queries) {
153
+ return queries
154
+ .flatMap(query => credentialQueriesOf(query))
155
+ .map(({ example }) => example)
156
+ .filter((example) => !!example && typeArray(example.type).length > 0);
157
+ }
158
+ /**
159
+ * Whether any of the QueryByExample queries pins an example `type` (and so
160
+ * should filter the share list). When false, the caller keeps showing all
161
+ * stored credentials.
162
+ *
163
+ * @param queries {IQueryByExample[]}
164
+ * @returns {boolean}
165
+ */
166
+ export function hasTypedExample(queries) {
167
+ return typedExamplesOf(queries).length > 0;
168
+ }
169
+ /**
170
+ * Whether any typed example in the query set explicitly lists the given
171
+ * credential `type`. Lets the caller distinguish a request that actually asks
172
+ * for a particular type (e.g. a LoginCredential) from a generic, untyped "any
173
+ * VC" request.
174
+ *
175
+ * @param options {object}
176
+ * @param options.queries {IQueryByExample[]}
177
+ * @param options.type {string}
178
+ * @returns {boolean}
179
+ */
180
+ export function requestsCredentialType({ queries, type }) {
181
+ return typedExamplesOf(queries).some(example => typeArray(example.type).includes(type));
182
+ }
183
+ //# sourceMappingURL=matching.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"matching.js","sourceRoot":"","sources":["../../src/request/matching.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,68 @@
1
+ /*!
2
+ * Copyright (c) 2026 Interop Alliance. All rights reserved.
3
+ */
4
+ /**
5
+ * Parsing of incoming wallet/VC API messages that arrive as JSON text or a
6
+ * deep-link URL (`dccrequest://...?request=<json>`), plus the small
7
+ * query-inspection helpers a caller runs over a parsed VPR body. Ported from
8
+ * DCW's `app/lib/walletRequestApi.ts`; the `query-string` dependency is dropped
9
+ * in favor of the native `URL` / `URLSearchParams`.
10
+ */
11
+ import type { IVPRQuery, IZcapQuery, WalletApiMessage } from './types.js';
12
+ export { isDIDAuthRequested as isDidAuthRequested } from './classify.js';
13
+ /**
14
+ * Whether a JSON string is a recognized wallet API message: an exchange
15
+ * invitation, a presentation request, a presentation offer, or an issuance
16
+ * request. Malformed JSON is not a message.
17
+ *
18
+ * @param text {string}
19
+ * @returns {boolean}
20
+ */
21
+ export declare function isWalletApiMessage(text: string): boolean;
22
+ /**
23
+ * Classifies a parsed message object into one of the wallet API message types
24
+ * by its discriminating property. Returns `undefined` for an unrecognized
25
+ * shape.
26
+ *
27
+ * @param options {object}
28
+ * @param options.messageObject {object}
29
+ * @returns {WalletApiMessage | undefined}
30
+ */
31
+ export declare function parseWalletApiMessage({ messageObject }: {
32
+ messageObject: object;
33
+ }): WalletApiMessage | undefined;
34
+ /**
35
+ * Extracts and parses the wallet API message carried in a deep-link URL's
36
+ * `request` query parameter (`dccrequest://...?request=<json>`). Returns
37
+ * `undefined` when the parameter is absent or its value is not valid JSON.
38
+ *
39
+ * @param options {object}
40
+ * @param options.url {string}
41
+ * @returns {Record<string, unknown> | undefined}
42
+ */
43
+ export declare function parseWalletApiUrl({ url }: {
44
+ url: string;
45
+ }): Record<string, unknown> | undefined;
46
+ /**
47
+ * Filters an incoming VCALM query set for capability (zcap) requests, returning
48
+ * only those. Recognizes both the canonical `AuthorizationCapabilityQuery` and
49
+ * the legacy `ZcapQuery` type strings.
50
+ *
51
+ * @param options {object}
52
+ * @param options.queries {IVPRQuery[]}
53
+ * @returns {{ zcapRequests?: IZcapQuery[] }}
54
+ */
55
+ export declare function zcapsRequested({ queries }: {
56
+ queries: IVPRQuery[];
57
+ }): {
58
+ zcapRequests?: IZcapQuery[];
59
+ };
60
+ /**
61
+ * Returns true if the message is a VPR whose only query type is
62
+ * `DIDAuthentication` (i.e. no credential sharing is involved).
63
+ *
64
+ * @param message {WalletApiMessage}
65
+ * @returns {boolean}
66
+ */
67
+ export declare function isDIDAuthOnlyRequest(message: WalletApiMessage): boolean;
68
+ //# sourceMappingURL=parse.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../../src/request/parse.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;GAMG;AACH,OAAO,KAAK,EAKV,SAAS,EACT,UAAU,EACV,gBAAgB,EACjB,MAAM,YAAY,CAAA;AAInB,OAAO,EAAE,kBAAkB,IAAI,kBAAkB,EAAE,MAAM,eAAe,CAAA;AAExE;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAexD;AAED;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CAAC,EACpC,aAAa,EACd,EAAE;IACD,aAAa,EAAE,MAAM,CAAA;CACtB,GAAG,gBAAgB,GAAG,SAAS,CAe/B;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,EAChC,GAAG,EACJ,EAAE;IACD,GAAG,EAAE,MAAM,CAAA;CACZ,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAqBtC;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,EAAE,OAAO,EAAE,EAAE;IAAE,OAAO,EAAE,SAAS,EAAE,CAAA;CAAE,GAAG;IACrE,YAAY,CAAC,EAAE,UAAU,EAAE,CAAA;CAC5B,CASA;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAUvE"}
@@ -0,0 +1,114 @@
1
+ // The DID-Auth query helper is spelled `isDIDAuthRequested` in `classify.ts`;
2
+ // DCW imported it as `isDidAuthRequested`. Both names resolve to one function.
3
+ export { isDIDAuthRequested as isDidAuthRequested } from './classify.js';
4
+ /**
5
+ * Whether a JSON string is a recognized wallet API message: an exchange
6
+ * invitation, a presentation request, a presentation offer, or an issuance
7
+ * request. Malformed JSON is not a message.
8
+ *
9
+ * @param text {string}
10
+ * @returns {boolean}
11
+ */
12
+ export function isWalletApiMessage(text) {
13
+ let messageObject;
14
+ try {
15
+ messageObject = JSON.parse(text);
16
+ }
17
+ catch (_) {
18
+ return false;
19
+ }
20
+ return (!!messageObject &&
21
+ typeof messageObject === 'object' &&
22
+ ('protocols' in messageObject ||
23
+ 'verifiablePresentationRequest' in messageObject ||
24
+ 'verifiablePresentation' in messageObject ||
25
+ 'issueRequest' in messageObject));
26
+ }
27
+ /**
28
+ * Classifies a parsed message object into one of the wallet API message types
29
+ * by its discriminating property. Returns `undefined` for an unrecognized
30
+ * shape.
31
+ *
32
+ * @param options {object}
33
+ * @param options.messageObject {object}
34
+ * @returns {WalletApiMessage | undefined}
35
+ */
36
+ export function parseWalletApiMessage({ messageObject }) {
37
+ if ('protocols' in messageObject) {
38
+ return messageObject;
39
+ }
40
+ if ('verifiablePresentationRequest' in messageObject) {
41
+ return messageObject;
42
+ }
43
+ if ('verifiablePresentation' in messageObject) {
44
+ return messageObject;
45
+ }
46
+ if ('issueRequest' in messageObject) {
47
+ return messageObject;
48
+ }
49
+ // Message not recognized / not supported, return undefined.
50
+ return undefined;
51
+ }
52
+ /**
53
+ * Extracts and parses the wallet API message carried in a deep-link URL's
54
+ * `request` query parameter (`dccrequest://...?request=<json>`). Returns
55
+ * `undefined` when the parameter is absent or its value is not valid JSON.
56
+ *
57
+ * @param options {object}
58
+ * @param options.url {string}
59
+ * @returns {Record<string, unknown> | undefined}
60
+ */
61
+ export function parseWalletApiUrl({ url }) {
62
+ let messageText;
63
+ try {
64
+ messageText = new URL(url).searchParams.get('request');
65
+ }
66
+ catch {
67
+ return undefined;
68
+ }
69
+ if (messageText === null) {
70
+ // URL does not contain a "request" parameter.
71
+ return undefined;
72
+ }
73
+ try {
74
+ // `URLSearchParams.get` has already percent-decoded the value.
75
+ return JSON.parse(messageText);
76
+ }
77
+ catch (err) {
78
+ console.error(`Error parsing incoming wallet API message: "${messageText}"`, err);
79
+ return undefined;
80
+ }
81
+ }
82
+ /**
83
+ * Filters an incoming VCALM query set for capability (zcap) requests, returning
84
+ * only those. Recognizes both the canonical `AuthorizationCapabilityQuery` and
85
+ * the legacy `ZcapQuery` type strings.
86
+ *
87
+ * @param options {object}
88
+ * @param options.queries {IVPRQuery[]}
89
+ * @returns {{ zcapRequests?: IZcapQuery[] }}
90
+ */
91
+ export function zcapsRequested({ queries }) {
92
+ const zcapRequests = queries.filter((q) => q.type === 'ZcapQuery' || q.type === 'AuthorizationCapabilityQuery');
93
+ if (zcapRequests.length > 0) {
94
+ return { zcapRequests };
95
+ }
96
+ return {};
97
+ }
98
+ /**
99
+ * Returns true if the message is a VPR whose only query type is
100
+ * `DIDAuthentication` (i.e. no credential sharing is involved).
101
+ *
102
+ * @param message {WalletApiMessage}
103
+ * @returns {boolean}
104
+ */
105
+ export function isDIDAuthOnlyRequest(message) {
106
+ if (!('verifiablePresentationRequest' in message)) {
107
+ return false;
108
+ }
109
+ const { query } = message.verifiablePresentationRequest;
110
+ const queries = Array.isArray(query) ? query : [query];
111
+ return (queries.length > 0 &&
112
+ queries.every(q => !!q && q.type === 'DIDAuthentication'));
113
+ }
114
+ //# sourceMappingURL=parse.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse.js","sourceRoot":"","sources":["../../src/request/parse.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,71 @@
1
+ /*!
2
+ * Copyright (c) 2026 Interop Alliance. All rights reserved.
3
+ */
4
+ /**
5
+ * Cryptosuite negotiation and proof-suite construction for signed Verifiable
6
+ * Presentations. `negotiateCryptosuite` decides which cryptosuite the wallet
7
+ * signs a presentation with (honoring a verifier's `acceptedCryptosuites`
8
+ * preference, or inferring VC 2.0 from a QueryByExample); `presentationSuiteFor`
9
+ * builds the matching proof suite and VC data-model version.
10
+ *
11
+ * Ported from Freewallet's `src/lib/walletRequest/presentationSuite.ts` (the
12
+ * superset of DCW's `app/lib/presentationSuite.ts`): it accepts both the VCALM
13
+ * `{ cryptosuite }` object form and the bare cryptosuite-string form verifiers
14
+ * send in practice, and reads `acceptedCryptosuites` from a QueryByExample's
15
+ * individual `credentialQuery` details as well as the query itself.
16
+ */
17
+ import { DataIntegrityProof } from '@interop/data-integrity-proof';
18
+ import type { ISigner } from '@interop/data-integrity-core';
19
+ import type { IVPRQuery } from './types.js';
20
+ /**
21
+ * VCALM cryptosuite identifier for the modern EdDSA Data Integrity proof. This
22
+ * is what a verifier lists in `acceptedCryptosuites` to ask for a
23
+ * `DataIntegrityProof` (VC 2.0) presentation instead of the legacy default.
24
+ *
25
+ * @see https://www.w3.org/TR/vc-data-integrity/
26
+ */
27
+ export declare const EDDSA_RDFC_2022 = "eddsa-rdfc-2022";
28
+ /**
29
+ * Decides the cryptosuite the wallet should sign a presentation with, in two
30
+ * tiers:
31
+ *
32
+ * 1. The explicit, spec-sanctioned signal: an `acceptedCryptosuites` preference
33
+ * (allowed on DIDAuthentication and QueryByExample queries, and on a
34
+ * QueryByExample's individual `credentialQuery` details). The verifier's
35
+ * stated order is honored, picking the first listed suite the wallet
36
+ * supports. If the verifier listed suites but none are supported, the wallet
37
+ * falls back to its default rather than overriding their explicit choice with
38
+ * the heuristic below.
39
+ * 2. A fallback heuristic when no `acceptedCryptosuites` is given: if a
40
+ * QueryByExample asks for a VC 2.0 example credential, infer the verifier
41
+ * wants a VC 2.0 `DataIntegrityProof` (eddsa-rdfc-2022) response.
42
+ *
43
+ * Returns `undefined` when neither tier yields a supported suite, signalling
44
+ * that the caller should sign with the wallet default (Ed25519Signature2020,
45
+ * VC 1.0).
46
+ *
47
+ * @param queries {IVPRQuery[]}
48
+ * @returns {string | undefined}
49
+ * @see https://w3c.github.io/vcalm/ -- the `acceptedCryptosuites` query field
50
+ */
51
+ export declare function negotiateCryptosuite(queries: IVPRQuery[]): string | undefined;
52
+ /**
53
+ * Builds the proof suite and the VC Data Model version to use for a presentation
54
+ * proof. The negotiated `eddsa-rdfc-2022` cryptosuite emits a
55
+ * `DataIntegrityProof` and requires the VC 2.0 context (which defines
56
+ * `challenge`/`domain` only within the `DataIntegrityProof` scope); the default
57
+ * `Ed25519Signature2020` suite uses the VC 1.0 context.
58
+ *
59
+ * @param options {object}
60
+ * @param options.signer {ISigner}
61
+ * @param [options.cryptosuite] {string}
62
+ * @returns {{ suite: DataIntegrityProof, version: number }}
63
+ */
64
+ export declare function presentationSuiteFor({ signer, cryptosuite }: {
65
+ signer: ISigner;
66
+ cryptosuite?: string;
67
+ }): {
68
+ suite: DataIntegrityProof;
69
+ version: number;
70
+ };
71
+ //# sourceMappingURL=presentationSuite.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"presentationSuite.d.ts","sourceRoot":"","sources":["../../src/request/presentationSuite.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;GAYG;AACH,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAA;AAGlE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,8BAA8B,CAAA;AAE3D,OAAO,KAAK,EAAyB,SAAS,EAAE,MAAM,YAAY,CAAA;AAElE;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,oBAAoB,CAAA;AAiEhD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,SAAS,EAAE,GAAG,MAAM,GAAG,SAAS,CAkB7E;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CAAC,EACnC,MAAM,EACN,WAAW,EACZ,EAAE;IACD,MAAM,EAAE,OAAO,CAAA;IACf,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB,GAAG;IAAE,KAAK,EAAE,kBAAkB,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAQjD"}
@@ -0,0 +1,139 @@
1
+ /*!
2
+ * Copyright (c) 2026 Interop Alliance. All rights reserved.
3
+ */
4
+ /**
5
+ * Cryptosuite negotiation and proof-suite construction for signed Verifiable
6
+ * Presentations. `negotiateCryptosuite` decides which cryptosuite the wallet
7
+ * signs a presentation with (honoring a verifier's `acceptedCryptosuites`
8
+ * preference, or inferring VC 2.0 from a QueryByExample); `presentationSuiteFor`
9
+ * builds the matching proof suite and VC data-model version.
10
+ *
11
+ * Ported from Freewallet's `src/lib/walletRequest/presentationSuite.ts` (the
12
+ * superset of DCW's `app/lib/presentationSuite.ts`): it accepts both the VCALM
13
+ * `{ cryptosuite }` object form and the bare cryptosuite-string form verifiers
14
+ * send in practice, and reads `acceptedCryptosuites` from a QueryByExample's
15
+ * individual `credentialQuery` details as well as the query itself.
16
+ */
17
+ import { DataIntegrityProof } from '@interop/data-integrity-proof';
18
+ import { Ed25519Signature2020 } from '@interop/ed25519-signature';
19
+ import { eddsaRdfc2022 } from '@interop/ed25519-signature/eddsa-rdfc-2022';
20
+ import { credentialQueriesOf } from './classify.js';
21
+ /**
22
+ * VCALM cryptosuite identifier for the modern EdDSA Data Integrity proof. This
23
+ * is what a verifier lists in `acceptedCryptosuites` to ask for a
24
+ * `DataIntegrityProof` (VC 2.0) presentation instead of the legacy default.
25
+ *
26
+ * @see https://www.w3.org/TR/vc-data-integrity/
27
+ */
28
+ export const EDDSA_RDFC_2022 = 'eddsa-rdfc-2022';
29
+ /**
30
+ * Cryptosuites this wallet can produce for a presentation proof when a verifier
31
+ * offers a choice via VCALM `acceptedCryptosuites`. `Ed25519Signature2020` is
32
+ * deliberately absent: it is the wallet's default, used as a fallback whenever
33
+ * the verifier expresses no (supported) preference, for backwards compatibility
34
+ * with verifiers that predate cryptosuite negotiation.
35
+ */
36
+ const SUPPORTED_CRYPTOSUITES = [EDDSA_RDFC_2022];
37
+ /** VC Data Model 2.0 context URL. */
38
+ const CREDENTIALS_CONTEXT_V2_URL = 'https://www.w3.org/ns/credentials/v2';
39
+ /** Returns true if a JSON-LD `@context` value contains the given URL. */
40
+ function contextIncludes(context, url) {
41
+ if (typeof context === 'string') {
42
+ return context === url;
43
+ }
44
+ if (Array.isArray(context)) {
45
+ return context.includes(url);
46
+ }
47
+ return false;
48
+ }
49
+ /**
50
+ * Normalizes an `acceptedCryptosuites` list to cryptosuite name strings,
51
+ * accepting both the VCALM `{ cryptosuite }` object form and the bare string
52
+ * form verifiers send in practice.
53
+ *
54
+ * @param [accepted] {IAcceptedCryptosuites}
55
+ * @returns {string[]}
56
+ */
57
+ function cryptosuiteNames(accepted) {
58
+ if (!Array.isArray(accepted)) {
59
+ return [];
60
+ }
61
+ return accepted
62
+ .map(entry => (typeof entry === 'string' ? entry : entry?.cryptosuite))
63
+ .filter((name) => typeof name === 'string');
64
+ }
65
+ /**
66
+ * Every cryptosuite a query offers, in the order the verifier stated them. A
67
+ * `QueryByExample` may carry the preference on the query itself (VCALM) or
68
+ * inside each of its `credentialQuery` details (what verifiers send in
69
+ * practice); both are collected.
70
+ *
71
+ * @param query {IVPRQuery}
72
+ * @returns {string[]}
73
+ */
74
+ function acceptedCryptosuitesOf(query) {
75
+ const onQuery = 'acceptedCryptosuites' in query
76
+ ? cryptosuiteNames(query.acceptedCryptosuites)
77
+ : [];
78
+ if (query.type !== 'QueryByExample') {
79
+ return onQuery;
80
+ }
81
+ const onDetails = credentialQueriesOf(query).flatMap(({ acceptedCryptosuites }) => cryptosuiteNames(acceptedCryptosuites));
82
+ return [...onQuery, ...onDetails];
83
+ }
84
+ /**
85
+ * Decides the cryptosuite the wallet should sign a presentation with, in two
86
+ * tiers:
87
+ *
88
+ * 1. The explicit, spec-sanctioned signal: an `acceptedCryptosuites` preference
89
+ * (allowed on DIDAuthentication and QueryByExample queries, and on a
90
+ * QueryByExample's individual `credentialQuery` details). The verifier's
91
+ * stated order is honored, picking the first listed suite the wallet
92
+ * supports. If the verifier listed suites but none are supported, the wallet
93
+ * falls back to its default rather than overriding their explicit choice with
94
+ * the heuristic below.
95
+ * 2. A fallback heuristic when no `acceptedCryptosuites` is given: if a
96
+ * QueryByExample asks for a VC 2.0 example credential, infer the verifier
97
+ * wants a VC 2.0 `DataIntegrityProof` (eddsa-rdfc-2022) response.
98
+ *
99
+ * Returns `undefined` when neither tier yields a supported suite, signalling
100
+ * that the caller should sign with the wallet default (Ed25519Signature2020,
101
+ * VC 1.0).
102
+ *
103
+ * @param queries {IVPRQuery[]}
104
+ * @returns {string | undefined}
105
+ * @see https://w3c.github.io/vcalm/ -- the `acceptedCryptosuites` query field
106
+ */
107
+ export function negotiateCryptosuite(queries) {
108
+ const accepted = queries.flatMap(query => acceptedCryptosuitesOf(query));
109
+ if (accepted.length > 0) {
110
+ return accepted.find(cryptosuite => SUPPORTED_CRYPTOSUITES.includes(cryptosuite));
111
+ }
112
+ // Fallback: a QueryByExample requesting a VC 2.0 example credential implies
113
+ // the verifier operates in the VC 2.0 data model, so respond in kind.
114
+ const requestsV2Example = queries.some(query => query.type === 'QueryByExample' &&
115
+ credentialQueriesOf(query).some(({ example }) => contextIncludes(example?.['@context'], CREDENTIALS_CONTEXT_V2_URL)));
116
+ return requestsV2Example ? EDDSA_RDFC_2022 : undefined;
117
+ }
118
+ /**
119
+ * Builds the proof suite and the VC Data Model version to use for a presentation
120
+ * proof. The negotiated `eddsa-rdfc-2022` cryptosuite emits a
121
+ * `DataIntegrityProof` and requires the VC 2.0 context (which defines
122
+ * `challenge`/`domain` only within the `DataIntegrityProof` scope); the default
123
+ * `Ed25519Signature2020` suite uses the VC 1.0 context.
124
+ *
125
+ * @param options {object}
126
+ * @param options.signer {ISigner}
127
+ * @param [options.cryptosuite] {string}
128
+ * @returns {{ suite: DataIntegrityProof, version: number }}
129
+ */
130
+ export function presentationSuiteFor({ signer, cryptosuite }) {
131
+ if (cryptosuite === EDDSA_RDFC_2022) {
132
+ return {
133
+ suite: new DataIntegrityProof({ signer, cryptosuite: eddsaRdfc2022 }),
134
+ version: 2.0
135
+ };
136
+ }
137
+ return { suite: new Ed25519Signature2020({ signer }), version: 1.0 };
138
+ }
139
+ //# sourceMappingURL=presentationSuite.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"presentationSuite.js","sourceRoot":"","sources":["../../src/request/presentationSuite.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ import type { IVerifiableCredential, IVPRDetails, PresentationSigner, RequestProcessors, WalletResponse } from './types.js';
2
+ /**
3
+ * Domain-binding check (VCALM §3.4.3 advisement): a DID-Auth `domain` MUST match
4
+ * the channel the request arrived on, otherwise a dishonest verifier could relay
5
+ * the challenge from another origin and replay the response.
6
+ *
7
+ * @param options {object}
8
+ * @param options.domain {string} - The `domain` from the request.
9
+ * @param [options.origin] {string} - The channel origin (for CHAPI,
10
+ * `event.credentialRequestOrigin`).
11
+ * @returns {boolean}
12
+ */
13
+ export declare function domainMatchesOrigin({ domain, origin }: {
14
+ domain: string;
15
+ origin?: string;
16
+ }): boolean;
17
+ /**
18
+ * Processes a Verifiable Presentation Request and composes the wallet's
19
+ * response. Assumes the user has already consented and (for VC sharing) picked
20
+ * which credentials to send.
21
+ *
22
+ * @param options {object}
23
+ * @param options.request {IVPRDetails} - The VPR body.
24
+ * @param options.presentationSigner {PresentationSigner} - Authentication signer
25
+ * and holder DID.
26
+ * @param [options.selectedVCs] {IVerifiableCredential[]} - VCs the user chose to
27
+ * share (empty for a DID-Auth-only or zcap-only response).
28
+ * @param [options.credentialRequestOrigin] {string} - Channel origin, used for
29
+ * the domain-binding check and required by the App Connect branch.
30
+ * @param [options.processors] {RequestProcessors} - App-side capability /
31
+ * App Connect processors.
32
+ * @param [options.cryptosuite] {string} - Cryptosuite override; when absent it
33
+ * is negotiated from the request's `acceptedCryptosuites`.
34
+ * @param [options.vocabBaseIri] {string} - Vocabulary base IRI passed through to
35
+ * {@link composeVp} for embedded-grant term definitions.
36
+ * @returns {Promise<WalletResponse>} The response VP (and any granted zcaps), or
37
+ * `{}` when there is nothing to send.
38
+ */
39
+ export declare function processRequest({ request, presentationSigner, selectedVCs, credentialRequestOrigin, processors, cryptosuite, vocabBaseIri }: {
40
+ request: IVPRDetails;
41
+ presentationSigner: PresentationSigner;
42
+ selectedVCs?: IVerifiableCredential[];
43
+ credentialRequestOrigin?: string;
44
+ processors?: RequestProcessors;
45
+ cryptosuite?: string;
46
+ vocabBaseIri?: string;
47
+ }): Promise<WalletResponse>;
48
+ //# sourceMappingURL=processRequest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"processRequest.d.ts","sourceRoot":"","sources":["../../src/request/processRequest.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EACV,qBAAqB,EACrB,WAAW,EAEX,kBAAkB,EAClB,iBAAiB,EACjB,cAAc,EACf,MAAM,YAAY,CAAA;AAkBnB;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CAAC,EAClC,MAAM,EACN,MAAM,EACP,EAAE;IACD,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB,GAAG,OAAO,CAOV;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAsB,cAAc,CAAC,EACnC,OAAO,EACP,kBAAkB,EAClB,WAAgB,EAChB,uBAAuB,EACvB,UAAU,EACV,WAAW,EACX,YAAY,EACb,EAAE;IACD,OAAO,EAAE,WAAW,CAAA;IACpB,kBAAkB,EAAE,kBAAkB,CAAA;IACtC,WAAW,CAAC,EAAE,qBAAqB,EAAE,CAAA;IACrC,uBAAuB,CAAC,EAAE,MAAM,CAAA;IAChC,UAAU,CAAC,EAAE,iBAAiB,CAAA;IAC9B,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB,GAAG,OAAO,CAAC,cAAc,CAAC,CA0E1B"}