@certiface/sdk 1.0.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 (68) hide show
  1. package/LICENSE +20 -0
  2. package/README.md +966 -0
  3. package/RnSdk.podspec +27 -0
  4. package/android/build.gradle +86 -0
  5. package/android/gradle.properties +6 -0
  6. package/android/src/main/AndroidManifest.xml +2 -0
  7. package/android/src/main/java/br/com/oititec/rn/sdk/RnSdkModule.kt +128 -0
  8. package/android/src/main/java/br/com/oititec/rn/sdk/RnSdkPackage.kt +33 -0
  9. package/android/src/main/java/br/com/oititec/rn/sdk/executor/LivenessExevutor.kt +66 -0
  10. package/android/src/main/java/br/com/oititec/rn/sdk/factories/FacetecThemeFactory.kt +233 -0
  11. package/android/src/main/java/br/com/oititec/rn/sdk/factories/IProovThemeFactory.kt +176 -0
  12. package/android/src/main/java/br/com/oititec/rn/sdk/managers/AssetManager.kt +152 -0
  13. package/android/src/main/java/br/com/oititec/rn/sdk/model/Featues.kt +6 -0
  14. package/android/src/main/java/br/com/oititec/rn/sdk/processors/AssetProcessor.kt +179 -0
  15. package/android/src/main/java/br/com/oititec/rn/sdk/strategy/FacetecStrategy.kt +25 -0
  16. package/android/src/main/java/br/com/oititec/rn/sdk/strategy/IProovStrategy.kt +25 -0
  17. package/android/src/main/java/br/com/oititec/rn/sdk/strategy/LivenessProviderStrategy.kt +16 -0
  18. package/android/src/main/java/br/com/oititec/rn/sdk/theme/FacetecFonts.kt +85 -0
  19. package/android/src/main/java/br/com/oititec/rn/sdk/theme/IProovFonts.kt +52 -0
  20. package/android/src/main/java/br/com/oititec/rn/sdk/utils/AssetProcessor.kt +181 -0
  21. package/android/src/main/res/drawable/backhand_left.xml +20 -0
  22. package/android/src/main/res/drawable/backhand_right.xml +20 -0
  23. package/android/src/main/res/drawable/camera_icon.xml +14 -0
  24. package/android/src/main/res/drawable/close_icon.xml +11 -0
  25. package/android/src/main/res/drawable/error_icon.xml +11 -0
  26. package/android/src/main/res/drawable/neutral_face.xml +11 -0
  27. package/android/src/main/res/drawable/success_icon.xml +11 -0
  28. package/android/src/main/res/font/sixty.ttf +0 -0
  29. package/ios/Extensions/RnSDK+Callbacks.swift +62 -0
  30. package/ios/Extensions/UIColor+Hex.swift +39 -0
  31. package/ios/Resources/Media.xcassets/Contents.json +6 -0
  32. package/ios/Resources/Media.xcassets/shell.imageset/Contents.json +12 -0
  33. package/ios/Resources/Media.xcassets/shell.imageset/shell.png +0 -0
  34. package/ios/Resources/Media.xcassets/test.imageset/Contents.json +12 -0
  35. package/ios/Resources/Media.xcassets/test.imageset/arrow_forward_ios.png +0 -0
  36. package/ios/RnSdk.h +5 -0
  37. package/ios/RnSdk.mm +71 -0
  38. package/ios/RnSdkImpl.swift +91 -0
  39. package/ios/Utils/RnSdkBundle.swift +27 -0
  40. package/ios/Utils/ThemeFactory.swift +424 -0
  41. package/lib/module/@types/result.js +2 -0
  42. package/lib/module/@types/result.js.map +1 -0
  43. package/lib/module/@types/theme.js +41 -0
  44. package/lib/module/@types/theme.js.map +1 -0
  45. package/lib/module/NativeRnSdk.js +5 -0
  46. package/lib/module/NativeRnSdk.js.map +1 -0
  47. package/lib/module/index.js +33 -0
  48. package/lib/module/index.js.map +1 -0
  49. package/lib/module/package.json +1 -0
  50. package/lib/module/utils/AssetProcessor.js +78 -0
  51. package/lib/module/utils/AssetProcessor.js.map +1 -0
  52. package/lib/typescript/package.json +1 -0
  53. package/lib/typescript/src/@types/result.d.ts +17 -0
  54. package/lib/typescript/src/@types/result.d.ts.map +1 -0
  55. package/lib/typescript/src/@types/theme.d.ts +306 -0
  56. package/lib/typescript/src/@types/theme.d.ts.map +1 -0
  57. package/lib/typescript/src/NativeRnSdk.d.ts +9 -0
  58. package/lib/typescript/src/NativeRnSdk.d.ts.map +1 -0
  59. package/lib/typescript/src/index.d.ts +14 -0
  60. package/lib/typescript/src/index.d.ts.map +1 -0
  61. package/lib/typescript/src/utils/AssetProcessor.d.ts +8 -0
  62. package/lib/typescript/src/utils/AssetProcessor.d.ts.map +1 -0
  63. package/package.json +165 -0
  64. package/src/@types/result.ts +19 -0
  65. package/src/@types/theme.ts +346 -0
  66. package/src/NativeRnSdk.ts +18 -0
  67. package/src/index.tsx +54 -0
  68. package/src/utils/AssetProcessor.ts +114 -0
package/README.md ADDED
@@ -0,0 +1,966 @@
1
+ <p align="center">
2
+ <img src="Documentation/images/certiface-header.png" alt="CertiFace" />
3
+ </p>
4
+ <div align="left">
5
+
6
+ # @certiface/sdk
7
+
8
+ SDK React Native para verificação biométrica de liveness (prova de vida), distribuído como `@certiface/sdk`. Integre detecção facial avançada com FaceTec e iProov em aplicações Android e iOS com suporte completo a personalização de temas e interface nativa de alta performance.
9
+
10
+ </div>
11
+
12
+ ---
13
+
14
+ ## 📦 Instalação
15
+
16
+ ```bash
17
+ npm install @certiface/sdk
18
+ ```
19
+
20
+ ou
21
+
22
+ ```bash
23
+ yarn add @certiface/sdk
24
+ ```
25
+
26
+ ## ⚙️ Configuração
27
+
28
+ ### Android
29
+
30
+ 1. Configure os repositórios necessários no `android/build.gradle`:
31
+
32
+ ```gradle
33
+ allprojects {
34
+ repositories {
35
+ google()
36
+ mavenCentral()
37
+ maven {
38
+ url 'https://raw.githubusercontent.com/oititec/android-oiti-sdk-versions/master'
39
+ }
40
+ }
41
+ }
42
+ ```
43
+
44
+ 2. Adicione as permissões no `android/app/src/main/AndroidManifest.xml`:
45
+
46
+ ```xml
47
+ <uses-permission android:name="android.permission.CAMERA" />
48
+ <uses-permission android:name="android.permission.INTERNET" />
49
+ ```
50
+
51
+ ### iOS
52
+
53
+ 1. Configure as fontes do CocoaPods no `ios/Podfile`:
54
+
55
+ ```ruby
56
+ source 'https://github.com/oititec/ios-artifactory.git'
57
+ source 'https://github.com/CocoaPods/Specs.git'
58
+ ```
59
+
60
+ 2. Adicione as permissões no `ios/YourApp/Info.plist`:
61
+
62
+ ```xml
63
+ <key>NSCameraUsageDescription</key>
64
+ <string>Precisamos acessar sua câmera para verificação de identidade</string>
65
+ <key>NSPhotoLibraryUsageDescription</key>
66
+ <string>Precisamos acessar suas fotos para verificação de identidade</string>
67
+ ```
68
+
69
+ 3. Execute a instalação dos pods:
70
+
71
+ ```bash
72
+ cd ios && pod install
73
+ ```
74
+
75
+ ## 🚀 Uso Básico
76
+
77
+ ### Importação
78
+
79
+ ```typescript
80
+ import {
81
+ CertifaceSDK,
82
+ LivenessProvider,
83
+ Environment,
84
+ type OitiTheme,
85
+ type LivenessResult,
86
+ } from '@certiface/sdk';
87
+ ```
88
+
89
+ Todas as chamadas à API passam pelo objeto `CertifaceSDK` (por exemplo `CertifaceSDK.startJourney(...)`).
90
+
91
+ ### Exemplo Simples
92
+
93
+ ```typescript
94
+ import React from 'react';
95
+ import { Button, Alert } from 'react-native';
96
+ import { CertifaceSDK, Environment, LivenessProvider } from '@certiface/sdk';
97
+
98
+ export default function App() {
99
+ const handleVerification = async () => {
100
+ try {
101
+ const appKey = 'your-app-key-here';
102
+ const result = await CertifaceSDK.startJourney(
103
+ appKey,
104
+ Environment.HML,
105
+ LivenessProvider.FACETEC,
106
+ false
107
+ );
108
+
109
+ Alert.alert('Sucesso!', `Verificação concluída: ${result.codID}`);
110
+ } catch (error) {
111
+ Alert.alert('Erro', `Falha: ${error.message}`);
112
+ }
113
+ };
114
+
115
+ return <Button title="Iniciar Verificação" onPress={handleVerification} />;
116
+ }
117
+ ```
118
+
119
+ ### Resultado Esperado
120
+
121
+ Quando bem-sucedido, `CertifaceSDK.startJourney` retorna um objeto `LivenessResult`:
122
+
123
+ ```typescript
124
+ {
125
+ valid: true,
126
+ codID: "abc123def456",
127
+ protocol: "20231105-001"
128
+ }
129
+ ```
130
+
131
+ ## 📚 API
132
+
133
+ ### `CertifaceSDK`
134
+
135
+ Objeto com os métodos expostos pelo SDK:
136
+
137
+ | Método | Descrição |
138
+ | ------ | --------- |
139
+ | `CertifaceSDK.startJourney(...)` | Inicia a jornada de liveness |
140
+ | `CertifaceSDK.checkCameraPermission()` | Verifica se a câmera está autorizada |
141
+ | `CertifaceSDK.requestCameraPermission()` | Solicita permissão da câmera |
142
+
143
+ ### `CertifaceSDK.startJourney(appKey, environment, provider, isCustomEnabled?, theme?)`
144
+
145
+ Inicia o processo de verificação de liveness.
146
+
147
+ **Parâmetros:**
148
+
149
+ | Nome | Tipo | Obrigatório | Descrição |
150
+ | ----------------- | ------------------ | ----------- | ---------------------------------------------- |
151
+ | `appKey` | `string` | ✅ | Chave de aplicação fornecida pela Oiti |
152
+ | `environment` | `Environment` | ✅ | Ambiente de execução (`HML` ou `PRD`) |
153
+ | `provider` | `LivenessProvider` | ✅ | Provedor de liveness (`FACETEC` ou `IPROOV`) |
154
+ | `isCustomEnabled` | `boolean` | ❌ | Habilita tema personalizado (padrão: `false`) |
155
+ | `theme` | `OitiTheme` | ❌ | Objeto com configurações de tema personalizado |
156
+
157
+ **Retorna:** `Promise<LivenessResult>` com o resultado da verificação
158
+
159
+ **Exemplo:**
160
+
161
+ ```typescript
162
+ const result = await CertifaceSDK.startJourney(
163
+ 'your-app-key',
164
+ Environment.HML,
165
+ LivenessProvider.FACETEC,
166
+ false
167
+ );
168
+
169
+ const resultWithTheme = await CertifaceSDK.startJourney(
170
+ 'your-app-key',
171
+ Environment.PRD,
172
+ LivenessProvider.IPROOV,
173
+ true,
174
+ customTheme
175
+ );
176
+ ```
177
+
178
+ ---
179
+
180
+ ### `LivenessResult`
181
+
182
+ Tipo de retorno de `CertifaceSDK.startJourney`:
183
+
184
+ ```typescript
185
+ interface LivenessResult {
186
+ valid: boolean;
187
+ codID: string | null;
188
+ protocol: string | null;
189
+ }
190
+ ```
191
+
192
+ **Propriedades:**
193
+
194
+ | Nome | Tipo | Descrição |
195
+ | ---------- | ---------------- | ---------------------------------------- |
196
+ | `valid` | `boolean` | Indica se a verificação foi bem-sucedida |
197
+ | `codID` | `string \| null` | Código de identificação da verificação |
198
+ | `protocol` | `string \| null` | Protocolo da sessão de verificação |
199
+
200
+ ---
201
+
202
+ ### `CertifaceSDK.checkCameraPermission()`
203
+
204
+ Verifica se a permissão da câmera foi concedida.
205
+
206
+ **Retorna:** `Promise<boolean>`
207
+
208
+ **Exemplo:**
209
+
210
+ ```typescript
211
+ const hasPermission = await CertifaceSDK.checkCameraPermission();
212
+ if (!hasPermission) {
213
+ console.log('Permissão não concedida');
214
+ }
215
+ ```
216
+
217
+ **Resultado:**
218
+
219
+ - `true` - Permissão concedida
220
+ - `false` - Permissão negada
221
+
222
+ ---
223
+
224
+ ### `CertifaceSDK.requestCameraPermission()`
225
+
226
+ Solicita permissão da câmera ao usuário.
227
+
228
+ **Retorna:** `Promise<boolean>`
229
+
230
+ **Exemplo:**
231
+
232
+ ```typescript
233
+ const granted = await CertifaceSDK.requestCameraPermission();
234
+ if (granted) {
235
+ console.log('Usuário concedeu permissão');
236
+ }
237
+ ```
238
+
239
+ **Resultado:**
240
+
241
+ - `true` - Usuário concedeu permissão
242
+ - `false` - Usuário negou permissão
243
+
244
+ ---
245
+
246
+ ## 🎨 Personalização de Tema
247
+
248
+ O SDK oferece suporte a temas personalizados para os provedores **FaceTec** e **iProov**.
249
+
250
+ ### Estrutura do Tema
251
+
252
+ ```typescript
253
+ import { CertifaceSDK, LivenessProvider, Environment, type OitiTheme } from '@certiface/sdk';
254
+
255
+ const customTheme: OitiTheme = {
256
+ facetec: {
257
+ colors: {
258
+ frameBackground: '#1A1A1A',
259
+ frameBorder: '#FF6B35',
260
+ ovalStroke: '#FF6B35',
261
+ ovalProgressFirst: '#FF6B35',
262
+ ovalProgressSecond: '#FFD700',
263
+ },
264
+ texts: {
265
+ readyHeader1: 'Prepare-se',
266
+ readyHeader2: 'para verificação',
267
+ readyButton: 'Iniciar',
268
+ },
269
+ fonts: {
270
+ readyScreenHeader: 'CustomFont',
271
+ },
272
+ },
273
+ };
274
+
275
+ await CertifaceSDK.startJourney(
276
+ appKey,
277
+ Environment.HML,
278
+ LivenessProvider.FACETEC,
279
+ true,
280
+ customTheme
281
+ );
282
+ ```
283
+
284
+ ### Opções de Provider
285
+
286
+ ```typescript
287
+ enum LivenessProvider {
288
+ FACETEC = 'FACETEC',
289
+ IPROOV = 'IPROOV',
290
+ }
291
+ ```
292
+
293
+ ### Opções de Environment
294
+
295
+ ```typescript
296
+ enum Environment {
297
+ HML = 'HML',
298
+ PRD = 'PRD',
299
+ }
300
+ ```
301
+
302
+ ## 💡 Exemplos
303
+
304
+ ### Exemplo com Gerenciamento de Permissões
305
+
306
+ ```typescript
307
+ import React, { useState } from 'react';
308
+ import { View, Button, Alert, ActivityIndicator } from 'react-native';
309
+ import {
310
+ CertifaceSDK,
311
+ Environment,
312
+ LivenessProvider,
313
+ type LivenessResult,
314
+ } from '@certiface/sdk';
315
+
316
+ export default function LivenessScreen() {
317
+ const [loading, setLoading] = useState(false);
318
+
319
+ const handleVerification = async () => {
320
+ setLoading(true);
321
+
322
+ try {
323
+ const hasPermission = await CertifaceSDK.checkCameraPermission();
324
+
325
+ if (!hasPermission) {
326
+ const granted = await CertifaceSDK.requestCameraPermission();
327
+ if (!granted) {
328
+ Alert.alert('Erro', 'Permissão da câmera é necessária');
329
+ setLoading(false);
330
+ return;
331
+ }
332
+ }
333
+
334
+ const appKey = 'your-app-key-here';
335
+ const result: LivenessResult = await CertifaceSDK.startJourney(
336
+ appKey,
337
+ Environment.HML,
338
+ LivenessProvider.FACETEC,
339
+ false
340
+ );
341
+
342
+ if (result.valid) {
343
+ Alert.alert(
344
+ 'Verificação Aprovada!',
345
+ `Protocolo: ${result.protocol}\nCódigo: ${result.codID}`
346
+ );
347
+ } else {
348
+ Alert.alert('Verificação Recusada');
349
+ }
350
+ } catch (error) {
351
+ Alert.alert('Erro', error.message);
352
+ } finally {
353
+ setLoading(false);
354
+ }
355
+ };
356
+
357
+ return (
358
+ <View style={{ flex: 1, justifyContent: 'center', padding: 20 }}>
359
+ {loading ? (
360
+ <ActivityIndicator size="large" color="#007AFF" />
361
+ ) : (
362
+ <Button title="Iniciar Verificação" onPress={handleVerification} />
363
+ )}
364
+ </View>
365
+ );
366
+ }
367
+ ```
368
+
369
+ **Resultado de Sucesso:**
370
+
371
+ ```typescript
372
+ {
373
+ valid: true,
374
+ codID: "abc123def456",
375
+ protocol: "20231105-001"
376
+ }
377
+ ```
378
+
379
+ **Resultado de Erro:**
380
+
381
+ ```typescript
382
+ {
383
+ valid: false,
384
+ codID: null,
385
+ protocol: null
386
+ }
387
+ ```
388
+
389
+ ---
390
+
391
+ ### Exemplo com Tema Customizado Completo
392
+
393
+ ```typescript
394
+ import React from 'react';
395
+ import { Button, Alert } from 'react-native';
396
+ import {
397
+ CertifaceSDK,
398
+ LivenessProvider,
399
+ Environment,
400
+ type OitiTheme,
401
+ type LivenessResult,
402
+ } from '@certiface/sdk';
403
+
404
+ const customTheme: OitiTheme = {
405
+ facetec: {
406
+ colors: {
407
+ frameBackground: '#1A1A1A',
408
+ frameBorder: '#FF6B35',
409
+ ovalStroke: '#FF6B35',
410
+ ovalProgressFirst: '#FF6B35',
411
+ ovalProgressSecond: '#FFD700',
412
+ guidanceButtonBackgroundNormal: '#FF6B35',
413
+ guidanceButtonTextNormal: '#FFFFFF',
414
+ },
415
+ texts: {
416
+ readyHeader1: 'Prepare-se',
417
+ readyHeader2: 'para a verificação',
418
+ readyMessage1: 'Posicione seu rosto',
419
+ readyMessage2: 'dentro do círculo',
420
+ readyButton: 'Começar',
421
+ feedbackCenterFace: 'Centralize seu rosto',
422
+ feedbackHoldSteady: 'Mantenha-se parado',
423
+ },
424
+ },
425
+ instructions: {
426
+ colors: {
427
+ background: '#2E2E2E',
428
+ title: '#FFFFFF',
429
+ continueButtonBackground: '#FF6B35',
430
+ },
431
+ texts: {
432
+ title: 'Verificação de Identidade',
433
+ caption: 'Siga as instruções',
434
+ continueButton: 'Continuar',
435
+ },
436
+ },
437
+ result: {
438
+ colors: {
439
+ successBackground: '#E8F5E8',
440
+ successText: '#2E7D32',
441
+ errorBackground: '#FFEBEE',
442
+ errorText: '#C62828',
443
+ },
444
+ texts: {
445
+ success: 'Verificação concluída com sucesso!',
446
+ error: 'Erro na verificação. Tente novamente.',
447
+ },
448
+ },
449
+ };
450
+
451
+ export default function ThemedVerification() {
452
+ const handleStart = async () => {
453
+ try {
454
+ const appKey = 'your-app-key-here';
455
+ const result: LivenessResult = await CertifaceSDK.startJourney(
456
+ appKey,
457
+ Environment.PRD,
458
+ LivenessProvider.FACETEC,
459
+ true,
460
+ customTheme
461
+ );
462
+
463
+ if (result.valid) {
464
+ Alert.alert('Sucesso!', `Protocolo: ${result.protocol}`);
465
+ }
466
+ } catch (error) {
467
+ Alert.alert('Erro', error.message);
468
+ }
469
+ };
470
+
471
+ return <Button title="Iniciar com Tema Custom" onPress={handleStart} />;
472
+ }
473
+ ```
474
+
475
+ ---
476
+
477
+ ### Exemplo com TypeScript e Tratamento de Erros
478
+
479
+ ```typescript
480
+ import React, { useState } from 'react';
481
+ import { View, Text, TouchableOpacity, StyleSheet, Alert } from 'react-native';
482
+ import {
483
+ CertifaceSDK,
484
+ Environment,
485
+ LivenessProvider,
486
+ type LivenessResult,
487
+ } from '@certiface/sdk';
488
+
489
+ export default function VerificationComponent() {
490
+ const [result, setResult] = useState<LivenessResult | null>(null);
491
+ const [loading, setLoading] = useState(false);
492
+
493
+ const handleVerification = async () => {
494
+ setLoading(true);
495
+ setResult(null);
496
+
497
+ try {
498
+ const appKey = process.env.OITI_APP_KEY || 'your-app-key';
499
+ const data: LivenessResult = await CertifaceSDK.startJourney(
500
+ appKey,
501
+ Environment.HML,
502
+ LivenessProvider.FACETEC,
503
+ false
504
+ );
505
+
506
+ setResult(data);
507
+
508
+ if (data.valid) {
509
+ Alert.alert('Sucesso', 'Identidade verificada!');
510
+ } else {
511
+ Alert.alert('Falha', 'Verificação não aprovada');
512
+ }
513
+ } catch (error) {
514
+ Alert.alert('Erro', `Não foi possível completar: ${error.message}`);
515
+ } finally {
516
+ setLoading(false);
517
+ }
518
+ };
519
+
520
+ return (
521
+ <View style={styles.container}>
522
+ <TouchableOpacity
523
+ style={[styles.button, loading && styles.buttonDisabled]}
524
+ onPress={handleVerification}
525
+ disabled={loading}
526
+ >
527
+ <Text style={styles.buttonText}>
528
+ {loading ? 'Verificando...' : 'Iniciar Verificação'}
529
+ </Text>
530
+ </TouchableOpacity>
531
+
532
+ {result && (
533
+ <View style={styles.resultContainer}>
534
+ <Text style={styles.resultTitle}>Resultado:</Text>
535
+ <Text>Status: {result.valid ? 'Aprovado' : 'Reprovado'}</Text>
536
+ {result.protocol && <Text>Protocolo: {result.protocol}</Text>}
537
+ {result.codID && <Text>Código: {result.codID}</Text>}
538
+ </View>
539
+ )}
540
+ </View>
541
+ );
542
+ }
543
+
544
+ const styles = StyleSheet.create({
545
+ container: {
546
+ flex: 1,
547
+ justifyContent: 'center',
548
+ padding: 20,
549
+ },
550
+ button: {
551
+ backgroundColor: '#007AFF',
552
+ padding: 15,
553
+ borderRadius: 8,
554
+ alignItems: 'center',
555
+ },
556
+ buttonDisabled: {
557
+ backgroundColor: '#cccccc',
558
+ },
559
+ buttonText: {
560
+ color: 'white',
561
+ fontSize: 16,
562
+ fontWeight: '600',
563
+ },
564
+ resultContainer: {
565
+ marginTop: 20,
566
+ padding: 15,
567
+ backgroundColor: '#f5f5f5',
568
+ borderRadius: 8,
569
+ },
570
+ resultTitle: {
571
+ fontSize: 18,
572
+ fontWeight: 'bold',
573
+ marginBottom: 10,
574
+ },
575
+ });
576
+ ```
577
+
578
+ **Possíveis Resultados:**
579
+
580
+ **Sucesso:**
581
+
582
+ ```typescript
583
+ {
584
+ valid: true,
585
+ codID: "abc123def456",
586
+ protocol: "20231105-001"
587
+ }
588
+ ```
589
+
590
+ **Falha:**
591
+
592
+ ```typescript
593
+ {
594
+ valid: false,
595
+ codID: null,
596
+ protocol: null
597
+ }
598
+ ```
599
+
600
+ ---
601
+
602
+ ## 🎭 Tema Completo
603
+
604
+ ### Exemplo de Tema Personalizado Completo
605
+
606
+ ```typescript
607
+ const customTheme: OitiTheme = {
608
+ facetec: {
609
+ colors: {
610
+ readyScreenHeader: '#FFFFFF',
611
+ readyScreenSubtext: '#CCCCCC',
612
+ readyScreenOvalFill: '#FF6B35',
613
+ readyScreenTextBackground: '#444444',
614
+ resultScreenForeground: '#FF6B35',
615
+ resultScreenBackground: '#F0F8FF',
616
+ ovalStroke: '#FF6B35',
617
+ ovalProgressFirst: '#FF6B35',
618
+ ovalProgressSecond: '#FFD700',
619
+ overlayBackground: '#80000000',
620
+ frameBorder: '#FF6B35',
621
+ frameBackground: '#1A1A1A',
622
+ feedbackBarBackground: '#FFF8DC',
623
+ feedbackMessage: '#333333',
624
+ guidanceBackground: '#2E2E2E',
625
+ guidanceForeground: '#FFFFFF',
626
+ guidanceButtonTextNormal: '#FFFFFF',
627
+ guidanceButtonTextHighlight: '#FFFFFF',
628
+ guidanceButtonTextDisabled: '#AAAAAA',
629
+ guidanceButtonBackgroundNormal: '#FF6B35',
630
+ guidanceButtonBackgroundHighlight: '#FF6B35',
631
+ guidanceButtonBackgroundDisabled: '#666666',
632
+ guidanceButtonBorder: '#FF6B35',
633
+ },
634
+ texts: {
635
+ readyHeader1: 'Prepare-se',
636
+ readyHeader2: 'para verificação',
637
+ readyMessage1: 'Posicione seu rosto',
638
+ readyMessage2: 'dentro do círculo',
639
+ readyButton: 'Iniciar',
640
+ retryHeader: 'Vamos tentar novamente',
641
+ retrySubheader: 'Ajustes necessários',
642
+ retryButton: 'Tentar Novamente',
643
+ resultSuccessMessage: 'Verificação concluída!',
644
+ feedbackCenterFace: 'Centralize seu rosto',
645
+ feedbackHoldSteady: 'Mantenha-se parado',
646
+ feedbackMovePhoneCloser: 'Aproxime o dispositivo',
647
+ feedbackMovePhoneAway: 'Afaste o dispositivo',
648
+ },
649
+ assets: {
650
+ overlayBrandImage: 'overlayBrandImage',
651
+ cancelButtonIcon: 'cancelButtonIcon',
652
+ resultScreenCustomActivityIndicatorImage:
653
+ 'resultScreenCustomActivityIndicatorImage',
654
+ },
655
+ fonts: {
656
+ readyScreenHeader: 'sixty',
657
+ readyScreenSubtext: 'sixty',
658
+ resultScreenMessage: 'sixty',
659
+ retryScreenHeader: 'sixty',
660
+ retryScreenSubtext: 'sixty',
661
+ feedbackMessage: 'sixty',
662
+ guidanceHeader: 'sixty',
663
+ guidanceSubtext: 'sixty',
664
+ guidanceButton: 'sixty',
665
+ },
666
+ },
667
+ iproov: {
668
+ colors: {
669
+ title: '#FFFFFF',
670
+ titleBackground: '#2E2E2E',
671
+ promptText: '#FFFFFF',
672
+ promptBackground: '#1A1A1A',
673
+ background: '#FF6B35',
674
+ ovalReady: '#FF6B35',
675
+ ovalNotReady: '#FF3030',
676
+ ovalCapturing: '#FFFFFF',
677
+ ovalCompleted: '#FF6B35',
678
+ },
679
+ texts: {
680
+ title: 'Verificação Biométrica',
681
+ },
682
+ assets: {
683
+ closeButtonIcon: 'closeButtonIcon',
684
+ logoImage: 'logoImage',
685
+ },
686
+ fonts: {
687
+ instructionsTitleFont: 'sixty',
688
+ instructionsCaptionFont: 'sixty',
689
+ instructionsDocumentTypesInstructionsFont: 'sixty',
690
+ instructionsDocumentTipsInstructionsFont: 'sixty',
691
+ instructionsButtonFont: 'sixty',
692
+ permissionTitleFont: 'sixty',
693
+ permissionCaptionFont: 'sixty',
694
+ permissionButtonFont: 'sixty',
695
+ resultMessageFont: 'sixty',
696
+ resultRetryButtonFont: 'sixty',
697
+ },
698
+ },
699
+ instructions: {
700
+ colors: {
701
+ statusBar: '#2E2E2E',
702
+ background: '#2E2E2E',
703
+ backButtonIcon: '#2E2E2E',
704
+ backButtonBackground: '#2E2E2E',
705
+ backButtonBorder: '#2E2E2E',
706
+ bottomSheet: '#1A1A1A',
707
+ title: '#FFFFFF',
708
+ caption: '#CCCCCC',
709
+ firstInstructionTitle: '#FFFFFF',
710
+ secondInstructionTitle: '#FFFFFF',
711
+ continueButtonText: '#FFFFFF',
712
+ continueButtonBackground: '#FF6B35',
713
+ continueButtonBorder: '#FF6B35',
714
+ },
715
+ texts: {
716
+ title: 'Verificação de Identidade',
717
+ caption: 'Siga as instruções para completar o processo',
718
+ firstInstruction: 'Mantenha o documento bem iluminado',
719
+ secondInstruction: 'Use um documento oficial com foto',
720
+ continueButton: 'Continuar',
721
+ },
722
+ assets: {
723
+ backButtonIcon: 'backButtonIcon',
724
+ contextImage: 'contextImage',
725
+ firstInstructionIcon: 'firstInstructionIcon',
726
+ secondInstructionIcon: 'secondInstructionIcon',
727
+ },
728
+ fonts: {
729
+ title: 'sixty',
730
+ caption: 'sixty',
731
+ firstInstructionTitle: 'sixty',
732
+ secondInstructionTitle: 'sixty',
733
+ continueButton: 'sixty',
734
+ },
735
+ },
736
+ permission: {
737
+ colors: {
738
+ statusBar: '#2E2E2E',
739
+ background: '#2E2E2E',
740
+ backButtonIcon: '#2E2E2E',
741
+ backButtonBackground: '#2E2E2E',
742
+ backButtonBorder: '#2E2E2E',
743
+ cameraImage: '#FFFFFF',
744
+ title: '#FFFFFF',
745
+ caption: '#FFFFFF',
746
+ checkPermissionButtonText: '#FFFFFF',
747
+ checkPermissionButtonBackground: '#FF6B35',
748
+ checkPermissionButtonBorder: '#FF6B35',
749
+ bottomSheet: '#FF6B35',
750
+ bottomSheetTitle: '#FF6B35',
751
+ bottomSheetCaption: '#FF6B35',
752
+ openSettingsButtonText: '#FF6B35',
753
+ openSettingsButtonBackground: '#FF6B35',
754
+ openSettingsButtonBorder: '#FF6B35',
755
+ closeButtonText: '#FF6B35',
756
+ closeButtonBackground: '#FF6B35',
757
+ closeButtonBorder: '#FF6B35',
758
+ },
759
+ texts: {
760
+ title: 'Permissões Necessárias',
761
+ caption: 'Permissões Necessárias',
762
+ checkPermissionButton: 'Permitir Acesso',
763
+ bottomSheetTitle: 'Permitir Acesso',
764
+ bottomSheetCaption: 'Permitir Acesso',
765
+ openSettingsButton: 'Permitir Acesso',
766
+ closeButton: 'Permitir Acesso',
767
+ },
768
+ assets: {
769
+ backButtonIcon: 'backButtonIcon',
770
+ cameraImage: 'cameraImage',
771
+ },
772
+ fonts: {
773
+ title: 'sixty',
774
+ caption: 'sixty',
775
+ checkPermissionButton: 'sixty',
776
+ bottomSheetTitle: 'sixty',
777
+ bottomSheetCaption: 'sixty',
778
+ opentSettingsButton: 'sixty',
779
+ closeButton: 'sixty',
780
+ },
781
+ },
782
+ processing: {
783
+ colors: {
784
+ statusBar: '#1A1A1A',
785
+ background: '#1A1A1A',
786
+ loading: '#FFFFFF',
787
+ },
788
+ },
789
+ result: {
790
+ colors: {
791
+ successStatusBar: '#E8F5E8',
792
+ successBackground: '#E8F5E8',
793
+ successText: '#2E7D32',
794
+ errorStatusBar: '#FFEBEE',
795
+ errorBackground: '#FFEBEE',
796
+ errorText: '#C62828',
797
+ retryBackground: '#C62828',
798
+ retryText: '#FFEBEE',
799
+ retryButtonText: '#FF6B35',
800
+ retryButtonBackground: '#FFFFFF',
801
+ retryButtonBorder: '#FFFFFF',
802
+ },
803
+ texts: {
804
+ success: 'Verificação concluída com sucesso!',
805
+ error: 'Houve um erro na verificação. Tente novamente.',
806
+ retryButton: 'Tentar Novamente',
807
+ },
808
+ assets: {
809
+ successImage: 'successImage',
810
+ errorImage: 'errorImage',
811
+ retryImage: 'retryImage',
812
+ },
813
+ fonts: {
814
+ text: 'sixty',
815
+ retryButton: 'sixty',
816
+ },
817
+ },
818
+ };
819
+ ```
820
+
821
+ ### Configuração de Assets e Fonts
822
+
823
+ Os assets e fonts referenciados no tema precisam ser cadastrados nativamente em cada plataforma:
824
+
825
+ #### Android - Drawable Resources
826
+
827
+ Os assets devem ser adicionados em `android/app/src/main/res/drawable/`:
828
+
829
+ ```
830
+ android/app/src/main/res/
831
+ └── drawable/
832
+ ├── shell.png
833
+ └── outros_assets.png
834
+ ```
835
+
836
+ Formatos aceitos: `.png`, `.jpg`, `.xml` (vector drawables)
837
+
838
+ #### Android - Fonts
839
+
840
+ As fontes devem ser adicionadas em `android/app/src/main/res/font/`:
841
+
842
+ ```
843
+ android/app/src/main/res/
844
+ └── font/
845
+ ├── sixty.ttf
846
+ └── outras_fontes.ttf
847
+ ```
848
+
849
+ Formatos aceitos: `.ttf`, `.otf`
850
+
851
+ #### iOS - Assets
852
+
853
+ Os assets devem ser adicionados em um Asset Catalog (`.xcassets`):
854
+
855
+ ```
856
+ ios/YourApp/
857
+ └── Images.xcassets/
858
+ ├── shell.imageset/
859
+ │ ├── Contents.json
860
+ │ ├── shell.png
861
+ │ ├── shell@2x.png
862
+ │ └── shell@3x.png
863
+ └── Contents.json
864
+ ```
865
+
866
+ Estrutura do `Contents.json` para cada imageset:
867
+
868
+ ```json
869
+ {
870
+ "images": [
871
+ {
872
+ "filename": "shell.png",
873
+ "idiom": "universal",
874
+ "scale": "1x"
875
+ },
876
+ {
877
+ "filename": "shell@2x.png",
878
+ "idiom": "universal",
879
+ "scale": "2x"
880
+ },
881
+ {
882
+ "filename": "shell@3x.png",
883
+ "idiom": "universal",
884
+ "scale": "3x"
885
+ }
886
+ ],
887
+ "info": {
888
+ "author": "xcode",
889
+ "version": 1
890
+ }
891
+ }
892
+ ```
893
+
894
+ #### iOS - Fonts
895
+
896
+ As fontes devem ser adicionadas ao projeto e registradas no `Info.plist`:
897
+
898
+ 1. Adicione os arquivos de fonte ao projeto:
899
+
900
+ ```
901
+ ios/YourApp/
902
+ └── Fonts/
903
+ ├── sixty.ttf
904
+ └── outras_fontes.ttf
905
+ ```
906
+
907
+ 2. Registre no `Info.plist`:
908
+
909
+ ```xml
910
+ <key>UIAppFonts</key>
911
+ <array>
912
+ <string>sixty.ttf</string>
913
+ <string>outras_fontes.ttf</string>
914
+ </array>
915
+ ```
916
+
917
+ 3. Adicione no Xcode: arraste os arquivos `.ttf` para o projeto no Xcode e marque "Copy items if needed" e o target correto.
918
+
919
+ ### Referenciando no Tema
920
+
921
+ Use apenas o nome base do asset/font (sem extensão):
922
+
923
+ ```typescript
924
+ assets: {
925
+ overlayBrandImage: 'shell',
926
+ },
927
+ fonts: {
928
+ readyScreenHeader: 'sixty',
929
+ }
930
+ ```
931
+
932
+ ---
933
+
934
+ ## ✨ Funcionalidades
935
+
936
+ - ✅ Verificação de liveness com FaceTec e iProov
937
+ - ✅ Gerenciamento automático de permissões
938
+ - ✅ Suporte completo a temas personalizados
939
+ - ✅ Interface TypeScript com tipagem completa
940
+ - ✅ Suporte para Android e iOS
941
+ - ✅ Integração com TurboModules para performance otimizada
942
+ - ✅ API em JavaScript baseada em `CertifaceSDK` e Promises
943
+ - ✅ Compatível com React Native 0.60+
944
+
945
+ ## 📋 Requisitos
946
+
947
+ - React Native ≥ 0.79
948
+ - Android API ≥ 26
949
+ - iOS ≥ 12.0
950
+ - TypeScript ≥ 4.0 (recomendado)
951
+
952
+ ## 🔗 Links Úteis
953
+
954
+ - [Changelog](https://github.com/oititec/certiface-sdk-rn/releases)
955
+
956
+ ## 📄 Licença
957
+
958
+ MIT © [Oiti](https://github.com/oititec)
959
+
960
+ ---
961
+
962
+ <div align="center">
963
+
964
+ **Feito com ❤️ pela equipe Oiti**
965
+
966
+ </div>