@docknetwork/wallet-sdk-core 1.5.11 → 1.7.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 (95) hide show
  1. package/generate-docs.js +33 -0
  2. package/jsdoc.conf.json +28 -0
  3. package/lib/biometric-provider.d.ts +123 -31
  4. package/lib/biometric-provider.d.ts.map +1 -1
  5. package/lib/biometric-provider.js +146 -7
  6. package/lib/biometric-provider.js.map +1 -1
  7. package/lib/cloud-wallet.d.ts +7 -3
  8. package/lib/cloud-wallet.d.ts.map +1 -1
  9. package/lib/cloud-wallet.js +29 -18
  10. package/lib/cloud-wallet.js.map +1 -1
  11. package/lib/credential-provider.d.ts +63 -30
  12. package/lib/credential-provider.d.ts.map +1 -1
  13. package/lib/credential-provider.js +220 -13
  14. package/lib/credential-provider.js.map +1 -1
  15. package/lib/credentials/oidvc.d.ts +1 -1
  16. package/lib/credentials/oidvc.d.ts.map +1 -1
  17. package/lib/credentials/oidvc.js +8 -9
  18. package/lib/credentials/oidvc.js.map +1 -1
  19. package/lib/did-provider.d.ts +102 -36
  20. package/lib/did-provider.d.ts.map +1 -1
  21. package/lib/did-provider.js +186 -28
  22. package/lib/did-provider.js.map +1 -1
  23. package/lib/ecosystem-tools.js +5 -6
  24. package/lib/ecosystem-tools.js.map +1 -1
  25. package/lib/helpers.js +6 -6
  26. package/lib/helpers.js.map +1 -1
  27. package/lib/message-provider.d.ts +39 -13
  28. package/lib/message-provider.d.ts.map +1 -1
  29. package/lib/message-provider.js +147 -21
  30. package/lib/message-provider.js.map +1 -1
  31. package/lib/messages/message-helpers.js +6 -6
  32. package/lib/messages/message-helpers.js.map +1 -1
  33. package/lib/network-resolver.d.ts +1 -1
  34. package/lib/network-resolver.js +5 -5
  35. package/lib/network-resolver.js.map +1 -1
  36. package/lib/qr-handlers/builtin/index.d.ts +30 -0
  37. package/lib/qr-handlers/builtin/index.d.ts.map +1 -0
  38. package/lib/qr-handlers/builtin/index.js +46 -0
  39. package/lib/qr-handlers/builtin/index.js.map +1 -0
  40. package/lib/qr-handlers/builtin/oid4vc-handler.d.ts +137 -0
  41. package/lib/qr-handlers/builtin/oid4vc-handler.d.ts.map +1 -0
  42. package/lib/qr-handlers/builtin/oid4vc-handler.js +134 -0
  43. package/lib/qr-handlers/builtin/oid4vc-handler.js.map +1 -0
  44. package/lib/qr-handlers/index.d.ts +76 -0
  45. package/lib/qr-handlers/index.d.ts.map +1 -0
  46. package/lib/qr-handlers/index.js +92 -0
  47. package/lib/qr-handlers/index.js.map +1 -0
  48. package/lib/qr-handlers/processor.d.ts +110 -0
  49. package/lib/qr-handlers/processor.d.ts.map +1 -0
  50. package/lib/qr-handlers/processor.js +251 -0
  51. package/lib/qr-handlers/processor.js.map +1 -0
  52. package/lib/qr-handlers/types.d.ts +205 -0
  53. package/lib/qr-handlers/types.d.ts.map +1 -0
  54. package/lib/qr-handlers/types.js +10 -0
  55. package/lib/qr-handlers/types.js.map +1 -0
  56. package/lib/types.d.ts +610 -14
  57. package/lib/types.d.ts.map +1 -1
  58. package/lib/types.js +16 -0
  59. package/lib/types.js.map +1 -1
  60. package/lib/verification-controller.d.ts +0 -1
  61. package/lib/verification-controller.d.ts.map +1 -1
  62. package/lib/verification-controller.js +12 -5
  63. package/lib/verification-controller.js.map +1 -1
  64. package/lib/wallet-to-wallet-verification/walletToWalletVerificationProvider.d.ts +0 -1
  65. package/lib/wallet-to-wallet-verification/walletToWalletVerificationProvider.d.ts.map +1 -1
  66. package/lib/wallet-to-wallet-verification/walletToWalletVerificationProvider.js +3 -3
  67. package/lib/wallet-to-wallet-verification/walletToWalletVerificationProvider.js.map +1 -1
  68. package/lib/wallet-wasm.d.ts.map +1 -1
  69. package/lib/wallet-wasm.js +13 -14
  70. package/lib/wallet-wasm.js.map +1 -1
  71. package/lib/wallet.d.ts +36 -20
  72. package/lib/wallet.d.ts.map +1 -1
  73. package/lib/wallet.js +174 -28
  74. package/lib/wallet.js.map +1 -1
  75. package/package.json +19 -11
  76. package/src/biometric-provider.ts +157 -42
  77. package/src/cloud-wallet.ts +13 -0
  78. package/src/credential-provider.test.ts +220 -1
  79. package/src/credential-provider.ts +222 -25
  80. package/src/credentials/oidvc.test.ts +1 -1
  81. package/src/credentials/oidvc.ts +1 -1
  82. package/src/did-provider.ts +183 -34
  83. package/src/message-provider.ts +149 -35
  84. package/src/qr-handlers/builtin/index.ts +30 -0
  85. package/src/qr-handlers/builtin/oid4vc-handler.ts +198 -0
  86. package/src/qr-handlers/index.ts +76 -0
  87. package/src/qr-handlers/processor.test.ts +514 -0
  88. package/src/qr-handlers/processor.ts +311 -0
  89. package/src/qr-handlers/types.ts +228 -0
  90. package/src/types.ts +666 -11
  91. package/src/verification-controller.test.ts +1 -2
  92. package/src/verification-controller.ts +9 -1
  93. package/src/wallet-wasm.ts +1 -3
  94. package/src/wallet.ts +173 -24
  95. package/tsconfig.build.tsbuildinfo +1 -1
@@ -0,0 +1,311 @@
1
+ import {
2
+ QRCodeContext,
3
+ QRCodeHandler,
4
+ QRCodeHandlerResult,
5
+ QRCodeProcessor,
6
+ ProcessOptions,
7
+ } from './types';
8
+
9
+ /**
10
+ * Default implementation of QRCodeProcessor
11
+ *
12
+ * This processor manages a registry of QR code handlers and executes them
13
+ * in priority order to process scanned QR codes. It provides a flexible,
14
+ * extensible system for handling various types of QR codes in a wallet application.
15
+ *
16
+ * @example
17
+ * ```typescript
18
+ * const processor = new DefaultQRCodeProcessor();
19
+ *
20
+ * // Register handlers
21
+ * processor.registerHandler(new OID4VCHandler());
22
+ * processor.registerHandler(new CredentialHandler());
23
+ *
24
+ * // Process QR code
25
+ * const result = await processor.process(scannedData);
26
+ * if (result.success) {
27
+ * console.log('QR code processed:', result.data);
28
+ * } else {
29
+ * console.error('Failed to process QR code:', result.error);
30
+ * }
31
+ * ```
32
+ */
33
+ export class DefaultQRCodeProcessor implements QRCodeProcessor {
34
+ private handlers: Map<string, QRCodeHandler> = new Map();
35
+
36
+ /**
37
+ * Register a new QR code handler
38
+ *
39
+ * @param handler - The handler to register
40
+ * @throws Error if a handler with the same ID is already registered
41
+ */
42
+ registerHandler(handler: QRCodeHandler): void {
43
+ if (this.handlers.has(handler.id)) {
44
+ throw new Error(
45
+ `Handler with id "${handler.id}" is already registered. ` +
46
+ `Please use a unique ID or unregister the existing handler first.`,
47
+ );
48
+ }
49
+ this.handlers.set(handler.id, handler);
50
+ }
51
+
52
+ /**
53
+ * Unregister a QR code handler by its ID
54
+ *
55
+ * @param id - The ID of the handler to unregister
56
+ * @returns True if the handler was found and removed, false otherwise
57
+ */
58
+ unregisterHandler(id: string): boolean {
59
+ return this.handlers.delete(id);
60
+ }
61
+
62
+ /**
63
+ * Get all registered handlers sorted by priority
64
+ *
65
+ * @returns Array of registered handlers sorted by priority (lowest first)
66
+ */
67
+ getHandlers(): QRCodeHandler[] {
68
+ return Array.from(this.handlers.values()).sort(
69
+ (a, b) => (a.priority ?? 100) - (b.priority ?? 100),
70
+ );
71
+ }
72
+
73
+ /**
74
+ * Get a specific handler by its ID
75
+ *
76
+ * @param id - The ID of the handler to retrieve
77
+ * @returns The handler if found, undefined otherwise
78
+ */
79
+ getHandler(id: string): QRCodeHandler | undefined {
80
+ return this.handlers.get(id);
81
+ }
82
+
83
+ /**
84
+ * Clear all registered handlers
85
+ */
86
+ clearHandlers(): void {
87
+ this.handlers.clear();
88
+ }
89
+
90
+ /**
91
+ * Process QR code data through registered handlers
92
+ *
93
+ * This method:
94
+ * 1. Prepares the context from raw QR data
95
+ * 2. Executes handlers in priority order
96
+ * 3. Returns the first successful result (or continues if stopOnFirstSuccess is false)
97
+ * 4. Returns an error result if no handler can process the data
98
+ *
99
+ * @param data - Raw QR code data string
100
+ * @param options - Processing options
101
+ * @returns Result of the processing
102
+ */
103
+ async process(
104
+ data: string,
105
+ options: ProcessOptions = {},
106
+ ): Promise<QRCodeHandlerResult> {
107
+ const {
108
+ timeout = 30000,
109
+ stopOnFirstSuccess = true,
110
+ prepareContext = this.defaultPrepareContext.bind(this),
111
+ onError,
112
+ onSuccess,
113
+ } = options;
114
+
115
+ // Prepare context from raw data
116
+ let context: QRCodeContext;
117
+ try {
118
+ context = await this.withTimeout(prepareContext(data), timeout);
119
+ } catch (error) {
120
+ return {
121
+ success: false,
122
+ error: error instanceof Error ? error : new Error(String(error)),
123
+ metadata: {phase: 'context-preparation'},
124
+ };
125
+ }
126
+
127
+ // Get sorted handlers
128
+ const handlers = this.getHandlers();
129
+
130
+ if (handlers.length === 0) {
131
+ return {
132
+ success: false,
133
+ error: new Error('No handlers registered'),
134
+ metadata: {phase: 'handler-execution'},
135
+ };
136
+ }
137
+
138
+ let lastError: Error | undefined;
139
+ const attemptedHandlers: string[] = [];
140
+
141
+ // Execute handlers in priority order
142
+ for (const handler of handlers) {
143
+ try {
144
+ // Check if handler can process this data
145
+ const canHandle = await this.withTimeout(
146
+ Promise.resolve(handler.canHandle(context)),
147
+ timeout,
148
+ );
149
+
150
+ if (!canHandle) {
151
+ continue;
152
+ }
153
+
154
+ attemptedHandlers.push(handler.id);
155
+
156
+ // Execute handler
157
+ const result = await this.withTimeout(handler.handle(context), timeout);
158
+
159
+ // Call success callback if provided
160
+ if (result.success && onSuccess) {
161
+ try {
162
+ onSuccess(result, handler);
163
+ } catch (callbackError) {
164
+ console.error(
165
+ `Success callback error for handler ${handler.id}:`,
166
+ callbackError,
167
+ );
168
+ }
169
+ }
170
+
171
+ // Stop on first success if configured
172
+ if (result.success && stopOnFirstSuccess) {
173
+ return {
174
+ ...result,
175
+ metadata: {
176
+ ...result.metadata,
177
+ handlerId: handler.id,
178
+ attemptedHandlers,
179
+ },
180
+ };
181
+ }
182
+
183
+ // Store error if handler failed
184
+ if (!result.success && result.error) {
185
+ lastError = result.error;
186
+ }
187
+ } catch (error) {
188
+ const handlerError =
189
+ error instanceof Error ? error : new Error(String(error));
190
+ lastError = handlerError;
191
+
192
+ // Call error callback if provided
193
+ if (onError) {
194
+ try {
195
+ onError(handlerError, handler);
196
+ } catch (callbackError) {
197
+ console.error(
198
+ `Error callback error for handler ${handler.id}:`,
199
+ callbackError,
200
+ );
201
+ }
202
+ }
203
+
204
+ // Continue to next handler
205
+ continue;
206
+ }
207
+ }
208
+
209
+ // No handler could process the data
210
+ return {
211
+ success: false,
212
+ error:
213
+ lastError ||
214
+ new Error(
215
+ `No handler could process the QR code. Attempted handlers: ${attemptedHandlers.join(', ') || 'none'}`,
216
+ ),
217
+ metadata: {
218
+ phase: 'handler-execution',
219
+ attemptedHandlers,
220
+ },
221
+ };
222
+ }
223
+
224
+ /**
225
+ * Default context preparation function
226
+ *
227
+ * This method attempts to parse the raw QR data as JSON or URL.
228
+ * Override this by providing a custom prepareContext function in ProcessOptions.
229
+ *
230
+ * @param data - Raw QR code data string
231
+ * @returns Prepared context object
232
+ */
233
+ private async defaultPrepareContext(data: string): Promise<QRCodeContext> {
234
+ const context: QRCodeContext = {data};
235
+
236
+ // Try to parse as URL
237
+ try {
238
+ // Basic URL validation
239
+ if (data.startsWith('http://') || data.startsWith('https://')) {
240
+ const url = new URL(data);
241
+ context.url = data;
242
+ context.parsedUrl = data;
243
+ }
244
+ } catch {
245
+ // Not a valid URL, continue
246
+ }
247
+
248
+ // Try to parse as JSON
249
+ try {
250
+ const parsed = JSON.parse(data);
251
+ context.jsonData = parsed;
252
+ } catch {
253
+ // Not valid JSON, continue
254
+ }
255
+
256
+ return context;
257
+ }
258
+
259
+ /**
260
+ * Execute a promise with a timeout
261
+ *
262
+ * @param promise - Promise to execute
263
+ * @param timeoutMs - Timeout in milliseconds
264
+ * @returns Result of the promise
265
+ * @throws Error if the promise times out
266
+ */
267
+ private async withTimeout<T>(
268
+ promise: Promise<T>,
269
+ timeoutMs: number,
270
+ ): Promise<T> {
271
+ return Promise.race([
272
+ promise,
273
+ new Promise<T>((_, reject) =>
274
+ setTimeout(
275
+ () => reject(new Error(`Operation timed out after ${timeoutMs}ms`)),
276
+ timeoutMs,
277
+ ),
278
+ ),
279
+ ]);
280
+ }
281
+ }
282
+
283
+ /**
284
+ * Create a new QR code processor instance
285
+ *
286
+ * This is a convenience factory function for creating a processor.
287
+ *
288
+ * @param handlers - Optional array of handlers to register immediately
289
+ * @returns New processor instance with handlers registered
290
+ *
291
+ * @example
292
+ * ```typescript
293
+ * const processor = createQRCodeProcessor([
294
+ * new OID4VCHandler(),
295
+ * new CredentialHandler(),
296
+ * ]);
297
+ * ```
298
+ */
299
+ export function createQRCodeProcessor(
300
+ handlers?: QRCodeHandler[],
301
+ ): QRCodeProcessor {
302
+ const processor = new DefaultQRCodeProcessor();
303
+
304
+ if (handlers) {
305
+ for (const handler of handlers) {
306
+ processor.registerHandler(handler);
307
+ }
308
+ }
309
+
310
+ return processor;
311
+ }
@@ -0,0 +1,228 @@
1
+ /**
2
+ * QR Code Handler Types
3
+ *
4
+ * This module provides interfaces and types for building a generic,
5
+ * extensible QR code handler system that can process various types
6
+ * of QR codes in a decentralized identity wallet.
7
+ */
8
+
9
+ /**
10
+ * Context object containing parsed QR code data and metadata
11
+ *
12
+ * @interface QRCodeContext
13
+ */
14
+ export interface QRCodeContext {
15
+ /**
16
+ * Raw scanned QR code data string
17
+ */
18
+ data: string;
19
+
20
+ /**
21
+ * Parsed JSON data if the QR code contained JSON,
22
+ * or data fetched from a URL if the QR code was a URL
23
+ */
24
+ jsonData?: any;
25
+
26
+ /**
27
+ * Original URL if the scanned data was a valid URL
28
+ */
29
+ url?: string;
30
+
31
+ /**
32
+ * Modified URL after processing (e.g., with authentication parameters added)
33
+ */
34
+ parsedUrl?: string;
35
+
36
+ /**
37
+ * Additional metadata that can be attached by context preparation
38
+ * or handlers for passing data between handlers
39
+ */
40
+ metadata?: Record<string, any>;
41
+ }
42
+
43
+ /**
44
+ * Result returned by a QR code handler after processing
45
+ *
46
+ * @interface QRCodeHandlerResult
47
+ */
48
+ export interface QRCodeHandlerResult {
49
+ /**
50
+ * Whether the handler successfully processed the QR code data
51
+ */
52
+ success: boolean;
53
+
54
+ /**
55
+ * Optional data returned by the handler
56
+ * Can be credentials, presentation requests, or any other processed data
57
+ */
58
+ data?: any;
59
+
60
+ /**
61
+ * Error object if processing failed
62
+ */
63
+ error?: Error;
64
+
65
+ /**
66
+ * Additional metadata about the processing result
67
+ */
68
+ metadata?: Record<string, any>;
69
+ }
70
+
71
+ /**
72
+ * Handler interface for processing specific types of QR codes
73
+ *
74
+ * Handlers are responsible for:
75
+ * 1. Identifying if they can process the QR code (canHandle)
76
+ * 2. Processing the QR code data (handle)
77
+ *
78
+ * @interface QRCodeHandler
79
+ */
80
+ export interface QRCodeHandler {
81
+ /**
82
+ * Unique identifier for this handler
83
+ * Used for registration, unregistration, and debugging
84
+ */
85
+ id: string;
86
+
87
+ /**
88
+ * Priority for handler execution (lower number = higher priority)
89
+ * Handlers are executed in priority order until one successfully handles the data
90
+ *
91
+ * @default 100
92
+ */
93
+ priority?: number;
94
+
95
+ /**
96
+ * Check if this handler can process the given QR code data
97
+ *
98
+ * This method should be fast and only do basic checks (string matching, type checking)
99
+ * without performing expensive operations like network requests.
100
+ *
101
+ * @param context - The QR code context containing parsed data
102
+ * @returns True if this handler can process the data, false otherwise
103
+ */
104
+ canHandle(context: QRCodeContext): boolean | Promise<boolean>;
105
+
106
+ /**
107
+ * Process the QR code data
108
+ *
109
+ * This method is only called if canHandle returns true.
110
+ * It should perform the actual processing logic (navigation, API calls, etc.)
111
+ *
112
+ * @param context - The QR code context containing parsed data
113
+ * @returns Result of the processing including success status and any data/errors
114
+ */
115
+ handle(context: QRCodeContext): Promise<QRCodeHandlerResult>;
116
+ }
117
+
118
+ /**
119
+ * Options for processing QR codes
120
+ *
121
+ * @interface ProcessOptions
122
+ */
123
+ export interface ProcessOptions {
124
+ /**
125
+ * Timeout in milliseconds for processing
126
+ * If a handler takes longer than this, it will be skipped
127
+ *
128
+ * @default 30000 (30 seconds)
129
+ */
130
+ timeout?: number;
131
+
132
+ /**
133
+ * Whether to stop processing after the first successful handler
134
+ * If false, all handlers will be tried even after one succeeds
135
+ *
136
+ * @default true
137
+ */
138
+ stopOnFirstSuccess?: boolean;
139
+
140
+ /**
141
+ * Custom context preparation function
142
+ *
143
+ * This function is called before any handlers to prepare the context
144
+ * from the raw scanned data. It can fetch data from URLs, parse JSON,
145
+ * add metadata, etc.
146
+ *
147
+ * @param data - Raw QR code data string
148
+ * @returns Prepared context object
149
+ */
150
+ prepareContext?: (data: string) => Promise<QRCodeContext>;
151
+
152
+ /**
153
+ * Error handler callback
154
+ *
155
+ * Called when a handler throws an error during processing.
156
+ * Useful for logging, analytics, or custom error handling.
157
+ *
158
+ * @param error - The error that was thrown
159
+ * @param handler - The handler that threw the error
160
+ */
161
+ onError?: (error: Error, handler: QRCodeHandler) => void;
162
+
163
+ /**
164
+ * Success callback
165
+ *
166
+ * Called when a handler successfully processes the QR code.
167
+ * Useful for logging, analytics, or side effects.
168
+ *
169
+ * @param result - The result returned by the handler
170
+ * @param handler - The handler that processed the data
171
+ */
172
+ onSuccess?: (result: QRCodeHandlerResult, handler: QRCodeHandler) => void;
173
+ }
174
+
175
+ /**
176
+ * Main processor interface for managing and executing QR code handlers
177
+ *
178
+ * @interface QRCodeProcessor
179
+ */
180
+ export interface QRCodeProcessor {
181
+ /**
182
+ * Register a new QR code handler
183
+ *
184
+ * @param handler - The handler to register
185
+ * @throws Error if a handler with the same ID is already registered
186
+ */
187
+ registerHandler(handler: QRCodeHandler): void;
188
+
189
+ /**
190
+ * Unregister a QR code handler by its ID
191
+ *
192
+ * @param id - The ID of the handler to unregister
193
+ * @returns True if the handler was found and removed, false otherwise
194
+ */
195
+ unregisterHandler(id: string): boolean;
196
+
197
+ /**
198
+ * Get all registered handlers sorted by priority
199
+ *
200
+ * @returns Array of registered handlers sorted by priority (lowest first)
201
+ */
202
+ getHandlers(): QRCodeHandler[];
203
+
204
+ /**
205
+ * Get a specific handler by its ID
206
+ *
207
+ * @param id - The ID of the handler to retrieve
208
+ * @returns The handler if found, undefined otherwise
209
+ */
210
+ getHandler(id: string): QRCodeHandler | undefined;
211
+
212
+ /**
213
+ * Process QR code data through registered handlers
214
+ *
215
+ * Handlers are executed in priority order until one successfully
216
+ * processes the data (or all handlers are tried if stopOnFirstSuccess is false)
217
+ *
218
+ * @param data - Raw QR code data string
219
+ * @param options - Processing options
220
+ * @returns Result of the processing
221
+ */
222
+ process(data: string, options?: ProcessOptions): Promise<QRCodeHandlerResult>;
223
+
224
+ /**
225
+ * Clear all registered handlers
226
+ */
227
+ clearHandlers(): void;
228
+ }