From 082d9ee18e6bb1eb8797b21ae24cc3599a8043ae Mon Sep 17 00:00:00 2001 From: minibits-cash Date: Mon, 1 Jun 2026 16:33:53 +0200 Subject: [PATCH] NFC cold and hot start support --- android/app/build.gradle | 2 +- android/app/src/main/AndroidManifest.xml | 269 +++++++----------- .../java/com/minibits_wallet/MainActivity.kt | 13 + android/app/src/main/res/values/strings.xml | 1 - fingerprint.json | 16 +- ios/minibits_wallet/Info.plist | 2 +- src/screens/NfcPayScreen.tsx | 67 ++++- src/screens/WalletScreen.tsx | 42 ++- src/services/nfcService.ts | 94 +++++- 9 files changed, 320 insertions(+), 186 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index c5d6cedf..6dbc7890 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -95,7 +95,7 @@ android { applicationId "com.minibits_wallet" minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion - versionCode 58073 + versionCode 58075 versionName "0.4.3" } diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index d9f8aa05..ecd6f3bc 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -4,163 +4,112 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android/app/src/main/java/com/minibits_wallet/MainActivity.kt b/android/app/src/main/java/com/minibits_wallet/MainActivity.kt index f7725974..1de34702 100644 --- a/android/app/src/main/java/com/minibits_wallet/MainActivity.kt +++ b/android/app/src/main/java/com/minibits_wallet/MainActivity.kt @@ -1,6 +1,7 @@ package com.minibits_wallet // minibits_wallet:react-native-screens +import android.content.Intent import android.os.Bundle import com.facebook.react.ReactActivity import com.facebook.react.ReactActivityDelegate @@ -26,4 +27,16 @@ open class MainActivity : ReactActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(null) } + + /** + * This activity is launchMode="singleTask", so when an NFC tap (or deep link) arrives while + * the app is already running it is delivered here via onNewIntent rather than a fresh start. + * super.onNewIntent forwards the intent to React Native's ActivityEventListeners (which the + * NFC manager and Linking module use), and setIntent updates getIntent() so launch-intent + * reads (getLaunchTagEvent / Linking.getInitialURL) reflect the new intent on warm resume. + */ + override fun onNewIntent(intent: Intent) { + super.onNewIntent(intent) + setIntent(intent) + } } diff --git a/android/app/src/main/res/values/strings.xml b/android/app/src/main/res/values/strings.xml index 9ab9f82a..80ff2a3e 100644 --- a/android/app/src/main/res/values/strings.xml +++ b/android/app/src/main/res/values/strings.xml @@ -1,4 +1,3 @@ Minibits - e9f51a75d88d5727c549de0e6250f351feb1e127 diff --git a/fingerprint.json b/fingerprint.json index bc159cd5..853036d6 100644 --- a/fingerprint.json +++ b/fingerprint.json @@ -15,7 +15,7 @@ "reasons": [ "rncoreAutolinking" ], - "hash": "69a7bbb3afa191a4772eb48464ad41d1d7581c3a" + "hash": "026ef4eb346e632647244781e9ce7d416227e0b7" }, { "type": "dir", @@ -237,14 +237,14 @@ { "type": "contents", "id": "rncoreAutolinkingConfig", - "contents": "{\"@hot-updater/react-native\":{\"root\":\"node_modules/@hot-updater/react-native\",\"name\":\"@hot-updater/react-native\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/@hot-updater/react-native/HotUpdater.podspec\",\"version\":\"0.23.1\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/@hot-updater/react-native/android\",\"packageImportPath\":\"import com.hotupdater.HotUpdaterPackage;\",\"packageInstance\":\"new HotUpdaterPackage()\",\"buildTypes\":[],\"libraryName\":\"HotUpdaterSpec\",\"componentDescriptors\":[],\"cmakeListsPath\":\"node_modules/@hot-updater/react-native/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"@notifee/react-native\":{\"root\":\"node_modules/@notifee/react-native\",\"name\":\"@notifee/react-native\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/@notifee/react-native/RNNotifee.podspec\",\"version\":\"9.1.8\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/@notifee/react-native/android\",\"packageImportPath\":\"import io.invertase.notifee.NotifeePackage;\",\"packageInstance\":\"new NotifeePackage()\",\"buildTypes\":[],\"componentDescriptors\":[],\"cmakeListsPath\":\"node_modules/@notifee/react-native/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"@op-engineering/op-sqlite\":{\"root\":\"node_modules/@op-engineering/op-sqlite\",\"name\":\"@op-engineering/op-sqlite\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/@op-engineering/op-sqlite/op-sqlite.podspec\",\"version\":\"16.2.0\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/@op-engineering/op-sqlite/android\",\"packageImportPath\":\"import com.op.sqlite.OPSQLitePackage;\",\"packageInstance\":\"new OPSQLitePackage()\",\"buildTypes\":[],\"libraryName\":\"OPSQLiteSpec\",\"componentDescriptors\":[],\"cmakeListsPath\":\"node_modules/@op-engineering/op-sqlite/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"@react-native-clipboard/clipboard\":{\"root\":\"node_modules/@react-native-clipboard/clipboard\",\"name\":\"@react-native-clipboard/clipboard\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/@react-native-clipboard/clipboard/RNCClipboard.podspec\",\"version\":\"1.16.3\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/@react-native-clipboard/clipboard/android\",\"packageImportPath\":\"import com.reactnativecommunity.clipboard.ClipboardPackage;\",\"packageInstance\":\"new ClipboardPackage()\",\"buildTypes\":[],\"libraryName\":\"rnclipboard\",\"componentDescriptors\":[],\"cmakeListsPath\":\"node_modules/@react-native-clipboard/clipboard/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"@react-native-community/netinfo\":{\"root\":\"node_modules/@react-native-community/netinfo\",\"name\":\"@react-native-community/netinfo\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/@react-native-community/netinfo/react-native-netinfo.podspec\",\"version\":\"11.4.1\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/@react-native-community/netinfo/android\",\"packageImportPath\":\"import com.reactnativecommunity.netinfo.NetInfoPackage;\",\"packageInstance\":\"new NetInfoPackage()\",\"buildTypes\":[],\"componentDescriptors\":[],\"cmakeListsPath\":\"node_modules/@react-native-community/netinfo/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"@react-native-firebase/app\":{\"root\":\"node_modules/@react-native-firebase/app\",\"name\":\"@react-native-firebase/app\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/@react-native-firebase/app/RNFBApp.podspec\",\"version\":\"23.5.0\",\"configurations\":[],\"scriptPhases\":[{\"name\":\"[RNFB] Core Configuration\",\"path\":\"./ios_config.sh\",\"execution_position\":\"after_compile\",\"input_files\":[\"$(BUILT_PRODUCTS_DIR)/$(INFOPLIST_PATH)\"]}]},\"android\":{\"sourceDir\":\"node_modules/@react-native-firebase/app/android\",\"packageImportPath\":\"import io.invertase.firebase.app.ReactNativeFirebaseAppPackage;\",\"packageInstance\":\"new ReactNativeFirebaseAppPackage()\",\"buildTypes\":[],\"componentDescriptors\":[],\"cmakeListsPath\":\"node_modules/@react-native-firebase/app/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"@react-native-firebase/messaging\":{\"root\":\"node_modules/@react-native-firebase/messaging\",\"name\":\"@react-native-firebase/messaging\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/@react-native-firebase/messaging/RNFBMessaging.podspec\",\"version\":\"23.5.0\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/@react-native-firebase/messaging/android\",\"packageImportPath\":\"import io.invertase.firebase.messaging.ReactNativeFirebaseMessagingPackage;\",\"packageInstance\":\"new ReactNativeFirebaseMessagingPackage()\",\"buildTypes\":[],\"componentDescriptors\":[],\"cmakeListsPath\":\"node_modules/@react-native-firebase/messaging/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"@sentry/react-native\":{\"root\":\"node_modules/@sentry/react-native\",\"name\":\"@sentry/react-native\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/@sentry/react-native/RNSentry.podspec\",\"version\":\"7.7.0\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/@sentry/react-native/android\",\"packageImportPath\":\"import io.sentry.react.RNSentryPackage;\",\"packageInstance\":\"new RNSentryPackage()\",\"buildTypes\":[],\"libraryName\":\"RNSentrySpec\",\"componentDescriptors\":[\"RNSentryReplayMaskComponentDescriptor\",\"RNSentryReplayUnmaskComponentDescriptor\"],\"cmakeListsPath\":\"node_modules/@sentry/react-native/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"react-native-camera-kit\":{\"root\":\"node_modules/react-native-camera-kit\",\"name\":\"react-native-camera-kit\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/react-native-camera-kit/ReactNativeCameraKit.podspec\",\"version\":\"16.2.1\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/react-native-camera-kit/android\",\"packageImportPath\":\"import com.rncamerakit.RNCameraKitPackage;\",\"packageInstance\":\"new RNCameraKitPackage()\",\"buildTypes\":[],\"libraryName\":\"NativeCameraKitSpec\",\"componentDescriptors\":[\"CKCameraComponentDescriptor\"],\"cmakeListsPath\":\"node_modules/react-native-camera-kit/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"react-native-change-icon\":{\"root\":\"node_modules/react-native-change-icon\",\"name\":\"react-native-change-icon\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/react-native-change-icon/react-native-change-icon.podspec\",\"version\":\"5.0.0\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/react-native-change-icon/android\",\"packageImportPath\":\"import com.reactnativechangeicon.ChangeIconPackage;\",\"packageInstance\":\"new ChangeIconPackage(BuildConfig.APPLICATION_ID)\",\"buildTypes\":[],\"libraryName\":\"RNChangeIconSpec\",\"componentDescriptors\":[],\"cmakeListsPath\":\"node_modules/react-native-change-icon/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"react-native-edge-to-edge\":{\"root\":\"node_modules/react-native-edge-to-edge\",\"name\":\"react-native-edge-to-edge\",\"platforms\":{\"ios\":null,\"android\":{\"sourceDir\":\"node_modules/react-native-edge-to-edge/android\",\"packageImportPath\":\"import com.zoontek.rnedgetoedge.EdgeToEdgePackage;\",\"packageInstance\":\"new EdgeToEdgePackage()\",\"buildTypes\":[],\"libraryName\":\"RNEdgeToEdge\",\"componentDescriptors\":[],\"cmakeListsPath\":\"node_modules/react-native-edge-to-edge/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"react-native-exit-app\":{\"root\":\"node_modules/react-native-exit-app\",\"name\":\"react-native-exit-app\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/react-native-exit-app/RNExitApp.podspec\",\"version\":\"2.0.0\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/react-native-exit-app/android\",\"packageImportPath\":\"import com.github.wumke.RNExitApp.RNExitAppPackage;\",\"packageInstance\":\"new RNExitAppPackage()\",\"buildTypes\":[],\"libraryName\":\"RNExitAppSpec\",\"componentDescriptors\":[],\"cmakeListsPath\":\"node_modules/react-native-exit-app/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"react-native-fast-image\":{\"root\":\"node_modules/react-native-fast-image\",\"name\":\"react-native-fast-image\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/react-native-fast-image/RNFastImage.podspec\",\"version\":\"8.6.3\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/react-native-fast-image/android\",\"packageImportPath\":\"import com.dylanvann.fastimage.FastImageViewPackage;\",\"packageInstance\":\"new FastImageViewPackage()\",\"buildTypes\":[],\"componentDescriptors\":[],\"cmakeListsPath\":\"node_modules/react-native-fast-image/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"react-native-gesture-handler\":{\"root\":\"node_modules/react-native-gesture-handler\",\"name\":\"react-native-gesture-handler\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/react-native-gesture-handler/RNGestureHandler.podspec\",\"version\":\"2.28.0\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/react-native-gesture-handler/android\",\"packageImportPath\":\"import com.swmansion.gesturehandler.RNGestureHandlerPackage;\",\"packageInstance\":\"new RNGestureHandlerPackage()\",\"buildTypes\":[],\"libraryName\":\"rngesturehandler_codegen\",\"componentDescriptors\":[\"RNGestureHandlerButtonComponentDescriptor\",\"RNGestureHandlerRootViewComponentDescriptor\"],\"cmakeListsPath\":\"node_modules/react-native-gesture-handler/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"react-native-hce\":{\"root\":\"node_modules/react-native-hce\",\"name\":\"react-native-hce\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/react-native-hce/react-native-hce.podspec\",\"version\":\"0.3.0\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/react-native-hce/android\",\"packageImportPath\":\"import com.reactnativehce.HcePackage;\",\"packageInstance\":\"new HcePackage()\",\"buildTypes\":[],\"componentDescriptors\":[],\"cmakeListsPath\":\"node_modules/react-native-hce/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"react-native-keychain\":{\"root\":\"node_modules/react-native-keychain\",\"name\":\"react-native-keychain\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/react-native-keychain/RNKeychain.podspec\",\"version\":\"10.0.0\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/react-native-keychain/android\",\"packageImportPath\":\"import com.oblador.keychain.KeychainPackage;\",\"packageInstance\":\"new KeychainPackage()\",\"buildTypes\":[],\"libraryName\":\"RNKeychainSpec\",\"componentDescriptors\":[],\"cmakeListsPath\":\"node_modules/react-native-keychain/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"react-native-localize\":{\"root\":\"node_modules/react-native-localize\",\"name\":\"react-native-localize\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/react-native-localize/RNLocalize.podspec\",\"version\":\"3.5.2\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/react-native-localize/android\",\"packageImportPath\":\"import com.zoontek.rnlocalize.RNLocalizePackage;\",\"packageInstance\":\"new RNLocalizePackage()\",\"buildTypes\":[],\"libraryName\":\"RNLocalizeSpec\",\"componentDescriptors\":[],\"cmakeListsPath\":\"node_modules/react-native-localize/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"react-native-mmkv\":{\"root\":\"node_modules/react-native-mmkv\",\"name\":\"react-native-mmkv\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/react-native-mmkv/react-native-mmkv.podspec\",\"version\":\"3.3.3\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/react-native-mmkv/android\",\"packageImportPath\":\"import com.mrousavy.mmkv.MmkvPackage;\",\"packageInstance\":\"new MmkvPackage()\",\"buildTypes\":[],\"libraryName\":\"RNMmkvSpec\",\"componentDescriptors\":[],\"cmakeListsPath\":\"node_modules/react-native-mmkv/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":\"react-native-mmkv\",\"cxxModuleCMakeListsPath\":\"node_modules/react-native-mmkv/android/CMakeLists.txt\",\"cxxModuleHeaderName\":\"NativeMmkvModule\",\"isPureCxxDependency\":false}}},\"react-native-nfc-manager\":{\"root\":\"node_modules/react-native-nfc-manager\",\"name\":\"react-native-nfc-manager\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/react-native-nfc-manager/react-native-nfc-manager.podspec\",\"version\":\"4.0.0-beta.7\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/react-native-nfc-manager/android\",\"packageImportPath\":\"import community.revteltech.nfc.NfcManagerPackage;\",\"packageInstance\":\"new NfcManagerPackage()\",\"buildTypes\":[],\"libraryName\":\"NativeNfcManagerSpec\",\"componentDescriptors\":[],\"cmakeListsPath\":\"node_modules/react-native-nfc-manager/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"react-native-pager-view\":{\"root\":\"node_modules/react-native-pager-view\",\"name\":\"react-native-pager-view\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/react-native-pager-view/react-native-pager-view.podspec\",\"version\":\"8.0.0\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/react-native-pager-view/android\",\"packageImportPath\":\"import com.reactnativepagerview.PagerViewPackage;\",\"packageInstance\":\"new PagerViewPackage()\",\"buildTypes\":[],\"libraryName\":\"pagerview\",\"componentDescriptors\":[\"RNCViewPagerComponentDescriptor\"],\"cmakeListsPath\":\"node_modules/react-native-pager-view/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"react-native-quick-crypto\":{\"root\":\"node_modules/react-native-quick-crypto\",\"name\":\"react-native-quick-crypto\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/react-native-quick-crypto/react-native-quick-crypto.podspec\",\"version\":\"0.7.17\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/react-native-quick-crypto/android\",\"packageImportPath\":\"import com.margelo.quickcrypto.QuickCryptoPackage;\",\"packageInstance\":\"new QuickCryptoPackage()\",\"buildTypes\":[],\"componentDescriptors\":[],\"cmakeListsPath\":\"node_modules/react-native-quick-crypto/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"react-native-reanimated\":{\"root\":\"node_modules/react-native-reanimated\",\"name\":\"react-native-reanimated\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/react-native-reanimated/RNReanimated.podspec\",\"version\":\"4.2.2\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/react-native-reanimated/android\",\"packageImportPath\":\"import com.swmansion.reanimated.ReanimatedPackage;\",\"packageInstance\":\"new ReanimatedPackage()\",\"buildTypes\":[],\"libraryName\":\"rnreanimated\",\"componentDescriptors\":[],\"cmakeListsPath\":\"node_modules/react-native-reanimated/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"react-native-safe-area-context\":{\"root\":\"node_modules/react-native-safe-area-context\",\"name\":\"react-native-safe-area-context\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/react-native-safe-area-context/react-native-safe-area-context.podspec\",\"version\":\"5.6.1\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/react-native-safe-area-context/android\",\"packageImportPath\":\"import com.th3rdwave.safeareacontext.SafeAreaContextPackage;\",\"packageInstance\":\"new SafeAreaContextPackage()\",\"buildTypes\":[],\"libraryName\":\"safeareacontext\",\"componentDescriptors\":[\"RNCSafeAreaProviderComponentDescriptor\",\"RNCSafeAreaViewComponentDescriptor\"],\"cmakeListsPath\":\"node_modules/react-native-safe-area-context/android/src/main/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"react-native-screens\":{\"root\":\"node_modules/react-native-screens\",\"name\":\"react-native-screens\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/react-native-screens/RNScreens.podspec\",\"version\":\"4.16.0\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/react-native-screens/android\",\"packageImportPath\":\"import com.swmansion.rnscreens.RNScreensPackage;\",\"packageInstance\":\"new RNScreensPackage()\",\"buildTypes\":[],\"libraryName\":\"rnscreens\",\"componentDescriptors\":[\"RNSFullWindowOverlayComponentDescriptor\",\"RNSScreenContainerComponentDescriptor\",\"RNSScreenNavigationContainerComponentDescriptor\",\"RNSScreenStackHeaderConfigComponentDescriptor\",\"RNSScreenStackHeaderSubviewComponentDescriptor\",\"RNSScreenStackComponentDescriptor\",\"RNSSearchBarComponentDescriptor\",\"RNSScreenComponentDescriptor\",\"RNSScreenFooterComponentDescriptor\",\"RNSScreenContentWrapperComponentDescriptor\",\"RNSModalScreenComponentDescriptor\",\"RNSBottomTabsComponentDescriptor\"],\"cmakeListsPath\":\"node_modules/react-native-screens/android/src/main/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"react-native-svg\":{\"root\":\"node_modules/react-native-svg\",\"name\":\"react-native-svg\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/react-native-svg/RNSVG.podspec\",\"version\":\"15.13.0\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/react-native-svg/android\",\"packageImportPath\":\"import com.horcrux.svg.SvgPackage;\",\"packageInstance\":\"new SvgPackage()\",\"buildTypes\":[],\"libraryName\":\"rnsvg\",\"componentDescriptors\":[\"RNSVGCircleComponentDescriptor\",\"RNSVGClipPathComponentDescriptor\",\"RNSVGDefsComponentDescriptor\",\"RNSVGFeBlendComponentDescriptor\",\"RNSVGFeColorMatrixComponentDescriptor\",\"RNSVGFeCompositeComponentDescriptor\",\"RNSVGFeFloodComponentDescriptor\",\"RNSVGFeGaussianBlurComponentDescriptor\",\"RNSVGFeMergeComponentDescriptor\",\"RNSVGFeOffsetComponentDescriptor\",\"RNSVGFilterComponentDescriptor\",\"RNSVGEllipseComponentDescriptor\",\"RNSVGForeignObjectComponentDescriptor\",\"RNSVGGroupComponentDescriptor\",\"RNSVGImageComponentDescriptor\",\"RNSVGLinearGradientComponentDescriptor\",\"RNSVGLineComponentDescriptor\",\"RNSVGMarkerComponentDescriptor\",\"RNSVGMaskComponentDescriptor\",\"RNSVGPathComponentDescriptor\",\"RNSVGPatternComponentDescriptor\",\"RNSVGRadialGradientComponentDescriptor\",\"RNSVGRectComponentDescriptor\",\"RNSVGSvgViewAndroidComponentDescriptor\",\"RNSVGSymbolComponentDescriptor\",\"RNSVGTextComponentDescriptor\",\"RNSVGTextPathComponentDescriptor\",\"RNSVGTSpanComponentDescriptor\",\"RNSVGUseComponentDescriptor\"],\"cmakeListsPath\":\"node_modules/react-native-svg/android/src/main/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"react-native-worklets\":{\"root\":\"node_modules/react-native-worklets\",\"name\":\"react-native-worklets\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/react-native-worklets/RNWorklets.podspec\",\"version\":\"0.7.4\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/react-native-worklets/android\",\"packageImportPath\":\"import com.swmansion.worklets.WorkletsPackage;\",\"packageInstance\":\"new WorkletsPackage()\",\"buildTypes\":[],\"libraryName\":\"rnworklets\",\"componentDescriptors\":[],\"cmakeListsPath\":\"node_modules/react-native-worklets/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}}}", + "contents": "{\"@hot-updater/react-native\":{\"root\":\"node_modules/@hot-updater/react-native\",\"name\":\"@hot-updater/react-native\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/@hot-updater/react-native/HotUpdater.podspec\",\"version\":\"0.32.0\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/@hot-updater/react-native/android\",\"packageImportPath\":\"import com.hotupdater.HotUpdaterPackage;\",\"packageInstance\":\"new HotUpdaterPackage()\",\"buildTypes\":[],\"libraryName\":\"HotUpdaterSpec\",\"componentDescriptors\":[],\"cmakeListsPath\":\"node_modules/@hot-updater/react-native/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"@notifee/react-native\":{\"root\":\"node_modules/@notifee/react-native\",\"name\":\"@notifee/react-native\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/@notifee/react-native/RNNotifee.podspec\",\"version\":\"9.1.8\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/@notifee/react-native/android\",\"packageImportPath\":\"import io.invertase.notifee.NotifeePackage;\",\"packageInstance\":\"new NotifeePackage()\",\"buildTypes\":[],\"componentDescriptors\":[],\"cmakeListsPath\":\"node_modules/@notifee/react-native/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"@op-engineering/op-sqlite\":{\"root\":\"node_modules/@op-engineering/op-sqlite\",\"name\":\"@op-engineering/op-sqlite\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/@op-engineering/op-sqlite/op-sqlite.podspec\",\"version\":\"16.2.0\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/@op-engineering/op-sqlite/android\",\"packageImportPath\":\"import com.op.sqlite.OPSQLitePackage;\",\"packageInstance\":\"new OPSQLitePackage()\",\"buildTypes\":[],\"libraryName\":\"OPSQLiteSpec\",\"componentDescriptors\":[],\"cmakeListsPath\":\"node_modules/@op-engineering/op-sqlite/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"@react-native-clipboard/clipboard\":{\"root\":\"node_modules/@react-native-clipboard/clipboard\",\"name\":\"@react-native-clipboard/clipboard\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/@react-native-clipboard/clipboard/RNCClipboard.podspec\",\"version\":\"1.16.3\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/@react-native-clipboard/clipboard/android\",\"packageImportPath\":\"import com.reactnativecommunity.clipboard.ClipboardPackage;\",\"packageInstance\":\"new ClipboardPackage()\",\"buildTypes\":[],\"libraryName\":\"rnclipboard\",\"componentDescriptors\":[],\"cmakeListsPath\":\"node_modules/@react-native-clipboard/clipboard/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"@react-native-community/netinfo\":{\"root\":\"node_modules/@react-native-community/netinfo\",\"name\":\"@react-native-community/netinfo\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/@react-native-community/netinfo/react-native-netinfo.podspec\",\"version\":\"11.4.1\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/@react-native-community/netinfo/android\",\"packageImportPath\":\"import com.reactnativecommunity.netinfo.NetInfoPackage;\",\"packageInstance\":\"new NetInfoPackage()\",\"buildTypes\":[],\"componentDescriptors\":[],\"cmakeListsPath\":\"node_modules/@react-native-community/netinfo/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"@react-native-firebase/app\":{\"root\":\"node_modules/@react-native-firebase/app\",\"name\":\"@react-native-firebase/app\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/@react-native-firebase/app/RNFBApp.podspec\",\"version\":\"23.5.0\",\"configurations\":[],\"scriptPhases\":[{\"name\":\"[RNFB] Core Configuration\",\"path\":\"./ios_config.sh\",\"execution_position\":\"after_compile\",\"input_files\":[\"$(BUILT_PRODUCTS_DIR)/$(INFOPLIST_PATH)\"]}]},\"android\":{\"sourceDir\":\"node_modules/@react-native-firebase/app/android\",\"packageImportPath\":\"import io.invertase.firebase.app.ReactNativeFirebaseAppPackage;\",\"packageInstance\":\"new ReactNativeFirebaseAppPackage()\",\"buildTypes\":[],\"componentDescriptors\":[],\"cmakeListsPath\":\"node_modules/@react-native-firebase/app/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"@react-native-firebase/messaging\":{\"root\":\"node_modules/@react-native-firebase/messaging\",\"name\":\"@react-native-firebase/messaging\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/@react-native-firebase/messaging/RNFBMessaging.podspec\",\"version\":\"23.5.0\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/@react-native-firebase/messaging/android\",\"packageImportPath\":\"import io.invertase.firebase.messaging.ReactNativeFirebaseMessagingPackage;\",\"packageInstance\":\"new ReactNativeFirebaseMessagingPackage()\",\"buildTypes\":[],\"componentDescriptors\":[],\"cmakeListsPath\":\"node_modules/@react-native-firebase/messaging/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"@sentry/react-native\":{\"root\":\"node_modules/@sentry/react-native\",\"name\":\"@sentry/react-native\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/@sentry/react-native/RNSentry.podspec\",\"version\":\"7.7.0\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/@sentry/react-native/android\",\"packageImportPath\":\"import io.sentry.react.RNSentryPackage;\",\"packageInstance\":\"new RNSentryPackage()\",\"buildTypes\":[],\"libraryName\":\"RNSentrySpec\",\"componentDescriptors\":[\"RNSentryReplayMaskComponentDescriptor\",\"RNSentryReplayUnmaskComponentDescriptor\"],\"cmakeListsPath\":\"node_modules/@sentry/react-native/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"react-native-camera-kit\":{\"root\":\"node_modules/react-native-camera-kit\",\"name\":\"react-native-camera-kit\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/react-native-camera-kit/ReactNativeCameraKit.podspec\",\"version\":\"16.2.1\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/react-native-camera-kit/android\",\"packageImportPath\":\"import com.rncamerakit.RNCameraKitPackage;\",\"packageInstance\":\"new RNCameraKitPackage()\",\"buildTypes\":[],\"libraryName\":\"NativeCameraKitSpec\",\"componentDescriptors\":[\"CKCameraComponentDescriptor\"],\"cmakeListsPath\":\"node_modules/react-native-camera-kit/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"react-native-change-icon\":{\"root\":\"node_modules/react-native-change-icon\",\"name\":\"react-native-change-icon\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/react-native-change-icon/react-native-change-icon.podspec\",\"version\":\"5.0.0\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/react-native-change-icon/android\",\"packageImportPath\":\"import com.reactnativechangeicon.ChangeIconPackage;\",\"packageInstance\":\"new ChangeIconPackage(BuildConfig.APPLICATION_ID)\",\"buildTypes\":[],\"libraryName\":\"RNChangeIconSpec\",\"componentDescriptors\":[],\"cmakeListsPath\":\"node_modules/react-native-change-icon/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"react-native-edge-to-edge\":{\"root\":\"node_modules/react-native-edge-to-edge\",\"name\":\"react-native-edge-to-edge\",\"platforms\":{\"ios\":null,\"android\":{\"sourceDir\":\"node_modules/react-native-edge-to-edge/android\",\"packageImportPath\":\"import com.zoontek.rnedgetoedge.EdgeToEdgePackage;\",\"packageInstance\":\"new EdgeToEdgePackage()\",\"buildTypes\":[],\"libraryName\":\"RNEdgeToEdge\",\"componentDescriptors\":[],\"cmakeListsPath\":\"node_modules/react-native-edge-to-edge/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"react-native-exit-app\":{\"root\":\"node_modules/react-native-exit-app\",\"name\":\"react-native-exit-app\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/react-native-exit-app/RNExitApp.podspec\",\"version\":\"2.0.0\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/react-native-exit-app/android\",\"packageImportPath\":\"import com.github.wumke.RNExitApp.RNExitAppPackage;\",\"packageInstance\":\"new RNExitAppPackage()\",\"buildTypes\":[],\"libraryName\":\"RNExitAppSpec\",\"componentDescriptors\":[],\"cmakeListsPath\":\"node_modules/react-native-exit-app/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"react-native-fast-image\":{\"root\":\"node_modules/react-native-fast-image\",\"name\":\"react-native-fast-image\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/react-native-fast-image/RNFastImage.podspec\",\"version\":\"8.6.3\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/react-native-fast-image/android\",\"packageImportPath\":\"import com.dylanvann.fastimage.FastImageViewPackage;\",\"packageInstance\":\"new FastImageViewPackage()\",\"buildTypes\":[],\"componentDescriptors\":[],\"cmakeListsPath\":\"node_modules/react-native-fast-image/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"react-native-gesture-handler\":{\"root\":\"node_modules/react-native-gesture-handler\",\"name\":\"react-native-gesture-handler\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/react-native-gesture-handler/RNGestureHandler.podspec\",\"version\":\"2.28.0\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/react-native-gesture-handler/android\",\"packageImportPath\":\"import com.swmansion.gesturehandler.RNGestureHandlerPackage;\",\"packageInstance\":\"new RNGestureHandlerPackage()\",\"buildTypes\":[],\"libraryName\":\"rngesturehandler_codegen\",\"componentDescriptors\":[\"RNGestureHandlerButtonComponentDescriptor\",\"RNGestureHandlerRootViewComponentDescriptor\"],\"cmakeListsPath\":\"node_modules/react-native-gesture-handler/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"react-native-hce\":{\"root\":\"node_modules/react-native-hce\",\"name\":\"react-native-hce\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/react-native-hce/react-native-hce.podspec\",\"version\":\"0.3.0\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/react-native-hce/android\",\"packageImportPath\":\"import com.reactnativehce.HcePackage;\",\"packageInstance\":\"new HcePackage()\",\"buildTypes\":[],\"componentDescriptors\":[],\"cmakeListsPath\":\"node_modules/react-native-hce/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"react-native-keychain\":{\"root\":\"node_modules/react-native-keychain\",\"name\":\"react-native-keychain\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/react-native-keychain/RNKeychain.podspec\",\"version\":\"10.0.0\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/react-native-keychain/android\",\"packageImportPath\":\"import com.oblador.keychain.KeychainPackage;\",\"packageInstance\":\"new KeychainPackage()\",\"buildTypes\":[],\"libraryName\":\"RNKeychainSpec\",\"componentDescriptors\":[],\"cmakeListsPath\":\"node_modules/react-native-keychain/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"react-native-localize\":{\"root\":\"node_modules/react-native-localize\",\"name\":\"react-native-localize\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/react-native-localize/RNLocalize.podspec\",\"version\":\"3.5.2\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/react-native-localize/android\",\"packageImportPath\":\"import com.zoontek.rnlocalize.RNLocalizePackage;\",\"packageInstance\":\"new RNLocalizePackage()\",\"buildTypes\":[],\"libraryName\":\"RNLocalizeSpec\",\"componentDescriptors\":[],\"cmakeListsPath\":\"node_modules/react-native-localize/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"react-native-mmkv\":{\"root\":\"node_modules/react-native-mmkv\",\"name\":\"react-native-mmkv\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/react-native-mmkv/react-native-mmkv.podspec\",\"version\":\"3.3.3\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/react-native-mmkv/android\",\"packageImportPath\":\"import com.mrousavy.mmkv.MmkvPackage;\",\"packageInstance\":\"new MmkvPackage()\",\"buildTypes\":[],\"libraryName\":\"RNMmkvSpec\",\"componentDescriptors\":[],\"cmakeListsPath\":\"node_modules/react-native-mmkv/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":\"react-native-mmkv\",\"cxxModuleCMakeListsPath\":\"node_modules/react-native-mmkv/android/CMakeLists.txt\",\"cxxModuleHeaderName\":\"NativeMmkvModule\",\"isPureCxxDependency\":false}}},\"react-native-nfc-manager\":{\"root\":\"node_modules/react-native-nfc-manager\",\"name\":\"react-native-nfc-manager\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/react-native-nfc-manager/react-native-nfc-manager.podspec\",\"version\":\"4.0.0-beta.7\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/react-native-nfc-manager/android\",\"packageImportPath\":\"import community.revteltech.nfc.NfcManagerPackage;\",\"packageInstance\":\"new NfcManagerPackage()\",\"buildTypes\":[],\"libraryName\":\"NativeNfcManagerSpec\",\"componentDescriptors\":[],\"cmakeListsPath\":\"node_modules/react-native-nfc-manager/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"react-native-pager-view\":{\"root\":\"node_modules/react-native-pager-view\",\"name\":\"react-native-pager-view\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/react-native-pager-view/react-native-pager-view.podspec\",\"version\":\"8.0.0\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/react-native-pager-view/android\",\"packageImportPath\":\"import com.reactnativepagerview.PagerViewPackage;\",\"packageInstance\":\"new PagerViewPackage()\",\"buildTypes\":[],\"libraryName\":\"pagerview\",\"componentDescriptors\":[\"RNCViewPagerComponentDescriptor\"],\"cmakeListsPath\":\"node_modules/react-native-pager-view/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"react-native-quick-crypto\":{\"root\":\"node_modules/react-native-quick-crypto\",\"name\":\"react-native-quick-crypto\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/react-native-quick-crypto/react-native-quick-crypto.podspec\",\"version\":\"0.7.17\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/react-native-quick-crypto/android\",\"packageImportPath\":\"import com.margelo.quickcrypto.QuickCryptoPackage;\",\"packageInstance\":\"new QuickCryptoPackage()\",\"buildTypes\":[],\"componentDescriptors\":[],\"cmakeListsPath\":\"node_modules/react-native-quick-crypto/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"react-native-reanimated\":{\"root\":\"node_modules/react-native-reanimated\",\"name\":\"react-native-reanimated\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/react-native-reanimated/RNReanimated.podspec\",\"version\":\"4.2.2\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/react-native-reanimated/android\",\"packageImportPath\":\"import com.swmansion.reanimated.ReanimatedPackage;\",\"packageInstance\":\"new ReanimatedPackage()\",\"buildTypes\":[],\"libraryName\":\"rnreanimated\",\"componentDescriptors\":[],\"cmakeListsPath\":\"node_modules/react-native-reanimated/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"react-native-safe-area-context\":{\"root\":\"node_modules/react-native-safe-area-context\",\"name\":\"react-native-safe-area-context\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/react-native-safe-area-context/react-native-safe-area-context.podspec\",\"version\":\"5.6.1\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/react-native-safe-area-context/android\",\"packageImportPath\":\"import com.th3rdwave.safeareacontext.SafeAreaContextPackage;\",\"packageInstance\":\"new SafeAreaContextPackage()\",\"buildTypes\":[],\"libraryName\":\"safeareacontext\",\"componentDescriptors\":[\"RNCSafeAreaProviderComponentDescriptor\",\"RNCSafeAreaViewComponentDescriptor\"],\"cmakeListsPath\":\"node_modules/react-native-safe-area-context/android/src/main/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"react-native-screens\":{\"root\":\"node_modules/react-native-screens\",\"name\":\"react-native-screens\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/react-native-screens/RNScreens.podspec\",\"version\":\"4.16.0\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/react-native-screens/android\",\"packageImportPath\":\"import com.swmansion.rnscreens.RNScreensPackage;\",\"packageInstance\":\"new RNScreensPackage()\",\"buildTypes\":[],\"libraryName\":\"rnscreens\",\"componentDescriptors\":[\"RNSFullWindowOverlayComponentDescriptor\",\"RNSScreenContainerComponentDescriptor\",\"RNSScreenNavigationContainerComponentDescriptor\",\"RNSScreenStackHeaderConfigComponentDescriptor\",\"RNSScreenStackHeaderSubviewComponentDescriptor\",\"RNSScreenStackComponentDescriptor\",\"RNSSearchBarComponentDescriptor\",\"RNSScreenComponentDescriptor\",\"RNSScreenFooterComponentDescriptor\",\"RNSScreenContentWrapperComponentDescriptor\",\"RNSModalScreenComponentDescriptor\",\"RNSBottomTabsComponentDescriptor\"],\"cmakeListsPath\":\"node_modules/react-native-screens/android/src/main/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"react-native-svg\":{\"root\":\"node_modules/react-native-svg\",\"name\":\"react-native-svg\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/react-native-svg/RNSVG.podspec\",\"version\":\"15.13.0\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/react-native-svg/android\",\"packageImportPath\":\"import com.horcrux.svg.SvgPackage;\",\"packageInstance\":\"new SvgPackage()\",\"buildTypes\":[],\"libraryName\":\"rnsvg\",\"componentDescriptors\":[\"RNSVGCircleComponentDescriptor\",\"RNSVGClipPathComponentDescriptor\",\"RNSVGDefsComponentDescriptor\",\"RNSVGFeBlendComponentDescriptor\",\"RNSVGFeColorMatrixComponentDescriptor\",\"RNSVGFeCompositeComponentDescriptor\",\"RNSVGFeFloodComponentDescriptor\",\"RNSVGFeGaussianBlurComponentDescriptor\",\"RNSVGFeMergeComponentDescriptor\",\"RNSVGFeOffsetComponentDescriptor\",\"RNSVGFilterComponentDescriptor\",\"RNSVGEllipseComponentDescriptor\",\"RNSVGForeignObjectComponentDescriptor\",\"RNSVGGroupComponentDescriptor\",\"RNSVGImageComponentDescriptor\",\"RNSVGLinearGradientComponentDescriptor\",\"RNSVGLineComponentDescriptor\",\"RNSVGMarkerComponentDescriptor\",\"RNSVGMaskComponentDescriptor\",\"RNSVGPathComponentDescriptor\",\"RNSVGPatternComponentDescriptor\",\"RNSVGRadialGradientComponentDescriptor\",\"RNSVGRectComponentDescriptor\",\"RNSVGSvgViewAndroidComponentDescriptor\",\"RNSVGSymbolComponentDescriptor\",\"RNSVGTextComponentDescriptor\",\"RNSVGTextPathComponentDescriptor\",\"RNSVGTSpanComponentDescriptor\",\"RNSVGUseComponentDescriptor\"],\"cmakeListsPath\":\"node_modules/react-native-svg/android/src/main/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"react-native-worklets\":{\"root\":\"node_modules/react-native-worklets\",\"name\":\"react-native-worklets\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/react-native-worklets/RNWorklets.podspec\",\"version\":\"0.7.4\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/react-native-worklets/android\",\"packageImportPath\":\"import com.swmansion.worklets.WorkletsPackage;\",\"packageInstance\":\"new WorkletsPackage()\",\"buildTypes\":[],\"libraryName\":\"rnworklets\",\"componentDescriptors\":[],\"cmakeListsPath\":\"node_modules/react-native-worklets/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}}}", "reasons": [ "rncoreAutolinking" ], - "hash": "464f9dc947d8c514a54da95962d6e4886bd4b413" + "hash": "572c60c8414e2294ee19e4cb40b65f1e8e3608e2" } ], - "hash": "e9f51a75d88d5727c549de0e6250f351feb1e127" + "hash": "87f7f5e2ff3ace8ca5c2fd2ab6df5d0b7b513ed8" }, "android": { "sources": [ @@ -262,7 +262,7 @@ "reasons": [ "rncoreAutolinking" ], - "hash": "69a7bbb3afa191a4772eb48464ad41d1d7581c3a" + "hash": "026ef4eb346e632647244781e9ce7d416227e0b7" }, { "type": "dir", @@ -484,13 +484,13 @@ { "type": "contents", "id": "rncoreAutolinkingConfig", - "contents": "{\"@hot-updater/react-native\":{\"root\":\"node_modules/@hot-updater/react-native\",\"name\":\"@hot-updater/react-native\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/@hot-updater/react-native/HotUpdater.podspec\",\"version\":\"0.23.1\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/@hot-updater/react-native/android\",\"packageImportPath\":\"import com.hotupdater.HotUpdaterPackage;\",\"packageInstance\":\"new HotUpdaterPackage()\",\"buildTypes\":[],\"libraryName\":\"HotUpdaterSpec\",\"componentDescriptors\":[],\"cmakeListsPath\":\"node_modules/@hot-updater/react-native/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"@notifee/react-native\":{\"root\":\"node_modules/@notifee/react-native\",\"name\":\"@notifee/react-native\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/@notifee/react-native/RNNotifee.podspec\",\"version\":\"9.1.8\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/@notifee/react-native/android\",\"packageImportPath\":\"import io.invertase.notifee.NotifeePackage;\",\"packageInstance\":\"new NotifeePackage()\",\"buildTypes\":[],\"componentDescriptors\":[],\"cmakeListsPath\":\"node_modules/@notifee/react-native/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"@op-engineering/op-sqlite\":{\"root\":\"node_modules/@op-engineering/op-sqlite\",\"name\":\"@op-engineering/op-sqlite\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/@op-engineering/op-sqlite/op-sqlite.podspec\",\"version\":\"16.2.0\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/@op-engineering/op-sqlite/android\",\"packageImportPath\":\"import com.op.sqlite.OPSQLitePackage;\",\"packageInstance\":\"new OPSQLitePackage()\",\"buildTypes\":[],\"libraryName\":\"OPSQLiteSpec\",\"componentDescriptors\":[],\"cmakeListsPath\":\"node_modules/@op-engineering/op-sqlite/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"@react-native-clipboard/clipboard\":{\"root\":\"node_modules/@react-native-clipboard/clipboard\",\"name\":\"@react-native-clipboard/clipboard\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/@react-native-clipboard/clipboard/RNCClipboard.podspec\",\"version\":\"1.16.3\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/@react-native-clipboard/clipboard/android\",\"packageImportPath\":\"import com.reactnativecommunity.clipboard.ClipboardPackage;\",\"packageInstance\":\"new ClipboardPackage()\",\"buildTypes\":[],\"libraryName\":\"rnclipboard\",\"componentDescriptors\":[],\"cmakeListsPath\":\"node_modules/@react-native-clipboard/clipboard/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"@react-native-community/netinfo\":{\"root\":\"node_modules/@react-native-community/netinfo\",\"name\":\"@react-native-community/netinfo\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/@react-native-community/netinfo/react-native-netinfo.podspec\",\"version\":\"11.4.1\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/@react-native-community/netinfo/android\",\"packageImportPath\":\"import com.reactnativecommunity.netinfo.NetInfoPackage;\",\"packageInstance\":\"new NetInfoPackage()\",\"buildTypes\":[],\"componentDescriptors\":[],\"cmakeListsPath\":\"node_modules/@react-native-community/netinfo/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"@react-native-firebase/app\":{\"root\":\"node_modules/@react-native-firebase/app\",\"name\":\"@react-native-firebase/app\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/@react-native-firebase/app/RNFBApp.podspec\",\"version\":\"23.5.0\",\"configurations\":[],\"scriptPhases\":[{\"name\":\"[RNFB] Core Configuration\",\"path\":\"./ios_config.sh\",\"execution_position\":\"after_compile\",\"input_files\":[\"$(BUILT_PRODUCTS_DIR)/$(INFOPLIST_PATH)\"]}]},\"android\":{\"sourceDir\":\"node_modules/@react-native-firebase/app/android\",\"packageImportPath\":\"import io.invertase.firebase.app.ReactNativeFirebaseAppPackage;\",\"packageInstance\":\"new ReactNativeFirebaseAppPackage()\",\"buildTypes\":[],\"componentDescriptors\":[],\"cmakeListsPath\":\"node_modules/@react-native-firebase/app/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"@react-native-firebase/messaging\":{\"root\":\"node_modules/@react-native-firebase/messaging\",\"name\":\"@react-native-firebase/messaging\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/@react-native-firebase/messaging/RNFBMessaging.podspec\",\"version\":\"23.5.0\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/@react-native-firebase/messaging/android\",\"packageImportPath\":\"import io.invertase.firebase.messaging.ReactNativeFirebaseMessagingPackage;\",\"packageInstance\":\"new ReactNativeFirebaseMessagingPackage()\",\"buildTypes\":[],\"componentDescriptors\":[],\"cmakeListsPath\":\"node_modules/@react-native-firebase/messaging/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"@sentry/react-native\":{\"root\":\"node_modules/@sentry/react-native\",\"name\":\"@sentry/react-native\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/@sentry/react-native/RNSentry.podspec\",\"version\":\"7.7.0\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/@sentry/react-native/android\",\"packageImportPath\":\"import io.sentry.react.RNSentryPackage;\",\"packageInstance\":\"new RNSentryPackage()\",\"buildTypes\":[],\"libraryName\":\"RNSentrySpec\",\"componentDescriptors\":[\"RNSentryReplayMaskComponentDescriptor\",\"RNSentryReplayUnmaskComponentDescriptor\"],\"cmakeListsPath\":\"node_modules/@sentry/react-native/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"react-native-camera-kit\":{\"root\":\"node_modules/react-native-camera-kit\",\"name\":\"react-native-camera-kit\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/react-native-camera-kit/ReactNativeCameraKit.podspec\",\"version\":\"16.2.1\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/react-native-camera-kit/android\",\"packageImportPath\":\"import com.rncamerakit.RNCameraKitPackage;\",\"packageInstance\":\"new RNCameraKitPackage()\",\"buildTypes\":[],\"libraryName\":\"NativeCameraKitSpec\",\"componentDescriptors\":[\"CKCameraComponentDescriptor\"],\"cmakeListsPath\":\"node_modules/react-native-camera-kit/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"react-native-change-icon\":{\"root\":\"node_modules/react-native-change-icon\",\"name\":\"react-native-change-icon\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/react-native-change-icon/react-native-change-icon.podspec\",\"version\":\"5.0.0\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/react-native-change-icon/android\",\"packageImportPath\":\"import com.reactnativechangeicon.ChangeIconPackage;\",\"packageInstance\":\"new ChangeIconPackage(BuildConfig.APPLICATION_ID)\",\"buildTypes\":[],\"libraryName\":\"RNChangeIconSpec\",\"componentDescriptors\":[],\"cmakeListsPath\":\"node_modules/react-native-change-icon/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"react-native-edge-to-edge\":{\"root\":\"node_modules/react-native-edge-to-edge\",\"name\":\"react-native-edge-to-edge\",\"platforms\":{\"ios\":null,\"android\":{\"sourceDir\":\"node_modules/react-native-edge-to-edge/android\",\"packageImportPath\":\"import com.zoontek.rnedgetoedge.EdgeToEdgePackage;\",\"packageInstance\":\"new EdgeToEdgePackage()\",\"buildTypes\":[],\"libraryName\":\"RNEdgeToEdge\",\"componentDescriptors\":[],\"cmakeListsPath\":\"node_modules/react-native-edge-to-edge/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"react-native-exit-app\":{\"root\":\"node_modules/react-native-exit-app\",\"name\":\"react-native-exit-app\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/react-native-exit-app/RNExitApp.podspec\",\"version\":\"2.0.0\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/react-native-exit-app/android\",\"packageImportPath\":\"import com.github.wumke.RNExitApp.RNExitAppPackage;\",\"packageInstance\":\"new RNExitAppPackage()\",\"buildTypes\":[],\"libraryName\":\"RNExitAppSpec\",\"componentDescriptors\":[],\"cmakeListsPath\":\"node_modules/react-native-exit-app/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"react-native-fast-image\":{\"root\":\"node_modules/react-native-fast-image\",\"name\":\"react-native-fast-image\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/react-native-fast-image/RNFastImage.podspec\",\"version\":\"8.6.3\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/react-native-fast-image/android\",\"packageImportPath\":\"import com.dylanvann.fastimage.FastImageViewPackage;\",\"packageInstance\":\"new FastImageViewPackage()\",\"buildTypes\":[],\"componentDescriptors\":[],\"cmakeListsPath\":\"node_modules/react-native-fast-image/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"react-native-gesture-handler\":{\"root\":\"node_modules/react-native-gesture-handler\",\"name\":\"react-native-gesture-handler\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/react-native-gesture-handler/RNGestureHandler.podspec\",\"version\":\"2.28.0\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/react-native-gesture-handler/android\",\"packageImportPath\":\"import com.swmansion.gesturehandler.RNGestureHandlerPackage;\",\"packageInstance\":\"new RNGestureHandlerPackage()\",\"buildTypes\":[],\"libraryName\":\"rngesturehandler_codegen\",\"componentDescriptors\":[\"RNGestureHandlerButtonComponentDescriptor\",\"RNGestureHandlerRootViewComponentDescriptor\"],\"cmakeListsPath\":\"node_modules/react-native-gesture-handler/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"react-native-hce\":{\"root\":\"node_modules/react-native-hce\",\"name\":\"react-native-hce\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/react-native-hce/react-native-hce.podspec\",\"version\":\"0.3.0\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/react-native-hce/android\",\"packageImportPath\":\"import com.reactnativehce.HcePackage;\",\"packageInstance\":\"new HcePackage()\",\"buildTypes\":[],\"componentDescriptors\":[],\"cmakeListsPath\":\"node_modules/react-native-hce/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"react-native-keychain\":{\"root\":\"node_modules/react-native-keychain\",\"name\":\"react-native-keychain\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/react-native-keychain/RNKeychain.podspec\",\"version\":\"10.0.0\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/react-native-keychain/android\",\"packageImportPath\":\"import com.oblador.keychain.KeychainPackage;\",\"packageInstance\":\"new KeychainPackage()\",\"buildTypes\":[],\"libraryName\":\"RNKeychainSpec\",\"componentDescriptors\":[],\"cmakeListsPath\":\"node_modules/react-native-keychain/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"react-native-localize\":{\"root\":\"node_modules/react-native-localize\",\"name\":\"react-native-localize\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/react-native-localize/RNLocalize.podspec\",\"version\":\"3.5.2\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/react-native-localize/android\",\"packageImportPath\":\"import com.zoontek.rnlocalize.RNLocalizePackage;\",\"packageInstance\":\"new RNLocalizePackage()\",\"buildTypes\":[],\"libraryName\":\"RNLocalizeSpec\",\"componentDescriptors\":[],\"cmakeListsPath\":\"node_modules/react-native-localize/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"react-native-mmkv\":{\"root\":\"node_modules/react-native-mmkv\",\"name\":\"react-native-mmkv\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/react-native-mmkv/react-native-mmkv.podspec\",\"version\":\"3.3.3\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/react-native-mmkv/android\",\"packageImportPath\":\"import com.mrousavy.mmkv.MmkvPackage;\",\"packageInstance\":\"new MmkvPackage()\",\"buildTypes\":[],\"libraryName\":\"RNMmkvSpec\",\"componentDescriptors\":[],\"cmakeListsPath\":\"node_modules/react-native-mmkv/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":\"react-native-mmkv\",\"cxxModuleCMakeListsPath\":\"node_modules/react-native-mmkv/android/CMakeLists.txt\",\"cxxModuleHeaderName\":\"NativeMmkvModule\",\"isPureCxxDependency\":false}}},\"react-native-nfc-manager\":{\"root\":\"node_modules/react-native-nfc-manager\",\"name\":\"react-native-nfc-manager\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/react-native-nfc-manager/react-native-nfc-manager.podspec\",\"version\":\"4.0.0-beta.7\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/react-native-nfc-manager/android\",\"packageImportPath\":\"import community.revteltech.nfc.NfcManagerPackage;\",\"packageInstance\":\"new NfcManagerPackage()\",\"buildTypes\":[],\"libraryName\":\"NativeNfcManagerSpec\",\"componentDescriptors\":[],\"cmakeListsPath\":\"node_modules/react-native-nfc-manager/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"react-native-pager-view\":{\"root\":\"node_modules/react-native-pager-view\",\"name\":\"react-native-pager-view\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/react-native-pager-view/react-native-pager-view.podspec\",\"version\":\"8.0.0\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/react-native-pager-view/android\",\"packageImportPath\":\"import com.reactnativepagerview.PagerViewPackage;\",\"packageInstance\":\"new PagerViewPackage()\",\"buildTypes\":[],\"libraryName\":\"pagerview\",\"componentDescriptors\":[\"RNCViewPagerComponentDescriptor\"],\"cmakeListsPath\":\"node_modules/react-native-pager-view/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"react-native-quick-crypto\":{\"root\":\"node_modules/react-native-quick-crypto\",\"name\":\"react-native-quick-crypto\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/react-native-quick-crypto/react-native-quick-crypto.podspec\",\"version\":\"0.7.17\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/react-native-quick-crypto/android\",\"packageImportPath\":\"import com.margelo.quickcrypto.QuickCryptoPackage;\",\"packageInstance\":\"new QuickCryptoPackage()\",\"buildTypes\":[],\"componentDescriptors\":[],\"cmakeListsPath\":\"node_modules/react-native-quick-crypto/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"react-native-reanimated\":{\"root\":\"node_modules/react-native-reanimated\",\"name\":\"react-native-reanimated\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/react-native-reanimated/RNReanimated.podspec\",\"version\":\"4.2.2\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/react-native-reanimated/android\",\"packageImportPath\":\"import com.swmansion.reanimated.ReanimatedPackage;\",\"packageInstance\":\"new ReanimatedPackage()\",\"buildTypes\":[],\"libraryName\":\"rnreanimated\",\"componentDescriptors\":[],\"cmakeListsPath\":\"node_modules/react-native-reanimated/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"react-native-safe-area-context\":{\"root\":\"node_modules/react-native-safe-area-context\",\"name\":\"react-native-safe-area-context\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/react-native-safe-area-context/react-native-safe-area-context.podspec\",\"version\":\"5.6.1\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/react-native-safe-area-context/android\",\"packageImportPath\":\"import com.th3rdwave.safeareacontext.SafeAreaContextPackage;\",\"packageInstance\":\"new SafeAreaContextPackage()\",\"buildTypes\":[],\"libraryName\":\"safeareacontext\",\"componentDescriptors\":[\"RNCSafeAreaProviderComponentDescriptor\",\"RNCSafeAreaViewComponentDescriptor\"],\"cmakeListsPath\":\"node_modules/react-native-safe-area-context/android/src/main/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"react-native-screens\":{\"root\":\"node_modules/react-native-screens\",\"name\":\"react-native-screens\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/react-native-screens/RNScreens.podspec\",\"version\":\"4.16.0\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/react-native-screens/android\",\"packageImportPath\":\"import com.swmansion.rnscreens.RNScreensPackage;\",\"packageInstance\":\"new RNScreensPackage()\",\"buildTypes\":[],\"libraryName\":\"rnscreens\",\"componentDescriptors\":[\"RNSFullWindowOverlayComponentDescriptor\",\"RNSScreenContainerComponentDescriptor\",\"RNSScreenNavigationContainerComponentDescriptor\",\"RNSScreenStackHeaderConfigComponentDescriptor\",\"RNSScreenStackHeaderSubviewComponentDescriptor\",\"RNSScreenStackComponentDescriptor\",\"RNSSearchBarComponentDescriptor\",\"RNSScreenComponentDescriptor\",\"RNSScreenFooterComponentDescriptor\",\"RNSScreenContentWrapperComponentDescriptor\",\"RNSModalScreenComponentDescriptor\",\"RNSBottomTabsComponentDescriptor\"],\"cmakeListsPath\":\"node_modules/react-native-screens/android/src/main/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"react-native-svg\":{\"root\":\"node_modules/react-native-svg\",\"name\":\"react-native-svg\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/react-native-svg/RNSVG.podspec\",\"version\":\"15.13.0\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/react-native-svg/android\",\"packageImportPath\":\"import com.horcrux.svg.SvgPackage;\",\"packageInstance\":\"new SvgPackage()\",\"buildTypes\":[],\"libraryName\":\"rnsvg\",\"componentDescriptors\":[\"RNSVGCircleComponentDescriptor\",\"RNSVGClipPathComponentDescriptor\",\"RNSVGDefsComponentDescriptor\",\"RNSVGFeBlendComponentDescriptor\",\"RNSVGFeColorMatrixComponentDescriptor\",\"RNSVGFeCompositeComponentDescriptor\",\"RNSVGFeFloodComponentDescriptor\",\"RNSVGFeGaussianBlurComponentDescriptor\",\"RNSVGFeMergeComponentDescriptor\",\"RNSVGFeOffsetComponentDescriptor\",\"RNSVGFilterComponentDescriptor\",\"RNSVGEllipseComponentDescriptor\",\"RNSVGForeignObjectComponentDescriptor\",\"RNSVGGroupComponentDescriptor\",\"RNSVGImageComponentDescriptor\",\"RNSVGLinearGradientComponentDescriptor\",\"RNSVGLineComponentDescriptor\",\"RNSVGMarkerComponentDescriptor\",\"RNSVGMaskComponentDescriptor\",\"RNSVGPathComponentDescriptor\",\"RNSVGPatternComponentDescriptor\",\"RNSVGRadialGradientComponentDescriptor\",\"RNSVGRectComponentDescriptor\",\"RNSVGSvgViewAndroidComponentDescriptor\",\"RNSVGSymbolComponentDescriptor\",\"RNSVGTextComponentDescriptor\",\"RNSVGTextPathComponentDescriptor\",\"RNSVGTSpanComponentDescriptor\",\"RNSVGUseComponentDescriptor\"],\"cmakeListsPath\":\"node_modules/react-native-svg/android/src/main/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"react-native-worklets\":{\"root\":\"node_modules/react-native-worklets\",\"name\":\"react-native-worklets\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/react-native-worklets/RNWorklets.podspec\",\"version\":\"0.7.4\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/react-native-worklets/android\",\"packageImportPath\":\"import com.swmansion.worklets.WorkletsPackage;\",\"packageInstance\":\"new WorkletsPackage()\",\"buildTypes\":[],\"libraryName\":\"rnworklets\",\"componentDescriptors\":[],\"cmakeListsPath\":\"node_modules/react-native-worklets/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}}}", + "contents": "{\"@hot-updater/react-native\":{\"root\":\"node_modules/@hot-updater/react-native\",\"name\":\"@hot-updater/react-native\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/@hot-updater/react-native/HotUpdater.podspec\",\"version\":\"0.32.0\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/@hot-updater/react-native/android\",\"packageImportPath\":\"import com.hotupdater.HotUpdaterPackage;\",\"packageInstance\":\"new HotUpdaterPackage()\",\"buildTypes\":[],\"libraryName\":\"HotUpdaterSpec\",\"componentDescriptors\":[],\"cmakeListsPath\":\"node_modules/@hot-updater/react-native/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"@notifee/react-native\":{\"root\":\"node_modules/@notifee/react-native\",\"name\":\"@notifee/react-native\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/@notifee/react-native/RNNotifee.podspec\",\"version\":\"9.1.8\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/@notifee/react-native/android\",\"packageImportPath\":\"import io.invertase.notifee.NotifeePackage;\",\"packageInstance\":\"new NotifeePackage()\",\"buildTypes\":[],\"componentDescriptors\":[],\"cmakeListsPath\":\"node_modules/@notifee/react-native/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"@op-engineering/op-sqlite\":{\"root\":\"node_modules/@op-engineering/op-sqlite\",\"name\":\"@op-engineering/op-sqlite\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/@op-engineering/op-sqlite/op-sqlite.podspec\",\"version\":\"16.2.0\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/@op-engineering/op-sqlite/android\",\"packageImportPath\":\"import com.op.sqlite.OPSQLitePackage;\",\"packageInstance\":\"new OPSQLitePackage()\",\"buildTypes\":[],\"libraryName\":\"OPSQLiteSpec\",\"componentDescriptors\":[],\"cmakeListsPath\":\"node_modules/@op-engineering/op-sqlite/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"@react-native-clipboard/clipboard\":{\"root\":\"node_modules/@react-native-clipboard/clipboard\",\"name\":\"@react-native-clipboard/clipboard\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/@react-native-clipboard/clipboard/RNCClipboard.podspec\",\"version\":\"1.16.3\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/@react-native-clipboard/clipboard/android\",\"packageImportPath\":\"import com.reactnativecommunity.clipboard.ClipboardPackage;\",\"packageInstance\":\"new ClipboardPackage()\",\"buildTypes\":[],\"libraryName\":\"rnclipboard\",\"componentDescriptors\":[],\"cmakeListsPath\":\"node_modules/@react-native-clipboard/clipboard/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"@react-native-community/netinfo\":{\"root\":\"node_modules/@react-native-community/netinfo\",\"name\":\"@react-native-community/netinfo\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/@react-native-community/netinfo/react-native-netinfo.podspec\",\"version\":\"11.4.1\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/@react-native-community/netinfo/android\",\"packageImportPath\":\"import com.reactnativecommunity.netinfo.NetInfoPackage;\",\"packageInstance\":\"new NetInfoPackage()\",\"buildTypes\":[],\"componentDescriptors\":[],\"cmakeListsPath\":\"node_modules/@react-native-community/netinfo/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"@react-native-firebase/app\":{\"root\":\"node_modules/@react-native-firebase/app\",\"name\":\"@react-native-firebase/app\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/@react-native-firebase/app/RNFBApp.podspec\",\"version\":\"23.5.0\",\"configurations\":[],\"scriptPhases\":[{\"name\":\"[RNFB] Core Configuration\",\"path\":\"./ios_config.sh\",\"execution_position\":\"after_compile\",\"input_files\":[\"$(BUILT_PRODUCTS_DIR)/$(INFOPLIST_PATH)\"]}]},\"android\":{\"sourceDir\":\"node_modules/@react-native-firebase/app/android\",\"packageImportPath\":\"import io.invertase.firebase.app.ReactNativeFirebaseAppPackage;\",\"packageInstance\":\"new ReactNativeFirebaseAppPackage()\",\"buildTypes\":[],\"componentDescriptors\":[],\"cmakeListsPath\":\"node_modules/@react-native-firebase/app/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"@react-native-firebase/messaging\":{\"root\":\"node_modules/@react-native-firebase/messaging\",\"name\":\"@react-native-firebase/messaging\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/@react-native-firebase/messaging/RNFBMessaging.podspec\",\"version\":\"23.5.0\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/@react-native-firebase/messaging/android\",\"packageImportPath\":\"import io.invertase.firebase.messaging.ReactNativeFirebaseMessagingPackage;\",\"packageInstance\":\"new ReactNativeFirebaseMessagingPackage()\",\"buildTypes\":[],\"componentDescriptors\":[],\"cmakeListsPath\":\"node_modules/@react-native-firebase/messaging/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"@sentry/react-native\":{\"root\":\"node_modules/@sentry/react-native\",\"name\":\"@sentry/react-native\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/@sentry/react-native/RNSentry.podspec\",\"version\":\"7.7.0\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/@sentry/react-native/android\",\"packageImportPath\":\"import io.sentry.react.RNSentryPackage;\",\"packageInstance\":\"new RNSentryPackage()\",\"buildTypes\":[],\"libraryName\":\"RNSentrySpec\",\"componentDescriptors\":[\"RNSentryReplayMaskComponentDescriptor\",\"RNSentryReplayUnmaskComponentDescriptor\"],\"cmakeListsPath\":\"node_modules/@sentry/react-native/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"react-native-camera-kit\":{\"root\":\"node_modules/react-native-camera-kit\",\"name\":\"react-native-camera-kit\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/react-native-camera-kit/ReactNativeCameraKit.podspec\",\"version\":\"16.2.1\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/react-native-camera-kit/android\",\"packageImportPath\":\"import com.rncamerakit.RNCameraKitPackage;\",\"packageInstance\":\"new RNCameraKitPackage()\",\"buildTypes\":[],\"libraryName\":\"NativeCameraKitSpec\",\"componentDescriptors\":[\"CKCameraComponentDescriptor\"],\"cmakeListsPath\":\"node_modules/react-native-camera-kit/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"react-native-change-icon\":{\"root\":\"node_modules/react-native-change-icon\",\"name\":\"react-native-change-icon\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/react-native-change-icon/react-native-change-icon.podspec\",\"version\":\"5.0.0\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/react-native-change-icon/android\",\"packageImportPath\":\"import com.reactnativechangeicon.ChangeIconPackage;\",\"packageInstance\":\"new ChangeIconPackage(BuildConfig.APPLICATION_ID)\",\"buildTypes\":[],\"libraryName\":\"RNChangeIconSpec\",\"componentDescriptors\":[],\"cmakeListsPath\":\"node_modules/react-native-change-icon/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"react-native-edge-to-edge\":{\"root\":\"node_modules/react-native-edge-to-edge\",\"name\":\"react-native-edge-to-edge\",\"platforms\":{\"ios\":null,\"android\":{\"sourceDir\":\"node_modules/react-native-edge-to-edge/android\",\"packageImportPath\":\"import com.zoontek.rnedgetoedge.EdgeToEdgePackage;\",\"packageInstance\":\"new EdgeToEdgePackage()\",\"buildTypes\":[],\"libraryName\":\"RNEdgeToEdge\",\"componentDescriptors\":[],\"cmakeListsPath\":\"node_modules/react-native-edge-to-edge/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"react-native-exit-app\":{\"root\":\"node_modules/react-native-exit-app\",\"name\":\"react-native-exit-app\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/react-native-exit-app/RNExitApp.podspec\",\"version\":\"2.0.0\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/react-native-exit-app/android\",\"packageImportPath\":\"import com.github.wumke.RNExitApp.RNExitAppPackage;\",\"packageInstance\":\"new RNExitAppPackage()\",\"buildTypes\":[],\"libraryName\":\"RNExitAppSpec\",\"componentDescriptors\":[],\"cmakeListsPath\":\"node_modules/react-native-exit-app/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"react-native-fast-image\":{\"root\":\"node_modules/react-native-fast-image\",\"name\":\"react-native-fast-image\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/react-native-fast-image/RNFastImage.podspec\",\"version\":\"8.6.3\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/react-native-fast-image/android\",\"packageImportPath\":\"import com.dylanvann.fastimage.FastImageViewPackage;\",\"packageInstance\":\"new FastImageViewPackage()\",\"buildTypes\":[],\"componentDescriptors\":[],\"cmakeListsPath\":\"node_modules/react-native-fast-image/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"react-native-gesture-handler\":{\"root\":\"node_modules/react-native-gesture-handler\",\"name\":\"react-native-gesture-handler\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/react-native-gesture-handler/RNGestureHandler.podspec\",\"version\":\"2.28.0\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/react-native-gesture-handler/android\",\"packageImportPath\":\"import com.swmansion.gesturehandler.RNGestureHandlerPackage;\",\"packageInstance\":\"new RNGestureHandlerPackage()\",\"buildTypes\":[],\"libraryName\":\"rngesturehandler_codegen\",\"componentDescriptors\":[\"RNGestureHandlerButtonComponentDescriptor\",\"RNGestureHandlerRootViewComponentDescriptor\"],\"cmakeListsPath\":\"node_modules/react-native-gesture-handler/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"react-native-hce\":{\"root\":\"node_modules/react-native-hce\",\"name\":\"react-native-hce\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/react-native-hce/react-native-hce.podspec\",\"version\":\"0.3.0\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/react-native-hce/android\",\"packageImportPath\":\"import com.reactnativehce.HcePackage;\",\"packageInstance\":\"new HcePackage()\",\"buildTypes\":[],\"componentDescriptors\":[],\"cmakeListsPath\":\"node_modules/react-native-hce/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"react-native-keychain\":{\"root\":\"node_modules/react-native-keychain\",\"name\":\"react-native-keychain\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/react-native-keychain/RNKeychain.podspec\",\"version\":\"10.0.0\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/react-native-keychain/android\",\"packageImportPath\":\"import com.oblador.keychain.KeychainPackage;\",\"packageInstance\":\"new KeychainPackage()\",\"buildTypes\":[],\"libraryName\":\"RNKeychainSpec\",\"componentDescriptors\":[],\"cmakeListsPath\":\"node_modules/react-native-keychain/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"react-native-localize\":{\"root\":\"node_modules/react-native-localize\",\"name\":\"react-native-localize\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/react-native-localize/RNLocalize.podspec\",\"version\":\"3.5.2\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/react-native-localize/android\",\"packageImportPath\":\"import com.zoontek.rnlocalize.RNLocalizePackage;\",\"packageInstance\":\"new RNLocalizePackage()\",\"buildTypes\":[],\"libraryName\":\"RNLocalizeSpec\",\"componentDescriptors\":[],\"cmakeListsPath\":\"node_modules/react-native-localize/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"react-native-mmkv\":{\"root\":\"node_modules/react-native-mmkv\",\"name\":\"react-native-mmkv\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/react-native-mmkv/react-native-mmkv.podspec\",\"version\":\"3.3.3\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/react-native-mmkv/android\",\"packageImportPath\":\"import com.mrousavy.mmkv.MmkvPackage;\",\"packageInstance\":\"new MmkvPackage()\",\"buildTypes\":[],\"libraryName\":\"RNMmkvSpec\",\"componentDescriptors\":[],\"cmakeListsPath\":\"node_modules/react-native-mmkv/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":\"react-native-mmkv\",\"cxxModuleCMakeListsPath\":\"node_modules/react-native-mmkv/android/CMakeLists.txt\",\"cxxModuleHeaderName\":\"NativeMmkvModule\",\"isPureCxxDependency\":false}}},\"react-native-nfc-manager\":{\"root\":\"node_modules/react-native-nfc-manager\",\"name\":\"react-native-nfc-manager\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/react-native-nfc-manager/react-native-nfc-manager.podspec\",\"version\":\"4.0.0-beta.7\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/react-native-nfc-manager/android\",\"packageImportPath\":\"import community.revteltech.nfc.NfcManagerPackage;\",\"packageInstance\":\"new NfcManagerPackage()\",\"buildTypes\":[],\"libraryName\":\"NativeNfcManagerSpec\",\"componentDescriptors\":[],\"cmakeListsPath\":\"node_modules/react-native-nfc-manager/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"react-native-pager-view\":{\"root\":\"node_modules/react-native-pager-view\",\"name\":\"react-native-pager-view\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/react-native-pager-view/react-native-pager-view.podspec\",\"version\":\"8.0.0\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/react-native-pager-view/android\",\"packageImportPath\":\"import com.reactnativepagerview.PagerViewPackage;\",\"packageInstance\":\"new PagerViewPackage()\",\"buildTypes\":[],\"libraryName\":\"pagerview\",\"componentDescriptors\":[\"RNCViewPagerComponentDescriptor\"],\"cmakeListsPath\":\"node_modules/react-native-pager-view/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"react-native-quick-crypto\":{\"root\":\"node_modules/react-native-quick-crypto\",\"name\":\"react-native-quick-crypto\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/react-native-quick-crypto/react-native-quick-crypto.podspec\",\"version\":\"0.7.17\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/react-native-quick-crypto/android\",\"packageImportPath\":\"import com.margelo.quickcrypto.QuickCryptoPackage;\",\"packageInstance\":\"new QuickCryptoPackage()\",\"buildTypes\":[],\"componentDescriptors\":[],\"cmakeListsPath\":\"node_modules/react-native-quick-crypto/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"react-native-reanimated\":{\"root\":\"node_modules/react-native-reanimated\",\"name\":\"react-native-reanimated\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/react-native-reanimated/RNReanimated.podspec\",\"version\":\"4.2.2\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/react-native-reanimated/android\",\"packageImportPath\":\"import com.swmansion.reanimated.ReanimatedPackage;\",\"packageInstance\":\"new ReanimatedPackage()\",\"buildTypes\":[],\"libraryName\":\"rnreanimated\",\"componentDescriptors\":[],\"cmakeListsPath\":\"node_modules/react-native-reanimated/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"react-native-safe-area-context\":{\"root\":\"node_modules/react-native-safe-area-context\",\"name\":\"react-native-safe-area-context\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/react-native-safe-area-context/react-native-safe-area-context.podspec\",\"version\":\"5.6.1\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/react-native-safe-area-context/android\",\"packageImportPath\":\"import com.th3rdwave.safeareacontext.SafeAreaContextPackage;\",\"packageInstance\":\"new SafeAreaContextPackage()\",\"buildTypes\":[],\"libraryName\":\"safeareacontext\",\"componentDescriptors\":[\"RNCSafeAreaProviderComponentDescriptor\",\"RNCSafeAreaViewComponentDescriptor\"],\"cmakeListsPath\":\"node_modules/react-native-safe-area-context/android/src/main/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"react-native-screens\":{\"root\":\"node_modules/react-native-screens\",\"name\":\"react-native-screens\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/react-native-screens/RNScreens.podspec\",\"version\":\"4.16.0\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/react-native-screens/android\",\"packageImportPath\":\"import com.swmansion.rnscreens.RNScreensPackage;\",\"packageInstance\":\"new RNScreensPackage()\",\"buildTypes\":[],\"libraryName\":\"rnscreens\",\"componentDescriptors\":[\"RNSFullWindowOverlayComponentDescriptor\",\"RNSScreenContainerComponentDescriptor\",\"RNSScreenNavigationContainerComponentDescriptor\",\"RNSScreenStackHeaderConfigComponentDescriptor\",\"RNSScreenStackHeaderSubviewComponentDescriptor\",\"RNSScreenStackComponentDescriptor\",\"RNSSearchBarComponentDescriptor\",\"RNSScreenComponentDescriptor\",\"RNSScreenFooterComponentDescriptor\",\"RNSScreenContentWrapperComponentDescriptor\",\"RNSModalScreenComponentDescriptor\",\"RNSBottomTabsComponentDescriptor\"],\"cmakeListsPath\":\"node_modules/react-native-screens/android/src/main/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"react-native-svg\":{\"root\":\"node_modules/react-native-svg\",\"name\":\"react-native-svg\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/react-native-svg/RNSVG.podspec\",\"version\":\"15.13.0\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/react-native-svg/android\",\"packageImportPath\":\"import com.horcrux.svg.SvgPackage;\",\"packageInstance\":\"new SvgPackage()\",\"buildTypes\":[],\"libraryName\":\"rnsvg\",\"componentDescriptors\":[\"RNSVGCircleComponentDescriptor\",\"RNSVGClipPathComponentDescriptor\",\"RNSVGDefsComponentDescriptor\",\"RNSVGFeBlendComponentDescriptor\",\"RNSVGFeColorMatrixComponentDescriptor\",\"RNSVGFeCompositeComponentDescriptor\",\"RNSVGFeFloodComponentDescriptor\",\"RNSVGFeGaussianBlurComponentDescriptor\",\"RNSVGFeMergeComponentDescriptor\",\"RNSVGFeOffsetComponentDescriptor\",\"RNSVGFilterComponentDescriptor\",\"RNSVGEllipseComponentDescriptor\",\"RNSVGForeignObjectComponentDescriptor\",\"RNSVGGroupComponentDescriptor\",\"RNSVGImageComponentDescriptor\",\"RNSVGLinearGradientComponentDescriptor\",\"RNSVGLineComponentDescriptor\",\"RNSVGMarkerComponentDescriptor\",\"RNSVGMaskComponentDescriptor\",\"RNSVGPathComponentDescriptor\",\"RNSVGPatternComponentDescriptor\",\"RNSVGRadialGradientComponentDescriptor\",\"RNSVGRectComponentDescriptor\",\"RNSVGSvgViewAndroidComponentDescriptor\",\"RNSVGSymbolComponentDescriptor\",\"RNSVGTextComponentDescriptor\",\"RNSVGTextPathComponentDescriptor\",\"RNSVGTSpanComponentDescriptor\",\"RNSVGUseComponentDescriptor\"],\"cmakeListsPath\":\"node_modules/react-native-svg/android/src/main/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}},\"react-native-worklets\":{\"root\":\"node_modules/react-native-worklets\",\"name\":\"react-native-worklets\",\"platforms\":{\"ios\":{\"podspecPath\":\"node_modules/react-native-worklets/RNWorklets.podspec\",\"version\":\"0.7.4\",\"configurations\":[],\"scriptPhases\":[]},\"android\":{\"sourceDir\":\"node_modules/react-native-worklets/android\",\"packageImportPath\":\"import com.swmansion.worklets.WorkletsPackage;\",\"packageInstance\":\"new WorkletsPackage()\",\"buildTypes\":[],\"libraryName\":\"rnworklets\",\"componentDescriptors\":[],\"cmakeListsPath\":\"node_modules/react-native-worklets/android/build/generated/source/codegen/jni/CMakeLists.txt\",\"cxxModuleCMakeListsModuleName\":null,\"cxxModuleCMakeListsPath\":null,\"cxxModuleHeaderName\":null,\"isPureCxxDependency\":false}}}}", "reasons": [ "rncoreAutolinking" ], - "hash": "464f9dc947d8c514a54da95962d6e4886bd4b413" + "hash": "572c60c8414e2294ee19e4cb40b65f1e8e3608e2" } ], - "hash": "e9f51a75d88d5727c549de0e6250f351feb1e127" + "hash": "87f7f5e2ff3ace8ca5c2fd2ab6df5d0b7b513ed8" } } \ No newline at end of file diff --git a/ios/minibits_wallet/Info.plist b/ios/minibits_wallet/Info.plist index 3fe91f17..73f3147a 100644 --- a/ios/minibits_wallet/Info.plist +++ b/ios/minibits_wallet/Info.plist @@ -89,7 +89,7 @@ UIViewControllerBasedStatusBarAppearance HOT_UPDATER_FINGERPRINT_HASH - e9f51a75d88d5727c549de0e6250f351feb1e127 + 87f7f5e2ff3ace8ca5c2fd2ab6df5d0b7b513ed8 CFBundleIcons CFBundlePrimaryIcon diff --git a/src/screens/NfcPayScreen.tsx b/src/screens/NfcPayScreen.tsx index da8655e5..5f67b322 100644 --- a/src/screens/NfcPayScreen.tsx +++ b/src/screens/NfcPayScreen.tsx @@ -48,6 +48,10 @@ import FastImage from 'react-native-fast-image' type Props = StaticScreenProps<{ unit: MintUnit + // When the screen is opened by an incoming NFC dispatch (cold/warm app launch via the + // OS NFC chooser), the tag has ALREADY been read by the OS; we pass the decoded text + // here and process it directly instead of arming the reader for a live tap. + incomingData?: string }> const SYNC_STATE_WITH_MINT_TIMEOUT = 10 * 1000 @@ -57,6 +61,11 @@ export const NfcPayScreen = observer(function NfcPayScreen({ route }: Props) { const { mintsStore, walletStore, proofsStore, transactionsStore, walletProfileStore } = useStores() const unitRef = useRef('sat') const isOnline = useRef(true) + // While true, the reader-mode session is re-armed after each read so the NEXT tap is + // captured by our exclusive reader-mode session instead of falling through to the OS + // "Complete action using…" chooser / other installed wallets. Turned off once a tag is + // actually being processed and on unmount. + const keepScanningRef = useRef(false) const isInternetReachable = useIsInternetReachable() @@ -99,11 +108,36 @@ export const NfcPayScreen = observer(function NfcPayScreen({ route }: Props) { log.trace({isInternetReachable}) const balance = proofsStore.getMintBalanceWithMaxBalance(unitRef.current) - + if (balance) { setMintBalanceToSendFrom(balance) } + // Opened by an incoming NFC dispatch (cold/warm launch via the OS chooser): + // the tag was already read by the OS, so process the decoded data directly + // and skip arming the live reader. + const incomingData = route.params?.incomingData + if (incomingData) { + keepScanningRef.current = false + setIsProcessing(true) + try { + await handleIncomingData(incomingData) + } catch (e: any) { + log.error(e.message, { params: e.params || {} }) + setResultModalInfo({ + status: TransactionStatus.ERROR, + title: e.params?.message ? e.message : 'NFC Payment failed', + message: e.params?.message || e.message || 'Unknown error during NFC payment processing.', + }) + setNfcInfo(e.message) + setIsError(true) + toggleResultModal() + } finally { + setIsProcessing(false) + } + return + } + /*setNfcInfo('Hold your device close to the NFC reader.') setIsNfcEnabled(true) return @@ -125,6 +159,7 @@ export const NfcPayScreen = observer(function NfcPayScreen({ route }: Props) { setNfcInfo('Hold your device close to the NFC reader.') setIsNfcEnabled(true) + keepScanningRef.current = true // Start listening for tags immediately startNfcSession() @@ -138,6 +173,7 @@ export const NfcPayScreen = observer(function NfcPayScreen({ route }: Props) { initNfc() return () => { + keepScanningRef.current = false NfcManager.cancelTechnologyRequest().catch(() => {}) NfcManager.setEventListener(NfcEvents.DiscoverTag, null) NfcManager.setEventListener(NfcEvents.SessionClosed, null) @@ -153,6 +189,7 @@ export const NfcPayScreen = observer(function NfcPayScreen({ route }: Props) { useEffect(() => { const unsubscribe = navigation.addListener('focus', () => { if (isNfcEnabled && !isProcessing) { + keepScanningRef.current = true startNfcSession() } }) @@ -326,6 +363,11 @@ export const NfcPayScreen = observer(function NfcPayScreen({ route }: Props) { const startNfcSession = async () => { let decoded: string | undefined = undefined; + // Whether this session read a real tag and handed off to the payment flow. When it + // did, we must NOT re-arm the reader (the result/processing UI owns the screen now). + // When it didn't (empty read, read error), we re-arm so a retry tap is captured by + // our reader-mode session rather than the OS chooser. + let didStartProcessing = false try { log.debug('[startNfcSession] Starting NFC session for payment request reading...') @@ -335,6 +377,8 @@ export const NfcPayScreen = observer(function NfcPayScreen({ route }: Props) { return } + didStartProcessing = true + keepScanningRef.current = false setIsProcessing(true) //log.info('NFC Tag found', {tag}); @@ -369,8 +413,20 @@ export const NfcPayScreen = observer(function NfcPayScreen({ route }: Props) { setIsError(true) toggleResultModal() } finally { - await NfcManager.cancelTechnologyRequest().catch(() => {}) + await NfcManager.cancelTechnologyRequest().catch(() => {}) setIsProcessing(false) + + // Re-arm the reader for the next tap unless we handed off to the payment flow + // or the screen is gone. cancelTechnologyRequest() above tears down reader mode, + // so without this the next tap would fall through to the OS chooser again. + // The short delay lets reader mode tear down cleanly and throttles re-arming in + // case the NFC stack is transiently erroring. + if (keepScanningRef.current && !didStartProcessing) { + await new Promise(r => setTimeout(r, 300)) + if (keepScanningRef.current && !didStartProcessing) { + startNfcSession() + } + } } } @@ -1142,9 +1198,6 @@ export const NfcPayScreen = observer(function NfcPayScreen({ route }: Props) { - - {info && } - {error && } + {info && } + {error && } ) }) @@ -1285,7 +1340,7 @@ export const PulsingContactlessIcon: React.FC = ({ const $screen: ViewStyle = { } const $contentContainer: ViewStyle = { flex: 1, padding: spacing.extraSmall } const $headerContainer: TextStyle = { alignItems: 'center', paddingVertical: spacing.medium,} -const $buttonContainer: ViewStyle = { flex: 1, marginTop: spacing.large, flexDirection: 'row', alignSelf: 'center' } +const $buttonContainer: ViewStyle = { flexDirection: 'row', alignSelf: 'center' } const $bottomContainer: ViewStyle = { position: 'absolute', bottom: 0, diff --git a/src/screens/WalletScreen.tsx b/src/screens/WalletScreen.tsx index 7097d19d..82e832d1 100644 --- a/src/screens/WalletScreen.tsx +++ b/src/screens/WalletScreen.tsx @@ -45,6 +45,7 @@ import { MINIBITS_MINT_URL, } from '@env' import { IncomingParser } from '../services/incomingParser' +import { NfcService } from '../services/nfcService' import useIsInternetReachable from '../utils/useIsInternetReachable' import { CurrencySign } from './Wallet/CurrencySign' import { CurrencyCode, MintUnit, MintUnitCurrencyPairs, convertToFromSats, getCurrency } from "../services/wallet/currency" @@ -166,11 +167,21 @@ export const WalletScreen = observer(function WalletScreen({ route }: Props) { // On app start useEffect(() => { const getInitialData = async () => { + // If the app was COLD-launched by an NFC tap (e.g. another wallet's HCE share, + // with Minibits picked in the OS chooser), route the decoded tag to the NFC pay + // screen. getLaunchNdefText returns undefined for non-NFC launches, so a normal + // deep link falls through to Linking below. + const nfcText = await NfcService.getLaunchNdefText() + if (nfcText) { + handleNfcData(nfcText) + return + } + // get deeplink data if any const url = await Linking.getInitialURL() - - if (url) { - handleDeeplink({url}) + + if (url) { + handleDeeplink({url}) return // skip further processing so that it does not slow down or clash deep link } @@ -220,18 +231,23 @@ export const WalletScreen = observer(function WalletScreen({ route }: Props) { } Linking.addEventListener('url', handleDeeplink) + // WARM resume: app backgrounded, then brought to foreground by an NFC tap. The tag + // arrives via the DiscoverBackgroundTag event (no data URI for text records, so + // Linking would miss it); route it to the NFC pay screen like the cold-start path. + NfcService.setBackgroundTagListener(handleNfcData) EventEmitter.on(`ev_${HANDLE_RECEIVED_EVENT_TASK}_result`, handleReceivedEventTaskResult) EventEmitter.on(`ev_${HANDLE_CLAIM_TASK}_result`, handleClaimTaskResult) - + getInitialData() // Unsubscribe from the task result event on component unmount return () => { + NfcService.removeBackgroundTagListener() EventEmitter.off(`ev_${HANDLE_RECEIVED_EVENT_TASK}_result`, handleReceivedEventTaskResult) - EventEmitter.off(`ev_${HANDLE_CLAIM_TASK}_result`, handleClaimTaskResult) + EventEmitter.off(`ev_${HANDLE_CLAIM_TASK}_result`, handleClaimTaskResult) } - + }, []) @@ -258,8 +274,8 @@ export const WalletScreen = observer(function WalletScreen({ route }: Props) { const incomingData = IncomingParser.findAndExtract(url) await IncomingParser.navigateWithIncomingData( - incomingData, - navigation, + incomingData, + navigation, currentUnit ) @@ -268,6 +284,16 @@ export const WalletScreen = observer(function WalletScreen({ route }: Props) { } } + // Routes NFC data (cold launch or warm resume) to the dedicated NFC pay screen, which + // processes the already-read payload via its own handleIncomingData. + const handleNfcData = function (data: string) { + // @ts-ignore + navigation.navigate('NfcPay', { + unit: currentUnit, + incomingData: data, + }) + } + const gotoUpdate = function() { setIsUpdateModalVisible(false) //@ts-ignore diff --git a/src/services/nfcService.ts b/src/services/nfcService.ts index ab69f9f6..40d1b082 100644 --- a/src/services/nfcService.ts +++ b/src/services/nfcService.ts @@ -6,6 +6,17 @@ import AppError, { Err } from '../utils/AppError' const NFC_STALE_DELAY_MS = 120 +// Android NfcAdapter reader-mode flags (react-native-nfc-manager passes these through +// to NfcAdapter.enableReaderMode). HCE peers present as ISO-DEP over NFC-A/NFC-B, so we +// must enable those. Enabling reader mode is what makes our foreground session take +// EXCLUSIVE control of the NFC stack and suppress the OS "Complete action using…" chooser +// + other installed wallets (Zeus/Blixt/WoS) from intercepting the tap. +const FLAG_READER_NFC_A = 0x1 +const FLAG_READER_NFC_B = 0x2 +const FLAG_READER_NO_PLATFORM_SOUNDS = 0x100 +const READER_MODE_FLAGS = + FLAG_READER_NFC_A | FLAG_READER_NFC_B | FLAG_READER_NO_PLATFORM_SOUNDS + const init = async function () { const supported = await NfcManager.isSupported() if (supported) { @@ -48,7 +59,10 @@ const goToNfcSetting = function () { const readNdefTag = async () => { log.trace('[readNdefTag] start') try { - await NfcManager.requestTechnology(NfcTech.Ndef) // needs to run only once per read/write session + await NfcManager.requestTechnology(NfcTech.Ndef, { + isReaderModeEnabled: true, // use NfcAdapter.enableReaderMode, not enableForegroundDispatch + readerModeFlags: READER_MODE_FLAGS, + }) // needs to run only once per read/write session log.trace('[readNdefTag] requestTechnology completed') const tag = await NfcManager.getTag() log.trace('[readNdefTag] tag read') // do not close session @@ -73,6 +87,81 @@ const writeNdefMessage = async (text: string) => { } +/** + * Decodes the text payload of the first NDEF record of a tag, handling both Well-Known + * Text records (how invoices/tokens are shared over NFC, see writeNdefMessage) and URI + * records (e.g. lightning: URIs). + */ +const decodeNdefTagText = function (tag: TagEvent | null | undefined): string | undefined { + const record = tag?.ndefMessage?.[0] + if (!record?.payload) return undefined + + const bytes = new Uint8Array(record.payload as number[]) + + if (Ndef.isType(record, Ndef.TNF_WELL_KNOWN, Ndef.RTD_URI)) { + return Ndef.uri.decodePayload(bytes) || undefined + } + return Ndef.text.decodePayload(bytes) || undefined +} + + +/** + * Returns the text content of the NDEF tag that COLD-launched the app, if any. + * + * When the app is launched from a closed state by an Android NDEF_DISCOVERED intent (e.g. + * tapping another wallet's HCE share and picking Minibits in the OS chooser), a Well-Known + * Text record carries no data URI — only an EXTRA_NDEF_MESSAGES extra on the launch intent, + * which React Native's Linking module misses. getLaunchTagEvent() parses that launch intent. + * + * Returns undefined when the app was not launched by an NFC tag (the parsed intent has no + * EXTRA_TAG), which makes this a reliable "was this an NFC launch?" discriminator. + * + * getLaunchTagEvent() reads the activity's launch intent, which persists across React + * remounts; we therefore consume the launch tag only ONCE per app process so a remount of + * the caller (e.g. WalletScreen) does not re-process and re-navigate to the same payment. + * + * @returns the decoded NDEF text, or undefined if the app was not launched by an NFC tag + */ +let launchNdefConsumed = false +const getLaunchNdefText = async function (): Promise { + if (Platform.OS !== 'android') return undefined // getLaunchTagEvent is Android-only + if (launchNdefConsumed) return undefined + try { + const tag = await NfcManager.getLaunchTagEvent() + const text = decodeNdefTagText(tag) + if (text) launchNdefConsumed = true // only consume when we actually found NFC data + return text + } catch (e: any) { + log.warn('[getLaunchNdefText] failed to read launch NFC tag', { error: String(e) }) + return undefined + } +} + + +/** + * Registers a listener for NDEF tags that arrive while the app is backgrounded (WARM resume) + * and brought to the foreground by an NFC dispatch. The library emits DiscoverBackgroundTag + * from its onNewIntent handler when no foreground reader session is active. + * + * @param onData called with the decoded NDEF text of the background tag + */ +const setBackgroundTagListener = function (onData: (text: string) => void) { + if (Platform.OS !== 'android') return + NfcManager.setEventListener(NfcEvents.DiscoverBackgroundTag, (tag: TagEvent) => { + const text = decodeNdefTagText(tag) + // Clear the stored background tag so it cannot be re-read later (e.g. via + // getBackgroundTag on a remount); the event already delivered it to us here. + NfcManager.clearBackgroundTag().catch(() => {}) + if (text) onData(text) + }) +} + +const removeBackgroundTagListener = function () { + if (Platform.OS !== 'android') return + NfcManager.setEventListener(NfcEvents.DiscoverBackgroundTag, null) +} + + /** * Checks if a string is safe to broadcast via Android NFC HCE (Type 4 Tag emulation) * Safe limit: 32,000 bytes (conservative, accounts for NDEF overhead) @@ -102,4 +191,7 @@ export const NfcService = { goToNfcSetting, readNdefTag, writeNdefMessage, + getLaunchNdefText, + setBackgroundTagListener, + removeBackgroundTagListener, } \ No newline at end of file