Tích hợp React Native
Yêu cầu
- Yêu cầu iOS >= 13.4
 - Yêu cầu Android: minSdkVersion = 21, compileSdkVersion = 34
 
Cài đặt cho Android
Bước 1: Tải SDK và cấu hình project
- Tải phiên bản SDK mới nhất ở link: https://github.com/VNPT-SmartCA/vnpt_smartca_sdk_android/releases/
 - Sau khi giải nén, copy các file .aar và thư mục repo vào thư mục 
android/app/libscủa project Android (nếu chưa có thư mụclibsthì tạo mới) 
Lưu ý
Ứng dụng viết bằng Flutter hoặc tích hợp Flutter module không copy thư mục repo
- Trong 
android/build.gradle, thêm cấu hình như sau 
buildscript {
    // ...
    repositories {
        // ...
        jcenter()
        flatDir {
            dirs 'libs'
        }
        maven {
            url 'https://jitpack.io'
        }
    }
    //...
}
String storageUrl = System.env.FLUTTER_STORAGE_BASE_URL ?: "https://storage.googleapis.com"
allprojects {
    repositories {
        google()
        mavenCentral()
        jcenter()
        maven {
            url '../app/libs/repo'
        }
        maven {
            url "$storageUrl/download.flutter.io"
        }
        maven { url "https://jitpack.io" }
    }
}
// ...
- Trong 
android/gradle.properties, enablenewArchEnabledcho project 
newArchEnabled=true
- Trong 
android/app/proguard-rules.pro, thêm cấu hình 
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontwarn android.support.**
-dontwarn com.squareup.**
-dontwarn com.google.android.**
-verbose
# -keepattributes *Annotation*
-dontwarn lombok.**
-dontwarn io.realm.**
-dontwarn java.awt.**
# okhttp3
-dontwarn okhttp3.**
-dontwarn okio.**
-dontwarn javax.annotation.**
-dontwarn org.conscrypt.**
# A resource is loaded with a relative path so the package of this class must be preserved.
-keepnames class okhttp3.internal.publicsuffix.PublicSuffixDatabase
# Application classes that will be serialized/deserialized over Gson
-keep class vnpt.it3.econtract.data.model.** { *; }
-keep class vnpt.it3.econtract.data.** { *; }
# Java 8
-dontwarn java.lang.invoke.*
-dontwarn **$$Lambda$*
# Retrofit 2
-dontnote retrofit2.Platform
-dontnote retrofit2.Platform$IOS$MainThreadExecutor
-dontwarn retrofit2.Platform$Java8
-keepattributes Signature
-keepattributes Exceptions
-keepclassmembernames,allowobfuscation interface * {
    @retrofit2.http.* <methods>;
}
-keepclasseswithmembers class * {
    @retrofit2.http.* <methods>;
}
-dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement
# pdf lib
-keep class com.shockwave.**
#To remove debug logs:
-assumenosideeffects class android.util.Log {
    public static *** d(...);
    public static *** v(...);
    public static *** w(...);
    public static *** i(...);
}
-keep public enum vnpt.it3.econtract.data.**{
    *;
}
-keepclassmembers class **.R$* {
  public static <fields>;
}
# Glide
-keep public class * implements com.bumptech.glide.module.GlideModule
-keep public class * extends com.bumptech.glide.module.AppGlideModule
-keep public enum com.bumptech.glide.load.ImageHeaderParser$** {
  **[] $VALUES;
  public *;
}
-keep enum org.greenrobot.eventbus.ThreadMode { *; }
-keep class com.vnptit.innovation.sample.model.** { *; }
-keep class ai.icenter.face3d.native_lib.Face3DConfig { *; }
-keep class ai.icenter.face3d.native_lib.CardConfig { *; }
- Trong 
android/app/build.gradle, thêm các cấu hình sau 
android {
    // ...
    defaultConfig {
        // ...
        multiDexEnabled true
        ndk {
            // abiFilters 'armeabi-v7a', 'arm64-v8a','x86_64'
            debugSymbolLevel 'FULL'
        }
    }
	// ...
    packagingOptions {
        pickFirst 'lib/x86/libc++_shared.so'
        pickFirst 'lib/x86_64/libc++_shared.so'
        pickFirst 'lib/armeabi-v7a/libc++_shared.so'
        pickFirst 'lib/arm64-v8a/libc++_shared.so'
    }
    aaptOptions {
        noCompress "bic"
    }
}
dependencies {
    implementation fileTree(dir: "libs", include: ["*.aar"])
    // ...
    implementation 'com.vnpt.smartca.module.vnpt_smartca_module:flutter_release:1.0'
    // Đường dẫn tới các file aar (xem bước 1)
    implementation files('libs/sdk_vnpt_smartca_library-release.aar')
    implementation files('libs/ekyc_sdk-release-v3.5.3.aar')
    implementation files('libs/scanqr_ic_sdk-release-v1.0.5.aar')
    // eContract
    implementation files('libs/eContract-v3.6.12.aar')
    implementation 'com.auth0.android:jwtdecode:2.0.0'
    implementation 'com.github.gcacace:signature-pad:1.3.1'
    implementation "androidx.multidex:multidex:2.0.1"
    implementation 'androidx.appcompat:appcompat:1.6.1'
    implementation 'com.google.android.material:material:1.4.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
    implementation 'androidx.test.espresso:espresso-idling-resource:3.5.1'
    implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
    implementation 'com.github.mhiew:android-pdf-viewer:3.2.0-beta.3'
    implementation 'com.squareup.okhttp3:okhttp:4.9.0'
    implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0'
    implementation 'com.squareup.retrofit2:retrofit:2.9.0'
    implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
    implementation 'com.squareup.retrofit2:adapter-rxjava2:2.9.0'
    implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.0.0'
    implementation 'com.karumi:dexter:6.0.0'
    implementation 'com.android.support:exifinterface:28.0.0'
    implementation 'com.google.code.gson:gson:2.10'
    implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
    implementation 'io.reactivex.rxjava2:rxjava:2.2.12'
    //end
    // eKYC
    implementation 'com.android.support:appcompat-v7:28.0.0'
    implementation 'com.android.support:design:28.0.0'
    implementation 'com.android.support.constraint:constraint-layout:2.0.4'
    implementation 'de.hdodenhof:circleimageview:3.1.0'
    implementation 'com.intuit.sdp:sdp-android:1.0.6'
    implementation 'androidx.appcompat:appcompat:1.6.1'
    implementation('me.dm7.barcodescanner:zxing:1.9.8')
    implementation 'com.airbnb.android:lottie:5.0.1'
}
- Trong 
android/app/src/main/AndroidManifest.xmlthêm các cấu hình sau 
// Thêm quyền
  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
  <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
  <uses-permission android:name="android.permission.CAMERA" />
  <uses-permission android:name="android.permission.USE_BIOMETRIC" />
  <uses-permission android:name="android.permission.USE_FINGERPRINT" />
  
// Thêm vào thẻ <application>
tools:replace="android:allowBackup"
tools:targetApi="m"
android:allowBackup="false"
android:fullBackupContent="false"
// Thêm setup 2 activity
<activity  android:name="io.flutter.embedding.android.FlutterFragmentActivity"
	android:launchMode="singleTop"
	android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection"
	android:hardwareAccelerated="true"
	android:windowSoftInputMode="adjustResize"
	android:exported="true"/>
<activity  android:name="io.flutter.embedding.android.FlutterActivity"
	android:launchMode="singleTop"
	android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection"
	android:hardwareAccelerated="true"
	android:windowSoftInputMode="adjustResize"
	android:exported="true"/>
Bước 2: Tạo Native Modules (https://reactnative.dev/docs/next/legacy/native-modules-android)
- Tạo file 
SmartCAModule.ktngang hàng vớiMainApplication.ktnhư sau 
package com.reactnativeapp
import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.util.Log
import android.widget.Toast
import com.facebook.react.bridge.Arguments
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.bridge.ReactContextBaseJavaModule
import com.facebook.react.bridge.ReactMethod
import com.vnpt.smartca.*
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json
import com.facebook.react.bridge.ReactContext
import com.facebook.react.bridge.WritableMap
import com.facebook.react.modules.core.DeviceEventManagerModule
class SmartCAModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
    override fun getName() = "SmartCAModule"
    private fun sendEvent(reactContext: ReactContext, eventName: String, params: WritableMap?) {
        reactContext
            .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
            .emit(eventName, params)
    }
    @ReactMethod
    fun addListener(type: String?) {
        // Keep: Required for RN built in Event Emitter Calls.
    }
    @ReactMethod
    fun removeListeners(type: Int?) {
        // Keep: Required for RN built in Event Emitter Calls.
    }
    @ReactMethod(isBlockingSynchronousMethod = true)
    private fun createAccount() {
        currentActivity?.runOnUiThread {
            try {
                VNPTSmartCA.createAccount { result ->
                    when (result.status) {
                        SmartCAResultCode.SUCCESS_CODE -> {
                            val obj: CallbackResult = Json.decodeFromString(
                                CallbackResult.serializer(), result.data.toString()
                            )
                            // SDK trả lại token, credential của khách hàng
                            // Đối tác tạo transaction cho khách hàng để lấy transId, sau đó gọi getWaitingTransaction
                            val token = obj.accessToken
                            val credentialId = obj.credentialId
                            val params = Arguments.createMap().apply {
                                putInt("code", 0)
                                putString("token", token)
                                putString("credentialId", credentialId)
                            }
                            sendEvent(this.reactApplicationContext, "EventReminder", params)
                        }
                        else -> {
                            val params = Arguments.createMap().apply {
                                putInt("code", 1)
                                putString("token",  result.status.toString())
                                putString("credentialId", result.statusDesc)
                            }
//
                            sendEvent(this.reactApplicationContext, "EventReminder", params)
                        }
                    }
                }
            } catch (ex: Exception) {
                throw ex;
            }
        }
    }
    @ReactMethod(isBlockingSynchronousMethod = true)
    private fun getAuth() {
        currentActivity?.runOnUiThread {
            try {
                VNPTSmartCA.getAuthentication { result ->
                    when (result.status) {
                        SmartCAResultCode.SUCCESS_CODE -> {
                            val obj: CallbackResult = Json.decodeFromString(
                                CallbackResult.serializer(), result.data.toString()
                            )
                            // SDK trả lại token, credential của khách hàng
                            // Đối tác tạo transaction cho khách hàng để lấy transId, sau đó gọi getWaitingTransaction
                            val token = obj.accessToken
                            val credentialId = obj.credentialId
                            val serial = obj.serial
                            val params = Arguments.createMap().apply {
                                putInt("code", 0)
                                putString("token", token)
                                putString("credentialId", credentialId)
                                putString("serial", serial)
                            }
                            sendEvent(this.reactApplicationContext, "EventReminder", params)
                        }
                        else -> {
                            // Xử lý lỗi
                            val params = Arguments.createMap().apply {
                                putInt("code", 1)
                                putString("token",  result.status.toString())
                                putString("credentialId", result.statusDesc)
                            }
//
                            sendEvent(this.reactApplicationContext, "EventReminder", params)
                        }
                    }
                }
            } catch (ex: Exception) {
                throw ex;
            }
        }
    }
    @ReactMethod(isBlockingSynchronousMethod = true)
    private fun getMainInfo() {
        currentActivity?.runOnUiThread {
            try {
                VNPTSmartCA.getMainInfo { result ->
                    when (result.status) {
                        SmartCAResultCode.SUCCESS_CODE -> {
                            // Xử lý khi confirm thành công
                        }
                        else -> {
                            // Xử lý khi confirm thất bại
                        }
                    }
                }
            } catch (ex: java.lang.Exception) {
                throw ex;
            }
        }
    }
    @ReactMethod(isBlockingSynchronousMethod = true)
    private fun getWaitingTransaction(transId: String) {
        currentActivity?.runOnUiThread {
            try {
                if (transId.isNullOrEmpty()) {
                   return;
                }
                VNPTSmartCA.getWaitingTransaction(transId) { result ->
                    val params = Arguments.createMap().apply {
                        putInt("code", 0)
                    }
                    sendEvent(this.reactApplicationContext, "EventReminder", params)
                    when (result.status) {
                        SmartCAResultCode.SUCCESS_CODE -> {
                            // Xử lý khi thành công
                        }
                        else -> {
                            // Xử lý khi thất bại
                        }
                    }
                }
            } catch (ex: Exception) {
                throw ex;
            }
        }
    }
    @ReactMethod(isBlockingSynchronousMethod = true)
    private fun signOut() {
        currentActivity?.runOnUiThread {
            try {
                VNPTSmartCA.signOut { result ->
                    when (result.status) {
                        SmartCAResultCode.SUCCESS_CODE -> {
                            val params = Arguments.createMap().apply {
                                putInt("code", 0)
                            }
                            sendEvent(this.reactApplicationContext, "EventReminder", params)
                        }
                        else -> {
                            val params = Arguments.createMap().apply {
                                putInt("code", 1)
                            }
                            sendEvent(this.reactApplicationContext, "EventReminder", params)
                        }
                    }
                }
            } catch (ex: Exception) {
                throw ex;
            }
        }
    }
    companion object {
        private var VNPTSmartCA = VNPTSmartCASDK()
        @SuppressLint("StaticFieldLeak")
        private lateinit var context: Context
        fun init(context: Context) {
            this.context = context
            var customParams = CustomParams(
                        customerId = "", // Số CCCD, giấy tờ của KH đăng nhập SDK, để trống KH tự nhập
                        borderRadiusBtn = 999.0, // Border radius của button
                        colorSecondBtn = "", // Màu background nút phụ ví dụ: #FFFFFF
                        colorPrimaryBtn = "", // Màu background nút chính ví dụ: #4788FF
                        featuresLink = "", // Đường dẫn tới trang hướng dẫn sử dụng các tính năng sdk
                        customerPhone = "", // Số ĐT của KH
                        packageDefault = "", // Gói mặc định hiển thị khi mua Chứng thư số, ví dụ: PS0
                        password = "", // Mật khẩu mặc định khi tạo tài khoản
                        logoCustom = "", // Logo của đối tác theo mã hoá Base64 dạng "iVBORw0KGgoAAAANSUhEUgAAANgAAA......"
                        backgroundLogin = "" // Background của đối tác theo mã hoá Base64 dạng "iVBORw0KGgoAAAANSUhEUgAAANgAAA......"
                    )
            var config = ConfigSDK(
                        clientId = "", // clientId tương ứng với môi trường được cấp qua email
                        clientSecret = "", // clientSecret tương ứng với môi trường được cấp qua email             
                        env = SmartCAEnvironment.DEMO_ENV, // Môi trường kết nối DEMO/PROD
                        customParams = customParams,
                        lang = SmartCALanguage.VI, // Ngôn ngữ vi/en
                        isFlutter = true, // true nếu ứng dụng phát triển bằng Flutter, hoặc tích hợp Flutter module
                    )
            VNPTSmartCA.initSDK(context, config)
            val x = mutableListOf<Int>()
            x.add(Intent.FLAG_ACTIVITY_NEW_TASK)
            VNPTSmartCA.initCustomIntentFlag(x)
        }
        fun onDestroy() {
//        super.onDestroy()
            VNPTSmartCA.destroySDK();
        }
    }
}
@Serializable
data class CallbackResult(
    val credentialId: String,
    val accessToken: String,
    val serial: String,
) : java.io.Serializable
- Tạo file 
MyAppPackage.ktngang hàng vớiMainApplication.kt 
import android.view.View
import com.facebook.react.ReactPackage
import com.facebook.react.bridge.NativeModule
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.uimanager.ReactShadowNode
import com.facebook.react.uimanager.ViewManager
class MyAppPackage : ReactPackage {
    override fun createViewManagers(
        reactContext: ReactApplicationContext
    ): MutableList<ViewManager<View, ReactShadowNode<*>>> = mutableListOf()
    override fun createNativeModules(
        reactContext: ReactApplicationContext
    ): MutableList<NativeModule> = listOf(SmartCAModule(reactContext)).toMutableList()
}
- Kết nối 
MyAppPackagevào functiongetPackagestrongMainApplication 
override fun getPackages(): List<ReactPackage> =
	PackageList(this).packages.apply {
	// Packages that cannot be autolinked yet can be added manually here, for example:
	// packages.add(new MyReactNativePackage());
	add(MyAppPackage())
}
- Trong 
MainActivitythêm hai function sau 
override fun onCreate(savedInstanceState: Bundle?) {
	super.onCreate(savedInstanceState)
	SmartCAModule.init(this)
}
override fun onDestroy() {
	super.onDestroy()
	SmartCAModule.onDestroy()
}
Bước 3: Chi tiết các hàm chính
Cài đặt cho iOS
Bước 1: Tải SDK và cấu hình Project
- Tải phiên bản SDK mới nhất từ link: https://github.com/VNPT-SmartCA/ios_vnptsmartca_sdk/releases
 - Kéo thả toàn bộ file _.xcframework và _.framework vào trong project. Đi tới Targets Project -> General -> Frameworks, Libraries, and Embedded Content
 
Lưu ý
Ứng dụng viết bằng Flutter hoặc tích hợp Flutter module chỉ kéo thả file ở thư mục eContract-eKYC
- Bổ sung quyền truy cập Camera, FaceID trong Info.plist
 
    <key>NSCameraUsageDescription</key>
    <string>$(PRODUCT_NAME) requires access to your phone’s camera</string>
    <key>NSFaceIDUsageDescription</key>
    <string>$(PRODUCT_NAME) Authentication with TouchId or FaceID</string>
Bước 2: Tạo Native Modules (https://reactnative.dev/docs/next/legacy/native-modules-ios)
- Sử dụng 
xcodeđể tạo và mở project ios (*.xcworkspace) - Tạo file swift với tên là 
SmartCAModule.swift, lúc này xcode sẽ gợi ý tạo file đểconfigure an Objective-C Bridging Header, chọnCreate Bridging Header 
import Foundation
import SmartCASDK
import FlutterPluginRegistrant
@objc(SmartCAModule)
class SmartCAModule: RCTEventEmitter {
  
  private var manager: SmartCAManager?
  private var hasListeners = false
  
  override init() {
      super.init()
      self.manager = SmartCAManager.shared
  }
  
  override func startObserving() {
    hasListeners = true
  }
  
  override func stopObserving() {
    hasListeners = false
  }
  
  @objc func createAccount() {
    DispatchQueue.main.async {
      self.manager?.vnptSmartCASDK?.createAccount(callback: { result in
          print(result)
      })
    }
  }
  
  @objc func signOut() {
    DispatchQueue.main.async {
      self.manager?.vnptSmartCASDK?.signOut(callback: { result in
                if result.status == SmartCAResultCode.SUCCESS_CODE {
                    // Xử lý khi thành công
                  if self.hasListeners {
                    self.sendEvent(withName: "EventReminder", body: ["code": 0, "token": "Thông báo", "credentialId": "Đăng xuất thành công"])
                      }
                } else {
                    // Xử lý khi thất bại
                }
            });
    }
  }
  
  @objc func getAuth() {
    DispatchQueue.main.async {
      // SDK tự động xử lý các trường hợp về token: Hết hạn, chưa kích hoạt...
    self.manager?.vnptSmartCASDK?.getAuthentication(callback: { result in
              if result.status == SmartCAResultCode.SUCCESS_CODE {
                  // Xử lý khi thành công
                if self.hasListeners {
                  self.sendEvent(withName: "EventReminder", body: ["code": 0, "token": result.data, "credentialId": ""])
                    }
              } else {
                  // Xử lý khi thất bại
              }
          });
    }
  }
  
  @objc func  getMainInfo(){
    DispatchQueue.main.async {
      self.manager?.vnptSmartCASDK?.getMainInfo(callback: { result in
      })
    }
  }
  
  @objc func getWaitingTransaction(_ tranId: String) {
    DispatchQueue.main.async {
      self.manager?.vnptSmartCASDK?.getWaitingTransaction(tranId: tranId, callback: { result in
            if result.status == SmartCAResultCode.SUCCESS_CODE {
                print("Giao dịch thành công: \(result.status) - \(result.statusDesc) - \(result.data)");
              
              if self.hasListeners {
                self.sendEvent(withName: "EventReminder", body: ["code": 0, "token": result.status, "credentialId": result.statusDesc])
                  }
              
              
            } else {
              if self.hasListeners {
                self.sendEvent(withName: "EventReminder", body: ["code": 1, "token": result.status, "credentialId": result.statusDesc])
                  }
            }
        });
    }
  }
  override static func requiresMainQueueSetup() -> Bool {
    return true
  }
}
class SmartCAManager: NSObject {
  static let shared = SmartCAManager()
  
  @objc class func getInstance() -> SmartCAManager {
    return SmartCAManager.shared
  }
  
  var vnptSmartCASDK: VNPTSmartCASDK?
  
  @objc
  func initSDK() {
    if let ab = RCTPresentedViewController() {
      
        let customParams = CustomParams(
            customerId: "",                 // Số CCCD, giấy tờ của KH đăng nhập SDK, để trống KH tự nhập
            borderRadiusBtn: 0,             // Border radius của button
            colorSecondBtn: "",             // Màu background nút phụ vd: #FFFFFF
            colorPrimaryBtn: "",            // Màu background nút chính vd: #4788FF
            featuresLink: "",               // Đường dẫn tới trang hướng dẫn sử dụng các tính năng sdk
            customerPhone: "",              // Số ĐT mặc định của KH
            packageDefault: "",             // Gói mặc định hiển thị khi mua Chứng thư số
            password: "",                   // Mật khẩu mặc định khi tạo tài khoản
            logoCustom: "",                 // Logo của đối tác theo mã hoá Base64
            backgroundLogin: ""             // Background của đối tác theo mã hoá Base64
        )
        
        let config = SDKConfig(
            clientId: "",                   // clientId tương ứng với môi trường được cấp qua email
            clientSecret: "",               // clientSecret tương ứng với môi trường được cấp qua email
            environment: ENVIRONMENT.DEMO,  // Môi trường kết nối DEMO/PROD
            lang: LANG.VI,                  // Ngôn ngữ vi/en
            isFlutterApp: false,            // true nếu ứng dụng phát triển bằng Flutter, hoặc tích hợp Flutter module
            customParams: customParams
        )
        self.vnptSmartCASDK = VNPTSmartCASDK(viewController: ab, config: config)
        
        GeneratedPluginRegistrant.register(with: self.vnptSmartCASDK?.flutterEngine as! FlutterPluginRegistry);
    }
  }
  
  @objc
  func destroySDK() {
    self.vnptSmartCASDK?.destroySDK();
  }
}
- Cấu hình file 
*-Bridging-Header.h 
//
//  Use this file to import your target's public headers that you would like to expose to Swift.
//
#import "React/RCTBridgeModule.h"
#import "React/RCTEventEmitter.h"
#import <React/RCTUtils.h>
- Tạo file 
SmartCAModule.m 
// RCTSmartCAModule.m
#import "React/RCTBridgeModule.h"
#import "React/RCTEventEmitter.h"
@interface RCT_EXTERN_MODULE(SmartCAModule, RCTEventEmitter)
RCT_EXTERN_METHOD(createAccount)
RCT_EXTERN_METHOD(getAuth)
RCT_EXTERN_METHOD(getMainInfo)
RCT_EXTERN_METHOD(getWaitingTransaction: String: String)
RCT_EXTERN_METHOD(signOut)
@end
Sử dụng trong React Native
- Import native module
 
import {NativeModules} from 'react-native';
- Khởi tạo
 
const {SmartCAModule} = NativeModules;
- Viết hàm lắng nghe sự kiện 
EventReminder(có thể tạo nhiều sự kiện) 
useEffect(() => {
	const  eventEmitter  =  new  NativeEventEmitter(SmartCAModule)
	let  eventListener  =  eventEmitter.addListener('EventReminder', event  => {
		let  code  =  event.code
		let  statusCode  =  event.statusCode
		let  statusDesc  =  event.statusDesc
		let  data = event.data
        let  testIOSEvent  =  eventEmitter.addListener('onIncrement', event  => {
            console.log('onIncrement event', event);
        });
	// Removes the listener once unmounted
	return () => {
		eventListener.remove();
		testIOSEvent.remove();
	};
}, []);
- Sử dụng các hàm chính
 
// create account
SmartCAModule.createAccount()
// get auth
SmartCAModule.getAuth()
// get main info
SmartCAModule.getMainInfo()
// get waiting transaction
// Lấy accessToken từ `SmartCAModule.getAuth()`
let transactionId = 'xxx'
SmartCAModule.getWaitingTransaction(transactionId)
// sign out
SmartCAModule.signOut()