From 62ba086e2c0721eed4e40a992e2226d3006ec90a Mon Sep 17 00:00:00 2001 From: JNdhlovu Date: Wed, 15 Jan 2025 17:11:12 +0200 Subject: [PATCH 01/12] feat: init with config and api key --- src/index.tsx | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/index.tsx b/src/index.tsx index e752520..20160c5 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -27,6 +27,7 @@ import { ValidDocumentsResponse, JobType, IdInfo, + Config, } from './types'; import type { DocumentVerificationRequest, @@ -68,6 +69,25 @@ const SmileID = { */ initialize: (useSandBox: boolean = false) => _SmileID.initialize(useSandBox), + initializeWithApiKey: ( + apiKey: string, + config: Config, + useSandBox: boolean, + enableCrashReporting: boolean + ) => + _SmileID.initializeWithApiKey( + apiKey, + config, + useSandBox, + enableCrashReporting + ), + + initializeWithConfig: ( + config: Config, + useSandBox: boolean, + enableCrashReporting: boolean + ) => _SmileID.initializeWithConfig(config, useSandBox, enableCrashReporting), + /** * Sets allow offline mode which enables * offline mode functionality to capture jobs offline and submit later From e2054477bcdf7be3310d75362584bfecc2488db6 Mon Sep 17 00:00:00 2001 From: JNdhlovu Date: Wed, 15 Jan 2025 17:18:26 +0200 Subject: [PATCH 02/12] feat: bump changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index dc6a19d..7eafd93 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Release Notes +## 10.2.3 +* Exposed `initializeWithApiKey` missing for initializing using the api key +* Exposed `initializeWithConfig` missing for initializing using the config json + ## 10.2.2 * Fixed setting `kotlinVersion` and `kotlinCompilerExtensionVersion` From 334a4ad5d6c2d49b8a043aedd3694def264f4ccb Mon Sep 17 00:00:00 2001 From: JNdhlovu Date: Wed, 15 Jan 2025 17:21:48 +0200 Subject: [PATCH 03/12] feat: update changelog --- example/ios/Podfile.lock | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index 2bce1dc..09f0bca 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -943,7 +943,7 @@ PODS: - React-debug - react-native-safe-area-context (4.14.0): - React-Core - - react-native-smile-id (10.2.2): + - react-native-smile-id (10.2.3): - DoubleConversion - glog - hermes-engine @@ -1444,7 +1444,7 @@ SPEC CHECKSUMS: React-logger: 29fa3e048f5f67fe396bc08af7606426d9bd7b5d React-Mapbuffer: bf56147c9775491e53122a94c423ac201417e326 react-native-safe-area-context: 4532f1a0c5d34a46b9324ccaaedcb5582a302b7d - react-native-smile-id: 51ea0d04401552e49a59558ca6eb1b199cc3f16d + react-native-smile-id: 2c6c6c6f5c42b74964c94ea84a91302508ca6526 React-nativeconfig: 9f223cd321823afdecf59ed00861ab2d69ee0fc1 React-NativeModulesApple: ff7efaff7098639db5631236cfd91d60abff04c0 React-perflogger: 32ed45d9cee02cf6639acae34251590dccd30994 diff --git a/package.json b/package.json index e15adae..0bfba8e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@smile_identity/react-native", - "version": "10.2.2", + "version": "10.2.3", "description": "Official wrapper for the Smile ID Date: Tue, 21 Jan 2025 14:50:54 +0200 Subject: [PATCH 04/12] feat: config init --- android/gradle.properties | 2 +- .../java/com/smileidentity/react/Mapper.kt | 5 ++-- .../react/views/SmileIDBiometricKYCView.kt | 4 ++-- .../react/views/SmileIDDocumentCaptureView.kt | 9 ++++++++ .../views/SmileIDDocumentVerificationView.kt | 6 ++--- ...SmileIDEnhancedDocumentVerificationView.kt | 8 +++---- .../SmileIDSmartSelfieAuthenticationView.kt | 2 -- .../views/SmileIDSmartSelfieEnrollmentView.kt | 2 -- example/ios/Podfile.lock | 10 ++++---- example/src/HomeScreen.tsx | 23 ++++++++++++++----- ios/View/SmileIDSmartSelfieAuthView.swift | 1 - ios/View/SmileIDSmartSelfieCaptureView.swift | 4 ++-- react-native-smile-id.podspec | 2 +- src/index.tsx | 1 + 14 files changed, 45 insertions(+), 34 deletions(-) diff --git a/android/gradle.properties b/android/gradle.properties index 60bccda..512e7cc 100644 --- a/android/gradle.properties +++ b/android/gradle.properties @@ -3,5 +3,5 @@ SmileId_minSdkVersion=21 SmileId_targetSdkVersion=34 SmileId_compileSdkVersion=34 SmileId_ndkversion=21.4.7075529 -SmileId_androidVersion=10.3.7 +SmileId_androidVersion=10.4.2 SmileId_kotlinCompilerExtensionVersion=1.5.11 diff --git a/android/src/main/java/com/smileidentity/react/Mapper.kt b/android/src/main/java/com/smileidentity/react/Mapper.kt index 02580e2..706f61f 100644 --- a/android/src/main/java/com/smileidentity/react/Mapper.kt +++ b/android/src/main/java/com/smileidentity/react/Mapper.kt @@ -3,7 +3,6 @@ package com.smileidentity.react import com.facebook.react.bridge.ReadableMap import com.smileidentity.models.AuthenticationRequest import com.smileidentity.models.Config -import com.smileidentity.models.ConsentInfo import com.smileidentity.models.EnhancedKycRequest import com.smileidentity.models.IdInfo import com.smileidentity.models.ImageType @@ -31,10 +30,10 @@ fun ReadableMap.toConfig(): Config { authToken = getStringOrDefault("authToken") ?: run { throw IllegalArgumentException("authToken is required") }, - prodBaseUrl = getStringOrDefault("prodBaseUrl") ?: run { + prodLambdaUrl = getStringOrDefault("prodLambdaUrl") ?: run { throw IllegalArgumentException("prodBaseUrl is required") }, - sandboxBaseUrl = getStringOrDefault("sandboxBaseUrl") ?: run { + testLambdaUrl = getStringOrDefault("testLambdaUrl") ?: run { throw IllegalArgumentException("sandboxBaseUrl is required") }, ) diff --git a/android/src/main/java/com/smileidentity/react/views/SmileIDBiometricKYCView.kt b/android/src/main/java/com/smileidentity/react/views/SmileIDBiometricKYCView.kt index a86522c..6496342 100644 --- a/android/src/main/java/com/smileidentity/react/views/SmileIDBiometricKYCView.kt +++ b/android/src/main/java/com/smileidentity/react/views/SmileIDBiometricKYCView.kt @@ -31,8 +31,8 @@ class SmileIDBiometricKYCView(context: ReactApplicationContext) : SmileIDView(co jobId = jobId ?: rememberSaveable { randomJobId() }, allowAgentMode = allowAgentMode ?: false, allowNewEnroll = allowNewEnroll ?: false, - showAttribution = showAttribution ?: true, - showInstructions = showInstructions ?: true, + showAttribution = showAttribution, + showInstructions = showInstructions, extraPartnerParams = extraPartnerParams, ) { res -> when (res) { diff --git a/android/src/main/java/com/smileidentity/react/views/SmileIDDocumentCaptureView.kt b/android/src/main/java/com/smileidentity/react/views/SmileIDDocumentCaptureView.kt index 5fe826a..40a4847 100644 --- a/android/src/main/java/com/smileidentity/react/views/SmileIDDocumentCaptureView.kt +++ b/android/src/main/java/com/smileidentity/react/views/SmileIDDocumentCaptureView.kt @@ -65,10 +65,19 @@ class SmileIDDocumentCaptureView(context: ReactApplicationContext) : SmileIDView DocumentCaptureScreen( jobId = jobId, side = if (front) DocumentCaptureSide.Front else DocumentCaptureSide.Back, + showInstructions = showInstructions, + showAttribution = showAttribution, + allowGallerySelection = allowGalleryUpload, + showConfirmation = showConfirmation, + showSkipButton = false, + instructionsHeroImage = hero, + instructionsTitleText = stringResource(instructionTitle), + instructionsSubtitleText = stringResource(instructionSubTitle), captureTitleText = stringResource(captureTitleText), knownIdAspectRatio = idAspectRatio, onConfirm = { file -> handleConfirmation(file) }, onError = { throwable -> emitFailure(throwable) }, + onSkip = { } ) } diff --git a/android/src/main/java/com/smileidentity/react/views/SmileIDDocumentVerificationView.kt b/android/src/main/java/com/smileidentity/react/views/SmileIDDocumentVerificationView.kt index 45d17dc..b9ac81e 100644 --- a/android/src/main/java/com/smileidentity/react/views/SmileIDDocumentVerificationView.kt +++ b/android/src/main/java/com/smileidentity/react/views/SmileIDDocumentVerificationView.kt @@ -11,7 +11,6 @@ import com.smileidentity.react.utils.DocumentCaptureResultAdapter import com.smileidentity.results.SmileIDResult import com.smileidentity.util.randomJobId import com.smileidentity.util.randomUserId -import kotlinx.collections.immutable.toImmutableMap import java.io.File class SmileIDDocumentVerificationView(context: ReactApplicationContext) : SmileIDView(context) { @@ -41,13 +40,12 @@ class SmileIDDocumentVerificationView(context: ReactApplicationContext) : SmileI countryCode = countryCode!!, documentType = documentType, idAspectRatio = idAspectRatio, - showAttribution = showAttribution ?: true, + showAttribution = showAttribution, allowAgentMode = allowAgentMode ?: false, - showInstructions = showInstructions ?: true, + showInstructions = showInstructions, allowGalleryUpload = allowGalleryUpload, captureBothSides = captureBothSides, allowNewEnroll = allowNewEnroll ?: false, - skipApiSubmission = skipApiSubmission, bypassSelfieCaptureWithFile = bypassSelfieCaptureWithFile, extraPartnerParams = extraPartnerParams, ) { res -> diff --git a/android/src/main/java/com/smileidentity/react/views/SmileIDEnhancedDocumentVerificationView.kt b/android/src/main/java/com/smileidentity/react/views/SmileIDEnhancedDocumentVerificationView.kt index 6d778fd..a430562 100644 --- a/android/src/main/java/com/smileidentity/react/views/SmileIDEnhancedDocumentVerificationView.kt +++ b/android/src/main/java/com/smileidentity/react/views/SmileIDEnhancedDocumentVerificationView.kt @@ -11,7 +11,6 @@ import com.smileidentity.react.utils.DocumentCaptureResultAdapter import com.smileidentity.results.SmileIDResult import com.smileidentity.util.randomJobId import com.smileidentity.util.randomUserId -import kotlinx.collections.immutable.toImmutableMap class SmileIDEnhancedDocumentVerificationView(context: ReactApplicationContext) : SmileIDView(context) { @@ -24,7 +23,7 @@ class SmileIDEnhancedDocumentVerificationView(context: ReactApplicationContext) override fun renderContent() { countryCode ?: run { emitFailure(IllegalArgumentException("countryCode is required for DocumentVerification")) - return; + return } composeView.apply { @@ -37,13 +36,12 @@ class SmileIDEnhancedDocumentVerificationView(context: ReactApplicationContext) countryCode = countryCode!!, documentType = documentType, idAspectRatio = idAspectRatio, - showAttribution = showAttribution ?: true, + showAttribution = showAttribution, allowAgentMode = allowAgentMode ?: false, - showInstructions = showInstructions ?: true, + showInstructions = showInstructions, allowNewEnroll = allowNewEnroll ?: false, allowGalleryUpload = allowGalleryUpload, captureBothSides = captureBothSides, - skipApiSubmission = skipApiSubmission, extraPartnerParams = extraPartnerParams, ) { res -> when (res) { diff --git a/android/src/main/java/com/smileidentity/react/views/SmileIDSmartSelfieAuthenticationView.kt b/android/src/main/java/com/smileidentity/react/views/SmileIDSmartSelfieAuthenticationView.kt index 539aa3f..379e0c4 100644 --- a/android/src/main/java/com/smileidentity/react/views/SmileIDSmartSelfieAuthenticationView.kt +++ b/android/src/main/java/com/smileidentity/react/views/SmileIDSmartSelfieAuthenticationView.kt @@ -10,7 +10,6 @@ import com.smileidentity.react.results.SmartSelfieCaptureResult import com.smileidentity.react.utils.SelfieCaptureResultAdapter import com.smileidentity.results.SmileIDResult import com.smileidentity.util.randomUserId -import kotlinx.collections.immutable.toImmutableMap class SmileIDSmartSelfieAuthenticationView(context: ReactApplicationContext) : SmileIDView(context) { @@ -26,7 +25,6 @@ class SmileIDSmartSelfieAuthenticationView(context: ReactApplicationContext) : allowNewEnroll = allowNewEnroll ?: false, showAttribution = showAttribution, showInstructions = showInstructions, - skipApiSubmission = skipApiSubmission, extraPartnerParams = extraPartnerParams, ) { res -> when (res) { diff --git a/android/src/main/java/com/smileidentity/react/views/SmileIDSmartSelfieEnrollmentView.kt b/android/src/main/java/com/smileidentity/react/views/SmileIDSmartSelfieEnrollmentView.kt index ebca2e4..f262d17 100644 --- a/android/src/main/java/com/smileidentity/react/views/SmileIDSmartSelfieEnrollmentView.kt +++ b/android/src/main/java/com/smileidentity/react/views/SmileIDSmartSelfieEnrollmentView.kt @@ -10,7 +10,6 @@ import com.smileidentity.react.results.SmartSelfieCaptureResult import com.smileidentity.react.utils.SelfieCaptureResultAdapter import com.smileidentity.results.SmileIDResult import com.smileidentity.util.randomUserId -import kotlinx.collections.immutable.toImmutableMap class SmileIDSmartSelfieEnrollmentView(context: ReactApplicationContext) : SmileIDView(context) { @@ -25,7 +24,6 @@ class SmileIDSmartSelfieEnrollmentView(context: ReactApplicationContext) : Smile allowNewEnroll = allowNewEnroll ?: false, showAttribution = showAttribution, showInstructions = showInstructions, - skipApiSubmission = skipApiSubmission, extraPartnerParams = extraPartnerParams, ) { res -> when (res) { diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index 09f0bca..100be37 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -963,7 +963,7 @@ PODS: - React-utils - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - - SmileID (= 10.2.17) + - SmileID (= 10.3.4) - Yoga - React-nativeconfig (0.74.2) - React-NativeModulesApple (0.74.2): @@ -1216,7 +1216,7 @@ PODS: - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - Yoga - - SmileID (10.2.17): + - SmileID (10.3.4): - FingerprintJS - lottie-ios (~> 4.4.2) - ZIPFoundation (~> 0.9) @@ -1444,7 +1444,7 @@ SPEC CHECKSUMS: React-logger: 29fa3e048f5f67fe396bc08af7606426d9bd7b5d React-Mapbuffer: bf56147c9775491e53122a94c423ac201417e326 react-native-safe-area-context: 4532f1a0c5d34a46b9324ccaaedcb5582a302b7d - react-native-smile-id: 2c6c6c6f5c42b74964c94ea84a91302508ca6526 + react-native-smile-id: 4af654d275ef792fea957ed0d0bfbbbf1b014728 React-nativeconfig: 9f223cd321823afdecf59ed00861ab2d69ee0fc1 React-NativeModulesApple: ff7efaff7098639db5631236cfd91d60abff04c0 React-perflogger: 32ed45d9cee02cf6639acae34251590dccd30994 @@ -1469,11 +1469,11 @@ SPEC CHECKSUMS: React-utils: 4476b7fcbbd95cfd002f3e778616155241d86e31 ReactCommon: ecad995f26e0d1e24061f60f4e5d74782f003f12 RNScreens: 48bc9eba07f93971071a5268b4fe5fcb784a5ef8 - SmileID: 44fef36001a02aa7362368e8a3f1127c03751166 + SmileID: 5a7c0437b9861b76d37a18e2f3d2f5a7b3056310 SocketRocket: abac6f5de4d4d62d24e11868d7a2f427e0ef940d Yoga: ae3c32c514802d30f687a04a6a35b348506d411f ZIPFoundation: b8c29ea7ae353b309bc810586181fd073cb3312c PODFILE CHECKSUM: 92128f18619da6c6e525b6e782e26be40527bc29 -COCOAPODS: 1.15.2 +COCOAPODS: 1.16.2 diff --git a/example/src/HomeScreen.tsx b/example/src/HomeScreen.tsx index 816870a..b895ee2 100644 --- a/example/src/HomeScreen.tsx +++ b/example/src/HomeScreen.tsx @@ -1,12 +1,13 @@ import * as React from 'react'; import { FlatList, Platform, StyleSheet, Text, View } from 'react-native'; -import type { - BiometricKYCRequest, - ConsentRequest, - DocumentVerificationRequest, - SmartSelfieAuthenticationRequest, - SmartSelfieEnrollmentRequest, +import { + // Config, import for config + type BiometricKYCRequest, + type ConsentRequest, + type DocumentVerificationRequest, + type SmartSelfieAuthenticationRequest, + type SmartSelfieEnrollmentRequest, } from '@smile_identity/react-native'; import { SmileID } from '@smile_identity/react-native'; @@ -90,6 +91,16 @@ export const HomeScreen = ({ navigation }: { navigation: any }) => { useEffect(() => { SmileID.initialize(false); + // const config = new Config( + // 'PARTNER ID', + // 'AUTH KEY', + // 'https://api.smileidentity.com/v1/', + // 'https://api.smileidentity.com/v1/' + // ); + //with api key + // SmileID.initializeWithApiKey('YOUR API KEY', config, false, false); + //with the config + // SmileID.initializeWithConfig(config, false, false); SmileID.disableCrashReporting(); setUserId(generateUuid('user_')); setJobId(generateUuid('job_')); diff --git a/ios/View/SmileIDSmartSelfieAuthView.swift b/ios/View/SmileIDSmartSelfieAuthView.swift index 7abaa1b..1a63c54 100644 --- a/ios/View/SmileIDSmartSelfieAuthView.swift +++ b/ios/View/SmileIDSmartSelfieAuthView.swift @@ -13,7 +13,6 @@ struct SmileIDSmartSelfieAuthView: View,SmileIDFileUtilsProtocol { allowAgentMode: product.allowAgentMode, showAttribution: product.showAttribution, showInstructions: product.showInstructions, - skipApiSubmission: product.skipApiSubmission, extraPartnerParams: product.extraPartnerParams as [String: String], delegate: self ) diff --git a/ios/View/SmileIDSmartSelfieCaptureView.swift b/ios/View/SmileIDSmartSelfieCaptureView.swift index 166d38e..32dce31 100644 --- a/ios/View/SmileIDSmartSelfieCaptureView.swift +++ b/ios/View/SmileIDSmartSelfieCaptureView.swift @@ -39,8 +39,8 @@ struct SmileIDSmartSelfieCaptureView: View, SmileIDFileUtilsProtocol { } } else { SelfieCaptureScreen( - allowAgentMode: self.product.allowAgentMode, - viewModel: viewModel + viewModel: viewModel, + allowAgentMode: self.product.allowAgentMode ).preferredColorScheme(.light) } } diff --git a/react-native-smile-id.podspec b/react-native-smile-id.podspec index ff87523..d5fe009 100644 --- a/react-native-smile-id.podspec +++ b/react-native-smile-id.podspec @@ -15,7 +15,7 @@ Pod::Spec.new do |s| s.source = { :git => "https://docs.usesmileid.com/.git", :tag => "#{s.version}" } s.source_files = "ios/**/*.{h,m,mm,swift}" - s.dependency "SmileID", "10.2.17" + s.dependency "SmileID", "10.3.4" # Use install_modules_dependencies helper to install the dependencies if React Native version >=0.71.0. # See https://github.com/facebook/react-native/blob/febf6b7f33fdb4904669f99d795eba4c0f95d7bf/scripts/cocoapods/new_architecture.rb#L79. diff --git a/src/index.tsx b/src/index.tsx index 20160c5..b599503 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -280,6 +280,7 @@ export { //module SmileID, //views + Config, SmileIDSmartSelfieEnrollmentView, SmileIDSmartSelfieAuthenticationView, SmileIDDocumentVerificationView, From 6c6460907fcc83edcb94089141d7029505883c2b Mon Sep 17 00:00:00 2001 From: JNdhlovu Date: Tue, 21 Jan 2025 15:06:04 +0200 Subject: [PATCH 05/12] feat: document capture navigation --- example/src/HomeScreen.tsx | 29 ++++++++++++++++++++--------- src/SmileIDDocumentCaptureView.tsx | 8 ++++---- 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/example/src/HomeScreen.tsx b/example/src/HomeScreen.tsx index b895ee2..950bb2b 100644 --- a/example/src/HomeScreen.tsx +++ b/example/src/HomeScreen.tsx @@ -4,6 +4,7 @@ import { FlatList, Platform, StyleSheet, Text, View } from 'react-native'; import { // Config, import for config type BiometricKYCRequest, + Config, type ConsentRequest, type DocumentVerificationRequest, type SmartSelfieAuthenticationRequest, @@ -51,8 +52,13 @@ export const HomeScreen = ({ navigation }: { navigation: any }) => { ...defaultProductRef.current, }); const [documentCapture, setDocumentCapture] = - useState({ + useState({ ...defaultProductRef.current, + countryCode: 'ZW', + documentType: 'PASSPORT', + isDocumentFrontSide: false, + captureBothSides: false, + allowGalleryUpload: false, }); const [smartSelfieAuthentication, setSmartSelfieAuthentication] = useState({ @@ -90,15 +96,15 @@ export const HomeScreen = ({ navigation }: { navigation: any }) => { const [smileProducts, setSmileProducts] = useState>([]); useEffect(() => { - SmileID.initialize(false); - // const config = new Config( - // 'PARTNER ID', - // 'AUTH KEY', - // 'https://api.smileidentity.com/v1/', - // 'https://api.smileidentity.com/v1/' - // ); + // SmileID.initialize(false); + const config = new Config( + 'PARTNER ID', + 'AUTH KEY', + 'https://api.smileidentity.com/v1/', + 'https://api.smileidentity.com/v1/' + ); //with api key - // SmileID.initializeWithApiKey('YOUR API KEY', config, false, false); + SmileID.initializeWithApiKey('YOUR API KEY', config, false, false); //with the config // SmileID.initializeWithConfig(config, false, false); SmileID.disableCrashReporting(); @@ -127,6 +133,11 @@ export const HomeScreen = ({ navigation }: { navigation: any }) => { setDocumentCapture({ ...defaultProductRef.current, + countryCode: 'ZW', + documentType: 'PASSPORT', + isDocumentFrontSide: false, + captureBothSides: false, + allowGalleryUpload: false, }); setSmartSelfieEnrollment({ diff --git a/src/SmileIDDocumentCaptureView.tsx b/src/SmileIDDocumentCaptureView.tsx index 53ec90f..c52bb99 100644 --- a/src/SmileIDDocumentCaptureView.tsx +++ b/src/SmileIDDocumentCaptureView.tsx @@ -2,14 +2,14 @@ import React, { Component } from 'react'; import type { HostComponent } from 'react-native'; import { UIManager, findNodeHandle, Platform } from 'react-native'; import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent'; -import type { SmartSelfieEnrollmentRequest } from './index'; +import type { DocumentVerificationRequest } from './index'; const SmileIDDocumentCaptureComponent = - codegenNativeComponent( + codegenNativeComponent( 'SmileIDDocumentCaptureView' - ) as HostComponent; + ) as HostComponent; -export default class SmileIDDocumentCaptureView extends Component { +export default class SmileIDDocumentCaptureView extends Component { private viewRef = React.createRef(); // componentDidMount() { From 74fe3861470c461124077b1b18ff04a97c8eb9e1 Mon Sep 17 00:00:00 2001 From: JNdhlovu Date: Tue, 21 Jan 2025 15:07:01 +0200 Subject: [PATCH 06/12] feat: update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7eafd93..8a9ac9c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## 10.2.3 * Exposed `initializeWithApiKey` missing for initializing using the api key * Exposed `initializeWithConfig` missing for initializing using the config json +* Fix document capture restore optional parameters and showing or hiding instruction and confirmation screen ## 10.2.2 * Fixed setting `kotlinVersion` and `kotlinCompilerExtensionVersion` From 44b20debe6871bb76e6a7012e5cfe6f673849d1a Mon Sep 17 00:00:00 2001 From: JNdhlovu Date: Tue, 21 Jan 2025 15:08:17 +0200 Subject: [PATCH 07/12] feat: update changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8a9ac9c..86392b1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ * Exposed `initializeWithApiKey` missing for initializing using the api key * Exposed `initializeWithConfig` missing for initializing using the config json * Fix document capture restore optional parameters and showing or hiding instruction and confirmation screen +* Bump android to 10.4.2 (https://github.com/smileidentity/android/releases/tag/v10.4.2) +* Bump iOS to 10.3.4 (https://github.com/smileidentity/ios/releases/tag/v10.3.4) ## 10.2.2 * Fixed setting `kotlinVersion` and `kotlinCompilerExtensionVersion` From d98dac1d5b538658c78051c1d6747c7694f7cb0c Mon Sep 17 00:00:00 2001 From: JNdhlovu Date: Wed, 22 Jan 2025 03:41:15 +0200 Subject: [PATCH 08/12] feat: update changelog and document initialize on home screen --- CHANGELOG.md | 4 ++-- example/src/HomeScreen.tsx | 12 ++++++++---- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 86392b1..ab70e36 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,8 @@ # Release Notes ## 10.2.3 -* Exposed `initializeWithApiKey` missing for initializing using the api key -* Exposed `initializeWithConfig` missing for initializing using the config json +* Exposed `initializeWithApiKey` missing for initializing using the api key see (https://docs.usesmileid.com/integration-options/mobile/getting-started) +* Exposed `initializeWithConfig` missing for initializing using the config json see (https://docs.usesmileid.com/integration-options/mobile/getting-started) * Fix document capture restore optional parameters and showing or hiding instruction and confirmation screen * Bump android to 10.4.2 (https://github.com/smileidentity/android/releases/tag/v10.4.2) * Bump iOS to 10.3.4 (https://github.com/smileidentity/ios/releases/tag/v10.3.4) diff --git a/example/src/HomeScreen.tsx b/example/src/HomeScreen.tsx index 950bb2b..f421147 100644 --- a/example/src/HomeScreen.tsx +++ b/example/src/HomeScreen.tsx @@ -2,7 +2,6 @@ import * as React from 'react'; import { FlatList, Platform, StyleSheet, Text, View } from 'react-native'; import { - // Config, import for config type BiometricKYCRequest, Config, type ConsentRequest, @@ -96,17 +95,22 @@ export const HomeScreen = ({ navigation }: { navigation: any }) => { const [smileProducts, setSmileProducts] = useState>([]); useEffect(() => { - // SmileID.initialize(false); const config = new Config( 'PARTNER ID', 'AUTH KEY', 'https://api.smileidentity.com/v1/', 'https://api.smileidentity.com/v1/' ); + /* + SmileID initialisation can be done in three ways + see https://docs.usesmileid.com/integration-options/mobile/getting-started for more details + */ + //with the config + // 1. SmileID.initializeWithConfig(config, false, false); + //with smile_onfig.json + // 2. SmileID.initialize(false); //with api key SmileID.initializeWithApiKey('YOUR API KEY', config, false, false); - //with the config - // SmileID.initializeWithConfig(config, false, false); SmileID.disableCrashReporting(); setUserId(generateUuid('user_')); setJobId(generateUuid('job_')); From 3be9a9e42beb49090da5a3fc73b41525ba4fce21 Mon Sep 17 00:00:00 2001 From: JNdhlovu Date: Thu, 23 Jan 2025 12:48:26 +0200 Subject: [PATCH 09/12] feat: initialize overloading --- CHANGELOG.md | 3 +- .../com/smileidentity/react/SmileIdModule.kt | 76 +++++++++---------- android/src/oldarch/SmileIdSpec.kt | 15 +--- ...kotlin-compiler-8651868944069913620.salive | 0 example/src/HomeScreen.tsx | 18 +---- ios/RNSmileID.mm | 9 ++- ios/RNSmileID.swift | 67 ++++++++-------- src/NativeSmileId.ts | 24 +++--- src/index.tsx | 32 +++----- 9 files changed, 101 insertions(+), 143 deletions(-) create mode 100644 example/android/.kotlin/sessions/kotlin-compiler-8651868944069913620.salive diff --git a/CHANGELOG.md b/CHANGELOG.md index ab70e36..99a9a43 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,7 @@ # Release Notes ## 10.2.3 -* Exposed `initializeWithApiKey` missing for initializing using the api key see (https://docs.usesmileid.com/integration-options/mobile/getting-started) -* Exposed `initializeWithConfig` missing for initializing using the config json see (https://docs.usesmileid.com/integration-options/mobile/getting-started) +* Added `apiKey` and `config` missing to allow multiple initialization options see (https://docs.usesmileid.com/integration-options/mobile/getting-started) * Fix document capture restore optional parameters and showing or hiding instruction and confirmation screen * Bump android to 10.4.2 (https://github.com/smileidentity/android/releases/tag/v10.4.2) * Bump iOS to 10.3.4 (https://github.com/smileidentity/ios/releases/tag/v10.3.4) diff --git a/android/src/main/java/com/smileidentity/react/SmileIdModule.kt b/android/src/main/java/com/smileidentity/react/SmileIdModule.kt index 2582663..431239a 100644 --- a/android/src/main/java/com/smileidentity/react/SmileIdModule.kt +++ b/android/src/main/java/com/smileidentity/react/SmileIdModule.kt @@ -1,6 +1,5 @@ package com.smileidentity.react -import android.util.Log import com.facebook.react.bridge.Arguments import com.facebook.react.bridge.Promise import com.facebook.react.bridge.ReactApplicationContext @@ -15,7 +14,6 @@ import com.smileidentity.models.BiometricKycJobStatusResponse import com.smileidentity.models.DocumentVerificationJobStatusResponse import com.smileidentity.models.EnhancedDocumentVerificationJobStatusResponse import com.smileidentity.models.EnhancedKycAsyncResponse -import com.smileidentity.models.EnhancedKycRequest import com.smileidentity.models.EnhancedKycResponse import com.smileidentity.models.PrepUploadResponse import com.smileidentity.models.ProductsConfigResponse @@ -27,18 +25,15 @@ import com.smileidentity.networking.pollDocumentVerificationJobStatus import com.smileidentity.networking.pollEnhancedDocumentVerificationJobStatus import com.smileidentity.networking.pollSmartSelfieJobStatus import com.smileidentity.react.utils.getIntOrDefault -import com.smileidentity.react.utils.getStringOrDefault -import com.smileidentity.results.SmartSelfieResult -import java.net.URL import kotlinx.coroutines.CoroutineExceptionHandler import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.last import kotlinx.coroutines.flow.map -import kotlinx.coroutines.flow.single import kotlinx.coroutines.launch import kotlinx.coroutines.withContext +import java.net.URL import kotlin.time.Duration import kotlin.time.Duration.Companion.milliseconds @@ -49,45 +44,48 @@ class SmileIdModule internal constructor( override fun getName(): String = NAME @ReactMethod - override fun initializeWithApiKey( - apiKey: String, - config: ReadableMap, - useSandBox: Boolean, - enableCrashReporting: Boolean, - promise: Promise - ) { - SmileID.initialize( - context = reactApplicationContext, - apiKey = apiKey, - config = config.toConfig(), - useSandbox = useSandBox, - enableCrashReporting = enableCrashReporting - ) - promise.resolve(null) - } - - @ReactMethod - override fun initializeWithConfig( - config: ReadableMap, + override fun initialize( useSandBox: Boolean, + apiKey: String?, + config: ReadableMap?, enableCrashReporting: Boolean, promise: Promise ) { - SmileID.initialize( - context = reactApplicationContext, - config = config.toConfig(), - useSandbox = useSandBox, - enableCrashReporting = enableCrashReporting - ) - promise.resolve(null) + try { + when { + // Case 1: Initialize with API key and config + apiKey != null && config != null -> { + SmileID.initialize( + context = reactApplicationContext, + apiKey = apiKey, + config = config.toConfig(), + useSandbox = useSandBox, + enableCrashReporting = enableCrashReporting + ) + } + // Case 2: Initialize with just config + config != null -> { + SmileID.initialize( + context = reactApplicationContext, + config = config.toConfig(), + useSandbox = useSandBox, + enableCrashReporting = enableCrashReporting + ) + } + // Case 3: Basic initialization + else -> { + SmileID.initialize( + context = reactApplicationContext, + useSandbox = useSandBox + ) + } + } + promise.resolve(null) + } catch (e: Exception) { + promise.reject("INITIALIZE_ERROR", e.message, e) + } } - @ReactMethod - override fun initialize(useSandBox: Boolean, promise: Promise) { - SmileID.initialize(context = reactApplicationContext, useSandbox = useSandBox) - promise.resolve(null) - } - @ReactMethod override fun setCallbackUrl(callbackUrl: String, promise: Promise) { SmileID.setCallbackUrl(callbackUrl = URL(callbackUrl)) diff --git a/android/src/oldarch/SmileIdSpec.kt b/android/src/oldarch/SmileIdSpec.kt index 3d44d91..b627532 100644 --- a/android/src/oldarch/SmileIdSpec.kt +++ b/android/src/oldarch/SmileIdSpec.kt @@ -8,23 +8,14 @@ import com.facebook.react.bridge.ReadableMap abstract class SmileIdSpec internal constructor(context: ReactApplicationContext) : ReactContextBaseJavaModule(context) { - abstract fun initializeWithApiKey( - apiKey: String, - config: ReadableMap, + abstract fun initialize( useSandBox: Boolean, + apiKey: String?, + config: ReadableMap?, enableCrashReporting: Boolean, promise: Promise ) - abstract fun initializeWithConfig( - config: ReadableMap, - useSandBox: Boolean, - enableCrashReporting: Boolean, - promise: Promise - ) - - abstract fun initialize(useSandBox: Boolean, promise: Promise) - abstract fun setCallbackUrl(callbackUrl: String, promise: Promise) abstract fun setAllowOfflineMode(allowOfflineMode: Boolean ,promise: Promise) diff --git a/example/android/.kotlin/sessions/kotlin-compiler-8651868944069913620.salive b/example/android/.kotlin/sessions/kotlin-compiler-8651868944069913620.salive new file mode 100644 index 0000000..e69de29 diff --git a/example/src/HomeScreen.tsx b/example/src/HomeScreen.tsx index f421147..3ad6959 100644 --- a/example/src/HomeScreen.tsx +++ b/example/src/HomeScreen.tsx @@ -3,7 +3,6 @@ import * as React from 'react'; import { FlatList, Platform, StyleSheet, Text, View } from 'react-native'; import { type BiometricKYCRequest, - Config, type ConsentRequest, type DocumentVerificationRequest, type SmartSelfieAuthenticationRequest, @@ -95,22 +94,11 @@ export const HomeScreen = ({ navigation }: { navigation: any }) => { const [smileProducts, setSmileProducts] = useState>([]); useEffect(() => { - const config = new Config( - 'PARTNER ID', - 'AUTH KEY', - 'https://api.smileidentity.com/v1/', - 'https://api.smileidentity.com/v1/' - ); /* - SmileID initialisation can be done in three ways + SmileID initialisation can be done in multiple ways see https://docs.usesmileid.com/integration-options/mobile/getting-started for more details - */ - //with the config - // 1. SmileID.initializeWithConfig(config, false, false); - //with smile_onfig.json - // 2. SmileID.initialize(false); - //with api key - SmileID.initializeWithApiKey('YOUR API KEY', config, false, false); + */ + SmileID.initialize(false); SmileID.disableCrashReporting(); setUserId(generateUuid('user_')); setJobId(generateUuid('job_')); diff --git a/ios/RNSmileID.mm b/ios/RNSmileID.mm index d9f573e..7cd894e 100644 --- a/ios/RNSmileID.mm +++ b/ios/RNSmileID.mm @@ -1,9 +1,12 @@ #import @interface RCT_EXTERN_MODULE(RNSmileID, NSObject) -RCT_EXTERN_METHOD(initializeWithApiKey:(NSString *)apiKey config:(NSDictionary *)config useSandBox:(BOOL)useSandBox enableCrashReporting:(BOOL)enableCrashReporting withResolver:(RCTPromiseResolveBlock)resolve withRejecter:(RCTPromiseRejectBlock)reject) -RCT_EXTERN_METHOD(initializeWithConfig:(NSDictionary *)config useSandBox:(BOOL)useSandBox enableCrashReporting:(BOOL)enableCrashReporting withResolver:(RCTPromiseResolveBlock)resolve withRejecter:(RCTPromiseRejectBlock)reject) -RCT_EXTERN_METHOD(initialize:(BOOL)useSandBox withResolver:(RCTPromiseResolveBlock)resolve withRejecter:(RCTPromiseRejectBlock)reject) +RCT_EXTERN_METHOD(initialize:(BOOL)useSandBox + apiKey:(nullable NSString *)apiKey + config:(nullable NSDictionary *)config + enableCrashReporting:(BOOL)enableCrashReporting + withResolver:(RCTPromiseResolveBlock)resolve + withRejecter:(RCTPromiseRejectBlock)reject) RCT_EXTERN_METHOD(setCallbackUrl:(NSString)callbackUrl withResolver:(RCTPromiseResolveBlock)resolve withRejecter:(RCTPromiseRejectBlock)reject) RCT_EXTERN_METHOD(setAllowOfflineMode:(BOOL)allowOfflineMode withResolver:(RCTPromiseResolveBlock)resolve withRejecter:(RCTPromiseRejectBlock)reject) RCT_EXTERN_METHOD(submitJob:(NSString *)jobId withResolver:(RCTPromiseResolveBlock)resolve withRejecter:(RCTPromiseRejectBlock)reject) diff --git a/ios/RNSmileID.swift b/ios/RNSmileID.swift index 219a6c7..214f71c 100644 --- a/ios/RNSmileID.swift +++ b/ios/RNSmileID.swift @@ -2,43 +2,36 @@ import SmileID @objc(RNSmileID) class RNSmileID: NSObject { - @objc(initializeWithApiKey:config:useSandBox:enableCrashReporting:withResolver:withRejecter:) - func initializeWithApiKey( - apiKey: String, - config: NSDictionary, - useSandBox: Bool, - enableCrashReporting: Bool, - resolve: @escaping RCTPromiseResolveBlock, - reject: @escaping RCTPromiseRejectBlock - ) { - SmileID.initialize( - apiKey: apiKey, - config: config.toConfig(), - useSandbox: useSandBox - ) - resolve(nil) - } - - @objc(initializeWithConfig:useSandBox:enableCrashReporting:withResolver:withRejecter:) - func initializeWithConfig( - config: NSDictionary, - useSandBox: Bool, - enableCrashReporting: Bool, - resolve: @escaping RCTPromiseResolveBlock, - reject: @escaping RCTPromiseRejectBlock - ) { - SmileID.initialize( - config: config.toConfig(), - useSandbox: useSandBox - ) - resolve(nil) - } - - @objc(initialize:withResolver:withRejecter:) - func initialize(useSandBox: Bool, resolve: @escaping RCTPromiseResolveBlock, reject _: @escaping RCTPromiseRejectBlock) { - SmileID.initialize(useSandbox: useSandBox) - resolve(nil) - } + @objc(initialize:apiKey:config:enableCrashReporting:withResolver:withRejecter:) + func initialize( + useSandBox: Bool, + apiKey: String?, + config: NSDictionary?, + enableCrashReporting: Bool, + resolve: @escaping RCTPromiseResolveBlock, + reject: @escaping RCTPromiseRejectBlock + ) { + // Handle different initialization scenarios based on provided parameters + if let apiKey = apiKey, let config = config { + // Initialize with API key and config + SmileID.initialize( + apiKey: apiKey, + config: config.toConfig(), + useSandbox: useSandBox + ) + } else if let config = config { + // Initialize with just config + SmileID.initialize( + config: config.toConfig(), + useSandbox: useSandBox + ) + } else { + // Basic initialization with just sandbox flag + SmileID.initialize(useSandbox: useSandBox) + } + + resolve(nil) + } @objc(setCallbackUrl:withResolver:withRejecter:) func setCallbackUrl(callbackUrl: String, resolve: @escaping RCTPromiseResolveBlock, reject _: @escaping RCTPromiseRejectBlock) { diff --git a/src/NativeSmileId.ts b/src/NativeSmileId.ts index 23c505b..1670148 100644 --- a/src/NativeSmileId.ts +++ b/src/NativeSmileId.ts @@ -23,22 +23,18 @@ import { Config } from './types'; export interface Spec extends TurboModule { /** - * Initialise the Smile ID SDK + * Initialize SmileID SDK with configuration + * @param useSandBox - Configuration object for the SDK + * @param apiKey - api key specific to the partner and also environment + * @param config - Configuration object for the SDK + * @param enableCrashReporting - Whether to enable crash reporting */ - initializeWithApiKey: ( - apiKey: string, - config: Config, + initialize( useSandBox: boolean, - enableCrashReporting: boolean - ) => Promise; - - initializeWithConfig: ( - config: Config, - useSandBox: boolean, - enableCrashReporting: boolean - ) => Promise; - - initialize: (useSandBox: boolean) => Promise; + apiKey?: string, + config?: Config, + enableCrashReporting?: boolean + ): Promise; /** * The callback mechanism allows for asynchronous job requests and responses. diff --git a/src/index.tsx b/src/index.tsx index b599503..a733f63 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -65,28 +65,18 @@ const _SmileID: Spec = SmileIdModule const SmileID = { /** - * Initialise the Smile ID SDK + * Initialize SmileID SDK with configuration + * @param useSandBox - Configuration object for the SDK + * @param apiKey - api key specific to the partner and also environment + * @param config - Configuration object for the SDK + * @param enableCrashReporting - Whether to enable crash reporting */ - initialize: (useSandBox: boolean = false) => _SmileID.initialize(useSandBox), - - initializeWithApiKey: ( - apiKey: string, - config: Config, - useSandBox: boolean, - enableCrashReporting: boolean - ) => - _SmileID.initializeWithApiKey( - apiKey, - config, - useSandBox, - enableCrashReporting - ), - - initializeWithConfig: ( - config: Config, - useSandBox: boolean, - enableCrashReporting: boolean - ) => _SmileID.initializeWithConfig(config, useSandBox, enableCrashReporting), + initialize: ( + useSandBox: boolean = false, + apiKey?: string, + config?: Config, + enableCrashReporting?: boolean + ) => _SmileID.initialize(useSandBox, apiKey, config, enableCrashReporting), /** * Sets allow offline mode which enables From ba4aa852c7c02a9392c6c62656b47d870cab86a9 Mon Sep 17 00:00:00 2001 From: JNdhlovu Date: Thu, 23 Jan 2025 12:49:06 +0200 Subject: [PATCH 10/12] feat: remove .kotlin --- .../.kotlin/sessions/kotlin-compiler-8651868944069913620.salive | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 example/android/.kotlin/sessions/kotlin-compiler-8651868944069913620.salive diff --git a/example/android/.kotlin/sessions/kotlin-compiler-8651868944069913620.salive b/example/android/.kotlin/sessions/kotlin-compiler-8651868944069913620.salive deleted file mode 100644 index e69de29..0000000 From 72070bc86650c9c363e5b487ceb0acc7a8f88aa8 Mon Sep 17 00:00:00 2001 From: JNdhlovu Date: Thu, 23 Jan 2025 13:13:10 +0200 Subject: [PATCH 11/12] feat: reorder config to be first optional --- README.md | 32 ++++---------------------------- src/index.tsx | 4 ++-- 2 files changed, 6 insertions(+), 30 deletions(-) diff --git a/README.md b/README.md index 4584b77..0eb005d 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ Please see [CHANGELOG.md](CHANGELOG.md) or [Releases](https://github.com/smileid ## Getting Started -Full documentation is available at [Smile ID Documentation](https://docs.usesmileid.com/integration-options/mobile) +Full documentation is available at [Smile ID Documentation]((https://docs.usesmileid.com/integration-options/mobile/getting-started)) ### 0. Requirements @@ -44,36 +44,12 @@ Add the dependency to your `package.json`: } ``` -### 2. Smile Config -#### Android +### 2. Initialization -Place the `smile_config.json` file under your application's assets, located at `src/main/assets` (This should be at the same level as your `java` and `res` directories). You may need to create the directory if it does not already exist. +There are multiple ways to initialize the SDK. See [Initialization](https://docs.usesmileid.com/integration-options/mobile/getting-started) and choose the best option +for your integration -#### iOS - -Drag the `smile_config.json` into your project's file inspector and ensure that the file is added to your app's target. Confirm that it is by checking the Copy Bundle Resources drop down in the Build Phases tab as shown below. - -### 3. Initialization - -Initialize the Smile ID SDK in your app's entry file (normally `index.tsx`) by calling `initialize`: - -```typescript -import { initialize } from 'rn-smile-id'; -import React, { useEffect } from 'react'; - -const App = () => { - useEffect(() => { - initialize().then(() => console.log('Smile ID Initialized')); - }, []); - - return ( - // ...rest of your component - ); -}; - -export default App; -``` ## Getting Help diff --git a/src/index.tsx b/src/index.tsx index a733f63..e3378fa 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -67,14 +67,14 @@ const SmileID = { /** * Initialize SmileID SDK with configuration * @param useSandBox - Configuration object for the SDK - * @param apiKey - api key specific to the partner and also environment * @param config - Configuration object for the SDK + * @param apiKey - api key specific to the partner and also environment * @param enableCrashReporting - Whether to enable crash reporting */ initialize: ( useSandBox: boolean = false, - apiKey?: string, config?: Config, + apiKey?: string, enableCrashReporting?: boolean ) => _SmileID.initialize(useSandBox, apiKey, config, enableCrashReporting), From 87731d2f8f057e88a9ba36dba736c2bc98931d69 Mon Sep 17 00:00:00 2001 From: JNdhlovu Date: Fri, 24 Jan 2025 13:11:28 +0200 Subject: [PATCH 12/12] feat: rn initialization updates --- .../com/smileidentity/react/SmileIdModule.kt | 4 +- android/src/oldarch/SmileIdSpec.kt | 4 +- ios/RNSmileID.mm | 4 +- ios/RNSmileID.swift | 936 +++++++++--------- src/NativeSmileId.ts | 4 +- src/index.tsx | 6 +- 6 files changed, 479 insertions(+), 479 deletions(-) diff --git a/android/src/main/java/com/smileidentity/react/SmileIdModule.kt b/android/src/main/java/com/smileidentity/react/SmileIdModule.kt index 431239a..d601472 100644 --- a/android/src/main/java/com/smileidentity/react/SmileIdModule.kt +++ b/android/src/main/java/com/smileidentity/react/SmileIdModule.kt @@ -46,9 +46,9 @@ class SmileIdModule internal constructor( @ReactMethod override fun initialize( useSandBox: Boolean, - apiKey: String?, - config: ReadableMap?, enableCrashReporting: Boolean, + config: ReadableMap?, + apiKey: String?, promise: Promise ) { try { diff --git a/android/src/oldarch/SmileIdSpec.kt b/android/src/oldarch/SmileIdSpec.kt index b627532..0efcbcf 100644 --- a/android/src/oldarch/SmileIdSpec.kt +++ b/android/src/oldarch/SmileIdSpec.kt @@ -10,9 +10,9 @@ abstract class SmileIdSpec internal constructor(context: ReactApplicationContext abstract fun initialize( useSandBox: Boolean, - apiKey: String?, - config: ReadableMap?, enableCrashReporting: Boolean, + config: ReadableMap?, + apiKey: String?, promise: Promise ) diff --git a/ios/RNSmileID.mm b/ios/RNSmileID.mm index 7cd894e..1f60c2e 100644 --- a/ios/RNSmileID.mm +++ b/ios/RNSmileID.mm @@ -2,9 +2,9 @@ @interface RCT_EXTERN_MODULE(RNSmileID, NSObject) RCT_EXTERN_METHOD(initialize:(BOOL)useSandBox - apiKey:(nullable NSString *)apiKey - config:(nullable NSDictionary *)config enableCrashReporting:(BOOL)enableCrashReporting + config:(nullable NSDictionary *)config + apiKey:(nullable NSString *)apiKey withResolver:(RCTPromiseResolveBlock)resolve withRejecter:(RCTPromiseRejectBlock)reject) RCT_EXTERN_METHOD(setCallbackUrl:(NSString)callbackUrl withResolver:(RCTPromiseResolveBlock)resolve withRejecter:(RCTPromiseRejectBlock)reject) diff --git a/ios/RNSmileID.swift b/ios/RNSmileID.swift index 214f71c..df8e013 100644 --- a/ios/RNSmileID.swift +++ b/ios/RNSmileID.swift @@ -2,506 +2,506 @@ import SmileID @objc(RNSmileID) class RNSmileID: NSObject { - @objc(initialize:apiKey:config:enableCrashReporting:withResolver:withRejecter:) + @objc(initialize:enableCrashReporting:config:apiKey:withResolver:withRejecter:) func initialize( - useSandBox: Bool, - apiKey: String?, - config: NSDictionary?, - enableCrashReporting: Bool, - resolve: @escaping RCTPromiseResolveBlock, - reject: @escaping RCTPromiseRejectBlock + useSandBox: Bool, + enableCrashReporting: Bool, + config: NSDictionary?, + apiKey: String?, + resolve: @escaping RCTPromiseResolveBlock, + reject: @escaping RCTPromiseRejectBlock ) { - // Handle different initialization scenarios based on provided parameters - if let apiKey = apiKey, let config = config { - // Initialize with API key and config - SmileID.initialize( - apiKey: apiKey, - config: config.toConfig(), - useSandbox: useSandBox - ) - } else if let config = config { - // Initialize with just config - SmileID.initialize( - config: config.toConfig(), - useSandbox: useSandBox - ) - } else { - // Basic initialization with just sandbox flag - SmileID.initialize(useSandbox: useSandBox) - } - + // Handle different initialization scenarios based on provided parameters + if let apiKey = apiKey, let config = config { + // Initialize with API key and config + SmileID.initialize( + apiKey: apiKey, + config: config.toConfig(), + useSandbox: useSandBox + ) + } else if let config = config { + // Initialize with just config + SmileID.initialize( + config: config.toConfig(), + useSandbox: useSandBox + ) + } else { + // Basic initialization with just sandbox flag + SmileID.initialize(useSandbox: useSandBox) + } + + resolve(nil) + } + + @objc(setCallbackUrl:withResolver:withRejecter:) + func setCallbackUrl(callbackUrl: String, resolve: @escaping RCTPromiseResolveBlock, reject _: @escaping RCTPromiseRejectBlock) { + SmileID.setCallbackUrl(url: URL(string: callbackUrl)) + resolve(nil) + } + + @objc(setAllowOfflineMode:withResolver:withRejecter:) + func setAllowOfflineMode(allowOfflineMode: Bool, resolve: @escaping RCTPromiseResolveBlock, reject _: @escaping RCTPromiseRejectBlock) { + SmileID.setAllowOfflineMode(allowOfflineMode: allowOfflineMode) + resolve(nil) + } + + @objc(submitJob:withResolver:withRejecter:) + func submitJob(jobId: String, resolve: @escaping RCTPromiseResolveBlock, reject : @escaping RCTPromiseRejectBlock) { + do { + try SmileID.submitJob(jobId: jobId) resolve(nil) + } catch let error as NSError { + reject("Error", error.localizedDescription, error) + } } - - @objc(setCallbackUrl:withResolver:withRejecter:) - func setCallbackUrl(callbackUrl: String, resolve: @escaping RCTPromiseResolveBlock, reject _: @escaping RCTPromiseRejectBlock) { - SmileID.setCallbackUrl(url: URL(string: callbackUrl)) - resolve(nil) + + @objc(getSubmittedJobs:withRejecter:) + func getSubmittedJobs(resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) { + do { + let jobs: [String] = SmileID.getUnsubmittedJobs() + resolve(jobs) + } catch let error as NSError { + reject("Error", error.localizedDescription, error) } - - @objc(setAllowOfflineMode:withResolver:withRejecter:) - func setAllowOfflineMode(allowOfflineMode: Bool, resolve: @escaping RCTPromiseResolveBlock, reject _: @escaping RCTPromiseRejectBlock) { - SmileID.setAllowOfflineMode(allowOfflineMode: allowOfflineMode) - resolve(nil) + } + + @objc(getUnsubmittedJobs:withRejecter:) + func getUnsubmittedJobs(resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) { + do { + let jobs: [String] = SmileID.getUnsubmittedJobs() + resolve(jobs) + } catch let error as NSError { + reject("Error", error.localizedDescription, error) } - - @objc(submitJob:withResolver:withRejecter:) - func submitJob(jobId: String, resolve: @escaping RCTPromiseResolveBlock, reject : @escaping RCTPromiseRejectBlock) { - do { - try SmileID.submitJob(jobId: jobId) - resolve(nil) - } catch let error as NSError { - reject("Error", error.localizedDescription, error) - } + } + + @objc(cleanup:withResolver:withRejecter:) + func cleanup(jobId: String, resolve: @escaping RCTPromiseResolveBlock, reject : @escaping RCTPromiseRejectBlock) { + do { + try SmileID.cleanup(jobId: jobId) + resolve(nil) + } catch let error as NSError { + reject("Error", error.localizedDescription, error) } - - @objc(getSubmittedJobs:withRejecter:) - func getSubmittedJobs(resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) { - do { - let jobs: [String] = SmileID.getUnsubmittedJobs() - resolve(jobs) - } catch let error as NSError { - reject("Error", error.localizedDescription, error) - } + } + + @objc(authenticate:withResolver:withRejecter:) + func authenticate(request: NSDictionary, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) { + guard let authenticationRequest = request.toAuthenticationRequest() else { + reject("Error", "Invalid request data", nil) + return } - - @objc(getUnsubmittedJobs:withRejecter:) - func getUnsubmittedJobs(resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) { - do { - let jobs: [String] = SmileID.getUnsubmittedJobs() - resolve(jobs) - } catch let error as NSError { - reject("Error", error.localizedDescription, error) - } + + Task { + do { + let response = try await SmileID.api.authenticate(request: authenticationRequest) + self.resolveResponse(response, resolve: resolve, reject: reject) + } catch { + reject("Error", error.localizedDescription, error) + } } - - @objc(cleanup:withResolver:withRejecter:) - func cleanup(jobId: String, resolve: @escaping RCTPromiseResolveBlock, reject : @escaping RCTPromiseRejectBlock) { - do { - try SmileID.cleanup(jobId: jobId) - resolve(nil) - } catch let error as NSError { - reject("Error", error.localizedDescription, error) - } + } + + @objc(prepUpload:withResolver:withRejecter:) + func prepUpload(request: NSDictionary, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) { + guard let prepUploadRequest = request.toPrepUploadRequest() else { + reject("Error", "Invalid prep upload request", nil) + return } - - @objc(authenticate:withResolver:withRejecter:) - func authenticate(request: NSDictionary, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) { - guard let authenticationRequest = request.toAuthenticationRequest() else { - reject("Error", "Invalid request data", nil) - return - } - - Task { - do { - let response = try await SmileID.api.authenticate(request: authenticationRequest) - self.resolveResponse(response, resolve: resolve, reject: reject) - } catch { - reject("Error", error.localizedDescription, error) - } - } + + Task { + do { + let response = try await SmileID.api.prepUpload(request: prepUploadRequest) + self.resolveResponse(response, resolve: resolve, reject: reject) + } catch { + reject("Error", error.localizedDescription, error) + } } - - @objc(prepUpload:withResolver:withRejecter:) - func prepUpload(request: NSDictionary, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) { - guard let prepUploadRequest = request.toPrepUploadRequest() else { - reject("Error", "Invalid prep upload request", nil) - return - } - - Task { - do { - let response = try await SmileID.api.prepUpload(request: prepUploadRequest) - self.resolveResponse(response, resolve: resolve, reject: reject) - } catch { - reject("Error", error.localizedDescription, error) - } - } + } + + @objc(upload:request:withResolver:withRejecter:) + func upload(url: String, request: NSDictionary, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) { + guard let uploadRequest = request.toUploadRequest() else { + reject("Error", "Invalid upload request", nil) + return } - - @objc(upload:request:withResolver:withRejecter:) - func upload(url: String, request: NSDictionary, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) { - guard let uploadRequest = request.toUploadRequest() else { - reject("Error", "Invalid upload request", nil) - return - } - - guard let zipData = try? LocalStorage.toZip(uploadRequest: uploadRequest) else { - reject("Error", "Unable to zip file", nil) - return - } - Task { - do { - try await SmileID.api.upload(zip: zipData, to: url) - resolve(nil) - } catch { - reject("Error", error.localizedDescription, error) - } - } + + guard let zipData = try? LocalStorage.toZip(uploadRequest: uploadRequest) else { + reject("Error", "Unable to zip file", nil) + return } - - @objc(doEnhancedKyc:withResolver:withRejecter:) - func doEnhancedKyc(request: NSDictionary, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) { - guard let partnerParamsDict = request["partnerParams"] as? NSDictionary else { - reject("doEnhancedKyc", "partnerParams is required", nil) - return - } - guard let partnerParams = partnerParamsDict.toPartnerParams() else { - reject("doEnhancedKyc", "partnerParams is missing required data", nil) - return - } - guard let country = request["country"] as? String else { - reject("doEnhancedKyc", "country is required", nil) - return - } - guard let idType = request["idType"] as? String else { - reject("doEnhancedKyc", "idType is required", nil) - return - } - guard let idNumber = request["idNumber"] as? String else { - reject("doEnhancedKyc", "idNumber is required", nil) - return - } - guard let timestamp = request["timestamp"] as? String else { - reject("doEnhancedKyc", "timestamp is required", nil) - return - } - guard let signature = request["signature"] as? String else { - reject("doEnhancedKyc", "signature is required", nil) - return - } - - let request = EnhancedKycRequest( - country: country, - idType: idType, - idNumber: idNumber, - firstName: request["firstName"] as? String, - middleName: request["middleName"] as? String, - lastName: request["lastName"] as? String, - dob: request["dob"] as? String, - phoneNumber: request["phoneNumber"] as? String, - bankCode: request["bankCode"] as? String, - callbackUrl: request["callbackUrl"] as? String, - partnerParams: partnerParams, - sourceSdk: "ios (react-native)", - timestamp: timestamp, - signature: signature - ) - - Task { - do { - let response = try await SmileID.api.doEnhancedKyc(request: request) - let encoder = JSONEncoder() - guard let jsonData = try? encoder.encode(response) else { - throw SmileIDError.unknown("doEnhancedKyc encoding error") - } - // Assuming you have a method to convert response to a dictionary - resolve(["result": String(data: jsonData, encoding: .utf8)!]) - } catch { - reject("Error", error.localizedDescription, error) - } - } + Task { + do { + try await SmileID.api.upload(zip: zipData, to: url) + resolve(nil) + } catch { + reject("Error", error.localizedDescription, error) + } } - - @objc(doEnhancedKycAsync:withResolver:withRejecter:) - func doEnhancedKycAsync(request: NSDictionary, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) { - guard let partnerParamsDict = request["partnerParams"] as? NSDictionary else { - reject("doEnhancedKyc", "partnerParams is required", nil) - return - } - guard let partnerParams = partnerParamsDict.toPartnerParams() else { - reject("doEnhancedKyc", "partnerParams is missing required data", nil) - return - } - guard let country = request["country"] as? String else { - reject("doEnhancedKyc", "country is required", nil) - return - } - guard let idType = request["idType"] as? String else { - reject("doEnhancedKyc", "idType is required", nil) - return - } - guard let idNumber = request["idNumber"] as? String else { - reject("doEnhancedKyc", "idNumber is required", nil) - return - } - guard let timestamp = request["timestamp"] as? String else { - reject("doEnhancedKyc", "timestamp is required", nil) - return - } - guard let signature = request["signature"] as? String else { - reject("doEnhancedKyc", "signature is required", nil) - return - } - - let request = EnhancedKycRequest( - country: country, - idType: idType, - idNumber: idNumber, - firstName: request["firstName"] as? String, - middleName: request["middleName"] as? String, - lastName: request["lastName"] as? String, - dob: request["dob"] as? String, - phoneNumber: request["phoneNumber"] as? String, - bankCode: request["bankCode"] as? String, - callbackUrl: request["callbackUrl"] as? String, - partnerParams: partnerParams, - sourceSdk: "ios (react-native)", - timestamp: timestamp, - signature: signature - ) - - Task { - do { - let response = try await SmileID.api.doEnhancedKycAsync(request: request) - let encoder = JSONEncoder() - guard let jsonData = try? encoder.encode(response) else { - throw SmileIDError.unknown("doEnhancedKyc encoding error") - } - // Assuming you have a method to convert response to a dictionary - resolve(["result": String(data: jsonData, encoding: .utf8)!]) - } catch { - reject("Error", error.localizedDescription, error) - } - } + } + + @objc(doEnhancedKyc:withResolver:withRejecter:) + func doEnhancedKyc(request: NSDictionary, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) { + guard let partnerParamsDict = request["partnerParams"] as? NSDictionary else { + reject("doEnhancedKyc", "partnerParams is required", nil) + return } - - @objc(getSmartSelfieJobStatus:withResolver:withRejecter:) - func getSmartSelfieJobStatus(request: NSDictionary, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) { - getJobStatus(request: request, resolve: resolve, reject: reject) + guard let partnerParams = partnerParamsDict.toPartnerParams() else { + reject("doEnhancedKyc", "partnerParams is missing required data", nil) + return } - - @objc(getDocumentVerificationJobStatus:withResolver:withRejecter:) - func getDocumentVerificationJobStatus(request: NSDictionary, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) { - getJobStatus(request: request, resolve: resolve, reject: reject) + guard let country = request["country"] as? String else { + reject("doEnhancedKyc", "country is required", nil) + return } - - @objc(getBiometricKycJobStatus:withResolver:withRejecter:) - func getBiometricKycJobStatus(request: NSDictionary, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) { - getJobStatus(request: request, resolve: resolve, reject: reject) + guard let idType = request["idType"] as? String else { + reject("doEnhancedKyc", "idType is required", nil) + return } - - @objc(getEnhancedDocumentVerificationJobStatus:withResolver:withRejecter:) - func getEnhancedDocumentVerificationJobStatus(request: NSDictionary, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) { - getJobStatus(request: request, resolve: resolve, reject: reject) + guard let idNumber = request["idNumber"] as? String else { + reject("doEnhancedKyc", "idNumber is required", nil) + return } - - @objc(getProductsConfig:withResolver:withRejecter:) - func getProductsConfig(request: NSDictionary, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) { - guard let productsConfigRequest = request.toProductsConfigRequest() else { - reject("Error", "Invalid products config request", nil) - return - } - - Task { - do { - let response = try await SmileID.api.getProductsConfig(request: productsConfigRequest) - self.resolveResponse(response, resolve: resolve, reject: reject) - } catch { - reject("Error", error.localizedDescription, error) - } - } + guard let timestamp = request["timestamp"] as? String else { + reject("doEnhancedKyc", "timestamp is required", nil) + return } - - @objc(getValidDocuments:withResolver:withRejecter:) - func getValidDocuments(request: NSDictionary, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) { - guard let validDocumentsRequest = request.toProductsConfigRequest() else { - reject("Error", "Invalid valid documents request", nil) - return - } - - Task { - do { - let response = try await SmileID.api.getValidDocuments(request: validDocumentsRequest) - self.resolveResponse(response, resolve: resolve, reject: reject) - } catch { - reject("Error", error.localizedDescription, error) - } - } + guard let signature = request["signature"] as? String else { + reject("doEnhancedKyc", "signature is required", nil) + return } - - @objc(getServicesWithResolver:withRejecter:) - func getServices(resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) { - Task { - do { - let response = try await SmileID.api.getServices() - self.resolveResponse(response, resolve: resolve, reject: reject) - } catch { - reject("Error", error.localizedDescription, error) - } + + let request = EnhancedKycRequest( + country: country, + idType: idType, + idNumber: idNumber, + firstName: request["firstName"] as? String, + middleName: request["middleName"] as? String, + lastName: request["lastName"] as? String, + dob: request["dob"] as? String, + phoneNumber: request["phoneNumber"] as? String, + bankCode: request["bankCode"] as? String, + callbackUrl: request["callbackUrl"] as? String, + partnerParams: partnerParams, + sourceSdk: "ios (react-native)", + timestamp: timestamp, + signature: signature + ) + + Task { + do { + let response = try await SmileID.api.doEnhancedKyc(request: request) + let encoder = JSONEncoder() + guard let jsonData = try? encoder.encode(response) else { + throw SmileIDError.unknown("doEnhancedKyc encoding error") } + // Assuming you have a method to convert response to a dictionary + resolve(["result": String(data: jsonData, encoding: .utf8)!]) + } catch { + reject("Error", error.localizedDescription, error) + } } - - @objc(getJobStatus:withResolver:withRejecter:) - func getJobStatus(request: NSDictionary, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) { - guard let jobStatusRequest = request.toJobStatusRequest() else { - reject("Error", "Invalid job status request", nil) - return - } - - Task { - do { - let response = try await SmileID.api.getJobStatus(request: jobStatusRequest) - self.resolveResponse(response, resolve: resolve, reject: reject) - } catch { - reject("Error", error.localizedDescription, error) - } - } + } + + @objc(doEnhancedKycAsync:withResolver:withRejecter:) + func doEnhancedKycAsync(request: NSDictionary, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) { + guard let partnerParamsDict = request["partnerParams"] as? NSDictionary else { + reject("doEnhancedKyc", "partnerParams is required", nil) + return } - - @objc(pollSmartSelfieJobStatus:withResolver:withRejecter:) - func pollSmartSelfieJobStatus(request: NSDictionary, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) { - guard let jobStatusRequest = request.toJobStatusRequest() else { - reject("Error", "Invalid job status request", nil) - return - } - - guard let interval = request["interval"] as? Int64 else { - reject("Error", "interval is required", nil) - return - } - - guard let numAttempts = request["numAttempts"] as? Int64 else { - reject("Error", "numAttempts is required", nil) - return - } - - pollJobStatus( - apiCall: SmileID.api.pollSmartSelfieJobStatus, - request: jobStatusRequest, - interval: interval, - numAttempts: numAttempts, - resolve: resolve, - reject: reject - ) + guard let partnerParams = partnerParamsDict.toPartnerParams() else { + reject("doEnhancedKyc", "partnerParams is missing required data", nil) + return } - - @objc(pollDocumentVerificationJobStatus:withResolver:withRejecter:) - func pollDocumentVerificationJobStatus(request: NSDictionary, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) { - guard let jobStatusRequest = request.toJobStatusRequest() else { - reject("Error", "Invalid job status request", nil) - return - } - - guard let interval = request["interval"] as? Int64 else { - reject("Error", "interval is required", nil) - return - } - - guard let numAttempts = request["numAttempts"] as? Int64 else { - reject("Error", "numAttempts is required", nil) - return - } - - pollJobStatus( - apiCall: SmileID.api.pollDocumentVerificationJobStatus, - request: jobStatusRequest, - interval: interval, - numAttempts: numAttempts, - resolve: resolve, - reject: reject - ) + guard let country = request["country"] as? String else { + reject("doEnhancedKyc", "country is required", nil) + return } - - @objc(pollBiometricKycJobStatus:withResolver:withRejecter:) - func pollBiometricKycJobStatus(request: NSDictionary, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) { - guard let jobStatusRequest = request.toJobStatusRequest() else { - reject("Error", "Invalid job status request", nil) - return - } - - guard let interval = request["interval"] as? Int64 else { - reject("Error", "interval is required", nil) - return - } - - guard let numAttempts = request["numAttempts"] as? Int64 else { - reject("Error", "numAttempts is required", nil) - return - } - - pollJobStatus( - apiCall: SmileID.api.pollBiometricKycJobStatus, - request: jobStatusRequest, - interval: interval, - numAttempts: numAttempts, - resolve: resolve, - reject: reject - ) + guard let idType = request["idType"] as? String else { + reject("doEnhancedKyc", "idType is required", nil) + return } - - @objc(pollEnhancedDocumentVerificationJobStatus:withResolver:withRejecter:) - func pollEnhancedDocumentVerificationJobStatus(request: NSDictionary, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) { - guard let jobStatusRequest = request.toJobStatusRequest() else { - reject("Error", "Invalid job status request", nil) - return - } - - guard let interval = request["interval"] as? Int64 else { - reject("Error", "interval is required", nil) - return - } - - guard let numAttempts = request["numAttempts"] as? Int64 else { - reject("Error", "numAttempts is required", nil) - return - } - - pollJobStatus( - apiCall: SmileID.api.pollEnhancedDocumentVerificationJobStatus, - request: jobStatusRequest, - interval: interval, - numAttempts: numAttempts, - resolve: resolve, - reject: reject - ) + guard let idNumber = request["idNumber"] as? String else { + reject("doEnhancedKyc", "idNumber is required", nil) + return } - - func pollJobStatus( - apiCall: @escaping (RequestType, TimeInterval, Int) async throws -> AsyncThrowingStream, Error>, - request: RequestType, - interval: Int64, - numAttempts: Int64, - resolve: @escaping RCTPromiseResolveBlock, - reject: @escaping RCTPromiseRejectBlock - ) { - let timeInterval = convertToTimeInterval(milliSeconds: interval) - guard let numAttemptsInt = Int(exactly: numAttempts) else { - reject("InvalidNumAttempts", "Invalid numAttempts value", NSError(domain: "Invalid numAttempts value", code: -1, userInfo: nil)) - return - } - - Task { - do { - let pollStream = try await apiCall(request, timeInterval, numAttemptsInt) - var result: JobStatusResponse? = nil - - for try await res in pollStream { - result = res - } - if let finalResult = result { - self.resolveResponse(finalResult, resolve: resolve, reject: reject) - } else { - reject("NoResult", "Polling completed without a result", NSError(domain: "No result obtained", code: -1, userInfo: nil)) - } - } catch { - reject("ApiCallFailure", "API call failed with error: \(error.localizedDescription)", error) - } - } + guard let timestamp = request["timestamp"] as? String else { + reject("doEnhancedKyc", "timestamp is required", nil) + return } - - - func convertToTimeInterval(milliSeconds:Int64) -> TimeInterval { - let seconds = milliSeconds/1000 - return TimeInterval(seconds) + guard let signature = request["signature"] as? String else { + reject("doEnhancedKyc", "signature is required", nil) + return } - - private func resolveResponse(_ response: T, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) { + + let request = EnhancedKycRequest( + country: country, + idType: idType, + idNumber: idNumber, + firstName: request["firstName"] as? String, + middleName: request["middleName"] as? String, + lastName: request["lastName"] as? String, + dob: request["dob"] as? String, + phoneNumber: request["phoneNumber"] as? String, + bankCode: request["bankCode"] as? String, + callbackUrl: request["callbackUrl"] as? String, + partnerParams: partnerParams, + sourceSdk: "ios (react-native)", + timestamp: timestamp, + signature: signature + ) + + Task { + do { + let response = try await SmileID.api.doEnhancedKycAsync(request: request) let encoder = JSONEncoder() guard let jsonData = try? encoder.encode(response) else { - reject("Error", "Encoding error", nil) - return + throw SmileIDError.unknown("doEnhancedKyc encoding error") } - resolve(String(data: jsonData, encoding: .utf8) ?? "") + // Assuming you have a method to convert response to a dictionary + resolve(["result": String(data: jsonData, encoding: .utf8)!]) + } catch { + reject("Error", error.localizedDescription, error) + } } + } + + @objc(getSmartSelfieJobStatus:withResolver:withRejecter:) + func getSmartSelfieJobStatus(request: NSDictionary, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) { + getJobStatus(request: request, resolve: resolve, reject: reject) + } + + @objc(getDocumentVerificationJobStatus:withResolver:withRejecter:) + func getDocumentVerificationJobStatus(request: NSDictionary, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) { + getJobStatus(request: request, resolve: resolve, reject: reject) + } + + @objc(getBiometricKycJobStatus:withResolver:withRejecter:) + func getBiometricKycJobStatus(request: NSDictionary, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) { + getJobStatus(request: request, resolve: resolve, reject: reject) + } + + @objc(getEnhancedDocumentVerificationJobStatus:withResolver:withRejecter:) + func getEnhancedDocumentVerificationJobStatus(request: NSDictionary, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) { + getJobStatus(request: request, resolve: resolve, reject: reject) + } + + @objc(getProductsConfig:withResolver:withRejecter:) + func getProductsConfig(request: NSDictionary, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) { + guard let productsConfigRequest = request.toProductsConfigRequest() else { + reject("Error", "Invalid products config request", nil) + return + } + + Task { + do { + let response = try await SmileID.api.getProductsConfig(request: productsConfigRequest) + self.resolveResponse(response, resolve: resolve, reject: reject) + } catch { + reject("Error", error.localizedDescription, error) + } + } + } + + @objc(getValidDocuments:withResolver:withRejecter:) + func getValidDocuments(request: NSDictionary, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) { + guard let validDocumentsRequest = request.toProductsConfigRequest() else { + reject("Error", "Invalid valid documents request", nil) + return + } + + Task { + do { + let response = try await SmileID.api.getValidDocuments(request: validDocumentsRequest) + self.resolveResponse(response, resolve: resolve, reject: reject) + } catch { + reject("Error", error.localizedDescription, error) + } + } + } + + @objc(getServicesWithResolver:withRejecter:) + func getServices(resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) { + Task { + do { + let response = try await SmileID.api.getServices() + self.resolveResponse(response, resolve: resolve, reject: reject) + } catch { + reject("Error", error.localizedDescription, error) + } + } + } + + @objc(getJobStatus:withResolver:withRejecter:) + func getJobStatus(request: NSDictionary, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) { + guard let jobStatusRequest = request.toJobStatusRequest() else { + reject("Error", "Invalid job status request", nil) + return + } + + Task { + do { + let response = try await SmileID.api.getJobStatus(request: jobStatusRequest) + self.resolveResponse(response, resolve: resolve, reject: reject) + } catch { + reject("Error", error.localizedDescription, error) + } + } + } + + @objc(pollSmartSelfieJobStatus:withResolver:withRejecter:) + func pollSmartSelfieJobStatus(request: NSDictionary, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) { + guard let jobStatusRequest = request.toJobStatusRequest() else { + reject("Error", "Invalid job status request", nil) + return + } + + guard let interval = request["interval"] as? Int64 else { + reject("Error", "interval is required", nil) + return + } + + guard let numAttempts = request["numAttempts"] as? Int64 else { + reject("Error", "numAttempts is required", nil) + return + } + + pollJobStatus( + apiCall: SmileID.api.pollSmartSelfieJobStatus, + request: jobStatusRequest, + interval: interval, + numAttempts: numAttempts, + resolve: resolve, + reject: reject + ) + } + + @objc(pollDocumentVerificationJobStatus:withResolver:withRejecter:) + func pollDocumentVerificationJobStatus(request: NSDictionary, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) { + guard let jobStatusRequest = request.toJobStatusRequest() else { + reject("Error", "Invalid job status request", nil) + return + } + + guard let interval = request["interval"] as? Int64 else { + reject("Error", "interval is required", nil) + return + } + + guard let numAttempts = request["numAttempts"] as? Int64 else { + reject("Error", "numAttempts is required", nil) + return + } + + pollJobStatus( + apiCall: SmileID.api.pollDocumentVerificationJobStatus, + request: jobStatusRequest, + interval: interval, + numAttempts: numAttempts, + resolve: resolve, + reject: reject + ) + } + + @objc(pollBiometricKycJobStatus:withResolver:withRejecter:) + func pollBiometricKycJobStatus(request: NSDictionary, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) { + guard let jobStatusRequest = request.toJobStatusRequest() else { + reject("Error", "Invalid job status request", nil) + return + } + + guard let interval = request["interval"] as? Int64 else { + reject("Error", "interval is required", nil) + return + } + + guard let numAttempts = request["numAttempts"] as? Int64 else { + reject("Error", "numAttempts is required", nil) + return + } + + pollJobStatus( + apiCall: SmileID.api.pollBiometricKycJobStatus, + request: jobStatusRequest, + interval: interval, + numAttempts: numAttempts, + resolve: resolve, + reject: reject + ) + } + + @objc(pollEnhancedDocumentVerificationJobStatus:withResolver:withRejecter:) + func pollEnhancedDocumentVerificationJobStatus(request: NSDictionary, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) { + guard let jobStatusRequest = request.toJobStatusRequest() else { + reject("Error", "Invalid job status request", nil) + return + } + + guard let interval = request["interval"] as? Int64 else { + reject("Error", "interval is required", nil) + return + } + + guard let numAttempts = request["numAttempts"] as? Int64 else { + reject("Error", "numAttempts is required", nil) + return + } + + pollJobStatus( + apiCall: SmileID.api.pollEnhancedDocumentVerificationJobStatus, + request: jobStatusRequest, + interval: interval, + numAttempts: numAttempts, + resolve: resolve, + reject: reject + ) + } + + func pollJobStatus( + apiCall: @escaping (RequestType, TimeInterval, Int) async throws -> AsyncThrowingStream, Error>, + request: RequestType, + interval: Int64, + numAttempts: Int64, + resolve: @escaping RCTPromiseResolveBlock, + reject: @escaping RCTPromiseRejectBlock + ) { + let timeInterval = convertToTimeInterval(milliSeconds: interval) + guard let numAttemptsInt = Int(exactly: numAttempts) else { + reject("InvalidNumAttempts", "Invalid numAttempts value", NSError(domain: "Invalid numAttempts value", code: -1, userInfo: nil)) + return + } + + Task { + do { + let pollStream = try await apiCall(request, timeInterval, numAttemptsInt) + var result: JobStatusResponse? = nil + + for try await res in pollStream { + result = res + } + if let finalResult = result { + self.resolveResponse(finalResult, resolve: resolve, reject: reject) + } else { + reject("NoResult", "Polling completed without a result", NSError(domain: "No result obtained", code: -1, userInfo: nil)) + } + } catch { + reject("ApiCallFailure", "API call failed with error: \(error.localizedDescription)", error) + } + } + } + + + func convertToTimeInterval(milliSeconds:Int64) -> TimeInterval { + let seconds = milliSeconds/1000 + return TimeInterval(seconds) + } + + private func resolveResponse(_ response: T, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) { + let encoder = JSONEncoder() + guard let jsonData = try? encoder.encode(response) else { + reject("Error", "Encoding error", nil) + return + } + resolve(String(data: jsonData, encoding: .utf8) ?? "") + } } diff --git a/src/NativeSmileId.ts b/src/NativeSmileId.ts index 1670148..d4680bf 100644 --- a/src/NativeSmileId.ts +++ b/src/NativeSmileId.ts @@ -31,9 +31,9 @@ export interface Spec extends TurboModule { */ initialize( useSandBox: boolean, - apiKey?: string, + enableCrashReporting: boolean, config?: Config, - enableCrashReporting?: boolean + apiKey?: string ): Promise; /** diff --git a/src/index.tsx b/src/index.tsx index e3378fa..8b72de8 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -73,10 +73,10 @@ const SmileID = { */ initialize: ( useSandBox: boolean = false, + enableCrashReporting: boolean = false, config?: Config, - apiKey?: string, - enableCrashReporting?: boolean - ) => _SmileID.initialize(useSandBox, apiKey, config, enableCrashReporting), + apiKey?: string + ) => _SmileID.initialize(useSandBox, enableCrashReporting, config, apiKey), /** * Sets allow offline mode which enables