react-native-hyperswitch-dev-sdk 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/HyperswitchSdkReactNative.podspec +42 -0
- package/LICENSE +201 -0
- package/android/build.gradle +161 -0
- package/android/gradle.properties +5 -0
- package/android/hyperswitch_autolinking.gradle +378 -0
- package/android/proguard-rules.pro +72 -0
- package/android/src/legacy/java/com/facebook/react/viewmanagers/GooglePayButtonManagerDelegate.java +41 -0
- package/android/src/legacy/java/com/facebook/react/viewmanagers/GooglePayButtonManagerInterface.java +20 -0
- package/android/src/legacy/java/com/facebook/react/viewmanagers/NativePaymentWidgetManagerDelegate.java +38 -0
- package/android/src/legacy/java/com/facebook/react/viewmanagers/NativePaymentWidgetManagerInterface.java +21 -0
- package/android/src/legacy/java/com/hyperswitchsdkreactnative/NativeHyperswitchSdkNativeSpec.java +106 -0
- package/android/src/legacy/java/com/hyperswitchsdkreactnative/NativeHyperswitchSdkReactNativeSpec.java +77 -0
- package/android/src/legacy/java/com/hyperswitchsdkreactnative/NativePaymentWidgetNativeSpec.java +36 -0
- package/android/src/main/AndroidManifest.xml +15 -0
- package/android/src/main/assets/hyperswitch.bundle +1535 -0
- package/android/src/main/java/com/hyperswitchsdkreactnative/HyperswitchSdkReactNativePackage.kt +47 -0
- package/android/src/main/java/com/hyperswitchsdkreactnative/modules/NativePaymentWidgetModule.kt +173 -0
- package/android/src/main/java/com/hyperswitchsdkreactnative/modules/ReactNativeHyperswitchModule.kt +396 -0
- package/android/src/main/java/com/hyperswitchsdkreactnative/views/PaymentElementViewManager.kt +99 -0
- package/android/src/main/java/io/hyperswitch/HyperswitchReactPackageProvider.kt +19 -0
- package/android/src/main/java/io/hyperswitch/PaymentEventType.kt +18 -0
- package/android/src/main/java/io/hyperswitch/model/ElementConfiguration.kt +58 -0
- package/android/src/main/java/io/hyperswitch/paymentsession/ExitHeadlessCallBackManager.kt +47 -0
- package/android/src/main/java/io/hyperswitch/paymentsession/GetPaymentSessionCallBackManager.kt +23 -0
- package/android/src/main/java/io/hyperswitch/paymentsession/PaymentMethod.kt +167 -0
- package/android/src/main/java/io/hyperswitch/paymentsession/PaymentSessionHandler.kt +68 -0
- package/android/src/main/java/io/hyperswitch/paymentsession/PaymentSessionHandlerImpl.kt +179 -0
- package/android/src/main/java/io/hyperswitch/paymentsession/PaymentSessionReactLauncher.kt +226 -0
- package/android/src/main/java/io/hyperswitch/paymentsession/PaymentSheetCallbackManager.kt +40 -0
- package/android/src/main/java/io/hyperswitch/paymentsheet/PaymentResult.kt +63 -0
- package/android/src/main/java/io/hyperswitch/react/GooglePayButtonManager.kt +54 -0
- package/android/src/main/java/io/hyperswitch/react/HyperActivity.kt +73 -0
- package/android/src/main/java/io/hyperswitch/react/HyperEventEmitter.kt +144 -0
- package/android/src/main/java/io/hyperswitch/react/HyperFragment.kt +429 -0
- package/android/src/main/java/io/hyperswitch/react/HyperFragmentManager.kt +155 -0
- package/android/src/main/java/io/hyperswitch/react/HyperHeadlessModule.kt +43 -0
- package/android/src/main/java/io/hyperswitch/react/HyperModule.kt +405 -0
- package/android/src/main/java/io/hyperswitch/react/HyperPackage.kt +16 -0
- package/android/src/main/java/io/hyperswitch/react/ReactNativeController.kt +251 -0
- package/android/src/main/java/io/hyperswitch/utils/ConversionUtils.kt +256 -0
- package/android/src/main/java/io/hyperswitch/utils/StandardResult.kt +45 -0
- package/android/src/main/java/io/hyperswitch/view/GooglePayButtonView.kt +59 -0
- package/android/src/main/java/io/hyperswitch/view/PaymentWidgetView.kt +405 -0
- package/android/src/main/res/values/attrs.xml +6 -0
- package/android/src/main/res/values/strings.xml +5 -0
- package/android/src/main/res/values/theme.xml +16 -0
- package/ios/Modules/ReactNative/HyperswitchModule.swift +470 -0
- package/ios/Modules/ReactNative/HyperswitchSdkReactNative.h +5 -0
- package/ios/Modules/ReactNative/HyperswitchSdkReactNative.mm +121 -0
- package/ios/Modules/ReactNative/NativeHyperswitchModule.h +18 -0
- package/ios/Modules/ReactNative/NativeHyperswitchModule.mm +165 -0
- package/ios/Modules/ReactNative/NativeHyperswitchModuleImpl.swift +290 -0
- package/ios/Modules/ReactNative/NativePaymentElementModule.mm +129 -0
- package/ios/Views/Fabric/ApplePayView.h +14 -0
- package/ios/Views/Fabric/ApplePayView.mm +89 -0
- package/ios/Views/Fabric/NativePaymentElementView.h +21 -0
- package/ios/Views/Fabric/NativePaymentElementView.mm +200 -0
- package/ios/Views/Fabric/NativePaymentWidgetViewRegistry.h +37 -0
- package/ios/Views/Fabric/NativePaymentWidgetViewRegistry.m +45 -0
- package/ios/Views/Native/NativePaymentWidget.m +26 -0
- package/ios/Views/Native/NativePaymentWidget.swift +420 -0
- package/ios/hyperswitchSDK/Core/ApplePay/ApplePayHandler.swift +261 -0
- package/ios/hyperswitchSDK/Core/ApplePay/ApplePayViewManager.m +18 -0
- package/ios/hyperswitchSDK/Core/ApplePay/ApplePayViewManager.swift +126 -0
- package/ios/hyperswitchSDK/Core/DeviceDataCollection/HeadlessWebView.swift +144 -0
- package/ios/hyperswitchSDK/Core/HyperCVCWidget/CVCWidget.swift +136 -0
- package/ios/hyperswitchSDK/Core/HyperExpressCheckout/ExpressCheckoutLauncher.swift +116 -0
- package/ios/hyperswitchSDK/Core/HyperExpressCheckout/ExpressCheckoutWidget.swift +42 -0
- package/ios/hyperswitchSDK/Core/HyperPaymentCardTextField/PaymentCardTextField+SwiftUI.swift +67 -0
- package/ios/hyperswitchSDK/Core/HyperPaymentCardTextField/PaymentCardTextField.swift +44 -0
- package/ios/hyperswitchSDK/Core/HyperPaymentCardTextField/PaymentHandler.swift +59 -0
- package/ios/hyperswitchSDK/Core/HyperPaymentCardTextField/PaymentIntentParams.swift +31 -0
- package/ios/hyperswitchSDK/Core/HyperPaymentCardTextField/PaymentMethodParams.swift +25 -0
- package/ios/hyperswitchSDK/Core/HyperPaymentMethodManagement/PaymentManagementConfiguration.swift +213 -0
- package/ios/hyperswitchSDK/Core/HyperPaymentMethodManagement/PaymentMethodManagementWidget.swift +92 -0
- package/ios/hyperswitchSDK/Core/HyperPaymentSheet/PaymentSheet+Events.swift +36 -0
- package/ios/hyperswitchSDK/Core/HyperPaymentSheet/PaymentSheetView+SwiftUI.swift +49 -0
- package/ios/hyperswitchSDK/Core/HyperPaymentSheet/PaymentSheetView+UIKit.swift +49 -0
- package/ios/hyperswitchSDK/Core/HyperPaymentSheet/PaymentSheetView.swift +68 -0
- package/ios/hyperswitchSDK/Core/HyperPaymentWidget/PaymentWidget.swift +212 -0
- package/ios/hyperswitchSDK/Core/HyperSession/PaymentSession+UIKit.swift +228 -0
- package/ios/hyperswitchSDK/Core/HyperSession/PaymentSessionTypes.swift +174 -0
- package/ios/hyperswitchSDK/Core/NativeModule/HyperHeadless.m +15 -0
- package/ios/hyperswitchSDK/Core/NativeModule/HyperHeadless.swift +108 -0
- package/ios/hyperswitchSDK/Core/NativeModule/HyperModule.m +31 -0
- package/ios/hyperswitchSDK/Core/NativeModule/HyperModule.swift +343 -0
- package/ios/hyperswitchSDK/Core/NativeModule/OTAServices.swift +117 -0
- package/ios/hyperswitchSDK/Core/NativeModule/RNHeadlessManager.swift +47 -0
- package/ios/hyperswitchSDK/Core/NativeModule/RNResponseHandler.swift +12 -0
- package/ios/hyperswitchSDK/Core/NativeModule/RNViewManager.swift +55 -0
- package/ios/hyperswitchSDK/Core/NativeModule/WidgetAction.swift +30 -0
- package/ios/hyperswitchSDK/Core/NativeModule/WidgetResponseRegistry.swift +92 -0
- package/ios/hyperswitchSDK/Core/NativeModule/hyper-Bridging-Header.h +12 -0
- package/ios/hyperswitchSDK/Core/Resources/HyperOTA.plist +20 -0
- package/ios/hyperswitchSDK/Core/Resources/hyperswitch.bundle +1531 -0
- package/ios/hyperswitchSDK/CoreLite/ApplePayHandlerLite.swift +251 -0
- package/ios/hyperswitchSDK/CoreLite/PaymentSession+Lite.swift +25 -0
- package/ios/hyperswitchSDK/CoreLite/PaymentSheetView+Lite.swift +45 -0
- package/ios/hyperswitchSDK/CoreLite/SwiftUI+Lite.swift +48 -0
- package/ios/hyperswitchSDK/CoreLite/WebViewController.swift +278 -0
- package/ios/hyperswitchSDK/Shared/APIClient.swift +22 -0
- package/ios/hyperswitchSDK/Shared/Codable+UIKit.swift +75 -0
- package/ios/hyperswitchSDK/Shared/CustomEndpointConfiguration.swift +67 -0
- package/ios/hyperswitchSDK/Shared/DictionaryConverter.swift +104 -0
- package/ios/hyperswitchSDK/Shared/Environment.swift +24 -0
- package/ios/hyperswitchSDK/Shared/Extensions.swift +101 -0
- package/ios/hyperswitchSDK/Shared/Helper.swift +40 -0
- package/ios/hyperswitchSDK/Shared/HyperEvents/PaymentEventData.swift +125 -0
- package/ios/hyperswitchSDK/Shared/HyperEvents/PaymentEventSubscriptionBuilder.swift +45 -0
- package/ios/hyperswitchSDK/Shared/HyperEvents/PaymentEventType.swift +30 -0
- package/ios/hyperswitchSDK/Shared/HyperNetworking.swift +151 -0
- package/ios/hyperswitchSDK/Shared/HyperParams.swift +44 -0
- package/ios/hyperswitchSDK/Shared/HyperUIViewController.swift +27 -0
- package/ios/hyperswitchSDK/Shared/Hyperswitch.swift +20 -0
- package/ios/hyperswitchSDK/Shared/HyperswitchConfigurationSchema.swift +54 -0
- package/ios/hyperswitchSDK/Shared/HyperswitchEnvironment.swift +11 -0
- package/ios/hyperswitchSDK/Shared/NativeLogger/Debouncer.swift +37 -0
- package/ios/hyperswitchSDK/Shared/NativeLogger/LogBuilder.swift +113 -0
- package/ios/hyperswitchSDK/Shared/NativeLogger/LogFileManager.swift +76 -0
- package/ios/hyperswitchSDK/Shared/NativeLogger/LogManager.swift +113 -0
- package/ios/hyperswitchSDK/Shared/NativeLogger/LogPayload.swift +91 -0
- package/ios/hyperswitchSDK/Shared/PaymentMethodType.swift +15 -0
- package/ios/hyperswitchSDK/Shared/PaymentSession.swift +98 -0
- package/ios/hyperswitchSDK/Shared/PaymentSessionConfiguration.swift +14 -0
- package/ios/hyperswitchSDK/Shared/PaymentSheet.swift +33 -0
- package/ios/hyperswitchSDK/Shared/PaymentSheetAppearance+Codable.swift +182 -0
- package/ios/hyperswitchSDK/Shared/PaymentSheetAppearance.swift +238 -0
- package/ios/hyperswitchSDK/Shared/PaymentSheetConfiguration.swift +161 -0
- package/ios/hyperswitchSDK/Shared/SDKParams.swift +43 -0
- package/ios/hyperswitchSDK/Shared/SavedPaymentMethodsConfiguration.swift +20 -0
- package/ios/hyperswitchSDK/Shared/SwiftUIManager.swift +28 -0
- package/ios/hyperswitchSDK/Shared/Version.swift +12 -0
- package/lib/bs/JuspayTechReactNativeHyperswitch.cmi +0 -0
- package/lib/bs/JuspayTechReactNativeHyperswitch.cmj +0 -0
- package/lib/bs/JuspayTechReactNativeHyperswitch.cmt +0 -0
- package/lib/bs/JuspayTechReactNativeHyperswitch.mlmap +0 -0
- package/lib/bs/build.ninja +8 -0
- package/lib/bs/install.ninja +9 -0
- package/lib/bs/src/context/HyperProvider-JuspayTechReactNativeHyperswitch.cmt +0 -0
- package/lib/bs/src/context/WidgetRegistry-JuspayTechReactNativeHyperswitch.cmt +0 -0
- package/lib/bs/src/core/Hyper-JuspayTechReactNativeHyperswitch.cmt +0 -0
- package/lib/bs/src/core/HyperElements-JuspayTechReactNativeHyperswitch.cmt +0 -0
- package/lib/bs/src/hooks/usePaymentSession-JuspayTechReactNativeHyperswitch.cmt +0 -0
- package/lib/bs/src/hooks/useWidget-JuspayTechReactNativeHyperswitch.cmt +0 -0
- package/lib/bs/src/modules/NativeHyperswitchSdk-JuspayTechReactNativeHyperswitch.cmt +0 -0
- package/lib/bs/src/types/HyperTypes-JuspayTechReactNativeHyperswitch.cmt +0 -0
- package/lib/bs/src/types/NativeModuleTypes-JuspayTechReactNativeHyperswitch.cmt +0 -0
- package/lib/bs/src/types/PaymentSheetConfiguration-JuspayTechReactNativeHyperswitch.cmt +0 -0
- package/lib/bs/src/utils/AppearanceTransformer-JuspayTechReactNativeHyperswitch.cmt +0 -0
- package/lib/bs/src/utils/EventValidator-JuspayTechReactNativeHyperswitch.cmt +0 -0
- package/lib/bs/src/utils/NewArchUtils-JuspayTechReactNativeHyperswitch.cmt +0 -0
- package/lib/bs/src/utils/PaymentSheetEventManager-JuspayTechReactNativeHyperswitch.cmt +0 -0
- package/lib/bs/src/utils/ReactNativeUtils-JuspayTechReactNativeHyperswitch.cmt +0 -0
- package/lib/bs/src/utils/ResponseHandler-JuspayTechReactNativeHyperswitch.cmt +0 -0
- package/lib/bs/src/views/CVCElement-JuspayTechReactNativeHyperswitch.cmt +0 -0
- package/lib/bs/src/views/NativePaymentWidget-JuspayTechReactNativeHyperswitch.cmt +0 -0
- package/lib/bs/src/views/NativePaymentWidgetImpl-JuspayTechReactNativeHyperswitch.cmt +0 -0
- package/lib/bs/src/views/PaymentElement-JuspayTechReactNativeHyperswitch.cmt +0 -0
- package/lib/commonjs/index.bundle.js +2 -0
- package/lib/commonjs/index.bundle.js.map +1 -0
- package/lib/module/index.bundle.js +2 -0
- package/lib/module/index.bundle.js.map +1 -0
- package/lib/typescript/babel.config.d.ts +10 -0
- package/lib/typescript/babel.config.d.ts.map +1 -0
- package/lib/typescript/eslint.config.d.mts +3 -0
- package/lib/typescript/eslint.config.d.mts.map +1 -0
- package/lib/typescript/rollup.config.d.ts +23 -0
- package/lib/typescript/rollup.config.d.ts.map +1 -0
- package/lib/typescript/scripts/bootstrap.d.ts +2 -0
- package/lib/typescript/scripts/bootstrap.d.ts.map +1 -0
- package/lib/typescript/src/context/Elements.d.ts +7 -0
- package/lib/typescript/src/context/Elements.d.ts.map +1 -0
- package/lib/typescript/src/context/HyperElements.d.ts +23 -0
- package/lib/typescript/src/context/HyperElements.d.ts.map +1 -0
- package/lib/typescript/src/context/PaymentSession.d.ts +15 -0
- package/lib/typescript/src/context/PaymentSession.d.ts.map +1 -0
- package/lib/typescript/src/context/SavedPaymentMethods.d.ts +5 -0
- package/lib/typescript/src/context/SavedPaymentMethods.d.ts.map +1 -0
- package/lib/typescript/src/context/WidgetRegistry.d.ts +8 -0
- package/lib/typescript/src/context/WidgetRegistry.d.ts.map +1 -0
- package/lib/typescript/src/context/hooks.d.ts +5 -0
- package/lib/typescript/src/context/hooks.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +10 -0
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/lib/typescript/src/modules/NativeHyperswitchSdk.d.ts +61 -0
- package/lib/typescript/src/modules/NativeHyperswitchSdk.d.ts.map +1 -0
- package/lib/typescript/src/specs/ApplePayViewNativeComponent.d.ts +10 -0
- package/lib/typescript/src/specs/ApplePayViewNativeComponent.d.ts.map +1 -0
- package/lib/typescript/src/specs/NativeHyperHeadless.d.ts +14 -0
- package/lib/typescript/src/specs/NativeHyperHeadless.d.ts.map +1 -0
- package/lib/typescript/src/specs/NativeHyperswitchModule.d.ts +32 -0
- package/lib/typescript/src/specs/NativeHyperswitchModule.d.ts.map +1 -0
- package/lib/typescript/src/specs/NativeHyperswitchSdkNative.d.ts +33 -0
- package/lib/typescript/src/specs/NativeHyperswitchSdkNative.d.ts.map +1 -0
- package/lib/typescript/src/specs/NativePaymentElementModule.d.ts +9 -0
- package/lib/typescript/src/specs/NativePaymentElementModule.d.ts.map +1 -0
- package/lib/typescript/src/specs/PaymentElementNativeComponent.d.ts +19 -0
- package/lib/typescript/src/specs/PaymentElementNativeComponent.d.ts.map +1 -0
- package/lib/typescript/src/specs/utils.d.ts +15 -0
- package/lib/typescript/src/specs/utils.d.ts.map +1 -0
- package/lib/typescript/src/types/NativeModuleTypes.d.ts +67 -0
- package/lib/typescript/src/types/NativeModuleTypes.d.ts.map +1 -0
- package/lib/typescript/src/types/PaymentSheetConfiguration.d.ts +255 -0
- package/lib/typescript/src/types/PaymentSheetConfiguration.d.ts.map +1 -0
- package/lib/typescript/src/types/definitions.d.ts +85 -0
- package/lib/typescript/src/types/definitions.d.ts.map +1 -0
- package/lib/typescript/src/types/elements/index.d.ts +23 -0
- package/lib/typescript/src/types/elements/index.d.ts.map +1 -0
- package/lib/typescript/src/types/paymentresult/index.d.ts +5 -0
- package/lib/typescript/src/types/paymentresult/index.d.ts.map +1 -0
- package/lib/typescript/src/types/savedPaymentMethods/index.d.ts +69 -0
- package/lib/typescript/src/types/savedPaymentMethods/index.d.ts.map +1 -0
- package/lib/typescript/src/utils/EventValidator.d.ts +9 -0
- package/lib/typescript/src/utils/EventValidator.d.ts.map +1 -0
- package/lib/typescript/src/utils/InitializationState.d.ts +13 -0
- package/lib/typescript/src/utils/InitializationState.d.ts.map +1 -0
- package/lib/typescript/src/utils/LaunchOptions.d.ts +7 -0
- package/lib/typescript/src/utils/LaunchOptions.d.ts.map +1 -0
- package/lib/typescript/src/utils/NewArchUtils.d.ts +7 -0
- package/lib/typescript/src/utils/NewArchUtils.d.ts.map +1 -0
- package/lib/typescript/src/utils/ReactNativeUtils.d.ts +3 -0
- package/lib/typescript/src/utils/ReactNativeUtils.d.ts.map +1 -0
- package/lib/typescript/src/views/CVCElement.d.ts +15 -0
- package/lib/typescript/src/views/CVCElement.d.ts.map +1 -0
- package/lib/typescript/src/views/NativePaymentWidget.d.ts +3 -0
- package/lib/typescript/src/views/NativePaymentWidget.d.ts.map +1 -0
- package/lib/typescript/src/views/NativePaymentWidgetImpl.d.ts +5 -0
- package/lib/typescript/src/views/NativePaymentWidgetImpl.d.ts.map +1 -0
- package/lib/typescript/src/views/PaymentElement.d.ts +18 -0
- package/lib/typescript/src/views/PaymentElement.d.ts.map +1 -0
- package/package.json +184 -0
- package/src/context/Elements.ts +80 -0
- package/src/context/HyperElements.tsx +81 -0
- package/src/context/PaymentSession.ts +121 -0
- package/src/context/SavedPaymentMethods.ts +80 -0
- package/src/context/WidgetRegistry.ts +74 -0
- package/src/context/hooks.ts +79 -0
- package/src/index.ts +53 -0
- package/src/modules/NativeHyperswitchSdk.ts +155 -0
- package/src/specs/ApplePayViewNativeComponent.ts +11 -0
- package/src/specs/NativeHyperHeadless.ts +22 -0
- package/src/specs/NativeHyperswitchModule.ts +51 -0
- package/src/specs/NativeHyperswitchSdkNative.ts +62 -0
- package/src/specs/NativePaymentElementModule.ts +25 -0
- package/src/specs/PaymentElementNativeComponent.ts +21 -0
- package/src/specs/utils.ts +15 -0
- package/src/types/NativeModuleTypes.ts +73 -0
- package/src/types/PaymentSheetConfiguration.ts +360 -0
- package/src/types/definitions.ts +109 -0
- package/src/types/elements/index.ts +33 -0
- package/src/types/paymentresult/index.ts +4 -0
- package/src/types/savedPaymentMethods/index.ts +74 -0
- package/src/utils/EventValidator.ts +39 -0
- package/src/utils/InitializationState.ts +28 -0
- package/src/utils/LaunchOptions.ts +41 -0
- package/src/utils/NewArchUtils.ts +18 -0
- package/src/utils/ReactNativeUtils.ts +13 -0
- package/src/views/CVCElement.tsx +122 -0
- package/src/views/NativePaymentWidget.ts +2 -0
- package/src/views/NativePaymentWidgetImpl.ts +16 -0
- package/src/views/PaymentElement.tsx +189 -0
- package/tsconfig.build.json +21 -0
|
@@ -0,0 +1,405 @@
|
|
|
1
|
+
package io.hyperswitch.react
|
|
2
|
+
|
|
3
|
+
import android.os.Handler
|
|
4
|
+
import android.os.Looper
|
|
5
|
+
import android.util.Log
|
|
6
|
+
import android.view.View
|
|
7
|
+
import android.view.ViewGroup
|
|
8
|
+
import android.webkit.WebResourceRequest
|
|
9
|
+
import android.webkit.WebView
|
|
10
|
+
import android.webkit.WebViewClient
|
|
11
|
+
import androidx.fragment.app.FragmentActivity
|
|
12
|
+
import androidx.fragment.app.FragmentManager
|
|
13
|
+
import com.facebook.react.bridge.Arguments
|
|
14
|
+
import com.facebook.react.bridge.Callback
|
|
15
|
+
import com.facebook.react.bridge.ReactApplicationContext
|
|
16
|
+
import com.facebook.react.bridge.ReactMethod
|
|
17
|
+
import com.facebook.react.bridge.ReadableMap
|
|
18
|
+
import com.facebook.react.uimanager.IllegalViewOperationException
|
|
19
|
+
import com.facebook.react.uimanager.UIManagerModule
|
|
20
|
+
import com.hyperswitchsdkreactnative.BuildConfig
|
|
21
|
+
import com.hyperswitchsdkreactnative.NativeHyperswitchSdkNativeSpec
|
|
22
|
+
import io.hyperswitch.payments.GooglePayCallbackManager
|
|
23
|
+
import io.hyperswitch.paymentsession.LaunchOptions
|
|
24
|
+
import io.hyperswitch.paymentsession.PaymentSheetCallbackManager
|
|
25
|
+
import io.hyperswitch.webview.utils.HSWebViewManagerImpl
|
|
26
|
+
import io.hyperswitch.webview.utils.HSWebViewWrapper
|
|
27
|
+
import java.util.concurrent.atomic.AtomicBoolean
|
|
28
|
+
import java.util.concurrent.atomic.AtomicInteger
|
|
29
|
+
import org.json.JSONObject
|
|
30
|
+
import io.hyperswitch.webview.utils.Callback as HSCallback
|
|
31
|
+
|
|
32
|
+
class HyperModule internal constructor(private val rct: ReactApplicationContext) :
|
|
33
|
+
NativeHyperswitchSdkNativeSpec(rct) {
|
|
34
|
+
companion object {
|
|
35
|
+
|
|
36
|
+
const val NAME = "HyperModule"
|
|
37
|
+
|
|
38
|
+
// Static methods with unique signatures for reflection access from lite SDK
|
|
39
|
+
@JvmStatic
|
|
40
|
+
fun confirmStatic(tag: String, map: MutableMap<String, String?>) {
|
|
41
|
+
HyperEventEmitter.confirmStatic(tag, map)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
@JvmStatic
|
|
45
|
+
fun confirmCardStatic(map: MutableMap<String, String?>) {
|
|
46
|
+
HyperEventEmitter.confirmCardStatic(map)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
@JvmStatic
|
|
50
|
+
fun confirmECStatic(map: MutableMap<String, String?>) {
|
|
51
|
+
HyperEventEmitter.confirmECStatic(map)
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
override fun getName(): String {
|
|
56
|
+
HyperEventEmitter.initialize(rct)
|
|
57
|
+
return NAME
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Using invalidate instead of deprecated onCatalystInstanceDestroy
|
|
61
|
+
override fun invalidate() {
|
|
62
|
+
super.invalidate()
|
|
63
|
+
HyperEventEmitter.deinitialize()
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
@ReactMethod
|
|
67
|
+
override fun updateWidgetHeight(height: Double) {
|
|
68
|
+
// Express checkout widget height adjustment is not yet implemented.
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Called from JS when a wallet confirm button is tapped.
|
|
73
|
+
* Stores the callback; native later calls [resolveConfirmCallback] to proceed/abort.
|
|
74
|
+
*/
|
|
75
|
+
@ReactMethod
|
|
76
|
+
override fun onPaymentConfirmButtonClick(rootTag: Double, payload: String, callback: Callback) {
|
|
77
|
+
findViewWithRootTag(rootTag.toInt()) {
|
|
78
|
+
try {
|
|
79
|
+
if (it == null) {
|
|
80
|
+
callback.invoke(true)
|
|
81
|
+
} else {
|
|
82
|
+
it.notifyConfirmButtonClicked(payload, { it: Boolean ->
|
|
83
|
+
callback.invoke(it)
|
|
84
|
+
})
|
|
85
|
+
}
|
|
86
|
+
} catch (_: Exception) {
|
|
87
|
+
callback.invoke(false)
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
@ReactMethod
|
|
93
|
+
override fun sendMessageToNative(rnMessage: String) {
|
|
94
|
+
val jsonObject = JSONObject(rnMessage)
|
|
95
|
+
if (jsonObject.optBoolean("isReady", false)) {
|
|
96
|
+
HyperEventEmitter.initialize(rct)
|
|
97
|
+
// WidgetLauncher.onPaymentReadyCallback(true)
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Method to launch Google Pay payment
|
|
102
|
+
@ReactMethod
|
|
103
|
+
override fun launchGPay(googlePayRequest: String, callBack: Callback) {
|
|
104
|
+
currentActivity?.let {
|
|
105
|
+
GooglePayCallbackManager.setCallback(
|
|
106
|
+
it,
|
|
107
|
+
googlePayRequest,
|
|
108
|
+
fun(data: Map<String, Any?>) {
|
|
109
|
+
callBack.invoke(
|
|
110
|
+
Arguments.fromBundle(
|
|
111
|
+
LaunchOptions(
|
|
112
|
+
it, BuildConfig.VERSION_NAME
|
|
113
|
+
).toBundle(data)
|
|
114
|
+
)
|
|
115
|
+
)
|
|
116
|
+
},
|
|
117
|
+
)
|
|
118
|
+
} ?: run {
|
|
119
|
+
GooglePayCallbackManager.setCallback(
|
|
120
|
+
reactApplicationContext,
|
|
121
|
+
googlePayRequest,
|
|
122
|
+
fun(data: Map<String, Any?>) {
|
|
123
|
+
callBack.invoke(
|
|
124
|
+
Arguments.fromBundle(
|
|
125
|
+
LaunchOptions(
|
|
126
|
+
reactApplicationContext, BuildConfig.VERSION_NAME
|
|
127
|
+
).toBundle(data)
|
|
128
|
+
)
|
|
129
|
+
)
|
|
130
|
+
},
|
|
131
|
+
)
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
override fun launchApplePay(
|
|
136
|
+
requestObj: String?,
|
|
137
|
+
callback: Callback?
|
|
138
|
+
) {
|
|
139
|
+
callback?.invoke("Apple pay is not supported")
|
|
140
|
+
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
override fun startApplePay(
|
|
144
|
+
requestObj: String?,
|
|
145
|
+
callback: Callback?
|
|
146
|
+
) {
|
|
147
|
+
callback?.invoke("Apple pay is not supported")
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
override fun presentApplePay(
|
|
151
|
+
requestObj: String?,
|
|
152
|
+
callback: Callback?
|
|
153
|
+
) {
|
|
154
|
+
callback?.invoke("Apple pay is not supported")
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// Method to exit the payment sheet
|
|
158
|
+
@ReactMethod
|
|
159
|
+
override fun exitPaymentsheet(rootTag: Double, paymentResult: String, reset: Boolean) {
|
|
160
|
+
val isFragment = PaymentSheetCallbackManager.executeCallback(paymentResult)
|
|
161
|
+
(currentActivity as? FragmentActivity)?.let {
|
|
162
|
+
if (isFragment) it.supportFragmentManager.findFragmentByTag("paymentSheet")
|
|
163
|
+
?.let { fragment ->
|
|
164
|
+
it.supportFragmentManager.beginTransaction().hide(fragment)
|
|
165
|
+
.commitAllowingStateLoss()
|
|
166
|
+
}
|
|
167
|
+
else it.finish()
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
override fun exitPaymentMethodManagement(
|
|
172
|
+
rootTag: Double,
|
|
173
|
+
result: String?,
|
|
174
|
+
reset: Boolean
|
|
175
|
+
) {
|
|
176
|
+
TODO("Not yet implemented")
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// Method to exit the widget
|
|
180
|
+
@ReactMethod
|
|
181
|
+
override fun exitWidget(paymentResult: String, widgetType: String) {
|
|
182
|
+
// WidgetLaunche.onPaymentResultCallback(widgetType, paymentResult)
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// Method to exit the card form
|
|
186
|
+
@ReactMethod
|
|
187
|
+
override fun exitCardForm(paymentResult: String) {
|
|
188
|
+
// WidgetLauncher.onPaymentResultCallback(PaymentMethod.CARD.apiValue, paymentResult)
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// Method to launch widget payment sheet
|
|
192
|
+
@ReactMethod
|
|
193
|
+
override fun launchWidgetPaymentSheet(paymentResult: String, callBack: Callback) {
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// Method to exit widget payment sheet
|
|
197
|
+
@ReactMethod
|
|
198
|
+
override fun exitWidgetPaymentsheet(rootTag: Double, paymentResult: String, reset: Boolean) {
|
|
199
|
+
findViewWithRootTag(rootTag.toInt(), {
|
|
200
|
+
it?.notifyResult(CallbackType.PAYMENT_RESULT, paymentResult)
|
|
201
|
+
})
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
@ReactMethod
|
|
205
|
+
override fun notifyWidgetPaymentResult(rootTag: Double, result: String) {
|
|
206
|
+
Log.i("Manideep", rootTag.toInt().toString())
|
|
207
|
+
findViewWithRootTag(rootTag.toInt(), { fragment ->
|
|
208
|
+
if (fragment == null) {
|
|
209
|
+
Log.w(
|
|
210
|
+
"HyperModule",
|
|
211
|
+
"notifyWidgetPaymentResult: no fragment found for rootTag=$rootTag"
|
|
212
|
+
)
|
|
213
|
+
} else {
|
|
214
|
+
fragment.notifyResult(CallbackType.CONFIRM_ACTION, result)
|
|
215
|
+
}
|
|
216
|
+
})
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
override fun onAddPaymentMethod(data: String?) {
|
|
220
|
+
TODO("Not yet implemented")
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
@ReactMethod
|
|
224
|
+
override fun onUpdateIntentEvent(rootTag: Double, type: String, result: String) {
|
|
225
|
+
findViewWithRootTag(rootTag.toInt(), { fragment ->
|
|
226
|
+
if (fragment == null) {
|
|
227
|
+
Log.w("HyperModule", "onUpdateIntentEvent: no fragment found for rootTag=$rootTag")
|
|
228
|
+
return@findViewWithRootTag
|
|
229
|
+
}
|
|
230
|
+
if (type == "UPDATE_INTENT_INIT_RETURNED") {
|
|
231
|
+
fragment.notifyResult(CallbackType.UPDATE_INTENT_INIT, result)
|
|
232
|
+
} else if (type == "UPDATE_INTENT_COMPLETE_RETURNED") {
|
|
233
|
+
fragment.notifyResult(CallbackType.UPDATE_INTENT_COMPLETE, result)
|
|
234
|
+
}
|
|
235
|
+
})
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
// Variable to keep track of event listener count
|
|
239
|
+
private val listenerCount = AtomicInteger(0)
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
// Method to add event listener
|
|
243
|
+
@ReactMethod
|
|
244
|
+
override fun addListener(eventName: String?) {
|
|
245
|
+
if (listenerCount.incrementAndGet() == 1) {
|
|
246
|
+
HyperEventEmitter.initialize(rct)
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
// Method to remove event listeners
|
|
251
|
+
@ReactMethod
|
|
252
|
+
override fun removeListeners(count: Double) {
|
|
253
|
+
listenerCount.addAndGet(-count.toInt())
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
@ReactMethod
|
|
257
|
+
override fun emitPaymentEvent(rootTag: Double, eventType: String, payload: ReadableMap) {
|
|
258
|
+
Log.i("Manideep", rootTag.toInt().toString())
|
|
259
|
+
findViewWithRootTag(rootTag.toInt(), { fragment ->
|
|
260
|
+
if (fragment == null) {
|
|
261
|
+
Log.w("HyperModule", "emitPaymentEvent: no fragment found for rootTag=$rootTag")
|
|
262
|
+
} else {
|
|
263
|
+
fragment.notifyEvent(eventType, payload)
|
|
264
|
+
}
|
|
265
|
+
})
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
@ReactMethod
|
|
269
|
+
override fun openIframeBridge(url: String, timeoutMs: Double, callback: Callback) {
|
|
270
|
+
if (timeoutMs <= 0) {
|
|
271
|
+
callback.invoke("")
|
|
272
|
+
return
|
|
273
|
+
}
|
|
274
|
+
if (url.isBlank()) {
|
|
275
|
+
callback.invoke("")
|
|
276
|
+
return
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
val mainHandler = Handler(Looper.getMainLooper())
|
|
280
|
+
val callbackInvoked = AtomicBoolean(false)
|
|
281
|
+
var webViewWrapper: HSWebViewWrapper? = null
|
|
282
|
+
var timeoutRunnable: Runnable? = null
|
|
283
|
+
|
|
284
|
+
val invokeCallback = { redirectUrl: String ->
|
|
285
|
+
if (callbackInvoked.compareAndSet(false, true)) {
|
|
286
|
+
timeoutRunnable?.let { mainHandler.removeCallbacks(it) }
|
|
287
|
+
mainHandler.post {
|
|
288
|
+
webViewWrapper?.let { wrapper ->
|
|
289
|
+
try {
|
|
290
|
+
(wrapper.parent as? ViewGroup)?.removeView(wrapper)
|
|
291
|
+
wrapper.webView.stopLoading()
|
|
292
|
+
wrapper.webView.destroy()
|
|
293
|
+
} catch (e: Exception) {
|
|
294
|
+
Log.e("HyperDDC", "cleanup error: ${e.message}")
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
webViewWrapper = null
|
|
298
|
+
}
|
|
299
|
+
callback.invoke(redirectUrl)
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
mainHandler.post {
|
|
304
|
+
val activity = currentActivity ?: run {
|
|
305
|
+
invokeCallback("")
|
|
306
|
+
return@post
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
val manager = HSWebViewManagerImpl(activity, HSCallback { _ -> })
|
|
310
|
+
|
|
311
|
+
var wrapper: HSWebViewWrapper? = null
|
|
312
|
+
repeat(2) { attempt ->
|
|
313
|
+
if (wrapper != null) return@repeat
|
|
314
|
+
try {
|
|
315
|
+
wrapper = manager.createViewInstance()
|
|
316
|
+
} catch (e: Exception) {
|
|
317
|
+
if (attempt == 0) Thread.sleep(200)
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
val resolvedWrapper = wrapper ?: run {
|
|
321
|
+
invokeCallback("")
|
|
322
|
+
return@post
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
manager.setJavaScriptEnabled(resolvedWrapper, true)
|
|
326
|
+
|
|
327
|
+
val ddcBridge = object : Any() {
|
|
328
|
+
@android.webkit.JavascriptInterface
|
|
329
|
+
fun onMessage(data: String) {
|
|
330
|
+
invokeCallback(data)
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
resolvedWrapper.webView.addJavascriptInterface(ddcBridge, "HyperDDCBridge")
|
|
334
|
+
|
|
335
|
+
resolvedWrapper.webView.webViewClient = object : WebViewClient() {
|
|
336
|
+
override fun shouldOverrideUrlLoading(view: WebView, request: WebResourceRequest): Boolean {
|
|
337
|
+
if (request.isForMainFrame) {
|
|
338
|
+
val url = request.url.toString()
|
|
339
|
+
Log.d("HyperDDC", "shouldOverride intercepted: $url")
|
|
340
|
+
invokeCallback("{\"next_action\":{\"type\":\"redirect_to_url\",\"url\":\"$url\"}}")
|
|
341
|
+
return true
|
|
342
|
+
}
|
|
343
|
+
return false
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
@Suppress("DEPRECATION")
|
|
347
|
+
override fun shouldOverrideUrlLoading(view: WebView, url: String): Boolean {
|
|
348
|
+
Log.d("HyperDDC", "shouldOverride intercepted (legacy): $url")
|
|
349
|
+
invokeCallback("{\"next_action\":{\"type\":\"redirect_to_url\",\"url\":\"$url\"}}")
|
|
350
|
+
return true
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
resolvedWrapper.apply {
|
|
355
|
+
isFocusable = false
|
|
356
|
+
isFocusableInTouchMode = false
|
|
357
|
+
layoutParams = ViewGroup.LayoutParams(1, 1)
|
|
358
|
+
translationX = -9999f
|
|
359
|
+
translationY = -9999f
|
|
360
|
+
importantForAccessibility = View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
activity.findViewById<ViewGroup>(android.R.id.content).addView(resolvedWrapper)
|
|
364
|
+
webViewWrapper = resolvedWrapper
|
|
365
|
+
|
|
366
|
+
val wrapperHtml = """
|
|
367
|
+
<html><body>
|
|
368
|
+
<iframe src="$url" style="display:none;width:1px;height:1px;"></iframe>
|
|
369
|
+
<script>
|
|
370
|
+
window.addEventListener('message', function(event) {
|
|
371
|
+
var str = typeof event.data === 'string' ? event.data : JSON.stringify(event.data);
|
|
372
|
+
try { HyperDDCBridge.onMessage(str); } catch(e) {}
|
|
373
|
+
});
|
|
374
|
+
</script>
|
|
375
|
+
</body></html>
|
|
376
|
+
""".trimIndent()
|
|
377
|
+
resolvedWrapper.webView.loadDataWithBaseURL(url, wrapperHtml, "text/html", "UTF-8", null)
|
|
378
|
+
|
|
379
|
+
timeoutRunnable = Runnable { invokeCallback("") }.also {
|
|
380
|
+
mainHandler.postDelayed(it, timeoutMs.toLong())
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
private fun findViewWithRootTag(rootTag: Int, onFound: (HyperFragment?) -> Unit) {
|
|
386
|
+
val uiManagerModule =
|
|
387
|
+
reactApplicationContext.getNativeModule<UIManagerModule?>(UIManagerModule::class.java)
|
|
388
|
+
|
|
389
|
+
if (uiManagerModule == null) {
|
|
390
|
+
onFound(null)
|
|
391
|
+
return
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
uiManagerModule.addUIBlock { nvhm ->
|
|
395
|
+
try {
|
|
396
|
+
val reactRootView = nvhm.resolveView(rootTag)
|
|
397
|
+
onFound(FragmentManager.findFragment(reactRootView))
|
|
398
|
+
} catch (e: IllegalViewOperationException) {
|
|
399
|
+
onFound(null)
|
|
400
|
+
} catch (e: Exception) {
|
|
401
|
+
onFound(null)
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
package io.hyperswitch.react
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.ReactPackage
|
|
4
|
+
import com.facebook.react.bridge.NativeModule
|
|
5
|
+
import com.facebook.react.bridge.ReactApplicationContext
|
|
6
|
+
import com.facebook.react.uimanager.ViewManager
|
|
7
|
+
|
|
8
|
+
class HyperPackage : ReactPackage {
|
|
9
|
+
override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>> {
|
|
10
|
+
return listOf(GooglePayButtonManager())
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
override fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule> {
|
|
14
|
+
return listOf(HyperModule(reactContext), HyperHeadlessModule(reactContext))
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
package io.hyperswitch.react
|
|
2
|
+
|
|
3
|
+
import android.app.Application
|
|
4
|
+
import android.content.Context
|
|
5
|
+
import com.facebook.react.HyperPackageList
|
|
6
|
+
import com.facebook.react.ReactHost
|
|
7
|
+
import com.facebook.react.ReactNativeHost
|
|
8
|
+
import com.facebook.react.ReactPackage
|
|
9
|
+
import com.facebook.react.bridge.JSBundleLoader
|
|
10
|
+
import com.facebook.react.bridge.ReactContext
|
|
11
|
+
import com.facebook.react.common.annotations.UnstableReactNativeAPI
|
|
12
|
+
import com.facebook.react.defaults.DefaultComponentsRegistry
|
|
13
|
+
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint
|
|
14
|
+
import com.facebook.react.defaults.DefaultReactHost
|
|
15
|
+
import com.facebook.react.defaults.DefaultReactHostDelegate
|
|
16
|
+
import com.facebook.react.defaults.DefaultReactNativeHost
|
|
17
|
+
import com.facebook.react.defaults.DefaultTurboModuleManagerDelegate
|
|
18
|
+
import com.facebook.react.fabric.ComponentFactory
|
|
19
|
+
import com.facebook.react.runtime.ReactHostImpl
|
|
20
|
+
import com.facebook.react.runtime.cxxreactpackage.CxxReactPackage
|
|
21
|
+
import com.facebook.react.runtime.hermes.HermesInstance
|
|
22
|
+
import com.facebook.react.soloader.OpenSourceMergedSoMapping
|
|
23
|
+
import com.facebook.soloader.SoLoader
|
|
24
|
+
import com.hyperswitchsdkreactnative.BuildConfig
|
|
25
|
+
import com.hyperswitchsdkreactnative.R
|
|
26
|
+
import io.hyperswitch.logs.CrashHandler
|
|
27
|
+
import io.hyperswitch.logs.EventName
|
|
28
|
+
import io.hyperswitch.logs.HSLog
|
|
29
|
+
import io.hyperswitch.logs.HyperLogManager
|
|
30
|
+
import io.hyperswitch.logs.LogCategory
|
|
31
|
+
import java.util.concurrent.atomic.AtomicBoolean
|
|
32
|
+
import java.util.concurrent.atomic.AtomicReference
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* ReactNativeController
|
|
36
|
+
*
|
|
37
|
+
* Entry point for initializing and accessing the Hyperswitch React Native runtime.
|
|
38
|
+
* This object is responsible for:
|
|
39
|
+
* - Initializing React Native (Old & New Architecture)
|
|
40
|
+
* - Loading JS bundles (OTA or bundled assets)
|
|
41
|
+
* - Managing ReactHost / ReactNativeHost lifecycle
|
|
42
|
+
* - Setting up crash handling and native dependencies
|
|
43
|
+
*
|
|
44
|
+
* This SDK is designed to be initialized once per application lifecycle.
|
|
45
|
+
*/
|
|
46
|
+
object ReactNativeController {
|
|
47
|
+
|
|
48
|
+
@Volatile
|
|
49
|
+
private var reactNativeHost = AtomicReference<ReactNativeHost?>(null)
|
|
50
|
+
|
|
51
|
+
@Volatile
|
|
52
|
+
private var reactHost = AtomicReference<ReactHost?>(null)
|
|
53
|
+
|
|
54
|
+
@Volatile
|
|
55
|
+
private var isInitialized = AtomicBoolean(false)
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Resolves the JavaScript bundle path using Hyper Airborne OTA if available.
|
|
59
|
+
*
|
|
60
|
+
* Behavior:
|
|
61
|
+
* - Determines SDK environment using the publishable key
|
|
62
|
+
* - Reads OTA endpoint from resources based on environment
|
|
63
|
+
* - Dynamically loads AirborneOTA via reflection (optional dependency)
|
|
64
|
+
* - Fetches the OTA-downloaded bundle path
|
|
65
|
+
* - Falls back to bundled assets if OTA is disabled, unavailable, or fails
|
|
66
|
+
*
|
|
67
|
+
* @param application Application context
|
|
68
|
+
* @return Path to the JS bundle (OTA or bundled asset)
|
|
69
|
+
*/
|
|
70
|
+
private fun getBundleFromAirborne(application: Application): String {
|
|
71
|
+
try {
|
|
72
|
+
// val environment = SDKEnvironment.PROD
|
|
73
|
+
// TODO: change this to ENV check based on the Configuration.
|
|
74
|
+
val airborneUrl = application.getString(
|
|
75
|
+
R.string.hyperOTAEndPoint
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
// Ensure OTA endpoint is valid
|
|
79
|
+
if (airborneUrl != "hyperOTA_END_POINT_") {
|
|
80
|
+
val airborneClass =
|
|
81
|
+
Class.forName("io.hyperswitch.airborne.AirborneOTA")
|
|
82
|
+
|
|
83
|
+
val constructor = airborneClass.getConstructor(
|
|
84
|
+
Context::class.java,
|
|
85
|
+
String::class.java,
|
|
86
|
+
String::class.java
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
val instance = constructor.newInstance(
|
|
90
|
+
application.applicationContext,
|
|
91
|
+
BuildConfig.VERSION_NAME,
|
|
92
|
+
airborneUrl
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
val getBundlePath =
|
|
96
|
+
airborneClass.getMethod("getBundlePath")
|
|
97
|
+
return getBundlePath.invoke(instance) as String
|
|
98
|
+
}
|
|
99
|
+
} catch (_: Exception) {
|
|
100
|
+
}
|
|
101
|
+
return "assets://hyperswitch.bundle"
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Creates and configures the ReactNativeHost instance.
|
|
106
|
+
*
|
|
107
|
+
* Responsibilities:
|
|
108
|
+
* - Registers required React Native packages
|
|
109
|
+
* - Enables Hermes and New Architecture flags
|
|
110
|
+
* - Resolves JS bundle source (OTA or bundled)
|
|
111
|
+
*
|
|
112
|
+
* @param application Application context
|
|
113
|
+
* @return Configured ReactNativeHost instance
|
|
114
|
+
*/
|
|
115
|
+
private fun createReactNativeHost(
|
|
116
|
+
application: Application,
|
|
117
|
+
): ReactNativeHost {
|
|
118
|
+
return object : DefaultReactNativeHost(application) {
|
|
119
|
+
override fun getPackages(): List<ReactPackage> {
|
|
120
|
+
return HyperPackageList(this).packages.apply {
|
|
121
|
+
add(HyperPackage())
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
override fun getJSMainModuleName(): String = "index"
|
|
126
|
+
override fun getUseDeveloperSupport(): Boolean = false
|
|
127
|
+
override val isNewArchEnabled: Boolean =
|
|
128
|
+
BuildConfig.IS_NEW_ARCHITECTURE_ENABLED
|
|
129
|
+
override val isHermesEnabled: Boolean =
|
|
130
|
+
BuildConfig.IS_HERMES_ENABLED
|
|
131
|
+
|
|
132
|
+
override fun getJSBundleFile(): String =
|
|
133
|
+
getBundleFromAirborne(application)
|
|
134
|
+
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Returns whether the SDK has already been initialized.
|
|
140
|
+
*
|
|
141
|
+
* @return true if initialized, false otherwise
|
|
142
|
+
*/
|
|
143
|
+
fun getIsInitialized(): Boolean {
|
|
144
|
+
return isInitialized.get()
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Returns the initialized ReactNativeHost instance.
|
|
149
|
+
*
|
|
150
|
+
* @throws IllegalStateException if SDK is not initialized
|
|
151
|
+
* @return ReactNativeHost
|
|
152
|
+
*/
|
|
153
|
+
fun getReactNativeHost(): ReactNativeHost {
|
|
154
|
+
return checkNotNull(reactNativeHost.get()) {
|
|
155
|
+
"ReactNative not initialized. Call ReactNativeController.initialize()"
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Returns the initialized ReactHost instance.
|
|
161
|
+
*
|
|
162
|
+
* @throws IllegalStateException if SDK is not initialized
|
|
163
|
+
* @return ReactHost
|
|
164
|
+
*/
|
|
165
|
+
fun getReactHost(): ReactHost {
|
|
166
|
+
return checkNotNull(reactHost.get()) {
|
|
167
|
+
"ReactNative not initialized. Call ReactNativeController.initialize()"
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
@OptIn(UnstableReactNativeAPI::class)
|
|
172
|
+
fun createReactHost(application: Application): ReactHost {
|
|
173
|
+
|
|
174
|
+
val bundleLoader =
|
|
175
|
+
JSBundleLoader.createAssetLoader(application, "assets://hyperswitch.bundle", true)
|
|
176
|
+
|
|
177
|
+
val defaultTmmDelegateBuilder = DefaultTurboModuleManagerDelegate.Builder()
|
|
178
|
+
val cxxReactPackageProviders: List<(ReactContext) -> CxxReactPackage> = emptyList()
|
|
179
|
+
cxxReactPackageProviders.forEach { defaultTmmDelegateBuilder.addCxxReactPackage(it) }
|
|
180
|
+
val defaultReactHostDelegate =
|
|
181
|
+
DefaultReactHostDelegate(
|
|
182
|
+
jsMainModulePath = "index",
|
|
183
|
+
jsBundleLoader = bundleLoader,
|
|
184
|
+
reactPackages = HyperPackageList(application).packages,
|
|
185
|
+
jsRuntimeFactory = HermesInstance(),
|
|
186
|
+
bindingsInstaller = null,
|
|
187
|
+
turboModuleManagerDelegateBuilder = defaultTmmDelegateBuilder,
|
|
188
|
+
exceptionHandler = {}
|
|
189
|
+
)
|
|
190
|
+
val componentFactory = ComponentFactory()
|
|
191
|
+
DefaultComponentsRegistry.register(componentFactory)
|
|
192
|
+
|
|
193
|
+
return ReactHostImpl(
|
|
194
|
+
application,
|
|
195
|
+
defaultReactHostDelegate,
|
|
196
|
+
componentFactory,
|
|
197
|
+
false, /* allowPackagerServerAccess */
|
|
198
|
+
false
|
|
199
|
+
)
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Initializes the ReactNativeController.
|
|
204
|
+
*
|
|
205
|
+
* This method:
|
|
206
|
+
* - Ensures single initialization (thread-safe)
|
|
207
|
+
* - Registers a global crash handler
|
|
208
|
+
* - Initializes SoLoader
|
|
209
|
+
* - Loads New Architecture entry point if enabled
|
|
210
|
+
* - Creates ReactNativeHost and ReactHost instances
|
|
211
|
+
* @param application Application instance
|
|
212
|
+
*/
|
|
213
|
+
fun initialize(application: Application) {
|
|
214
|
+
try {
|
|
215
|
+
synchronized(this) {
|
|
216
|
+
if (isInitialized.get()) return
|
|
217
|
+
|
|
218
|
+
Thread.setDefaultUncaughtExceptionHandler(
|
|
219
|
+
CrashHandler(application, BuildConfig.VERSION_NAME)
|
|
220
|
+
)
|
|
221
|
+
|
|
222
|
+
if (false) {
|
|
223
|
+
SoLoader.init(application, OpenSourceMergedSoMapping)
|
|
224
|
+
|
|
225
|
+
if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
|
|
226
|
+
DefaultNewArchitectureEntryPoint.load()
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
reactNativeHost.set(createReactNativeHost(application))
|
|
233
|
+
// TODO use the proper React Host that fixes the proper developer
|
|
234
|
+
reactHost.set(
|
|
235
|
+
createReactHost(application)
|
|
236
|
+
)
|
|
237
|
+
|
|
238
|
+
isInitialized.set(true)
|
|
239
|
+
}
|
|
240
|
+
} catch (e: Exception) {
|
|
241
|
+
HyperLogManager.addLog(
|
|
242
|
+
HSLog.LogBuilder()
|
|
243
|
+
.value("Failed to initialize Hyperswitch SDK: ${e.message}")
|
|
244
|
+
.category(LogCategory.API)
|
|
245
|
+
.eventName(EventName.CRASH_EVENT)
|
|
246
|
+
.logType("error")
|
|
247
|
+
.build()
|
|
248
|
+
)
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|