@koraidv/core 1.5.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/dist/index.d.mts +1049 -0
- package/dist/index.d.ts +1049 -0
- package/dist/index.js +1938 -0
- package/dist/index.mjs +1893 -0
- package/package.json +44 -0
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,1049 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Supported document types.
|
|
3
|
+
*
|
|
4
|
+
* Note: This enum is maintained for backward compatibility. The SDK now fetches
|
|
5
|
+
* the full list of supported countries and document types dynamically from the API.
|
|
6
|
+
*/
|
|
7
|
+
declare enum DocumentType {
|
|
8
|
+
US_DRIVERS_LICENSE = "us_drivers_license",
|
|
9
|
+
US_STATE_ID = "us_state_id",
|
|
10
|
+
US_GREEN_CARD = "us_green_card",
|
|
11
|
+
INTERNATIONAL_PASSPORT = "international_passport",
|
|
12
|
+
EU_ID_GERMANY = "eu_id_de",
|
|
13
|
+
EU_ID_FRANCE = "eu_id_fr",
|
|
14
|
+
EU_ID_SPAIN = "eu_id_es",
|
|
15
|
+
EU_ID_ITALY = "eu_id_it",
|
|
16
|
+
GHANA_CARD = "ghana_card",
|
|
17
|
+
NIGERIA_NIN = "ng_nin",
|
|
18
|
+
NIGERIA_DRIVERS_LICENSE = "ng_drivers_license",
|
|
19
|
+
GHANA_DRIVERS_LICENSE = "gh_drivers_license",
|
|
20
|
+
KENYA_ID = "ke_id",
|
|
21
|
+
KENYA_DRIVERS_LICENSE = "ke_drivers_license",
|
|
22
|
+
SOUTH_AFRICA_ID = "za_id",
|
|
23
|
+
SOUTH_AFRICA_DRIVERS_LICENSE = "za_drivers_license",
|
|
24
|
+
UK_DRIVERS_LICENSE = "uk_drivers_license",
|
|
25
|
+
NIGERIA_VOTERS_CARD = "ng_voters_card",
|
|
26
|
+
LIBERIA_ID = "lr_id",
|
|
27
|
+
LIBERIA_DRIVERS_LICENSE = "lr_drivers_license",
|
|
28
|
+
LIBERIA_VOTERS_CARD = "lr_voters_card",
|
|
29
|
+
SIERRA_LEONE_ID = "sl_id",
|
|
30
|
+
SIERRA_LEONE_DRIVERS_LICENSE = "sl_drivers_license",
|
|
31
|
+
SIERRA_LEONE_VOTERS_CARD = "sl_voters_card",
|
|
32
|
+
GAMBIA_ID = "gm_id",
|
|
33
|
+
GAMBIA_DRIVERS_LICENSE = "gm_drivers_license",
|
|
34
|
+
UK_BRP = "uk_brp",
|
|
35
|
+
CANADA_DRIVERS_LICENSE = "ca_drivers_license",
|
|
36
|
+
CANADA_PR_CARD = "ca_pr_card",
|
|
37
|
+
CANADA_NATIONAL_ID = "ca_national_id",
|
|
38
|
+
INDIA_DRIVERS_LICENSE = "in_drivers_license",
|
|
39
|
+
GERMANY_RP = "de_rp",
|
|
40
|
+
FRANCE_RP = "fr_rp",
|
|
41
|
+
ITALY_RP = "it_rp",
|
|
42
|
+
SPAIN_RP = "es_rp",
|
|
43
|
+
IRELAND_RP = "ie_rp",
|
|
44
|
+
PORTUGAL_RP = "pt_rp",
|
|
45
|
+
SWEDEN_RP = "se_rp",
|
|
46
|
+
DENMARK_RP = "dk_rp",
|
|
47
|
+
NORWAY_RP = "no_rp",
|
|
48
|
+
FINLAND_RP = "fi_rp",
|
|
49
|
+
POLAND_RP = "pl_rp"
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Document type metadata
|
|
53
|
+
*/
|
|
54
|
+
interface DocumentTypeInfo {
|
|
55
|
+
code: DocumentType;
|
|
56
|
+
displayName: string;
|
|
57
|
+
hasMRZ: boolean;
|
|
58
|
+
requiresBack: boolean;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Get document type info
|
|
62
|
+
*/
|
|
63
|
+
declare function getDocumentTypeInfo(type: DocumentType): DocumentTypeInfo;
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* SDK Configuration
|
|
67
|
+
*/
|
|
68
|
+
interface Configuration {
|
|
69
|
+
/** API key (starts with ck_live_ or ck_sandbox_) */
|
|
70
|
+
apiKey: string;
|
|
71
|
+
/** Tenant ID (UUID) */
|
|
72
|
+
tenantId: string;
|
|
73
|
+
/** API environment */
|
|
74
|
+
environment: Environment;
|
|
75
|
+
/** Allowed document types */
|
|
76
|
+
documentTypes: DocumentType[];
|
|
77
|
+
/** Liveness detection mode */
|
|
78
|
+
livenessMode: LivenessMode;
|
|
79
|
+
/** Custom theme for UI */
|
|
80
|
+
theme: Theme;
|
|
81
|
+
/** Localization settings */
|
|
82
|
+
locale: Locale;
|
|
83
|
+
/** Session timeout in seconds */
|
|
84
|
+
timeout: number;
|
|
85
|
+
/** Enable debug logging */
|
|
86
|
+
debugLogging: boolean;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* API Environment
|
|
90
|
+
*/
|
|
91
|
+
type Environment = 'production' | 'sandbox';
|
|
92
|
+
/**
|
|
93
|
+
* Liveness detection mode
|
|
94
|
+
*/
|
|
95
|
+
type LivenessMode = 'active' | 'passive';
|
|
96
|
+
/**
|
|
97
|
+
* Theme configuration
|
|
98
|
+
*/
|
|
99
|
+
interface Theme {
|
|
100
|
+
primaryColor: string;
|
|
101
|
+
backgroundColor: string;
|
|
102
|
+
surfaceColor: string;
|
|
103
|
+
textColor: string;
|
|
104
|
+
secondaryTextColor: string;
|
|
105
|
+
errorColor: string;
|
|
106
|
+
successColor: string;
|
|
107
|
+
borderRadius: number;
|
|
108
|
+
fontFamily?: string;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Localization settings
|
|
112
|
+
*/
|
|
113
|
+
interface Locale {
|
|
114
|
+
language: string;
|
|
115
|
+
region?: string;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Verification model
|
|
120
|
+
*/
|
|
121
|
+
interface Verification {
|
|
122
|
+
/** Unique verification ID */
|
|
123
|
+
id: string;
|
|
124
|
+
/** External ID provided by the client */
|
|
125
|
+
externalId: string;
|
|
126
|
+
/** Tenant ID */
|
|
127
|
+
tenantId: string;
|
|
128
|
+
/** Verification tier */
|
|
129
|
+
tier: string;
|
|
130
|
+
/** Current status */
|
|
131
|
+
status: VerificationStatus;
|
|
132
|
+
/** Document verification result */
|
|
133
|
+
documentVerification?: DocumentVerification;
|
|
134
|
+
/** Face verification result */
|
|
135
|
+
faceVerification?: FaceVerification;
|
|
136
|
+
/** Liveness verification result */
|
|
137
|
+
livenessVerification?: LivenessVerification;
|
|
138
|
+
/** Risk signals */
|
|
139
|
+
riskSignals?: RiskSignal[];
|
|
140
|
+
/** Overall risk score (0-100) */
|
|
141
|
+
riskScore?: number;
|
|
142
|
+
/** Creation timestamp */
|
|
143
|
+
createdAt: Date;
|
|
144
|
+
/** Last update timestamp */
|
|
145
|
+
updatedAt: Date;
|
|
146
|
+
/** Completion timestamp */
|
|
147
|
+
completedAt?: Date;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Verification status
|
|
151
|
+
*/
|
|
152
|
+
type VerificationStatus = 'pending' | 'document_required' | 'selfie_required' | 'liveness_required' | 'processing' | 'approved' | 'rejected' | 'review_required' | 'expired';
|
|
153
|
+
/**
|
|
154
|
+
* Document verification result
|
|
155
|
+
*/
|
|
156
|
+
interface DocumentVerification {
|
|
157
|
+
documentType: string;
|
|
158
|
+
documentNumber?: string;
|
|
159
|
+
firstName?: string;
|
|
160
|
+
lastName?: string;
|
|
161
|
+
dateOfBirth?: string;
|
|
162
|
+
expirationDate?: string;
|
|
163
|
+
issuingCountry?: string;
|
|
164
|
+
mrzValid?: boolean;
|
|
165
|
+
authenticityScore?: number;
|
|
166
|
+
extractedFields?: Record<string, string>;
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Face verification result
|
|
170
|
+
*/
|
|
171
|
+
interface FaceVerification {
|
|
172
|
+
matchScore: number;
|
|
173
|
+
matchResult: string;
|
|
174
|
+
confidence: number;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Liveness verification result
|
|
178
|
+
*/
|
|
179
|
+
interface LivenessVerification {
|
|
180
|
+
livenessScore: number;
|
|
181
|
+
isLive: boolean;
|
|
182
|
+
challengeResults?: ChallengeResult[];
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Individual challenge result
|
|
186
|
+
*/
|
|
187
|
+
interface ChallengeResult {
|
|
188
|
+
type: string;
|
|
189
|
+
passed: boolean;
|
|
190
|
+
confidence: number;
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Risk signal
|
|
194
|
+
*/
|
|
195
|
+
interface RiskSignal {
|
|
196
|
+
code: string;
|
|
197
|
+
severity: string;
|
|
198
|
+
message: string;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Kora error codes
|
|
203
|
+
*/
|
|
204
|
+
declare enum KoraErrorCode {
|
|
205
|
+
NOT_CONFIGURED = "NOT_CONFIGURED",
|
|
206
|
+
INVALID_API_KEY = "INVALID_API_KEY",
|
|
207
|
+
INVALID_TENANT_ID = "INVALID_TENANT_ID",
|
|
208
|
+
NETWORK_ERROR = "NETWORK_ERROR",
|
|
209
|
+
TIMEOUT = "TIMEOUT",
|
|
210
|
+
NO_INTERNET = "NO_INTERNET",
|
|
211
|
+
UNAUTHORIZED = "UNAUTHORIZED",
|
|
212
|
+
FORBIDDEN = "FORBIDDEN",
|
|
213
|
+
NOT_FOUND = "NOT_FOUND",
|
|
214
|
+
VALIDATION_ERROR = "VALIDATION_ERROR",
|
|
215
|
+
RATE_LIMITED = "RATE_LIMITED",
|
|
216
|
+
SERVER_ERROR = "SERVER_ERROR",
|
|
217
|
+
HTTP_ERROR = "HTTP_ERROR",
|
|
218
|
+
CAMERA_ACCESS_DENIED = "CAMERA_ACCESS_DENIED",
|
|
219
|
+
CAMERA_NOT_AVAILABLE = "CAMERA_NOT_AVAILABLE",
|
|
220
|
+
CAPTURE_FAILED = "CAPTURE_FAILED",
|
|
221
|
+
QUALITY_VALIDATION_FAILED = "QUALITY_VALIDATION_FAILED",
|
|
222
|
+
DOCUMENT_NOT_DETECTED = "DOCUMENT_NOT_DETECTED",
|
|
223
|
+
DOCUMENT_TYPE_NOT_SUPPORTED = "DOCUMENT_TYPE_NOT_SUPPORTED",
|
|
224
|
+
MRZ_READ_FAILED = "MRZ_READ_FAILED",
|
|
225
|
+
FACE_NOT_DETECTED = "FACE_NOT_DETECTED",
|
|
226
|
+
MULTIPLE_FACES_DETECTED = "MULTIPLE_FACES_DETECTED",
|
|
227
|
+
FACE_MATCH_FAILED = "FACE_MATCH_FAILED",
|
|
228
|
+
LIVENESS_CHECK_FAILED = "LIVENESS_CHECK_FAILED",
|
|
229
|
+
CHALLENGE_NOT_COMPLETED = "CHALLENGE_NOT_COMPLETED",
|
|
230
|
+
SESSION_EXPIRED = "SESSION_EXPIRED",
|
|
231
|
+
VERIFICATION_EXPIRED = "VERIFICATION_EXPIRED",
|
|
232
|
+
VERIFICATION_ALREADY_COMPLETED = "VERIFICATION_ALREADY_COMPLETED",
|
|
233
|
+
INVALID_VERIFICATION_STATE = "INVALID_VERIFICATION_STATE",
|
|
234
|
+
UNKNOWN = "UNKNOWN",
|
|
235
|
+
USER_CANCELLED = "USER_CANCELLED"
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Kora SDK Error
|
|
239
|
+
*/
|
|
240
|
+
declare class KoraError extends Error {
|
|
241
|
+
readonly code: KoraErrorCode;
|
|
242
|
+
readonly recoverySuggestion?: string;
|
|
243
|
+
readonly details?: unknown;
|
|
244
|
+
constructor(code: KoraErrorCode, details?: unknown);
|
|
245
|
+
/**
|
|
246
|
+
* Create error from HTTP status code
|
|
247
|
+
*/
|
|
248
|
+
static fromHttpStatus(status: number, details?: unknown): KoraError;
|
|
249
|
+
/**
|
|
250
|
+
* Check if error is retryable
|
|
251
|
+
*/
|
|
252
|
+
get isRetryable(): boolean;
|
|
253
|
+
toJSON(): {
|
|
254
|
+
name: string;
|
|
255
|
+
code: KoraErrorCode;
|
|
256
|
+
message: string;
|
|
257
|
+
recoverySuggestion: string | undefined;
|
|
258
|
+
details: unknown;
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Create verification request
|
|
264
|
+
*/
|
|
265
|
+
interface CreateVerificationRequest {
|
|
266
|
+
externalId: string;
|
|
267
|
+
tier: string;
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Document upload response
|
|
271
|
+
*/
|
|
272
|
+
interface DocumentUploadResponse {
|
|
273
|
+
success: boolean;
|
|
274
|
+
documentId?: string;
|
|
275
|
+
qualityScore?: number;
|
|
276
|
+
qualityIssues?: QualityIssue$1[];
|
|
277
|
+
extractedData?: DocumentExtractedData;
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* Quality issue
|
|
281
|
+
*/
|
|
282
|
+
interface QualityIssue$1 {
|
|
283
|
+
type: string;
|
|
284
|
+
message: string;
|
|
285
|
+
severity: 'error' | 'warning';
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* Extracted document data
|
|
289
|
+
*/
|
|
290
|
+
interface DocumentExtractedData {
|
|
291
|
+
documentType: string;
|
|
292
|
+
documentNumber?: string;
|
|
293
|
+
firstName?: string;
|
|
294
|
+
lastName?: string;
|
|
295
|
+
dateOfBirth?: string;
|
|
296
|
+
expirationDate?: string;
|
|
297
|
+
issuingCountry?: string;
|
|
298
|
+
mrzValid?: boolean;
|
|
299
|
+
}
|
|
300
|
+
/**
|
|
301
|
+
* Selfie upload response
|
|
302
|
+
*/
|
|
303
|
+
interface SelfieUploadResponse {
|
|
304
|
+
success: boolean;
|
|
305
|
+
selfieId?: string;
|
|
306
|
+
faceDetected: boolean;
|
|
307
|
+
qualityScore?: number;
|
|
308
|
+
qualityIssues?: QualityIssue$1[];
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* Liveness session
|
|
312
|
+
*/
|
|
313
|
+
interface LivenessSession {
|
|
314
|
+
sessionId: string;
|
|
315
|
+
challenges: LivenessChallenge[];
|
|
316
|
+
expiresAt: Date;
|
|
317
|
+
}
|
|
318
|
+
/**
|
|
319
|
+
* Liveness challenge
|
|
320
|
+
*/
|
|
321
|
+
interface LivenessChallenge {
|
|
322
|
+
id: string;
|
|
323
|
+
type: ChallengeType;
|
|
324
|
+
instruction: string;
|
|
325
|
+
order: number;
|
|
326
|
+
}
|
|
327
|
+
/**
|
|
328
|
+
* Challenge type
|
|
329
|
+
*/
|
|
330
|
+
type ChallengeType = 'blink' | 'smile' | 'turn_left' | 'turn_right' | 'nod_up' | 'nod_down';
|
|
331
|
+
/**
|
|
332
|
+
* Liveness challenge response
|
|
333
|
+
*/
|
|
334
|
+
interface LivenessChallengeResponse {
|
|
335
|
+
success: boolean;
|
|
336
|
+
challengePassed: boolean;
|
|
337
|
+
confidence: number;
|
|
338
|
+
remainingChallenges: number;
|
|
339
|
+
}
|
|
340
|
+
/**
|
|
341
|
+
* Document quality check response
|
|
342
|
+
*/
|
|
343
|
+
interface DocumentQualityResponse {
|
|
344
|
+
success: boolean;
|
|
345
|
+
qualityScore: number;
|
|
346
|
+
qualityIssues: string[];
|
|
347
|
+
details: {
|
|
348
|
+
textReadability: number;
|
|
349
|
+
faceQuality: number;
|
|
350
|
+
imageClarity: number;
|
|
351
|
+
};
|
|
352
|
+
}
|
|
353
|
+
/**
|
|
354
|
+
* Supported country with its available document types
|
|
355
|
+
*/
|
|
356
|
+
interface SupportedCountry {
|
|
357
|
+
id: string;
|
|
358
|
+
name: string;
|
|
359
|
+
flagEmoji: string;
|
|
360
|
+
documentTypes: string[];
|
|
361
|
+
}
|
|
362
|
+
/**
|
|
363
|
+
* Handoff session created by the web SDK for cross-device mobile capture.
|
|
364
|
+
*/
|
|
365
|
+
interface HandoffSession {
|
|
366
|
+
token: string;
|
|
367
|
+
captureUrl: string;
|
|
368
|
+
expiresAt: string;
|
|
369
|
+
expiresIn: number;
|
|
370
|
+
}
|
|
371
|
+
/**
|
|
372
|
+
* Context returned when a mobile browser validates a handoff token.
|
|
373
|
+
*/
|
|
374
|
+
interface HandoffContext {
|
|
375
|
+
verificationId: string;
|
|
376
|
+
tenantId: string;
|
|
377
|
+
apiKey: string;
|
|
378
|
+
expiresAt: string;
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
/**
|
|
382
|
+
* Verification flow callbacks
|
|
383
|
+
*/
|
|
384
|
+
interface VerificationCallbacks {
|
|
385
|
+
onComplete?: (verification: Verification) => void;
|
|
386
|
+
onError?: (error: KoraError) => void;
|
|
387
|
+
onCancel?: () => void;
|
|
388
|
+
onStepChange?: (step: VerificationStep) => void;
|
|
389
|
+
}
|
|
390
|
+
/**
|
|
391
|
+
* Verification flow options
|
|
392
|
+
*/
|
|
393
|
+
interface VerificationOptions {
|
|
394
|
+
externalId: string;
|
|
395
|
+
tier?: 'basic' | 'standard' | 'enhanced';
|
|
396
|
+
documentTypes?: DocumentType[];
|
|
397
|
+
}
|
|
398
|
+
/**
|
|
399
|
+
* Verification step
|
|
400
|
+
*/
|
|
401
|
+
type VerificationStep = 'consent' | 'document_selection' | 'document_front' | 'document_back' | 'selfie' | 'liveness' | 'processing' | 'complete';
|
|
402
|
+
/**
|
|
403
|
+
* Main Kora IDV SDK class
|
|
404
|
+
*/
|
|
405
|
+
declare class KoraIDV {
|
|
406
|
+
private configuration;
|
|
407
|
+
private apiClient;
|
|
408
|
+
private currentVerification;
|
|
409
|
+
private livenessSession;
|
|
410
|
+
private sessionStartTime;
|
|
411
|
+
static readonly VERSION = "1.5.0";
|
|
412
|
+
constructor(config: Partial<Configuration> & {
|
|
413
|
+
apiKey: string;
|
|
414
|
+
tenantId: string;
|
|
415
|
+
});
|
|
416
|
+
private detectEnvironment;
|
|
417
|
+
/**
|
|
418
|
+
* Get supported countries and their document types from the API
|
|
419
|
+
*/
|
|
420
|
+
getSupportedCountries(): Promise<SupportedCountry[]>;
|
|
421
|
+
/**
|
|
422
|
+
* Start a new verification flow
|
|
423
|
+
*/
|
|
424
|
+
startVerification(options: VerificationOptions, callbacks: VerificationCallbacks): Promise<void>;
|
|
425
|
+
/**
|
|
426
|
+
* Resume an existing verification
|
|
427
|
+
*/
|
|
428
|
+
resumeVerification(verificationId: string, callbacks: VerificationCallbacks): Promise<void>;
|
|
429
|
+
/**
|
|
430
|
+
* Check document quality before uploading (no active verification required)
|
|
431
|
+
*/
|
|
432
|
+
checkDocumentQuality(imageData: Blob, documentType: string): Promise<DocumentQualityResponse>;
|
|
433
|
+
/**
|
|
434
|
+
* Upload document image
|
|
435
|
+
*/
|
|
436
|
+
uploadDocument(imageData: Blob, side: 'front' | 'back', documentType: DocumentType): Promise<{
|
|
437
|
+
success: boolean;
|
|
438
|
+
qualityIssues?: string[];
|
|
439
|
+
}>;
|
|
440
|
+
/**
|
|
441
|
+
* Upload selfie image
|
|
442
|
+
*/
|
|
443
|
+
uploadSelfie(imageData: Blob): Promise<{
|
|
444
|
+
success: boolean;
|
|
445
|
+
qualityIssues?: string[];
|
|
446
|
+
}>;
|
|
447
|
+
/**
|
|
448
|
+
* Start liveness session
|
|
449
|
+
*/
|
|
450
|
+
startLivenessSession(): Promise<LivenessSession>;
|
|
451
|
+
/**
|
|
452
|
+
* Submit liveness challenge
|
|
453
|
+
*/
|
|
454
|
+
submitLivenessChallenge(challenge: LivenessChallenge, imageData: Blob): Promise<{
|
|
455
|
+
passed: boolean;
|
|
456
|
+
remainingChallenges: number;
|
|
457
|
+
}>;
|
|
458
|
+
/**
|
|
459
|
+
* Complete the verification
|
|
460
|
+
*/
|
|
461
|
+
completeVerification(): Promise<Verification>;
|
|
462
|
+
/**
|
|
463
|
+
* Get current verification
|
|
464
|
+
*/
|
|
465
|
+
getCurrentVerification(): Verification | null;
|
|
466
|
+
/**
|
|
467
|
+
* Get current liveness session
|
|
468
|
+
*/
|
|
469
|
+
getLivenessSession(): LivenessSession | null;
|
|
470
|
+
/**
|
|
471
|
+
* Check if session has timed out
|
|
472
|
+
*/
|
|
473
|
+
isSessionTimedOut(): boolean;
|
|
474
|
+
/**
|
|
475
|
+
* Reset the session
|
|
476
|
+
*/
|
|
477
|
+
reset(): void;
|
|
478
|
+
private determineStepFromStatus;
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
/**
|
|
482
|
+
* API Client for Kora IDV
|
|
483
|
+
*/
|
|
484
|
+
declare class ApiClient {
|
|
485
|
+
private readonly baseUrl;
|
|
486
|
+
private readonly configuration;
|
|
487
|
+
private readonly maxRetries;
|
|
488
|
+
private readonly baseDelay;
|
|
489
|
+
constructor(configuration: Configuration);
|
|
490
|
+
/**
|
|
491
|
+
* Get supported countries and their document types
|
|
492
|
+
*/
|
|
493
|
+
getSupportedCountries(): Promise<SupportedCountry[]>;
|
|
494
|
+
/**
|
|
495
|
+
* Create a new verification
|
|
496
|
+
*/
|
|
497
|
+
createVerification(request: CreateVerificationRequest): Promise<Verification>;
|
|
498
|
+
/**
|
|
499
|
+
* Get an existing verification
|
|
500
|
+
*/
|
|
501
|
+
getVerification(id: string): Promise<Verification>;
|
|
502
|
+
/**
|
|
503
|
+
* Upload document image.
|
|
504
|
+
*
|
|
505
|
+
* `decodedBarcodePayload` is the optional Phase 4 fast-path: when the
|
|
506
|
+
* client decoded the PDF417 / QR / DataMatrix on-device using the
|
|
507
|
+
* browser's BarcodeDetector API (or a polyfill), the AAMVA payload
|
|
508
|
+
* travels here so the server can skip image-based barcode decoding
|
|
509
|
+
* (~1-3 s round-trip savings). Empty/`undefined` = server falls
|
|
510
|
+
* back to its zxing-cpp + pdf417decoder cascade. Only meaningful for
|
|
511
|
+
* back captures on documents that carry a barcode.
|
|
512
|
+
* See `docs/architecture/idv-decode-roadmap.md` Phase 4.
|
|
513
|
+
*/
|
|
514
|
+
uploadDocument(verificationId: string, imageData: Blob, side: 'front' | 'back', documentType: DocumentType, decodedBarcodePayload?: string): Promise<DocumentUploadResponse>;
|
|
515
|
+
/**
|
|
516
|
+
* Upload selfie image
|
|
517
|
+
*/
|
|
518
|
+
uploadSelfie(verificationId: string, imageData: Blob): Promise<SelfieUploadResponse>;
|
|
519
|
+
/**
|
|
520
|
+
* Create liveness session
|
|
521
|
+
*/
|
|
522
|
+
createLivenessSession(verificationId: string): Promise<LivenessSession>;
|
|
523
|
+
/**
|
|
524
|
+
* Submit liveness challenge
|
|
525
|
+
*/
|
|
526
|
+
submitLivenessChallenge(verificationId: string, challenge: LivenessChallenge, imageData: Blob): Promise<LivenessChallengeResponse>;
|
|
527
|
+
/**
|
|
528
|
+
* Check document quality before uploading
|
|
529
|
+
*/
|
|
530
|
+
checkDocumentQuality(imageData: Blob, documentType: string): Promise<DocumentQualityResponse>;
|
|
531
|
+
/**
|
|
532
|
+
* Complete the verification
|
|
533
|
+
*/
|
|
534
|
+
completeVerification(verificationId: string): Promise<Verification>;
|
|
535
|
+
/**
|
|
536
|
+
* Create a handoff session for cross-device mobile capture.
|
|
537
|
+
* Returns a token and capture URL to encode in a QR code.
|
|
538
|
+
*/
|
|
539
|
+
createHandoffSession(verificationId: string): Promise<HandoffSession>;
|
|
540
|
+
/**
|
|
541
|
+
* Validate a handoff token (called by the mobile capture page).
|
|
542
|
+
* Returns the verification context needed to continue capture.
|
|
543
|
+
*/
|
|
544
|
+
validateHandoffToken(token: string): Promise<HandoffContext>;
|
|
545
|
+
/**
|
|
546
|
+
* Subscribe to verification status events via Server-Sent Events.
|
|
547
|
+
* Returns an EventSource that emits 'status' and 'complete' events.
|
|
548
|
+
*/
|
|
549
|
+
subscribeToVerificationEvents(verificationId: string): EventSource;
|
|
550
|
+
/**
|
|
551
|
+
* Make an API request with retry logic
|
|
552
|
+
*/
|
|
553
|
+
private request;
|
|
554
|
+
private executeWithRetry;
|
|
555
|
+
private shouldRetry;
|
|
556
|
+
private shouldRetryNetworkError;
|
|
557
|
+
private calculateDelay;
|
|
558
|
+
private sleep;
|
|
559
|
+
private blobToBase64;
|
|
560
|
+
/**
|
|
561
|
+
* Transform snake_case response to camelCase
|
|
562
|
+
*/
|
|
563
|
+
private transformResponse;
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
/**
|
|
567
|
+
* Quality validation thresholds
|
|
568
|
+
*/
|
|
569
|
+
interface QualityThresholds {
|
|
570
|
+
/** Minimum blur score (Laplacian variance) */
|
|
571
|
+
minBlurScore: number;
|
|
572
|
+
/** Minimum brightness (0-1) */
|
|
573
|
+
minBrightness: number;
|
|
574
|
+
/** Maximum brightness (0-1) */
|
|
575
|
+
maxBrightness: number;
|
|
576
|
+
/** Maximum glare percentage */
|
|
577
|
+
maxGlarePercentage: number;
|
|
578
|
+
/** Minimum face size as percentage of frame */
|
|
579
|
+
minFaceSizePercentage: number;
|
|
580
|
+
/** Face detection confidence threshold */
|
|
581
|
+
minFaceConfidence: number;
|
|
582
|
+
}
|
|
583
|
+
/**
|
|
584
|
+
* Quality validation result
|
|
585
|
+
*/
|
|
586
|
+
interface QualityResult {
|
|
587
|
+
isValid: boolean;
|
|
588
|
+
issues: QualityIssue[];
|
|
589
|
+
metrics: QualityMetrics;
|
|
590
|
+
}
|
|
591
|
+
/**
|
|
592
|
+
* Quality issue
|
|
593
|
+
*/
|
|
594
|
+
interface QualityIssue {
|
|
595
|
+
type: QualityIssueType;
|
|
596
|
+
message: string;
|
|
597
|
+
severity: 'error' | 'warning';
|
|
598
|
+
}
|
|
599
|
+
/**
|
|
600
|
+
* Quality issue types
|
|
601
|
+
*/
|
|
602
|
+
type QualityIssueType = 'blur' | 'too_dark' | 'too_bright' | 'glare' | 'face_not_detected' | 'face_too_small' | 'face_off_center' | 'multiple_faces' | 'document_not_detected' | 'document_partially_visible';
|
|
603
|
+
/**
|
|
604
|
+
* Quality metrics
|
|
605
|
+
*/
|
|
606
|
+
interface QualityMetrics {
|
|
607
|
+
blurScore?: number;
|
|
608
|
+
brightness?: number;
|
|
609
|
+
glarePercentage?: number;
|
|
610
|
+
faceSize?: number;
|
|
611
|
+
faceConfidence?: number;
|
|
612
|
+
faceCenterOffset?: {
|
|
613
|
+
x: number;
|
|
614
|
+
y: number;
|
|
615
|
+
};
|
|
616
|
+
}
|
|
617
|
+
/**
|
|
618
|
+
* Quality validator for captured images
|
|
619
|
+
*/
|
|
620
|
+
declare class QualityValidator {
|
|
621
|
+
private thresholds;
|
|
622
|
+
constructor(thresholds?: Partial<QualityThresholds>);
|
|
623
|
+
/**
|
|
624
|
+
* Validate document image quality
|
|
625
|
+
*/
|
|
626
|
+
validateDocumentImage(imageData: ImageData): Promise<QualityResult>;
|
|
627
|
+
/**
|
|
628
|
+
* Validate selfie image quality
|
|
629
|
+
*/
|
|
630
|
+
validateSelfieImage(imageData: ImageData, faceDetection?: {
|
|
631
|
+
confidence: number;
|
|
632
|
+
boundingBox: DOMRect;
|
|
633
|
+
}): Promise<QualityResult>;
|
|
634
|
+
/**
|
|
635
|
+
* Calculate blur score using Laplacian variance
|
|
636
|
+
*/
|
|
637
|
+
private calculateBlurScore;
|
|
638
|
+
/**
|
|
639
|
+
* Calculate average brightness (0-1)
|
|
640
|
+
*/
|
|
641
|
+
private calculateBrightness;
|
|
642
|
+
/**
|
|
643
|
+
* Calculate percentage of overexposed pixels (glare)
|
|
644
|
+
*/
|
|
645
|
+
private calculateGlarePercentage;
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
/**
|
|
649
|
+
* MRZ (Machine Readable Zone) Parser
|
|
650
|
+
* Supports TD1, TD2, and TD3 formats
|
|
651
|
+
*/
|
|
652
|
+
/**
|
|
653
|
+
* Parsed MRZ data
|
|
654
|
+
*/
|
|
655
|
+
interface MrzData {
|
|
656
|
+
/** Document format (TD1, TD2, TD3) */
|
|
657
|
+
format: MrzFormat;
|
|
658
|
+
/** Document type (P=Passport, I=ID, etc.) */
|
|
659
|
+
documentType: string;
|
|
660
|
+
/** Issuing country code (3-letter) */
|
|
661
|
+
issuingCountry: string;
|
|
662
|
+
/** Last name (surname) */
|
|
663
|
+
lastName: string;
|
|
664
|
+
/** First name(s) */
|
|
665
|
+
firstName: string;
|
|
666
|
+
/** Document number */
|
|
667
|
+
documentNumber: string;
|
|
668
|
+
/** Nationality (3-letter country code) */
|
|
669
|
+
nationality: string;
|
|
670
|
+
/** Date of birth (YYMMDD) */
|
|
671
|
+
dateOfBirth: string;
|
|
672
|
+
/** Sex (M/F/<) */
|
|
673
|
+
sex: string;
|
|
674
|
+
/** Expiration date (YYMMDD) */
|
|
675
|
+
expirationDate: string;
|
|
676
|
+
/** Optional data field 1 */
|
|
677
|
+
optionalData1?: string;
|
|
678
|
+
/** Optional data field 2 */
|
|
679
|
+
optionalData2?: string;
|
|
680
|
+
/** Whether all check digits are valid */
|
|
681
|
+
isValid: boolean;
|
|
682
|
+
/** Validation errors */
|
|
683
|
+
validationErrors: string[];
|
|
684
|
+
}
|
|
685
|
+
/**
|
|
686
|
+
* MRZ format type
|
|
687
|
+
*/
|
|
688
|
+
type MrzFormat = 'TD1' | 'TD2' | 'TD3';
|
|
689
|
+
/**
|
|
690
|
+
* MRZ Parser class
|
|
691
|
+
*/
|
|
692
|
+
declare class MrzParser {
|
|
693
|
+
/**
|
|
694
|
+
* Parse MRZ text
|
|
695
|
+
*/
|
|
696
|
+
parse(mrzText: string): MrzData | null;
|
|
697
|
+
/**
|
|
698
|
+
* Clean and normalize MRZ text
|
|
699
|
+
*/
|
|
700
|
+
private cleanMrzText;
|
|
701
|
+
/**
|
|
702
|
+
* Detect MRZ line length
|
|
703
|
+
*/
|
|
704
|
+
private detectLineLength;
|
|
705
|
+
/**
|
|
706
|
+
* Detect MRZ format
|
|
707
|
+
*/
|
|
708
|
+
private detectFormat;
|
|
709
|
+
/**
|
|
710
|
+
* Parse TD1 format (ID cards - 3 lines × 30 chars)
|
|
711
|
+
*/
|
|
712
|
+
private parseTD1;
|
|
713
|
+
/**
|
|
714
|
+
* Parse TD2 format (Some ID cards - 2 lines × 36 chars)
|
|
715
|
+
*/
|
|
716
|
+
private parseTD2;
|
|
717
|
+
/**
|
|
718
|
+
* Parse TD3 format (Passports - 2 lines × 44 chars)
|
|
719
|
+
*/
|
|
720
|
+
private parseTD3;
|
|
721
|
+
/**
|
|
722
|
+
* Parse name field
|
|
723
|
+
*/
|
|
724
|
+
private parseName;
|
|
725
|
+
/**
|
|
726
|
+
* Validate MRZ check digit
|
|
727
|
+
*/
|
|
728
|
+
private validateCheckDigit;
|
|
729
|
+
/**
|
|
730
|
+
* Format date from YYMMDD to human readable
|
|
731
|
+
*/
|
|
732
|
+
static formatDate(yymmdd: string): string;
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
/**
|
|
736
|
+
* Convert a Blob to a base64-encoded string (no data URL prefix).
|
|
737
|
+
*
|
|
738
|
+
* Used by the back-side document upload path to build the JSON request
|
|
739
|
+
* body that matches the server's `imageBase64` contract (and the
|
|
740
|
+
* Android/iOS SDK wire formats).
|
|
741
|
+
*/
|
|
742
|
+
declare function blobToBase64(blob: Blob): Promise<string>;
|
|
743
|
+
|
|
744
|
+
/**
|
|
745
|
+
* On-device barcode decoder for the back side of identity documents.
|
|
746
|
+
*
|
|
747
|
+
* The KoraIDV pipeline cascades through three decoders in priority order:
|
|
748
|
+
* 1. **This class (browser BarcodeDetector)** — runs on the captured
|
|
749
|
+
* back-side image before upload. When it succeeds, the decoded
|
|
750
|
+
* AAMVA payload travels to the server in
|
|
751
|
+
* `uploadDocument(..., decodedBarcodePayload)` and the server skips
|
|
752
|
+
* image decoding entirely.
|
|
753
|
+
* 2. **zxing-cpp** (server-side) — primary decoder when the client failed
|
|
754
|
+
* or the browser lacks BarcodeDetector.
|
|
755
|
+
* 3. **pdf417decoder** (server-side) — fallback for captures zxing-cpp
|
|
756
|
+
* can't read.
|
|
757
|
+
*
|
|
758
|
+
* Why decode in the browser when the server can do it? Three reasons:
|
|
759
|
+
* - **Latency**: in-browser decode finishes in ~100-300 ms vs. ~1-3 s
|
|
760
|
+
* server round-trip + cascade.
|
|
761
|
+
* - **Cost**: zero ml-service compute on the happy path.
|
|
762
|
+
* - **Offline-friendly**: in some embedded flows (kiosk, on-prem),
|
|
763
|
+
* server-side decode is unavailable but the browser can still read
|
|
764
|
+
* the barcode.
|
|
765
|
+
*
|
|
766
|
+
* Browser support (as of 2026):
|
|
767
|
+
* - **Native**: Chrome 88+, Edge 88+, Samsung Internet 15+, Opera 74+
|
|
768
|
+
* on Android. Safari 16.4+ macOS/iOS supports a subset (no PDF417 on
|
|
769
|
+
* iOS Safari yet — the symbology list is a moving target). When
|
|
770
|
+
* unsupported, `isSupported()` returns false and the SDK silently
|
|
771
|
+
* falls back to the server cascade.
|
|
772
|
+
* - **Polyfill**: applications that need cross-browser support can
|
|
773
|
+
* install a JS polyfill (e.g. `barcode-detector` from npm) before
|
|
774
|
+
* the SDK loads; it registers `globalThis.BarcodeDetector` and this
|
|
775
|
+
* class will pick it up automatically.
|
|
776
|
+
*
|
|
777
|
+
* See `docs/architecture/idv-decode-roadmap.md` Phase 4.
|
|
778
|
+
*/
|
|
779
|
+
type BarcodeFormat = 'pdf417' | 'qr_code' | 'data_matrix' | 'aztec' | 'code_128' | 'code_39' | 'code_93' | 'codabar' | 'ean_13' | 'ean_8' | 'itf' | 'upc_a' | 'upc_e';
|
|
780
|
+
declare class WebBarcodeScanner {
|
|
781
|
+
private detector;
|
|
782
|
+
/**
|
|
783
|
+
* Whether the current environment has a usable BarcodeDetector.
|
|
784
|
+
* Either native (modern Chromium / Samsung) or a polyfill.
|
|
785
|
+
*/
|
|
786
|
+
static isSupported(): boolean;
|
|
787
|
+
/**
|
|
788
|
+
* Construct a scanner. Restricts to PDF417 by default to avoid false
|
|
789
|
+
* positives on the small Code128 strip US DLs also carry. Callers
|
|
790
|
+
* onboarding QR-based docs (Nigeria voter's card) should pass
|
|
791
|
+
* `['pdf417', 'qr_code']`.
|
|
792
|
+
*/
|
|
793
|
+
constructor(formats?: BarcodeFormat[]);
|
|
794
|
+
/**
|
|
795
|
+
* Attempt to decode a PDF417 barcode from the supplied image source.
|
|
796
|
+
* Accepts any `ImageBitmapSource`: Blob, HTMLImageElement,
|
|
797
|
+
* HTMLCanvasElement, ImageBitmap, OffscreenCanvas.
|
|
798
|
+
*
|
|
799
|
+
* Returns the raw AAMVA payload as a single string (newline-separated
|
|
800
|
+
* records, exactly the form the server's AAMVA parser expects) or
|
|
801
|
+
* `null` when no barcode was found, decoding failed, or the API is
|
|
802
|
+
* unavailable.
|
|
803
|
+
*/
|
|
804
|
+
decodePdf417(source: ImageBitmapSource): Promise<string | null>;
|
|
805
|
+
}
|
|
806
|
+
|
|
807
|
+
/**
|
|
808
|
+
* WalletModels.ts
|
|
809
|
+
* KoraIDV Wallet — W3C Verifiable Credential types for Web
|
|
810
|
+
*
|
|
811
|
+
* Types are prefixed with "Wallet" to avoid conflicts with existing KoraIDV types.
|
|
812
|
+
*/
|
|
813
|
+
interface WalletCredential {
|
|
814
|
+
readonly '@context': string[];
|
|
815
|
+
readonly id: string;
|
|
816
|
+
readonly type: string[];
|
|
817
|
+
readonly issuer: string;
|
|
818
|
+
readonly issuanceDate: string;
|
|
819
|
+
readonly expirationDate: string;
|
|
820
|
+
readonly credentialSubject: WalletCredentialSubject;
|
|
821
|
+
readonly credentialStatus?: WalletCredentialStatus;
|
|
822
|
+
readonly proof?: WalletDataIntegrityProof;
|
|
823
|
+
}
|
|
824
|
+
interface WalletCredentialSubject {
|
|
825
|
+
readonly id: string;
|
|
826
|
+
readonly fullName: string;
|
|
827
|
+
readonly dateOfBirth?: string;
|
|
828
|
+
readonly nationality?: string;
|
|
829
|
+
readonly verificationLevel: string;
|
|
830
|
+
readonly documentType: string;
|
|
831
|
+
readonly documentCountry: string;
|
|
832
|
+
readonly biometricMatch: boolean;
|
|
833
|
+
readonly livenessCheck: boolean;
|
|
834
|
+
readonly governmentDbVerified: boolean;
|
|
835
|
+
readonly verifiedAt: string;
|
|
836
|
+
readonly confidenceScore: number;
|
|
837
|
+
}
|
|
838
|
+
interface WalletCredentialStatus {
|
|
839
|
+
readonly id: string;
|
|
840
|
+
readonly type: string;
|
|
841
|
+
readonly statusPurpose: string;
|
|
842
|
+
readonly statusListIndex: string;
|
|
843
|
+
readonly statusListCredential: string;
|
|
844
|
+
}
|
|
845
|
+
interface WalletDataIntegrityProof {
|
|
846
|
+
readonly type: string;
|
|
847
|
+
readonly cryptosuite: string;
|
|
848
|
+
readonly created: string;
|
|
849
|
+
readonly verificationMethod: string;
|
|
850
|
+
readonly proofPurpose: string;
|
|
851
|
+
readonly proofValue: string;
|
|
852
|
+
}
|
|
853
|
+
interface StoredWalletCredential {
|
|
854
|
+
readonly id: string;
|
|
855
|
+
readonly credential: WalletCredential;
|
|
856
|
+
readonly storedAt: string;
|
|
857
|
+
readonly issuerDID: string;
|
|
858
|
+
readonly subjectName: string;
|
|
859
|
+
readonly expiresAt: string;
|
|
860
|
+
}
|
|
861
|
+
interface WalletPresentation {
|
|
862
|
+
readonly '@context': string[];
|
|
863
|
+
readonly type: string[];
|
|
864
|
+
readonly holder: string | null;
|
|
865
|
+
readonly verifiableCredential: WalletCredential[];
|
|
866
|
+
readonly created: string;
|
|
867
|
+
readonly audience: string | null;
|
|
868
|
+
readonly challenge: string | null;
|
|
869
|
+
}
|
|
870
|
+
declare class WalletError extends Error {
|
|
871
|
+
readonly code: string;
|
|
872
|
+
constructor(code: string, message: string);
|
|
873
|
+
static storageFailed(): WalletError;
|
|
874
|
+
static credentialNotFound(): WalletError;
|
|
875
|
+
static credentialExpired(): WalletError;
|
|
876
|
+
static encodingFailed(): WalletError;
|
|
877
|
+
static cryptoUnavailable(): WalletError;
|
|
878
|
+
}
|
|
879
|
+
declare function createWalletCredential(params: Omit<WalletCredential, '@context' | 'type'> & {
|
|
880
|
+
'@context'?: string[];
|
|
881
|
+
type?: string[];
|
|
882
|
+
}): WalletCredential;
|
|
883
|
+
|
|
884
|
+
/**
|
|
885
|
+
* SelectiveDisclosure.ts
|
|
886
|
+
* KoraIDV Wallet — Selective disclosure profiles for Verifiable Presentations (Web)
|
|
887
|
+
*/
|
|
888
|
+
|
|
889
|
+
declare enum DisclosureClaim {
|
|
890
|
+
FullName = "fullName",
|
|
891
|
+
DateOfBirth = "dateOfBirth",
|
|
892
|
+
Nationality = "nationality",
|
|
893
|
+
VerificationLevel = "verificationLevel",
|
|
894
|
+
DocumentType = "documentType",
|
|
895
|
+
DocumentCountry = "documentCountry",
|
|
896
|
+
BiometricMatch = "biometricMatch",
|
|
897
|
+
LivenessCheck = "livenessCheck",
|
|
898
|
+
GovernmentDbVerified = "governmentDbVerified",
|
|
899
|
+
VerifiedAt = "verifiedAt",
|
|
900
|
+
ConfidenceScore = "confidenceScore"
|
|
901
|
+
}
|
|
902
|
+
type DisclosureProfile = {
|
|
903
|
+
type: 'full';
|
|
904
|
+
} | {
|
|
905
|
+
type: 'onboarding';
|
|
906
|
+
} | {
|
|
907
|
+
type: 'ageOnly';
|
|
908
|
+
} | {
|
|
909
|
+
type: 'nationalityOnly';
|
|
910
|
+
} | {
|
|
911
|
+
type: 'verificationOnly';
|
|
912
|
+
} | {
|
|
913
|
+
type: 'custom';
|
|
914
|
+
claims: Set<DisclosureClaim>;
|
|
915
|
+
};
|
|
916
|
+
declare const DisclosureProfiles: {
|
|
917
|
+
full: DisclosureProfile;
|
|
918
|
+
onboarding: DisclosureProfile;
|
|
919
|
+
ageOnly: DisclosureProfile;
|
|
920
|
+
nationalityOnly: DisclosureProfile;
|
|
921
|
+
verificationOnly: DisclosureProfile;
|
|
922
|
+
custom: (claims: Set<DisclosureClaim>) => DisclosureProfile;
|
|
923
|
+
};
|
|
924
|
+
/**
|
|
925
|
+
* Apply a disclosure profile to a credential, returning a new credential
|
|
926
|
+
* containing only the disclosed claims in its subject.
|
|
927
|
+
*/
|
|
928
|
+
declare function applyDisclosure(profile: DisclosureProfile, credential: WalletCredential): WalletCredential;
|
|
929
|
+
/**
|
|
930
|
+
* For ageOnly profile, compute whether the subject is over 18.
|
|
931
|
+
*/
|
|
932
|
+
declare function computeAgeOver18(dateOfBirth?: string): boolean;
|
|
933
|
+
|
|
934
|
+
/**
|
|
935
|
+
* KoraWallet.ts
|
|
936
|
+
* KoraIDV Wallet — Main wallet class for Web
|
|
937
|
+
*/
|
|
938
|
+
|
|
939
|
+
/**
|
|
940
|
+
* Main entry point for the Kora Wallet SDK module on Web.
|
|
941
|
+
*
|
|
942
|
+
* Provides credential storage (IndexedDB + Web Crypto), selective disclosure,
|
|
943
|
+
* Verifiable Presentation creation, and deep-link sharing.
|
|
944
|
+
*/
|
|
945
|
+
declare class KoraWallet {
|
|
946
|
+
private readonly credentialStore;
|
|
947
|
+
constructor();
|
|
948
|
+
/**
|
|
949
|
+
* Store a Verifiable Credential in the wallet.
|
|
950
|
+
* Returns the storage ID (same as the credential's `id`).
|
|
951
|
+
*/
|
|
952
|
+
store(credential: WalletCredential): Promise<string>;
|
|
953
|
+
/**
|
|
954
|
+
* Retrieve all stored credentials.
|
|
955
|
+
*/
|
|
956
|
+
getCredentials(): Promise<StoredWalletCredential[]>;
|
|
957
|
+
/**
|
|
958
|
+
* Retrieve a single credential by ID.
|
|
959
|
+
*/
|
|
960
|
+
getCredential(id: string): Promise<StoredWalletCredential | null>;
|
|
961
|
+
/**
|
|
962
|
+
* Delete a credential from the wallet.
|
|
963
|
+
*/
|
|
964
|
+
deleteCredential(id: string): Promise<void>;
|
|
965
|
+
/**
|
|
966
|
+
* Number of credentials currently stored.
|
|
967
|
+
*/
|
|
968
|
+
getCredentialCount(): Promise<number>;
|
|
969
|
+
/**
|
|
970
|
+
* Create a Verifiable Presentation with selective disclosure.
|
|
971
|
+
*/
|
|
972
|
+
createPresentation(params: {
|
|
973
|
+
credentialId: string;
|
|
974
|
+
profile: DisclosureProfile;
|
|
975
|
+
audience?: string;
|
|
976
|
+
nonce?: string;
|
|
977
|
+
}): Promise<WalletPresentation>;
|
|
978
|
+
/**
|
|
979
|
+
* Generate a deep link URL for sharing a presentation.
|
|
980
|
+
*/
|
|
981
|
+
generateDeepLink(presentation: WalletPresentation, profile?: DisclosureProfile): string | null;
|
|
982
|
+
/**
|
|
983
|
+
* Check whether a stored credential has expired.
|
|
984
|
+
*/
|
|
985
|
+
isExpired(credentialId: string): Promise<boolean>;
|
|
986
|
+
/**
|
|
987
|
+
* Close the store and free resources.
|
|
988
|
+
*/
|
|
989
|
+
close(): void;
|
|
990
|
+
}
|
|
991
|
+
|
|
992
|
+
/**
|
|
993
|
+
* CredentialStore.ts
|
|
994
|
+
* KoraIDV Wallet — IndexedDB + Web Crypto API encrypted credential storage for Web
|
|
995
|
+
*
|
|
996
|
+
* Uses the native SubtleCrypto API for AES-GCM encryption and IndexedDB
|
|
997
|
+
* for persistent storage. No external crypto libraries required.
|
|
998
|
+
*/
|
|
999
|
+
|
|
1000
|
+
/**
|
|
1001
|
+
* Encrypted credential storage backed by IndexedDB and Web Crypto API.
|
|
1002
|
+
*/
|
|
1003
|
+
declare class WalletCredentialStore {
|
|
1004
|
+
private db;
|
|
1005
|
+
private cryptoKey;
|
|
1006
|
+
private getDb;
|
|
1007
|
+
private getCryptoKey;
|
|
1008
|
+
private encrypt;
|
|
1009
|
+
private decrypt;
|
|
1010
|
+
save(id: string, credential: StoredWalletCredential): Promise<void>;
|
|
1011
|
+
load(id: string): Promise<StoredWalletCredential | null>;
|
|
1012
|
+
delete(id: string): Promise<void>;
|
|
1013
|
+
listIds(): Promise<string[]>;
|
|
1014
|
+
/**
|
|
1015
|
+
* Close the database connection and clear cached crypto key.
|
|
1016
|
+
*/
|
|
1017
|
+
close(): void;
|
|
1018
|
+
}
|
|
1019
|
+
|
|
1020
|
+
/**
|
|
1021
|
+
* VerifiablePresentation.ts
|
|
1022
|
+
* KoraIDV Wallet — VP creation with selective disclosure for Web
|
|
1023
|
+
*/
|
|
1024
|
+
|
|
1025
|
+
/**
|
|
1026
|
+
* Factory for building W3C Verifiable Presentations.
|
|
1027
|
+
*/
|
|
1028
|
+
declare const WalletPresentationBuilder: {
|
|
1029
|
+
/**
|
|
1030
|
+
* Create a Verifiable Presentation from a credential with selective disclosure.
|
|
1031
|
+
*/
|
|
1032
|
+
create(params: {
|
|
1033
|
+
credential: WalletCredential;
|
|
1034
|
+
profile: DisclosureProfile;
|
|
1035
|
+
holder?: string;
|
|
1036
|
+
audience?: string;
|
|
1037
|
+
nonce?: string;
|
|
1038
|
+
}): WalletPresentation;
|
|
1039
|
+
/**
|
|
1040
|
+
* Serialize a presentation to a JSON string.
|
|
1041
|
+
*/
|
|
1042
|
+
encode(presentation: WalletPresentation): string;
|
|
1043
|
+
/**
|
|
1044
|
+
* Deserialize a presentation from a JSON string.
|
|
1045
|
+
*/
|
|
1046
|
+
decode(json: string): WalletPresentation;
|
|
1047
|
+
};
|
|
1048
|
+
|
|
1049
|
+
export { ApiClient, type ChallengeResult, type ChallengeType, type Configuration, type CreateVerificationRequest, DisclosureClaim, type DisclosureProfile, DisclosureProfiles, type DocumentQualityResponse, DocumentType, type DocumentTypeInfo, type DocumentUploadResponse, type DocumentVerification, type Environment, type FaceVerification, type HandoffContext, type HandoffSession, KoraError, KoraErrorCode, KoraIDV, KoraWallet, type LivenessChallenge, type LivenessChallengeResponse, type LivenessMode, type LivenessSession, type LivenessVerification, type Locale, MrzParser, type QualityIssue$1 as QualityIssue, QualityValidator, type RiskSignal, type SelfieUploadResponse, type StoredWalletCredential, type SupportedCountry, type Theme, type Verification, type VerificationCallbacks, type VerificationOptions, type VerificationStatus, type VerificationStep, type WalletCredential, type WalletCredentialStatus, WalletCredentialStore, type WalletCredentialSubject, type WalletDataIntegrityProof, WalletError, type WalletPresentation, WalletPresentationBuilder, WebBarcodeScanner, applyDisclosure, blobToBase64, computeAgeOver18, createWalletCredential, getDocumentTypeInfo };
|