1+ import {
2+ QRCodeContext ,
3+ QRCodeHandler ,
4+ QRCodeHandlerResult ,
5+ } from '../types' ;
6+
7+ /**
8+ * Configuration options for OID4VC handler
9+ */
10+ export interface OID4VCHandlerConfig {
11+ /**
12+ * URI prefixes to match (default: ['openid-credential-offer://'])
13+ */
14+ uriPrefixes ?: string [ ] ;
15+
16+ /**
17+ * Priority for this handler (default: 5)
18+ */
19+ priority ?: number ;
20+
21+ /**
22+ * Callback to handle credential import
23+ * This is where app-specific logic (navigation, UI, etc.) should be implemented
24+ *
25+ * @param uri - The OID4VC URI to process
26+ * @param context - The full QR code context
27+ * @returns Result of the import operation
28+ */
29+ onImportCredential : (
30+ uri : string ,
31+ context : QRCodeContext ,
32+ ) => Promise < OID4VCImportResult > ;
33+ }
34+
35+ /**
36+ * Result from importing an OID4VC credential
37+ */
38+ export interface OID4VCImportResult {
39+ /**
40+ * Whether the import was successful
41+ */
42+ success : boolean ;
43+
44+ /**
45+ * Credential data if import succeeded
46+ */
47+ credential ?: any ;
48+
49+ /**
50+ * Error if import failed
51+ */
52+ error ?: Error ;
53+
54+ /**
55+ * Additional metadata
56+ */
57+ metadata ?: Record < string , any > ;
58+ }
59+
60+ /**
61+ * Built-in handler for OID4VC (OpenID for Verifiable Credentials) URIs
62+ *
63+ * This is a generic handler that can be configured with app-specific callbacks
64+ * for importing credentials. The handler itself only handles protocol detection
65+ * and delegates the actual import logic to the configured callback.
66+ *
67+ * ## Example Usage
68+ *
69+ * ```typescript
70+ * import { OID4VCHandler } from '@docknetwork/wallet-sdk-core/src/qr-handlers/builtin';
71+ * import { getCredentialProvider } from '@docknetwork/wallet-sdk-react-native';
72+ *
73+ * const handler = new OID4VCHandler({
74+ * onImportCredential: async (uri, context) => {
75+ * try {
76+ * // Use SDK to import credential
77+ * await getCredentialProvider().importCredentialFromURI({
78+ * uri,
79+ * didProvider: getDIDProvider(),
80+ * getAuthCode: async (authUrl) => {
81+ * // App-specific auth handling
82+ * return await showAuthWebView(authUrl);
83+ * },
84+ * });
85+ *
86+ * return { success: true };
87+ * } catch (error) {
88+ * return {
89+ * success: false,
90+ * error: error instanceof Error ? error : new Error(String(error)),
91+ * };
92+ * }
93+ * },
94+ * });
95+ *
96+ * processor.registerHandler(handler);
97+ * ```
98+ *
99+ * ## Handler Priority
100+ *
101+ * Default priority: 5 (very high)
102+ * This ensures OID4VC URIs are checked before other credential handlers.
103+ *
104+ * @category Built-in Handlers
105+ */
106+ export class OID4VCHandler implements QRCodeHandler {
107+ id = 'oid4vc' ;
108+ priority : number ;
109+
110+ private uriPrefixes : string [ ] ;
111+ private onImportCredential : (
112+ uri : string ,
113+ context : QRCodeContext ,
114+ ) => Promise < OID4VCImportResult > ;
115+
116+ constructor ( config : OID4VCHandlerConfig ) {
117+ if ( ! config . onImportCredential ) {
118+ throw new Error ( 'onImportCredential callback is required' ) ;
119+ }
120+
121+ this . priority = config . priority ?? 5 ;
122+ this . uriPrefixes = config . uriPrefixes ?? [ 'openid-credential-offer://' ] ;
123+ this . onImportCredential = config . onImportCredential ;
124+ }
125+
126+ /**
127+ * Check if this is an OID4VC URI
128+ *
129+ * Matches URIs that start with any of the configured prefixes.
130+ * By default, matches: openid-credential-offer://
131+ *
132+ * @param context - The QR code context
133+ * @returns True if this handler can process the URI
134+ */
135+ canHandle ( context : QRCodeContext ) : boolean {
136+ return this . uriPrefixes . some ( prefix => context . data . startsWith ( prefix ) ) ;
137+ }
138+
139+ /**
140+ * Process the OID4VC credential offer URI
141+ *
142+ * Delegates to the configured onImportCredential callback for actual processing.
143+ * This allows apps to implement their own navigation, UI, and error handling.
144+ *
145+ * @param context - The QR code context
146+ * @returns Result of the processing
147+ */
148+ async handle ( context : QRCodeContext ) : Promise < QRCodeHandlerResult > {
149+ try {
150+ const result = await this . onImportCredential ( context . data , context ) ;
151+
152+ return {
153+ success : result . success ,
154+ data : result . credential ,
155+ error : result . error ,
156+ metadata : {
157+ type : 'oid4vc' ,
158+ uri : context . data ,
159+ ...result . metadata ,
160+ } ,
161+ } ;
162+ } catch ( error ) {
163+ const err = error instanceof Error ? error : new Error ( String ( error ) ) ;
164+ return {
165+ success : false ,
166+ error : err ,
167+ metadata : {
168+ type : 'oid4vc' ,
169+ uri : context . data ,
170+ } ,
171+ } ;
172+ }
173+ }
174+ }
175+
176+ /**
177+ * Create an OID4VC handler with custom configuration
178+ *
179+ * This is a convenience factory function for creating an OID4VC handler.
180+ *
181+ * @param config - Handler configuration
182+ * @returns Configured OID4VC handler
183+ *
184+ * @example
185+ * ```typescript
186+ * const handler = createOID4VCHandler({
187+ * onImportCredential: async (uri) => {
188+ * // Your import logic
189+ * return { success: true };
190+ * },
191+ * });
192+ * ```
193+ */
194+ export function createOID4VCHandler (
195+ config : OID4VCHandlerConfig ,
196+ ) : OID4VCHandler {
197+ return new OID4VCHandler ( config ) ;
198+ }
0 commit comments