@interop/wallet-request 0.1.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.
- package/LICENSE.md +20 -0
- package/README.md +160 -0
- package/dist/appKey.d.ts +295 -0
- package/dist/appKey.d.ts.map +1 -0
- package/dist/appKey.js +516 -0
- package/dist/appKey.js.map +1 -0
- package/dist/capabilityRequest.d.ts +41 -0
- package/dist/capabilityRequest.d.ts.map +1 -0
- package/dist/capabilityRequest.js +46 -0
- package/dist/capabilityRequest.js.map +1 -0
- package/dist/classify.d.ts +233 -0
- package/dist/classify.d.ts.map +1 -0
- package/dist/classify.js +419 -0
- package/dist/classify.js.map +1 -0
- package/dist/composeVp.d.ts +52 -0
- package/dist/composeVp.d.ts.map +1 -0
- package/dist/composeVp.js +176 -0
- package/dist/composeVp.js.map +1 -0
- package/dist/ephemeralExchange.d.ts +100 -0
- package/dist/ephemeralExchange.d.ts.map +1 -0
- package/dist/ephemeralExchange.js +230 -0
- package/dist/ephemeralExchange.js.map +1 -0
- package/dist/exchangeClient.d.ts +142 -0
- package/dist/exchangeClient.d.ts.map +1 -0
- package/dist/exchangeClient.js +241 -0
- package/dist/exchangeClient.js.map +1 -0
- package/dist/index.d.ts +63 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +62 -0
- package/dist/index.js.map +1 -0
- package/dist/interactionRequest.d.ts +23 -0
- package/dist/interactionRequest.d.ts.map +1 -0
- package/dist/interactionRequest.js +46 -0
- package/dist/interactionRequest.js.map +1 -0
- package/dist/interactionUrl.d.ts +42 -0
- package/dist/interactionUrl.d.ts.map +1 -0
- package/dist/interactionUrl.js +104 -0
- package/dist/interactionUrl.js.map +1 -0
- package/dist/log.d.ts +49 -0
- package/dist/log.d.ts.map +1 -0
- package/dist/log.js +53 -0
- package/dist/log.js.map +1 -0
- package/dist/matching.d.ts +95 -0
- package/dist/matching.d.ts.map +1 -0
- package/dist/matching.js +205 -0
- package/dist/matching.js.map +1 -0
- package/dist/onboarding.d.ts +96 -0
- package/dist/onboarding.d.ts.map +1 -0
- package/dist/onboarding.js +174 -0
- package/dist/onboarding.js.map +1 -0
- package/dist/parse.d.ts +63 -0
- package/dist/parse.d.ts.map +1 -0
- package/dist/parse.js +153 -0
- package/dist/parse.js.map +1 -0
- package/dist/presentationSuite.d.ts +71 -0
- package/dist/presentationSuite.d.ts.map +1 -0
- package/dist/presentationSuite.js +143 -0
- package/dist/presentationSuite.js.map +1 -0
- package/dist/processRequest.d.ts +45 -0
- package/dist/processRequest.d.ts.map +1 -0
- package/dist/processRequest.js +146 -0
- package/dist/processRequest.js.map +1 -0
- package/dist/queryPredicates.d.ts +112 -0
- package/dist/queryPredicates.d.ts.map +1 -0
- package/dist/queryPredicates.js +157 -0
- package/dist/queryPredicates.js.map +1 -0
- package/dist/types.d.ts +257 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/walletInput.d.ts +118 -0
- package/dist/walletInput.d.ts.map +1 -0
- package/dist/walletInput.js +169 -0
- package/dist/walletInput.js.map +1 -0
- package/package.json +98 -0
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) 2026 Interop Alliance. All rights reserved.
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Shared types for `@interop/wallet-request`. The Verifiable
|
|
6
|
+
* Presentation Request (VPR) vocabulary itself is owned by
|
|
7
|
+
* `@interop/data-integrity-core` (its `VPR` module) and re-exported here so a
|
|
8
|
+
* request consumer imports one package; this file adds only the request-local
|
|
9
|
+
* types the app sources carried alongside that vocabulary: the CHAPI event
|
|
10
|
+
* shapes, the VC-API exchange reply shape, the classified-request profile, and
|
|
11
|
+
* the injection-seam types (`PresentationSigner`, `FetchLike`,
|
|
12
|
+
* `RequestProcessors`) that keep this layer free of any single app's session /
|
|
13
|
+
* network / consent machinery.
|
|
14
|
+
*
|
|
15
|
+
* Ported from DCW's `app/lib/walletRequestApi.ts` and Freewallet's
|
|
16
|
+
* `src/lib/walletRequest/{types,classify}.ts`.
|
|
17
|
+
*
|
|
18
|
+
* The VPR vocabulary (and the loose-shape guards in `classify` / `matching`) is
|
|
19
|
+
* imported from the `@interop/data-integrity-core/vpr` and `/guards` subpaths
|
|
20
|
+
* rather than the package root: the vocabulary was added to data-integrity-core
|
|
21
|
+
* without a version bump, so the package root can dedup onto an older cached
|
|
22
|
+
* build that predates it, whereas the subpath entry points resolve only against
|
|
23
|
+
* the current build that defines them.
|
|
24
|
+
*/
|
|
25
|
+
import type { ISigner } from '@interop/data-integrity-core';
|
|
26
|
+
import type { IVerifiableCredential, IVerifiablePresentation, IZcap } from '@interop/data-integrity-core';
|
|
27
|
+
import type { ICapabilityQueryDetail, IQueryByExample, IVPRDetails as ISpecVPRDetails, WalletResponse } from '@interop/data-integrity-core/vpr';
|
|
28
|
+
export type { IVPRequest, IVPOffer, IIssueRequest, IExchangeInvitation, IOid4VCIOffer, IVPRInteract, IVPRQuery, IQueryByExample, ICredentialQuery, IAcceptedCryptosuites, IDIDAuthenticationQuery, IZcapQuery, ICapabilityQueryDetail, IInvocationTarget, IAllowedAction, WalletApiMessage, WalletResponse, IVpRequest, IVpOffer, IVprDetails, IVprQuery, IDidAuthenticationQuery } from '@interop/data-integrity-core/vpr';
|
|
29
|
+
export type { IVerifiableCredential, IVerifiablePresentation, IZcap } from '@interop/data-integrity-core';
|
|
30
|
+
/**
|
|
31
|
+
* The protocol handles a verifier offers alongside a CHAPI request. Only
|
|
32
|
+
* `vcapi` (and the newer `interact` meta-protocol) are acted on; `OID4VP` /
|
|
33
|
+
* `OID4VCI` are recognized but unused.
|
|
34
|
+
*/
|
|
35
|
+
export interface CHAPIProtocols {
|
|
36
|
+
vcapi?: string;
|
|
37
|
+
interact?: string;
|
|
38
|
+
OID4VP?: string;
|
|
39
|
+
OID4VCI?: string;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* The body of a Verifiable Presentation Request, widened from the spec
|
|
43
|
+
* vocabulary with the wallet-layer `agent` member: the requester's
|
|
44
|
+
* self-declared display name on a standalone capability request (an agent
|
|
45
|
+
* asking for grants through an interaction URL, where no attested origin
|
|
46
|
+
* names it). One member at the VPR root rather than one per query, since a
|
|
47
|
+
* single agent sends the whole request. Display only and attacker-controlled,
|
|
48
|
+
* like App Connect's `app.name`; `requestingAgentOf` validates it.
|
|
49
|
+
*/
|
|
50
|
+
export type IVPRDetails = ISpecVPRDetails & {
|
|
51
|
+
agent?: {
|
|
52
|
+
name: string;
|
|
53
|
+
};
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* Raw CHAPI credential-get event. The `VerifiablePresentation` object CHAPI
|
|
57
|
+
* hands us *is* the VPR body (`query` / `challenge` / `domain`); classification
|
|
58
|
+
* rewraps it as an `IVPRequest`. When the verifier names a `protocols` handle
|
|
59
|
+
* it sends that body empty instead, and the VPR must be fetched from the
|
|
60
|
+
* protocol exchange (see `exchangeClient.ts`).
|
|
61
|
+
*/
|
|
62
|
+
export interface CHAPIGetEvent {
|
|
63
|
+
credentialRequestOrigin: string;
|
|
64
|
+
credentialRequestOptions?: {
|
|
65
|
+
web?: {
|
|
66
|
+
VerifiablePresentation?: IVPRDetails;
|
|
67
|
+
protocols?: CHAPIProtocols;
|
|
68
|
+
};
|
|
69
|
+
};
|
|
70
|
+
respondWith(promise: Promise<{
|
|
71
|
+
dataType: string;
|
|
72
|
+
data: unknown;
|
|
73
|
+
} | null>): void;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Raw CHAPI credential-store event. `credential.data` is the offered payload,
|
|
77
|
+
* and `credential.dataType` names its shape: issuers may offer either a
|
|
78
|
+
* `VerifiablePresentation` wrapping the credential(s), or a bare
|
|
79
|
+
* `VerifiableCredential` (what vcplayground.org sends). An issuer that names a
|
|
80
|
+
* `protocols` handle in `credential.options` sends `data` empty instead, and
|
|
81
|
+
* the offered credentials must be fetched from the protocol exchange (see
|
|
82
|
+
* `exchangeClient.ts`).
|
|
83
|
+
*/
|
|
84
|
+
export interface CHAPIStoreEvent {
|
|
85
|
+
credentialRequestOrigin?: string;
|
|
86
|
+
credential: {
|
|
87
|
+
dataType?: string;
|
|
88
|
+
data: IVerifiablePresentation | IVerifiableCredential;
|
|
89
|
+
options?: {
|
|
90
|
+
protocols?: CHAPIProtocols;
|
|
91
|
+
recommendedHandlerOrigins?: string[];
|
|
92
|
+
};
|
|
93
|
+
};
|
|
94
|
+
respondWith(promise: Promise<{
|
|
95
|
+
dataType: string;
|
|
96
|
+
data: unknown;
|
|
97
|
+
} | null>): void;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* The exchange's reply to either wallet call. A multi-step exchange answers a
|
|
101
|
+
* submitted presentation with another `verifiablePresentationRequest`; a
|
|
102
|
+
* finished one answers with nothing, or with credentials it issued, or with a
|
|
103
|
+
* `redirectUrl` for the user to land on.
|
|
104
|
+
*/
|
|
105
|
+
export interface VCAPIExchangeResponse {
|
|
106
|
+
verifiablePresentationRequest?: IVPRDetails;
|
|
107
|
+
verifiablePresentation?: IVerifiablePresentation;
|
|
108
|
+
redirectUrl?: string;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* A VP Request classified on independent axes: whether DID Authentication is
|
|
112
|
+
* requested, what credentials are asked for (`vcQueries`), and what capability
|
|
113
|
+
* delegations are asked for (`zcapRequests`). Any combination is valid,
|
|
114
|
+
* including zcap-only. An app that layers additional query kinds on top (e.g.
|
|
115
|
+
* Freewallet's App Connect) extends this shape with its own field.
|
|
116
|
+
*/
|
|
117
|
+
export interface WalletRequestProfile {
|
|
118
|
+
didAuth: boolean;
|
|
119
|
+
vcQueries: IQueryByExample[];
|
|
120
|
+
zcapRequests: ICapabilityQueryDetail[];
|
|
121
|
+
/**
|
|
122
|
+
* The requester's self-declared display name (the VPR's `agent.name`,
|
|
123
|
+
* validated and trimmed), present only when the request carried one.
|
|
124
|
+
*/
|
|
125
|
+
agent?: {
|
|
126
|
+
name: string;
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* A capability request entry as an `AppConnectQuery` carries it: the standard
|
|
131
|
+
* capability-query detail minus the members the wallet itself fills or refuses
|
|
132
|
+
* (`controller` is filled with the app-key subject DID at delegation time;
|
|
133
|
+
* `reason` is display-bearing and not accepted from an App Connect request).
|
|
134
|
+
*/
|
|
135
|
+
export type IAppConnectCapabilityQuery = Omit<ICapabilityQueryDetail, 'controller' | 'reason'>;
|
|
136
|
+
/**
|
|
137
|
+
* The app identity an App Connect request presents: a display `name` for the
|
|
138
|
+
* consent surface (attacker-controlled free text, never evidence of identity)
|
|
139
|
+
* and the application's canonical `appUrl`, which scopes the app-key identity
|
|
140
|
+
* within the requesting origin. Validated by `appConnectRequestOf`: the
|
|
141
|
+
* `appUrl` must parse as an absolute URL, carry no fragment, and be
|
|
142
|
+
* same-origin with the attested requesting origin.
|
|
143
|
+
*/
|
|
144
|
+
export type IAppConnectApp = {
|
|
145
|
+
name: string;
|
|
146
|
+
appUrl: string;
|
|
147
|
+
};
|
|
148
|
+
/**
|
|
149
|
+
* "Connect this app to the user's wallet and Space" -- a single-round request
|
|
150
|
+
* that combines app-key recovery-or-minting with capability delegation. The
|
|
151
|
+
* wallet finds (or self-issues) the app-key credential for the requesting
|
|
152
|
+
* origin and `appUrl`, delegates the requested capabilities to its subject
|
|
153
|
+
* DID, and returns credential + grants in one signed presentation.
|
|
154
|
+
*/
|
|
155
|
+
export type IAppConnectQuery = {
|
|
156
|
+
type: 'AppConnectQuery';
|
|
157
|
+
app: IAppConnectApp;
|
|
158
|
+
capabilityQuery?: IAppConnectCapabilityQuery | IAppConnectCapabilityQuery[];
|
|
159
|
+
};
|
|
160
|
+
/**
|
|
161
|
+
* An App Connect request as classified and validated by
|
|
162
|
+
* `appConnectRequestOf`: the app identity (its `appUrl` already in serialized
|
|
163
|
+
* form) plus its capability queries normalized to an array.
|
|
164
|
+
*/
|
|
165
|
+
export type IAppConnectRequest = {
|
|
166
|
+
app: IAppConnectApp;
|
|
167
|
+
capabilityQueries: IAppConnectCapabilityQuery[];
|
|
168
|
+
};
|
|
169
|
+
/**
|
|
170
|
+
* "Connect a new wallet client to this account" -- the query an already-
|
|
171
|
+
* enrolled wallet client (the inviter) puts in the VPR of an ephemeral
|
|
172
|
+
* exchange for a fresh wallet (the enrollee) to answer. It carries everything
|
|
173
|
+
* the enrollee needs to find the account, so no secret is required of the
|
|
174
|
+
* person joining:
|
|
175
|
+
*
|
|
176
|
+
* - `did` -- the account's stable did:webvh id, whose log is world-readable
|
|
177
|
+
* and is where the enrollee verifies its own approval.
|
|
178
|
+
* - `spaceId` and `host` -- where the account lives (the WAS server base URL
|
|
179
|
+
* and the Space on it); together with `did` these are exactly the account
|
|
180
|
+
* pointer a keyring record carries (keyring's `AccountPointer` shape), so
|
|
181
|
+
* the inviter passes its session pointer straight in.
|
|
182
|
+
* - `controller` -- the account controller did:key, what the enrollee's own
|
|
183
|
+
* profile link stores once it has joined.
|
|
184
|
+
*
|
|
185
|
+
* Discovery only: the query names the account but authorizes nothing. Every
|
|
186
|
+
* act on the Space still requires zcaps a holder of the QR or capability URL
|
|
187
|
+
* does not have, and nothing is authorized before the ceremony's
|
|
188
|
+
* confirmation-code comparison. The enrollee answers off-band of the VPR
|
|
189
|
+
* vocabulary, with the onboarding response envelope
|
|
190
|
+
* (`@interop/wallet-core`'s `enrollment` subpath), whose payload is an ordinary connect
|
|
191
|
+
* code.
|
|
192
|
+
*/
|
|
193
|
+
export type IWalletOnboardingQuery = {
|
|
194
|
+
type: 'WalletOnboardingQuery';
|
|
195
|
+
host: string;
|
|
196
|
+
did: string;
|
|
197
|
+
spaceId: string;
|
|
198
|
+
controller: string;
|
|
199
|
+
};
|
|
200
|
+
/**
|
|
201
|
+
* A wallet-onboarding request as classified and validated by
|
|
202
|
+
* `walletOnboardingRequestOf`: the account's did:webvh `did`, its `spaceId`,
|
|
203
|
+
* the `host` already in serialized URL form (the three together being the
|
|
204
|
+
* account pointer), and the account controller did:key.
|
|
205
|
+
*/
|
|
206
|
+
export type IWalletOnboardingRequest = {
|
|
207
|
+
host: string;
|
|
208
|
+
did: string;
|
|
209
|
+
spaceId: string;
|
|
210
|
+
controller: string;
|
|
211
|
+
};
|
|
212
|
+
/**
|
|
213
|
+
* The authentication signer plus the DID to name as the VP `holder`. Each app
|
|
214
|
+
* resolves this from its own key material (DCW from the selected profile's
|
|
215
|
+
* `authentication` signer + DID; Freewallet from the KMS did:web key or the
|
|
216
|
+
* passphrase-derived root key) before handing it to the shared compose path.
|
|
217
|
+
*/
|
|
218
|
+
export interface PresentationSigner {
|
|
219
|
+
signer: ISigner;
|
|
220
|
+
holder: string;
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Injected network transport. Defaults to `globalThis.fetch`; DCW passes its
|
|
224
|
+
* `fetchWithTimeout`, Freewallet its CORS-proxy fetch.
|
|
225
|
+
*/
|
|
226
|
+
export type FetchLike = (url: string, init?: RequestInit) => Promise<Response>;
|
|
227
|
+
/**
|
|
228
|
+
* App-side processors injected into {@link processRequest}. Both are optional:
|
|
229
|
+
* a wallet that grants no capabilities omits `processZcaps`, and a wallet
|
|
230
|
+
* without an App Connect flow omits `processAppConnect` (the branch is then
|
|
231
|
+
* inert).
|
|
232
|
+
*/
|
|
233
|
+
export interface RequestProcessors {
|
|
234
|
+
/**
|
|
235
|
+
* Delegates the approved capabilities and returns the minted zcaps.
|
|
236
|
+
* Freewallet supplies `processZcaps(session)`; DCW supplies a no-op / `[]`.
|
|
237
|
+
*/
|
|
238
|
+
processZcaps?: (args: {
|
|
239
|
+
zcapRequests: ICapabilityQueryDetail[];
|
|
240
|
+
}) => Promise<IZcap[]>;
|
|
241
|
+
/**
|
|
242
|
+
* Handles the App Connect single-round branch. Invoked when the request
|
|
243
|
+
* carries an `AppConnectQuery`; `appConnect` arrives already validated by
|
|
244
|
+
* `appConnectRequestOf` (its `app.appUrl` in serialized form), so the
|
|
245
|
+
* processor never sees a malformed app block.
|
|
246
|
+
*/
|
|
247
|
+
processAppConnect?: (args: {
|
|
248
|
+
request: IVPRDetails;
|
|
249
|
+
appConnect: IAppConnectRequest;
|
|
250
|
+
origin: string;
|
|
251
|
+
challenge?: string;
|
|
252
|
+
domain?: string;
|
|
253
|
+
didAuthRequested: boolean;
|
|
254
|
+
cryptosuite?: string;
|
|
255
|
+
}) => Promise<WalletResponse>;
|
|
256
|
+
}
|
|
257
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import type { WalletApiMessage } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* What a piece of wallet input turned out to be. Every variant carries the
|
|
4
|
+
* trimmed `text` it was classified from, plus whatever the classification
|
|
5
|
+
* already parsed (a classifier that recognized a grammar has usually parsed
|
|
6
|
+
* enough of it that re-parsing in the handler would be waste and drift).
|
|
7
|
+
*/
|
|
8
|
+
export type WalletInput = {
|
|
9
|
+
kind: 'was-link';
|
|
10
|
+
text: string;
|
|
11
|
+
} | {
|
|
12
|
+
kind: 'connect-code';
|
|
13
|
+
text: string;
|
|
14
|
+
} | {
|
|
15
|
+
kind: 'legacy-request';
|
|
16
|
+
text: string;
|
|
17
|
+
params: Record<string, string>;
|
|
18
|
+
} | {
|
|
19
|
+
kind: 'interaction-url';
|
|
20
|
+
text: string;
|
|
21
|
+
} | {
|
|
22
|
+
kind: 'deep-link';
|
|
23
|
+
text: string;
|
|
24
|
+
} | {
|
|
25
|
+
kind: 'wallet-api-message';
|
|
26
|
+
text: string;
|
|
27
|
+
message: WalletApiMessage;
|
|
28
|
+
} | {
|
|
29
|
+
kind: 'credentials';
|
|
30
|
+
text: string;
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* The account-convention recognizers a caller injects, one per grammar the
|
|
34
|
+
* classifier recognizes but does not own. Each is a predicate over the
|
|
35
|
+
* trimmed input; an absent one means the branch never matches. A wallet on a
|
|
36
|
+
* WAS account passes `@interop/wallet-core`'s own predicates
|
|
37
|
+
* (`isWasLinkPayload` from `space`, `isConnectCode` from `enrollment`), so
|
|
38
|
+
* the grammar keeps its one spelling there.
|
|
39
|
+
*/
|
|
40
|
+
export interface WalletInputRecognizers {
|
|
41
|
+
/**
|
|
42
|
+
* Whether the text is a `was-link` wallet-connection payload.
|
|
43
|
+
*/
|
|
44
|
+
isWasLink?: (text: string) => boolean;
|
|
45
|
+
/**
|
|
46
|
+
* Whether the text is a client-enrollment connect code.
|
|
47
|
+
*/
|
|
48
|
+
isConnectCode?: (text: string) => boolean;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Classifies one piece of wallet input. See the module doc for the order and
|
|
52
|
+
* why each branch sits where it does.
|
|
53
|
+
*
|
|
54
|
+
* @param text {string} the scanned, pasted, or opened text
|
|
55
|
+
* @param [options] {object}
|
|
56
|
+
* @param [options.deepLinkSchemes] {string[]} the link prefixes this app has
|
|
57
|
+
* registered (custom protocols and universal app links). Empty, the
|
|
58
|
+
* deep-link and legacy-request branches never match -- a wallet with no
|
|
59
|
+
* registered links has nothing to route them to
|
|
60
|
+
* @param [options.recognizers] {WalletInputRecognizers} the account-
|
|
61
|
+
* convention predicates for the `was-link` and `connect-code` branches.
|
|
62
|
+
* Absent, neither branch ever matches
|
|
63
|
+
* @returns {WalletInput}
|
|
64
|
+
*/
|
|
65
|
+
export declare function classifyWalletInput(text: string, { deepLinkSchemes, recognizers }?: {
|
|
66
|
+
deepLinkSchemes?: string[];
|
|
67
|
+
recognizers?: WalletInputRecognizers;
|
|
68
|
+
}): WalletInput;
|
|
69
|
+
/**
|
|
70
|
+
* The handlers a caller injects, one per classified kind. Every handler is
|
|
71
|
+
* optional: an input whose kind has no handler throws, which is what keeps a
|
|
72
|
+
* wallet that does not implement a grammar from silently doing the wrong thing
|
|
73
|
+
* with it.
|
|
74
|
+
*/
|
|
75
|
+
export interface WalletInputHandlers<T> {
|
|
76
|
+
wasLink?: (input: {
|
|
77
|
+
text: string;
|
|
78
|
+
}) => T | Promise<T>;
|
|
79
|
+
connectCode?: (input: {
|
|
80
|
+
text: string;
|
|
81
|
+
}) => T | Promise<T>;
|
|
82
|
+
legacyRequest?: (input: {
|
|
83
|
+
text: string;
|
|
84
|
+
params: Record<string, string>;
|
|
85
|
+
}) => T | Promise<T>;
|
|
86
|
+
interactionUrl?: (input: {
|
|
87
|
+
text: string;
|
|
88
|
+
}) => T | Promise<T>;
|
|
89
|
+
deepLink?: (input: {
|
|
90
|
+
text: string;
|
|
91
|
+
}) => T | Promise<T>;
|
|
92
|
+
walletApiMessage?: (input: {
|
|
93
|
+
text: string;
|
|
94
|
+
message: WalletApiMessage;
|
|
95
|
+
}) => T | Promise<T>;
|
|
96
|
+
credentials?: (input: {
|
|
97
|
+
text: string;
|
|
98
|
+
}) => T | Promise<T>;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Classifies input and dispatches it to the matching handler.
|
|
102
|
+
*
|
|
103
|
+
* @param options {object}
|
|
104
|
+
* @param options.text {string} the scanned, pasted, or opened text
|
|
105
|
+
* @param [options.deepLinkSchemes] {string[]} this app's registered link
|
|
106
|
+
* prefixes
|
|
107
|
+
* @param [options.recognizers] {WalletInputRecognizers} the account-
|
|
108
|
+
* convention predicates for the `was-link` and `connect-code` branches
|
|
109
|
+
* @param options.handlers {WalletInputHandlers} the injected handlers
|
|
110
|
+
* @returns {Promise<*>} whatever the matching handler resolves to
|
|
111
|
+
*/
|
|
112
|
+
export declare function handleWalletInput<T>({ text, deepLinkSchemes, recognizers, handlers }: {
|
|
113
|
+
text: string;
|
|
114
|
+
deepLinkSchemes?: string[];
|
|
115
|
+
recognizers?: WalletInputRecognizers;
|
|
116
|
+
handlers: WalletInputHandlers<T>;
|
|
117
|
+
}): Promise<T>;
|
|
118
|
+
//# sourceMappingURL=walletInput.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"walletInput.d.ts","sourceRoot":"","sources":["../src/walletInput.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) 2026 Interop Alliance. All rights reserved.
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* The universal wallet-input classifier: one ordered discrimination for every
|
|
6
|
+
* place a wallet accepts arbitrary text -- a QR scan, a paste box, a file
|
|
7
|
+
* drop, an opened deep link. Each wallet had grown its own ladder, so a
|
|
8
|
+
* grammar one wallet routed the other silently mis-handled (a connect code
|
|
9
|
+
* read as a credential URL, a connection payload read as nothing at all).
|
|
10
|
+
*
|
|
11
|
+
* Classification only: nothing here fetches, navigates, or stores. The caller
|
|
12
|
+
* supplies the handlers ({@link handleWalletInput}) or switches on the
|
|
13
|
+
* discriminated result itself.
|
|
14
|
+
*
|
|
15
|
+
* The order is the whole design, because several grammars are subsets of
|
|
16
|
+
* others. Most specific first:
|
|
17
|
+
*
|
|
18
|
+
* 1. **`was-link`** -- the wallet-connection QR payload, a non-URL JSON blob
|
|
19
|
+
* (deliberately not a link, so no OS handler ever routes it). Checked first
|
|
20
|
+
* because it is JSON that would otherwise fall through to the credential
|
|
21
|
+
* branch.
|
|
22
|
+
* 2. **`connect-code`** -- a client-enrollment connect code, recognized by
|
|
23
|
+
* prefix.
|
|
24
|
+
* 3. **`legacy-request`** -- the legacy credential-request link: a registered
|
|
25
|
+
* deep link carrying both `vc_request_url` and `issuer`. Necessarily ahead
|
|
26
|
+
* of the generic deep-link branch, which it would otherwise be swallowed by.
|
|
27
|
+
* 4. **`interaction-url`** -- a VCALM interaction URL (`interaction:` scheme,
|
|
28
|
+
* or `iuv=1`), the indirection that resolves to a protocols map.
|
|
29
|
+
* 5. **`deep-link`** -- any other link on one of the app's registered schemes,
|
|
30
|
+
* routed by the app's own link handling.
|
|
31
|
+
* 6. **`wallet-api-message`** -- a wallet API message, either as raw JSON or
|
|
32
|
+
* carried in a `request` query parameter of a link that is NOT on a
|
|
33
|
+
* registered scheme (a plain `https:` QR from a site that has one). The
|
|
34
|
+
* parameter form is checked before the raw-JSON form so the message is
|
|
35
|
+
* handed back parsed either way.
|
|
36
|
+
* 7. **`credentials`** -- the fallback: raw VC/VP JSON, or a URL to fetch one
|
|
37
|
+
* from. Deliberately last, since it is the only branch that cannot be
|
|
38
|
+
* recognized positively.
|
|
39
|
+
*
|
|
40
|
+
* Nothing is classified as "unrecognized": the credential branch is where
|
|
41
|
+
* unrecognized text lands, and the resolver a caller runs there is what
|
|
42
|
+
* produces the honest error message.
|
|
43
|
+
*
|
|
44
|
+
* The first two grammars are account conventions this package does not own:
|
|
45
|
+
* the `was-link` payload shape and the connect-code prefix are defined by
|
|
46
|
+
* `@interop/wallet-core` (`space` and `enrollment`), beside the ceremonies
|
|
47
|
+
* that consume them. The classifier takes each as an injected recognizer
|
|
48
|
+
* ({@link WalletInputRecognizers}) rather than importing the convention, the
|
|
49
|
+
* same way it takes the app's registered link schemes: a wallet that holds no
|
|
50
|
+
* WAS account has no such grammar to route, and one that does passes the
|
|
51
|
+
* owning package's predicate. An absent recognizer means that branch never
|
|
52
|
+
* matches, so the ordering above is preserved whichever subset is wired.
|
|
53
|
+
*/
|
|
54
|
+
import { isInteractionUrl } from './interactionUrl.js';
|
|
55
|
+
import { isWalletApiMessage, parseWalletApiMessage, parseWalletApiUrl } from './parse.js';
|
|
56
|
+
/**
|
|
57
|
+
* The query parameters of a link, whatever its scheme. Uses the substring
|
|
58
|
+
* after the first `?` rather than `new URL`, so a custom-protocol link parses
|
|
59
|
+
* the same way an `https:` one does.
|
|
60
|
+
*
|
|
61
|
+
* @param text {string}
|
|
62
|
+
* @returns {URLSearchParams}
|
|
63
|
+
*/
|
|
64
|
+
function queryParamsOf(text) {
|
|
65
|
+
const start = text.indexOf('?');
|
|
66
|
+
return new URLSearchParams(start === -1 ? '' : text.slice(start + 1));
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Classifies one piece of wallet input. See the module doc for the order and
|
|
70
|
+
* why each branch sits where it does.
|
|
71
|
+
*
|
|
72
|
+
* @param text {string} the scanned, pasted, or opened text
|
|
73
|
+
* @param [options] {object}
|
|
74
|
+
* @param [options.deepLinkSchemes] {string[]} the link prefixes this app has
|
|
75
|
+
* registered (custom protocols and universal app links). Empty, the
|
|
76
|
+
* deep-link and legacy-request branches never match -- a wallet with no
|
|
77
|
+
* registered links has nothing to route them to
|
|
78
|
+
* @param [options.recognizers] {WalletInputRecognizers} the account-
|
|
79
|
+
* convention predicates for the `was-link` and `connect-code` branches.
|
|
80
|
+
* Absent, neither branch ever matches
|
|
81
|
+
* @returns {WalletInput}
|
|
82
|
+
*/
|
|
83
|
+
export function classifyWalletInput(text, { deepLinkSchemes = [], recognizers = {} } = {}) {
|
|
84
|
+
const trimmed = text.trim();
|
|
85
|
+
if (recognizers.isWasLink?.(trimmed)) {
|
|
86
|
+
return { kind: 'was-link', text: trimmed };
|
|
87
|
+
}
|
|
88
|
+
if (recognizers.isConnectCode?.(trimmed)) {
|
|
89
|
+
return { kind: 'connect-code', text: trimmed };
|
|
90
|
+
}
|
|
91
|
+
const isDeepLink = deepLinkSchemes.some(scheme => trimmed.startsWith(scheme));
|
|
92
|
+
if (isDeepLink) {
|
|
93
|
+
const params = queryParamsOf(trimmed);
|
|
94
|
+
if (params.has('vc_request_url') && params.has('issuer')) {
|
|
95
|
+
return {
|
|
96
|
+
kind: 'legacy-request',
|
|
97
|
+
text: trimmed,
|
|
98
|
+
params: Object.fromEntries(params.entries())
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
if (isInteractionUrl(trimmed)) {
|
|
103
|
+
return { kind: 'interaction-url', text: trimmed };
|
|
104
|
+
}
|
|
105
|
+
if (isDeepLink) {
|
|
106
|
+
return { kind: 'deep-link', text: trimmed };
|
|
107
|
+
}
|
|
108
|
+
// A link on an unregistered scheme can still carry a wallet API message in
|
|
109
|
+
// its `request` parameter (a site's own QR code).
|
|
110
|
+
const carried = parseWalletApiUrl({ url: trimmed });
|
|
111
|
+
const message = carried
|
|
112
|
+
? parseWalletApiMessage({ messageObject: carried })
|
|
113
|
+
: isWalletApiMessage(trimmed)
|
|
114
|
+
? parseWalletApiMessage({
|
|
115
|
+
messageObject: JSON.parse(trimmed)
|
|
116
|
+
})
|
|
117
|
+
: undefined;
|
|
118
|
+
if (message) {
|
|
119
|
+
return { kind: 'wallet-api-message', text: trimmed, message };
|
|
120
|
+
}
|
|
121
|
+
return { kind: 'credentials', text: trimmed };
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Classifies input and dispatches it to the matching handler.
|
|
125
|
+
*
|
|
126
|
+
* @param options {object}
|
|
127
|
+
* @param options.text {string} the scanned, pasted, or opened text
|
|
128
|
+
* @param [options.deepLinkSchemes] {string[]} this app's registered link
|
|
129
|
+
* prefixes
|
|
130
|
+
* @param [options.recognizers] {WalletInputRecognizers} the account-
|
|
131
|
+
* convention predicates for the `was-link` and `connect-code` branches
|
|
132
|
+
* @param options.handlers {WalletInputHandlers} the injected handlers
|
|
133
|
+
* @returns {Promise<*>} whatever the matching handler resolves to
|
|
134
|
+
*/
|
|
135
|
+
export async function handleWalletInput({ text, deepLinkSchemes, recognizers, handlers }) {
|
|
136
|
+
const input = classifyWalletInput(text, { deepLinkSchemes, recognizers });
|
|
137
|
+
switch (input.kind) {
|
|
138
|
+
case 'was-link':
|
|
139
|
+
return dispatch({ handler: handlers.wasLink, input });
|
|
140
|
+
case 'connect-code':
|
|
141
|
+
return dispatch({ handler: handlers.connectCode, input });
|
|
142
|
+
case 'legacy-request':
|
|
143
|
+
return dispatch({ handler: handlers.legacyRequest, input });
|
|
144
|
+
case 'interaction-url':
|
|
145
|
+
return dispatch({ handler: handlers.interactionUrl, input });
|
|
146
|
+
case 'deep-link':
|
|
147
|
+
return dispatch({ handler: handlers.deepLink, input });
|
|
148
|
+
case 'wallet-api-message':
|
|
149
|
+
return dispatch({ handler: handlers.walletApiMessage, input });
|
|
150
|
+
default:
|
|
151
|
+
return dispatch({ handler: handlers.credentials, input });
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Runs one handler, or refuses because this wallet does not implement the
|
|
156
|
+
* grammar the input turned out to be.
|
|
157
|
+
*
|
|
158
|
+
* @param options {object}
|
|
159
|
+
* @param [options.handler] {Function}
|
|
160
|
+
* @param options.input {WalletInput}
|
|
161
|
+
* @returns {Promise<*>}
|
|
162
|
+
*/
|
|
163
|
+
async function dispatch({ handler, input }) {
|
|
164
|
+
if (!handler) {
|
|
165
|
+
throw new Error(`Unhandled wallet input of kind "${input.kind}".`);
|
|
166
|
+
}
|
|
167
|
+
return handler(input);
|
|
168
|
+
}
|
|
169
|
+
//# sourceMappingURL=walletInput.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"walletInput.js","sourceRoot":"","sources":["../src/walletInput.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@interop/wallet-request",
|
|
3
|
+
"description": "Wallet-request and exchange protocol handling for Interop wallet apps: input classification, VPR parsing, QueryByExample matching, cryptosuite negotiation, VP composition, the App Connect app-key credential, and the VC-API / ephemeral-exchange clients.",
|
|
4
|
+
"version": "0.1.0",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"build": "pnpm run clear && tsc",
|
|
8
|
+
"clear": "rimraf dist/*",
|
|
9
|
+
"dev": "vite",
|
|
10
|
+
"fix": "eslint --fix src test && pnpm run format",
|
|
11
|
+
"format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\" \"*.md\"",
|
|
12
|
+
"lint": "eslint src test",
|
|
13
|
+
"prepare": "pnpm run build",
|
|
14
|
+
"rebuild": "pnpm run clear && pnpm run build",
|
|
15
|
+
"typecheck": "tsc -p tsconfig.dev.json",
|
|
16
|
+
"test": "pnpm run fix && pnpm run lint && pnpm run typecheck && pnpm run test:node && pnpm run test:dist",
|
|
17
|
+
"test:browser": "playwright test",
|
|
18
|
+
"test:node": "vitest run",
|
|
19
|
+
"test:coverage": "vitest run --coverage",
|
|
20
|
+
"test:dist": "pnpm run build && ! grep -rl @interop/logger dist"
|
|
21
|
+
},
|
|
22
|
+
"files": [
|
|
23
|
+
"dist",
|
|
24
|
+
"README.md",
|
|
25
|
+
"LICENSE.md"
|
|
26
|
+
],
|
|
27
|
+
"exports": {
|
|
28
|
+
".": {
|
|
29
|
+
"types": "./dist/index.d.ts",
|
|
30
|
+
"react-native": "./dist/index.js",
|
|
31
|
+
"import": "./dist/index.js",
|
|
32
|
+
"default": "./dist/index.js"
|
|
33
|
+
},
|
|
34
|
+
"./matching": {
|
|
35
|
+
"types": "./dist/matching.d.ts",
|
|
36
|
+
"react-native": "./dist/matching.js",
|
|
37
|
+
"import": "./dist/matching.js",
|
|
38
|
+
"default": "./dist/matching.js"
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
"module": "dist/index.js",
|
|
42
|
+
"browser": "dist/index.js",
|
|
43
|
+
"types": "dist/index.d.ts",
|
|
44
|
+
"sideEffects": false,
|
|
45
|
+
"dependencies": {
|
|
46
|
+
"@interop/data-integrity-core": "^8.7.1",
|
|
47
|
+
"@interop/data-integrity-proof": "^3.4.5",
|
|
48
|
+
"@interop/ed25519-signature": "^7.2.1",
|
|
49
|
+
"@interop/security-document-loader": "^10.1.1",
|
|
50
|
+
"@interop/vc": "^11.0.8",
|
|
51
|
+
"@interop/webkms-client": "^14.7.5",
|
|
52
|
+
"@scure/base": "^2.3.0",
|
|
53
|
+
"byoe-context": "^0.5.0"
|
|
54
|
+
},
|
|
55
|
+
"devDependencies": {
|
|
56
|
+
"@eslint/js": "^10.0.1",
|
|
57
|
+
"@interop/ed25519-verification-key": "^8.1.0",
|
|
58
|
+
"@interop/logger": "^0.2.0",
|
|
59
|
+
"@playwright/test": "^1.60.0",
|
|
60
|
+
"@types/node": "^26.0.1",
|
|
61
|
+
"@vitest/coverage-v8": "^4.1.7",
|
|
62
|
+
"eslint": "^10.4.0",
|
|
63
|
+
"eslint-config-prettier": "^10.1.8",
|
|
64
|
+
"globals": "^17.6.0",
|
|
65
|
+
"prettier": "^3.8.3",
|
|
66
|
+
"rimraf": "^6.1.3",
|
|
67
|
+
"typescript": "^6.0.3",
|
|
68
|
+
"typescript-eslint": "^8.59.4",
|
|
69
|
+
"vite": "^8.0.14",
|
|
70
|
+
"vitest": "^4.1.7"
|
|
71
|
+
},
|
|
72
|
+
"publishConfig": {
|
|
73
|
+
"access": "public"
|
|
74
|
+
},
|
|
75
|
+
"keywords": [
|
|
76
|
+
"wallet",
|
|
77
|
+
"verifiable-credentials",
|
|
78
|
+
"verifiable-presentation-request",
|
|
79
|
+
"vc-api",
|
|
80
|
+
"app-connect",
|
|
81
|
+
"isomorphic"
|
|
82
|
+
],
|
|
83
|
+
"packageManager": "pnpm@12.3.4+sha512.961aa41fb077da3a04a441d9f8e15ebc0c96da8ef710b2eb67bf9ee7cb0610eabd48f1fd85f51cffe73846785fa0f87c56a3a872a1d893f8446741b5cce45457",
|
|
84
|
+
"engines": {
|
|
85
|
+
"node": ">=24.0"
|
|
86
|
+
},
|
|
87
|
+
"author": {
|
|
88
|
+
"name": "Interop Alliance",
|
|
89
|
+
"url": "https://github.com/interop-alliance/"
|
|
90
|
+
},
|
|
91
|
+
"license": "MIT",
|
|
92
|
+
"repository": {
|
|
93
|
+
"type": "git",
|
|
94
|
+
"url": "git+https://github.com/interop-alliance/wallet-request.git"
|
|
95
|
+
},
|
|
96
|
+
"homepage": "https://github.com/interop-alliance/wallet-request",
|
|
97
|
+
"bugs": "https://github.com/interop-alliance/wallet-request/issues"
|
|
98
|
+
}
|