mirror of
https://github.com/minibits-cash/minibits_wallet.git
synced 2026-10-06 03:38:24 +00:00
NFC stub
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
|
||||
<uses-permission android:name="android.permission.USE_BIOMETRIC"/>
|
||||
<uses-permission android:name="android.permission.NFC" />
|
||||
<application
|
||||
android:name=".MainApplication"
|
||||
android:label="@string/app_name"
|
||||
|
||||
+189
-101
@@ -1,29 +1,30 @@
|
||||
PODS:
|
||||
- BitByteData (2.0.4)
|
||||
- boost (1.84.0)
|
||||
- DoubleConversion (1.1.6)
|
||||
- fast_float (8.0.0)
|
||||
- FBLazyVector (0.81.4)
|
||||
- Firebase/CoreOnly (12.3.0):
|
||||
- FirebaseCore (~> 12.3.0)
|
||||
- Firebase/Messaging (12.3.0):
|
||||
- Firebase/CoreOnly (12.4.0):
|
||||
- FirebaseCore (~> 12.4.0)
|
||||
- Firebase/Messaging (12.4.0):
|
||||
- Firebase/CoreOnly
|
||||
- FirebaseMessaging (~> 12.3.0)
|
||||
- FirebaseCore (12.3.0):
|
||||
- FirebaseCoreInternal (~> 12.3.0)
|
||||
- FirebaseMessaging (~> 12.4.0)
|
||||
- FirebaseCore (12.4.0):
|
||||
- FirebaseCoreInternal (~> 12.4.0)
|
||||
- GoogleUtilities/Environment (~> 8.1)
|
||||
- GoogleUtilities/Logger (~> 8.1)
|
||||
- FirebaseCoreExtension (12.3.0):
|
||||
- FirebaseCore (~> 12.3.0)
|
||||
- FirebaseCoreInternal (12.3.0):
|
||||
- FirebaseCoreExtension (12.4.0):
|
||||
- FirebaseCore (~> 12.4.0)
|
||||
- FirebaseCoreInternal (12.4.0):
|
||||
- "GoogleUtilities/NSData+zlib (~> 8.1)"
|
||||
- FirebaseInstallations (12.3.0):
|
||||
- FirebaseCore (~> 12.3.0)
|
||||
- FirebaseInstallations (12.4.0):
|
||||
- FirebaseCore (~> 12.4.0)
|
||||
- GoogleUtilities/Environment (~> 8.1)
|
||||
- GoogleUtilities/UserDefaults (~> 8.1)
|
||||
- PromisesObjC (~> 2.4)
|
||||
- FirebaseMessaging (12.3.0):
|
||||
- FirebaseCore (~> 12.3.0)
|
||||
- FirebaseInstallations (~> 12.3.0)
|
||||
- FirebaseMessaging (12.4.0):
|
||||
- FirebaseCore (~> 12.4.0)
|
||||
- FirebaseInstallations (~> 12.4.0)
|
||||
- GoogleDataTransport (~> 10.1)
|
||||
- GoogleUtilities/AppDelegateSwizzler (~> 8.1)
|
||||
- GoogleUtilities/Environment (~> 8.1)
|
||||
@@ -62,7 +63,7 @@ PODS:
|
||||
- hermes-engine (0.81.4):
|
||||
- hermes-engine/Pre-built (= 0.81.4)
|
||||
- hermes-engine/Pre-built (0.81.4)
|
||||
- HotUpdater (0.20.0):
|
||||
- HotUpdater (0.23.0):
|
||||
- boost
|
||||
- DoubleConversion
|
||||
- fast_float
|
||||
@@ -89,7 +90,7 @@ PODS:
|
||||
- ReactCommon/turbomodule/bridging
|
||||
- ReactCommon/turbomodule/core
|
||||
- SocketRocket
|
||||
- SSZipArchive (~> 2.2.2)
|
||||
- SWCompression (~> 4.8.0)
|
||||
- Yoga
|
||||
- libwebp (1.5.0):
|
||||
- libwebp/demux (= 1.5.0)
|
||||
@@ -103,11 +104,72 @@ PODS:
|
||||
- libwebp/sharpyuv (1.5.0)
|
||||
- libwebp/webp (1.5.0):
|
||||
- libwebp/sharpyuv
|
||||
- MMKVCore (2.2.4)
|
||||
- nanopb (3.30910.0):
|
||||
- nanopb/decode (= 3.30910.0)
|
||||
- nanopb/encode (= 3.30910.0)
|
||||
- nanopb/decode (3.30910.0)
|
||||
- nanopb/encode (3.30910.0)
|
||||
- NitroMmkv (4.0.1):
|
||||
- boost
|
||||
- DoubleConversion
|
||||
- fast_float
|
||||
- fmt
|
||||
- glog
|
||||
- hermes-engine
|
||||
- MMKVCore (= 2.2.4)
|
||||
- NitroModules
|
||||
- RCT-Folly
|
||||
- RCT-Folly/Fabric
|
||||
- RCTRequired
|
||||
- RCTTypeSafety
|
||||
- React-callinvoker
|
||||
- React-Core
|
||||
- React-debug
|
||||
- React-Fabric
|
||||
- React-featureflags
|
||||
- React-graphics
|
||||
- React-ImageManager
|
||||
- React-jsi
|
||||
- React-NativeModulesApple
|
||||
- React-RCTFabric
|
||||
- React-renderercss
|
||||
- React-rendererdebug
|
||||
- React-utils
|
||||
- ReactCodegen
|
||||
- ReactCommon/turbomodule/bridging
|
||||
- ReactCommon/turbomodule/core
|
||||
- SocketRocket
|
||||
- Yoga
|
||||
- NitroModules (0.31.10):
|
||||
- boost
|
||||
- DoubleConversion
|
||||
- fast_float
|
||||
- fmt
|
||||
- glog
|
||||
- hermes-engine
|
||||
- RCT-Folly
|
||||
- RCT-Folly/Fabric
|
||||
- RCTRequired
|
||||
- RCTTypeSafety
|
||||
- React-callinvoker
|
||||
- React-Core
|
||||
- React-debug
|
||||
- React-Fabric
|
||||
- React-featureflags
|
||||
- React-graphics
|
||||
- React-ImageManager
|
||||
- React-jsi
|
||||
- React-NativeModulesApple
|
||||
- React-RCTFabric
|
||||
- React-renderercss
|
||||
- React-rendererdebug
|
||||
- React-utils
|
||||
- ReactCodegen
|
||||
- ReactCommon/turbomodule/bridging
|
||||
- ReactCommon/turbomodule/core
|
||||
- SocketRocket
|
||||
- Yoga
|
||||
- OpenSSL-Universal (3.3.3001)
|
||||
- PromisesObjC (2.4.0)
|
||||
- RCT-Folly (2024.11.18.00):
|
||||
@@ -1851,37 +1913,11 @@ PODS:
|
||||
- React-RCTFBReactNativeSpec
|
||||
- ReactCommon/turbomodule/core
|
||||
- SocketRocket
|
||||
- react-native-mmkv (3.3.3):
|
||||
- boost
|
||||
- DoubleConversion
|
||||
- fast_float
|
||||
- fmt
|
||||
- glog
|
||||
- hermes-engine
|
||||
- RCT-Folly
|
||||
- RCT-Folly/Fabric
|
||||
- RCTRequired
|
||||
- RCTTypeSafety
|
||||
- React-Core
|
||||
- React-debug
|
||||
- React-Fabric
|
||||
- React-featureflags
|
||||
- React-graphics
|
||||
- React-ImageManager
|
||||
- React-jsi
|
||||
- React-NativeModulesApple
|
||||
- React-RCTFabric
|
||||
- React-renderercss
|
||||
- React-rendererdebug
|
||||
- React-utils
|
||||
- ReactCodegen
|
||||
- ReactCommon/turbomodule/bridging
|
||||
- ReactCommon/turbomodule/core
|
||||
- SocketRocket
|
||||
- Yoga
|
||||
- react-native-netinfo (11.4.1):
|
||||
- React-Core
|
||||
- react-native-pager-view (6.9.1):
|
||||
- react-native-nfc-manager (3.17.2):
|
||||
- React-Core
|
||||
- react-native-pager-view (7.0.1):
|
||||
- boost
|
||||
- DoubleConversion
|
||||
- fast_float
|
||||
@@ -1967,7 +2003,7 @@ PODS:
|
||||
- ReactCommon/turbomodule/core
|
||||
- SocketRocket
|
||||
- Yoga
|
||||
- react-native-safe-area-context (5.6.1):
|
||||
- react-native-safe-area-context (5.6.2):
|
||||
- boost
|
||||
- DoubleConversion
|
||||
- fast_float
|
||||
@@ -1985,8 +2021,8 @@ PODS:
|
||||
- React-graphics
|
||||
- React-ImageManager
|
||||
- React-jsi
|
||||
- react-native-safe-area-context/common (= 5.6.1)
|
||||
- react-native-safe-area-context/fabric (= 5.6.1)
|
||||
- react-native-safe-area-context/common (= 5.6.2)
|
||||
- react-native-safe-area-context/fabric (= 5.6.2)
|
||||
- React-NativeModulesApple
|
||||
- React-RCTFabric
|
||||
- React-renderercss
|
||||
@@ -1997,7 +2033,7 @@ PODS:
|
||||
- ReactCommon/turbomodule/core
|
||||
- SocketRocket
|
||||
- Yoga
|
||||
- react-native-safe-area-context/common (5.6.1):
|
||||
- react-native-safe-area-context/common (5.6.2):
|
||||
- boost
|
||||
- DoubleConversion
|
||||
- fast_float
|
||||
@@ -2025,7 +2061,7 @@ PODS:
|
||||
- ReactCommon/turbomodule/core
|
||||
- SocketRocket
|
||||
- Yoga
|
||||
- react-native-safe-area-context/fabric (5.6.1):
|
||||
- react-native-safe-area-context/fabric (5.6.2):
|
||||
- boost
|
||||
- DoubleConversion
|
||||
- fast_float
|
||||
@@ -2627,15 +2663,15 @@ PODS:
|
||||
- React-Core
|
||||
- SDWebImage (~> 5.11.1)
|
||||
- SDWebImageWebPCoder (~> 0.8.4)
|
||||
- RNFBApp (23.4.0):
|
||||
- Firebase/CoreOnly (= 12.3.0)
|
||||
- RNFBApp (23.5.0):
|
||||
- Firebase/CoreOnly (= 12.4.0)
|
||||
- React-Core
|
||||
- RNFBMessaging (23.4.0):
|
||||
- Firebase/Messaging (= 12.3.0)
|
||||
- RNFBMessaging (23.5.0):
|
||||
- Firebase/Messaging (= 12.4.0)
|
||||
- FirebaseCoreExtension
|
||||
- React-Core
|
||||
- RNFBApp
|
||||
- RNGestureHandler (2.28.0):
|
||||
- RNGestureHandler (2.29.1):
|
||||
- boost
|
||||
- DoubleConversion
|
||||
- fast_float
|
||||
@@ -2692,7 +2728,7 @@ PODS:
|
||||
- ReactCommon/turbomodule/core
|
||||
- SocketRocket
|
||||
- Yoga
|
||||
- RNLocalize (3.5.2):
|
||||
- RNLocalize (3.6.0):
|
||||
- boost
|
||||
- DoubleConversion
|
||||
- fast_float
|
||||
@@ -2725,7 +2761,7 @@ PODS:
|
||||
- RNNotifee/NotifeeCore (= 9.1.8)
|
||||
- RNNotifee/NotifeeCore (9.1.8):
|
||||
- React-Core
|
||||
- RNReanimated (4.1.2):
|
||||
- RNReanimated (4.1.5):
|
||||
- boost
|
||||
- DoubleConversion
|
||||
- fast_float
|
||||
@@ -2752,11 +2788,11 @@ PODS:
|
||||
- ReactCodegen
|
||||
- ReactCommon/turbomodule/bridging
|
||||
- ReactCommon/turbomodule/core
|
||||
- RNReanimated/reanimated (= 4.1.2)
|
||||
- RNReanimated/reanimated (= 4.1.5)
|
||||
- RNWorklets
|
||||
- SocketRocket
|
||||
- Yoga
|
||||
- RNReanimated/reanimated (4.1.2):
|
||||
- RNReanimated/reanimated (4.1.5):
|
||||
- boost
|
||||
- DoubleConversion
|
||||
- fast_float
|
||||
@@ -2783,11 +2819,11 @@ PODS:
|
||||
- ReactCodegen
|
||||
- ReactCommon/turbomodule/bridging
|
||||
- ReactCommon/turbomodule/core
|
||||
- RNReanimated/reanimated/apple (= 4.1.2)
|
||||
- RNReanimated/reanimated/apple (= 4.1.5)
|
||||
- RNWorklets
|
||||
- SocketRocket
|
||||
- Yoga
|
||||
- RNReanimated/reanimated/apple (4.1.2):
|
||||
- RNReanimated/reanimated/apple (4.1.5):
|
||||
- boost
|
||||
- DoubleConversion
|
||||
- fast_float
|
||||
@@ -2817,7 +2853,7 @@ PODS:
|
||||
- RNWorklets
|
||||
- SocketRocket
|
||||
- Yoga
|
||||
- RNScreens (4.16.0):
|
||||
- RNScreens (4.18.0):
|
||||
- boost
|
||||
- DoubleConversion
|
||||
- fast_float
|
||||
@@ -2844,10 +2880,10 @@ PODS:
|
||||
- ReactCodegen
|
||||
- ReactCommon/turbomodule/bridging
|
||||
- ReactCommon/turbomodule/core
|
||||
- RNScreens/common (= 4.16.0)
|
||||
- RNScreens/common (= 4.18.0)
|
||||
- SocketRocket
|
||||
- Yoga
|
||||
- RNScreens/common (4.16.0):
|
||||
- RNScreens/common (4.18.0):
|
||||
- boost
|
||||
- DoubleConversion
|
||||
- fast_float
|
||||
@@ -2876,7 +2912,7 @@ PODS:
|
||||
- ReactCommon/turbomodule/core
|
||||
- SocketRocket
|
||||
- Yoga
|
||||
- RNSentry (6.22.0):
|
||||
- RNSentry (7.7.0):
|
||||
- boost
|
||||
- DoubleConversion
|
||||
- fast_float
|
||||
@@ -2903,10 +2939,10 @@ PODS:
|
||||
- ReactCodegen
|
||||
- ReactCommon/turbomodule/bridging
|
||||
- ReactCommon/turbomodule/core
|
||||
- Sentry/HybridSDK (= 8.56.2)
|
||||
- Sentry/HybridSDK (= 8.57.3)
|
||||
- SocketRocket
|
||||
- Yoga
|
||||
- RNSVG (15.13.0):
|
||||
- RNSVG (15.15.0):
|
||||
- boost
|
||||
- DoubleConversion
|
||||
- fast_float
|
||||
@@ -2932,10 +2968,10 @@ PODS:
|
||||
- ReactCodegen
|
||||
- ReactCommon/turbomodule/bridging
|
||||
- ReactCommon/turbomodule/core
|
||||
- RNSVG/common (= 15.13.0)
|
||||
- RNSVG/common (= 15.15.0)
|
||||
- SocketRocket
|
||||
- Yoga
|
||||
- RNSVG/common (15.13.0):
|
||||
- RNSVG/common (15.15.0):
|
||||
- boost
|
||||
- DoubleConversion
|
||||
- fast_float
|
||||
@@ -2963,7 +2999,7 @@ PODS:
|
||||
- ReactCommon/turbomodule/core
|
||||
- SocketRocket
|
||||
- Yoga
|
||||
- RNWorklets (0.6.0):
|
||||
- RNWorklets (0.6.1):
|
||||
- boost
|
||||
- DoubleConversion
|
||||
- fast_float
|
||||
@@ -2990,10 +3026,10 @@ PODS:
|
||||
- ReactCodegen
|
||||
- ReactCommon/turbomodule/bridging
|
||||
- ReactCommon/turbomodule/core
|
||||
- RNWorklets/worklets (= 0.6.0)
|
||||
- RNWorklets/worklets (= 0.6.1)
|
||||
- SocketRocket
|
||||
- Yoga
|
||||
- RNWorklets/worklets (0.6.0):
|
||||
- RNWorklets/worklets (0.6.1):
|
||||
- boost
|
||||
- DoubleConversion
|
||||
- fast_float
|
||||
@@ -3020,10 +3056,10 @@ PODS:
|
||||
- ReactCodegen
|
||||
- ReactCommon/turbomodule/bridging
|
||||
- ReactCommon/turbomodule/core
|
||||
- RNWorklets/worklets/apple (= 0.6.0)
|
||||
- RNWorklets/worklets/apple (= 0.6.1)
|
||||
- SocketRocket
|
||||
- Yoga
|
||||
- RNWorklets/worklets/apple (0.6.0):
|
||||
- RNWorklets/worklets/apple (0.6.1):
|
||||
- boost
|
||||
- DoubleConversion
|
||||
- fast_float
|
||||
@@ -3058,9 +3094,49 @@ PODS:
|
||||
- SDWebImageWebPCoder (0.8.5):
|
||||
- libwebp (~> 1.0)
|
||||
- SDWebImage/Core (~> 5.10)
|
||||
- Sentry/HybridSDK (8.56.2)
|
||||
- Sentry/HybridSDK (8.57.3)
|
||||
- SocketRocket (0.7.1)
|
||||
- SSZipArchive (2.2.3)
|
||||
- SWCompression (4.8.6):
|
||||
- BitByteData (~> 2.0)
|
||||
- SWCompression/BZip2 (= 4.8.6)
|
||||
- SWCompression/Deflate (= 4.8.6)
|
||||
- SWCompression/GZip (= 4.8.6)
|
||||
- SWCompression/LZ4 (= 4.8.6)
|
||||
- SWCompression/LZMA (= 4.8.6)
|
||||
- SWCompression/LZMA2 (= 4.8.6)
|
||||
- SWCompression/SevenZip (= 4.8.6)
|
||||
- SWCompression/TAR (= 4.8.6)
|
||||
- SWCompression/XZ (= 4.8.6)
|
||||
- SWCompression/ZIP (= 4.8.6)
|
||||
- SWCompression/Zlib (= 4.8.6)
|
||||
- SWCompression/BZip2 (4.8.6):
|
||||
- BitByteData (~> 2.0)
|
||||
- SWCompression/Deflate (4.8.6):
|
||||
- BitByteData (~> 2.0)
|
||||
- SWCompression/GZip (4.8.6):
|
||||
- BitByteData (~> 2.0)
|
||||
- SWCompression/Deflate
|
||||
- SWCompression/LZ4 (4.8.6):
|
||||
- BitByteData (~> 2.0)
|
||||
- SWCompression/LZMA (4.8.6):
|
||||
- BitByteData (~> 2.0)
|
||||
- SWCompression/LZMA2 (4.8.6):
|
||||
- BitByteData (~> 2.0)
|
||||
- SWCompression/LZMA
|
||||
- SWCompression/SevenZip (4.8.6):
|
||||
- BitByteData (~> 2.0)
|
||||
- SWCompression/LZMA2
|
||||
- SWCompression/TAR (4.8.6):
|
||||
- BitByteData (~> 2.0)
|
||||
- SWCompression/XZ (4.8.6):
|
||||
- BitByteData (~> 2.0)
|
||||
- SWCompression/LZMA2
|
||||
- SWCompression/ZIP (4.8.6):
|
||||
- BitByteData (~> 2.0)
|
||||
- SWCompression/Deflate
|
||||
- SWCompression/Zlib (4.8.6):
|
||||
- BitByteData (~> 2.0)
|
||||
- SWCompression/Deflate
|
||||
- Yoga (0.0.0)
|
||||
|
||||
DEPENDENCIES:
|
||||
@@ -3072,6 +3148,8 @@ DEPENDENCIES:
|
||||
- glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`)
|
||||
- hermes-engine (from `../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec`)
|
||||
- "HotUpdater (from `../node_modules/@hot-updater/react-native`)"
|
||||
- NitroMmkv (from `../node_modules/react-native-mmkv`)
|
||||
- NitroModules (from `../node_modules/react-native-nitro-modules`)
|
||||
- RCT-Folly (from `../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec`)
|
||||
- RCTDeprecation (from `../node_modules/react-native/ReactApple/Libraries/RCTFoundation/RCTDeprecation`)
|
||||
- RCTRequired (from `../node_modules/react-native/Libraries/Required`)
|
||||
@@ -3106,8 +3184,8 @@ DEPENDENCIES:
|
||||
- React-logger (from `../node_modules/react-native/ReactCommon/logger`)
|
||||
- React-Mapbuffer (from `../node_modules/react-native/ReactCommon`)
|
||||
- React-microtasksnativemodule (from `../node_modules/react-native/ReactCommon/react/nativemodule/microtasks`)
|
||||
- react-native-mmkv (from `../node_modules/react-native-mmkv`)
|
||||
- "react-native-netinfo (from `../node_modules/@react-native-community/netinfo`)"
|
||||
- react-native-nfc-manager (from `../node_modules/react-native-nfc-manager`)
|
||||
- react-native-pager-view (from `../node_modules/react-native-pager-view`)
|
||||
- react-native-quick-crypto (from `../node_modules/react-native-quick-crypto`)
|
||||
- react-native-quick-sqlite (from `../node_modules/react-native-quick-sqlite`)
|
||||
@@ -3162,6 +3240,7 @@ DEPENDENCIES:
|
||||
|
||||
SPEC REPOS:
|
||||
trunk:
|
||||
- BitByteData
|
||||
- Firebase
|
||||
- FirebaseCore
|
||||
- FirebaseCoreExtension
|
||||
@@ -3171,6 +3250,7 @@ SPEC REPOS:
|
||||
- GoogleDataTransport
|
||||
- GoogleUtilities
|
||||
- libwebp
|
||||
- MMKVCore
|
||||
- nanopb
|
||||
- OpenSSL-Universal
|
||||
- PromisesObjC
|
||||
@@ -3179,7 +3259,7 @@ SPEC REPOS:
|
||||
- SDWebImageWebPCoder
|
||||
- Sentry
|
||||
- SocketRocket
|
||||
- SSZipArchive
|
||||
- SWCompression
|
||||
|
||||
EXTERNAL SOURCES:
|
||||
boost:
|
||||
@@ -3199,6 +3279,10 @@ EXTERNAL SOURCES:
|
||||
:tag: hermes-2025-07-07-RNv0.81.0-e0fc67142ec0763c6b6153ca2bf96df815539782
|
||||
HotUpdater:
|
||||
:path: "../node_modules/@hot-updater/react-native"
|
||||
NitroMmkv:
|
||||
:path: "../node_modules/react-native-mmkv"
|
||||
NitroModules:
|
||||
:path: "../node_modules/react-native-nitro-modules"
|
||||
RCT-Folly:
|
||||
:podspec: "../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec"
|
||||
RCTDeprecation:
|
||||
@@ -3265,10 +3349,10 @@ EXTERNAL SOURCES:
|
||||
:path: "../node_modules/react-native/ReactCommon"
|
||||
React-microtasksnativemodule:
|
||||
:path: "../node_modules/react-native/ReactCommon/react/nativemodule/microtasks"
|
||||
react-native-mmkv:
|
||||
:path: "../node_modules/react-native-mmkv"
|
||||
react-native-netinfo:
|
||||
:path: "../node_modules/@react-native-community/netinfo"
|
||||
react-native-nfc-manager:
|
||||
:path: "../node_modules/react-native-nfc-manager"
|
||||
react-native-pager-view:
|
||||
:path: "../node_modules/react-native-pager-view"
|
||||
react-native-quick-crypto:
|
||||
@@ -3371,24 +3455,28 @@ EXTERNAL SOURCES:
|
||||
:path: "../node_modules/react-native/ReactCommon/yoga"
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
BitByteData: 2422ed269fcddc44976d97f171a183d25ef535ce
|
||||
boost: 7e761d76ca2ce687f7cc98e698152abd03a18f90
|
||||
DoubleConversion: cb417026b2400c8f53ae97020b2be961b59470cb
|
||||
fast_float: b32c788ed9c6a8c584d114d0047beda9664e7cc6
|
||||
FBLazyVector: 941bef1c8eeabd9fe1f501e30a5220beee913886
|
||||
Firebase: f5439b235721ceeef14ca1f327c0da8e4e8556b5
|
||||
FirebaseCore: ff47fe1ad3ab9ef66edd3e8bc4647b493d2067f8
|
||||
FirebaseCoreExtension: 898ca55c7cb126f83747b32cb0daa95394b10853
|
||||
FirebaseCoreInternal: a9e1ff270f217489d9258563b693d11a312903bf
|
||||
FirebaseInstallations: ca48ec60ea51b66b9f214a91847ea3720cde97f5
|
||||
FirebaseMessaging: 919ce76cb353f0c36d463f5461d8ab584e6ed765
|
||||
Firebase: f07b15ae5a6ec0f93713e30b923d9970d144af3e
|
||||
FirebaseCore: bb595f3114953664e3c1dc032f008a244147cfd3
|
||||
FirebaseCoreExtension: 7e1f7118ee970e001a8013719fb90950ee5e0018
|
||||
FirebaseCoreInternal: d7f5a043c2cd01a08103ab586587c1468047bca6
|
||||
FirebaseInstallations: ae9f4902cb5bf1d0c5eaa31ec1f4e5495a0714e2
|
||||
FirebaseMessaging: d33971b7bb252745ea6cd31ab190d1a1df4b8ed5
|
||||
fmt: a40bb5bd0294ea969aaaba240a927bd33d878cdd
|
||||
glog: 5683914934d5b6e4240e497e0f4a3b42d1854183
|
||||
GoogleDataTransport: aae35b7ea0c09004c3797d53c8c41f66f219d6a7
|
||||
GoogleUtilities: 00c88b9a86066ef77f0da2fab05f65d7768ed8e1
|
||||
hermes-engine: 35c763d57c9832d0eef764316ca1c4d043581394
|
||||
HotUpdater: af56906e6be7aa821d10036f8f7d6a63c8e4ad22
|
||||
HotUpdater: ecbc87212adaf29fbd04eab80f105cf9a972f12f
|
||||
libwebp: 02b23773aedb6ff1fd38cec7a77b81414c6842a8
|
||||
MMKVCore: f2dd4c9befea04277a55e84e7812f930537993df
|
||||
nanopb: fad817b59e0457d11a5dfbde799381cd727c1275
|
||||
NitroMmkv: bdd120d9e6b234ebd637e60d066fbedf73004d11
|
||||
NitroModules: cf8804dafa637b6535c73fd113c3202b11307bfd
|
||||
OpenSSL-Universal: 6082b0bf950e5636fe0d78def171184e2b3899c2
|
||||
PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47
|
||||
RCT-Folly: 846fda9475e61ec7bcbf8a3fe81edfcaeb090669
|
||||
@@ -3425,12 +3513,12 @@ SPEC CHECKSUMS:
|
||||
React-logger: a3cb5b29c32b8e447b5a96919340e89334062b48
|
||||
React-Mapbuffer: e4a65db5f4df53369f39558c0cf2f480f6d3d6c7
|
||||
React-microtasksnativemodule: 86334c5c06315e0bccb7b6e6f2c905e92f98b615
|
||||
react-native-mmkv: 7b9c7469fa0a7e463f9411ad3e4fe273bd5ff030
|
||||
react-native-netinfo: cec9c4e86083cb5b6aba0e0711f563e2fbbff187
|
||||
react-native-pager-view: 0e228ec2dfdd87807d125c7bbfb83299edede19c
|
||||
react-native-nfc-manager: c8891e460b4943b695d63f7f4effc6345bbefc83
|
||||
react-native-pager-view: d91a84dd23f9fba7e63c4b9d68f32f52c9ec62ca
|
||||
react-native-quick-crypto: 2c53f72c27485924b444dda124639ee363cf1d69
|
||||
react-native-quick-sqlite: 7d9f9fda3aa1fea00387454f5d912c2271dc35fb
|
||||
react-native-safe-area-context: ee1e8e2a7abf737a8d4d9d1a5686a7f2e7466236
|
||||
react-native-safe-area-context: 0a3b034bb63a5b684dd2f5fffd3c90ef6ed41ee8
|
||||
React-NativeModulesApple: 8c7eb6057b00c191a11ad5ced41826ec5a0e4d78
|
||||
React-oscompat: 93b5535ea7f7dff46aaee4f78309a70979bdde9d
|
||||
React-perflogger: 5536d2df3d18fe0920263466f7b46a56351c0510
|
||||
@@ -3465,22 +3553,22 @@ SPEC CHECKSUMS:
|
||||
RNCClipboard: e560338bf6cc4656a09ff90610b62ddc0dbdad65
|
||||
RNExitApp: a2fd7923ab37b9166704fdc488622a48dcd372a2
|
||||
RNFastImage: 462a183c4b0b6b26fdfd639e1ed6ba37536c3b87
|
||||
RNFBApp: 0211ae65fadcb017cc787b2bd539847330687b93
|
||||
RNFBMessaging: 97dc90cb79d1d015250d9d10032c920f1d49c354
|
||||
RNGestureHandler: b8d2e75c2e88fc2a1f6be3b3beeeed80b88fa37d
|
||||
RNFBApp: 78d866e12b98c79b7cb141fcdcdf9813eae09b15
|
||||
RNFBMessaging: e16ebeae1f64f57603a193f1be6f3be7ab55c5e4
|
||||
RNGestureHandler: 9462ba64b3fdb2cb04cbc1b572d020c8d0a096e8
|
||||
RNKeychain: 76d042fc1dfba47f3945920bc82e0bce9ad1ff55
|
||||
RNLocalize: d8ccb568b40c72c767714db3808ce66a1ecf444a
|
||||
RNLocalize: a0bf70cf27f116db4e32be09a6f549715db0686d
|
||||
RNNotifee: 5e3b271e8ea7456a36eec994085543c9adca9168
|
||||
RNReanimated: 44af5b24b999a70c737df8e407582c32d12b3a87
|
||||
RNScreens: 2e9c41cd099b1ca50136af8d57c3594214d0086a
|
||||
RNSentry: 9584c841b049b0b751befefc324d2edb769f546e
|
||||
RNSVG: 08e4ffbf2e7e5b9f46dcc4b46b1326d1025cad52
|
||||
RNWorklets: 564218881b4c63ab941bd5b3be37ae585a30a1c6
|
||||
RNReanimated: c3de6d69dba4054d4f35562b14c84061699188e5
|
||||
RNScreens: 98771ad898d1c0528fc8139606bbacf5a2e9d237
|
||||
RNSentry: 145033a3996d33faa023a496c8338275b10269a3
|
||||
RNSVG: f2979aa72b14050b9220415c19de398f9cec9aaf
|
||||
RNWorklets: ab618bf7d1c7fd2cb793b9f0f39c3e29274b3ebf
|
||||
SDWebImage: a7f831e1a65eb5e285e3fb046a23fcfbf08e696d
|
||||
SDWebImageWebPCoder: 908b83b6adda48effe7667cd2b7f78c897e5111d
|
||||
Sentry: b53951377b78e21a734f5dc8318e333dbfc682d7
|
||||
Sentry: c643eb180df401dd8c734c5036ddd9dd9218daa6
|
||||
SocketRocket: d4aabe649be1e368d1318fdf28a022d714d65748
|
||||
SSZipArchive: 62d4947b08730e4cda640473b0066d209ff033c9
|
||||
SWCompression: 9379873ad5e9f25b31db88c441649b59a4c2bab7
|
||||
Yoga: 9b30b783a17681321b52ac507a37219d7d795ace
|
||||
|
||||
PODFILE CHECKSUM: b335b509a9bfd90d0626f23590a7a32278b465d8
|
||||
|
||||
File diff suppressed because one or more lines are too long
+32
-30
@@ -21,7 +21,7 @@
|
||||
"machine-translate": "npx @inlang/cli machine translate --project minibits.inlang"
|
||||
},
|
||||
"dependencies": {
|
||||
"@cashu/cashu-ts": "minibits-cash/cashu-ts#b3ba36757d84ec03f1064029db02308eb3a09cc4",
|
||||
"@cashu/cashu-ts": "minibits-cash/cashu-ts#c85d4638c007ac8126bc83a7287a6d848fcc8153",
|
||||
"@fortawesome/fontawesome-svg-core": "^7.1.0",
|
||||
"@fortawesome/free-brands-svg-icons": "^7.1.0",
|
||||
"@fortawesome/free-regular-svg-icons": "^7.1.0",
|
||||
@@ -30,30 +30,30 @@
|
||||
"@gandlaf21/bc-ur": "^1.1.12",
|
||||
"@gandlaf21/bolt11-decode": "^3.1.1",
|
||||
"@gocodingnow/rn-size-matters": "^0.0.4",
|
||||
"@hot-updater/react-native": "0.20.11",
|
||||
"@hot-updater/react-native": "0.23.1",
|
||||
"@notifee/react-native": "^9.1.8",
|
||||
"@react-native-clipboard/clipboard": "^1.16.3",
|
||||
"@react-native-community/netinfo": "^11.4.1",
|
||||
"@react-native-firebase/app": "^23.4.0",
|
||||
"@react-native-firebase/messaging": "^23.4.0",
|
||||
"@react-navigation/bottom-tabs": "^7.4.8",
|
||||
"@react-navigation/native": "^7.1.18",
|
||||
"@react-navigation/native-stack": "^7.3.27",
|
||||
"@react-navigation/stack": "^7.4.9",
|
||||
"@react-native-firebase/app": "^23.5.0",
|
||||
"@react-native-firebase/messaging": "^23.5.0",
|
||||
"@react-navigation/bottom-tabs": "^7.8.8",
|
||||
"@react-navigation/native": "^7.1.22",
|
||||
"@react-navigation/native-stack": "^7.8.2",
|
||||
"@react-navigation/stack": "^7.6.8",
|
||||
"@scure/bip39": "1.6.0",
|
||||
"@sentry/react-native": "^6.22.0",
|
||||
"@sentry/react-native": "^7.7.0",
|
||||
"date-fns": "^4.1.0",
|
||||
"i18n-js": "^4.5.1",
|
||||
"js-lnurl": "^0.6.0",
|
||||
"lodash.clonedeep": "^4.5.0",
|
||||
"lodash.debounce": "4.0.8",
|
||||
"message-port-polyfill": "^0.2.0",
|
||||
"mobx": "^6.13.7",
|
||||
"mobx-react-lite": "^4.1.0",
|
||||
"mobx": "^6.15.0",
|
||||
"mobx-react-lite": "^4.1.1",
|
||||
"mobx-state-tree": "^7.0.2",
|
||||
"nostr-tools": "minibits-cash/nostr-tools#2991f59d0150a0cb2c71e2f9a4cb6c8aca3b19d7",
|
||||
"numbro": "^2.5.0",
|
||||
"patch-package": "^8.0.0",
|
||||
"patch-package": "^8.0.1",
|
||||
"react": "19.1.0",
|
||||
"react-native": "0.81.4",
|
||||
"react-native-animated-pagination-dots": "^0.1.73",
|
||||
@@ -61,24 +61,26 @@
|
||||
"react-native-exit-app": "^2.0.0",
|
||||
"react-native-fast-image": "^8.6.3",
|
||||
"react-native-flash-message": "^0.4.2",
|
||||
"react-native-gesture-handler": "^2.28.0",
|
||||
"react-native-gesture-handler": "^2.29.1",
|
||||
"react-native-json-tree": "^1.5.0",
|
||||
"react-native-keychain": "^10.0.0",
|
||||
"react-native-localize": "^3.5.2",
|
||||
"react-native-localize": "^3.6.0",
|
||||
"react-native-logs": "^5.5.0",
|
||||
"react-native-mmkv": "^3.3.3",
|
||||
"react-native-mmkv": "^4.0.1",
|
||||
"react-native-modal": "^14.0.0-rc.1",
|
||||
"react-native-pager-view": "^6.9.1",
|
||||
"react-native-qrcode-svg": "^6.3.15",
|
||||
"react-native-nfc-manager": "^3.17.2",
|
||||
"react-native-nitro-modules": "^0.31.10",
|
||||
"react-native-pager-view": "^7.0.1",
|
||||
"react-native-qrcode-svg": "^6.3.20",
|
||||
"react-native-quick-crypto": "^0.7.17",
|
||||
"react-native-quick-sqlite": "8.2.7",
|
||||
"react-native-reanimated": "4.1.2",
|
||||
"react-native-safe-area-context": "^5.6.1",
|
||||
"react-native-screens": "^4.16.0",
|
||||
"react-native-svg": "^15.13.0",
|
||||
"react-native-tab-view": "^4.1.3",
|
||||
"react-native-reanimated": "4.1.5",
|
||||
"react-native-safe-area-context": "^5.6.2",
|
||||
"react-native-screens": "^4.18.0",
|
||||
"react-native-svg": "^15.15.0",
|
||||
"react-native-tab-view": "^4.2.0",
|
||||
"react-native-url-polyfill": "^3.0.0",
|
||||
"react-native-worklets": "^0.6.0",
|
||||
"react-native-worklets": "^0.6.1",
|
||||
"taskon": "^0.3.1",
|
||||
"text-encoding-polyfill": "^0.6.7",
|
||||
"util": "^0.12.5"
|
||||
@@ -88,9 +90,9 @@
|
||||
"@babel/plugin-proposal-export-namespace-from": "^7.18.9",
|
||||
"@babel/preset-env": "^7.25.3",
|
||||
"@babel/runtime": "^7.25.0",
|
||||
"@hot-updater/bare": "0.20.11",
|
||||
"@hot-updater/firebase": "0.20.11",
|
||||
"@hot-updater/sentry-plugin": "^0.20.11",
|
||||
"@hot-updater/bare": "0.23.1",
|
||||
"@hot-updater/firebase": "0.23.1",
|
||||
"@hot-updater/sentry-plugin": "^0.23.1",
|
||||
"@react-native-community/cli": "20.0.0",
|
||||
"@react-native-community/cli-platform-android": "20.0.0",
|
||||
"@react-native-community/cli-platform-ios": "20.0.0",
|
||||
@@ -98,7 +100,7 @@
|
||||
"@react-native/eslint-config": "0.81.4",
|
||||
"@react-native/metro-config": "0.81.4",
|
||||
"@react-native/typescript-config": "0.81.4",
|
||||
"@sentry/cli": "^2.56.0",
|
||||
"@sentry/cli": "^2.58.2",
|
||||
"@tsconfig/react-native": "^3.0.7",
|
||||
"@types/jest": "^29.5.13",
|
||||
"@types/lodash.clonedeep": "^4.5.9",
|
||||
@@ -108,9 +110,9 @@
|
||||
"dotenv": "^17.2.3",
|
||||
"eslint": "^8.56.0",
|
||||
"eslint-plugin-unused-imports": "^2.0.0",
|
||||
"firebase-admin": "^13.5.0",
|
||||
"firebase-tools": "^14.19.0",
|
||||
"hot-updater": "^0.19.9",
|
||||
"firebase-admin": "^13.6.0",
|
||||
"firebase-tools": "^14.26.0",
|
||||
"hot-updater": "^0.23.1",
|
||||
"jest": "^29.6.3",
|
||||
"prettier": "2.8.8",
|
||||
"react-native-clean-project": "^4.0.3",
|
||||
|
||||
@@ -23,6 +23,7 @@ import { faTelegramPlane } from "@fortawesome/free-brands-svg-icons/faTelegramPl
|
||||
import { faDiscord } from "@fortawesome/free-brands-svg-icons/faDiscord"
|
||||
import { faGithub } from "@fortawesome/free-brands-svg-icons/faGithub"
|
||||
import { faReddit } from "@fortawesome/free-brands-svg-icons/faReddit"
|
||||
import { faNfcSymbol } from '@fortawesome/free-brands-svg-icons/faNfcSymbol'
|
||||
|
||||
import { faWallet } from '@fortawesome/free-solid-svg-icons/faWallet'
|
||||
import { faAddressCard } from '@fortawesome/free-solid-svg-icons/faAddressCard'
|
||||
@@ -99,13 +100,15 @@ import { faHeartPulse } from "@fortawesome/free-solid-svg-icons/faHeartPulse"
|
||||
import { faSeedling } from "@fortawesome/free-solid-svg-icons/faSeedling"
|
||||
import { faChevronLeft } from '@fortawesome/free-solid-svg-icons/faChevronLeft'
|
||||
import { faArrowRightArrowLeft } from "@fortawesome/free-solid-svg-icons"
|
||||
import { faWifi } from "@fortawesome/free-solid-svg-icons"
|
||||
|
||||
|
||||
|
||||
export type IconTypes = keyof typeof iconRegistry
|
||||
|
||||
// TODO remove need for manual iconregistry?
|
||||
// would be best to just import all of them, i guess, or figure out something smart
|
||||
export const iconRegistry = { faAddressCard, faAddressBook, faWallet, faQrcode, faClipboard, faSliders, faCoins, faEllipsisVertical, faEllipsis, faArrowUp, faArrowDown, faArrowLeft, faXmark, faInfoCircle, faBug, faCheckCircle, faArrowTurnUp, faArrowTurnDown, faPencil, faTags, faShareFromSquare, faRotate, faCode, faBan, faCircle, faPaperPlane, faBolt, faArrowUpFromBracket, faArrowRightToBracket, faPlus, faShieldHalved, faCloudArrowUp, faPaintbrush, faCopy, faBurst, faUserShield, faLock, faLockOpen, faTriangleExclamation, faDownload, faUpload, faRecycle, faListUl, faExpand, faFingerprint, faWandMagicSparkles, faCircleUser, faComment, faKey, faCircleNodes, faBullseye, faEyeSlash, faUpRightFromSquare, faShareNodes, faPaste, faKeyboard, faMoneyBill1, faGears, faTag, faBank, faChevronDown, faChevronUp, faCircleExclamation, faCircleQuestion, faEnvelope, faTwitter, faTelegramPlane, faDiscord, faGithub, faReddit, faCircleArrowUp, faCircleArrowDown, faGlobe, faCubes, faClock, faArrowRotateLeft, faHeartPulse, faSeedling, faChevronLeft, faArrowRightArrowLeft }
|
||||
export const iconRegistry = { faWifi, faNfcSymbol, faAddressCard, faAddressBook, faWallet, faQrcode, faClipboard, faSliders, faCoins, faEllipsisVertical, faEllipsis, faArrowUp, faArrowDown, faArrowLeft, faXmark, faInfoCircle, faBug, faCheckCircle, faArrowTurnUp, faArrowTurnDown, faPencil, faTags, faShareFromSquare, faRotate, faCode, faBan, faCircle, faPaperPlane, faBolt, faArrowUpFromBracket, faArrowRightToBracket, faPlus, faShieldHalved, faCloudArrowUp, faPaintbrush, faCopy, faBurst, faUserShield, faLock, faLockOpen, faTriangleExclamation, faDownload, faUpload, faRecycle, faListUl, faExpand, faFingerprint, faWandMagicSparkles, faCircleUser, faComment, faKey, faCircleNodes, faBullseye, faEyeSlash, faUpRightFromSquare, faShareNodes, faPaste, faKeyboard, faMoneyBill1, faGears, faTag, faBank, faChevronDown, faChevronUp, faCircleExclamation, faCircleQuestion, faEnvelope, faTwitter, faTelegramPlane, faDiscord, faGithub, faReddit, faCircleArrowUp, faCircleArrowDown, faGlobe, faCubes, faClock, faArrowRotateLeft, faHeartPulse, faSeedling, faChevronLeft, faArrowRightArrowLeft }
|
||||
|
||||
|
||||
interface IconProps extends TouchableOpacityProps {
|
||||
|
||||
@@ -12,6 +12,7 @@ import {
|
||||
SendScreen,
|
||||
ScanScreen,
|
||||
LightningPayScreen,
|
||||
NfcPayScreen,
|
||||
ContactsScreen,
|
||||
PictureScreen,
|
||||
ContactDetailScreen,
|
||||
@@ -68,7 +69,8 @@ const WalletStack = createNativeStackNavigator({
|
||||
Receive: ReceiveScreen,
|
||||
Send: SendScreen,
|
||||
Scan: ScanScreen,
|
||||
LightningPay: LightningPayScreen,
|
||||
LightningPay: LightningPayScreen,
|
||||
NfcPay: NfcPayScreen,
|
||||
Transfer: TransferScreen,
|
||||
Topup: TopupScreen,
|
||||
CashuPaymentRequest: CashuPaymentRequestScreen,
|
||||
|
||||
@@ -165,7 +165,7 @@ export const LightningPayScreen = function LightningPayScreen({ route }: Props)
|
||||
const scanIcon = useThemeColor('text')
|
||||
const inputBg = useThemeColor('background')
|
||||
const inputText = useThemeColor('text')
|
||||
const contactIcon = useThemeColor('headerTitle')
|
||||
const contactIcon = useThemeColor('textDim')
|
||||
const headerBg = useThemeColor('header')
|
||||
const headerTitle = useThemeColor('headerTitle')
|
||||
|
||||
|
||||
@@ -0,0 +1,428 @@
|
||||
import React, { FC, useState, useEffect, useRef } from 'react'
|
||||
import {
|
||||
ViewStyle,
|
||||
View,
|
||||
TextStyle,
|
||||
Alert,
|
||||
Platform,
|
||||
DeviceEventEmitter,
|
||||
} from 'react-native'
|
||||
import { PaymentRequest as CashuPaymentRequest, PaymentRequestTransport, PaymentRequestTransportType, decodePaymentRequest, getDecodedToken } from '@cashu/cashu-ts'
|
||||
import NfcManager, { NfcTech, Ndef, NfcEvents } from 'react-native-nfc-manager'
|
||||
import { colors, spacing, typography, useThemeColor } from '../theme'
|
||||
import EventEmitter from '../utils/eventEmitter'
|
||||
import { log } from '../services/logService'
|
||||
import { IncomingDataType, IncomingParser } from '../services/incomingParser'
|
||||
import AppError, { Err } from '../utils/AppError'
|
||||
import { Button, Card, ErrorModal, Icon, InfoModal, ListItem, ScanIcon, Screen, Text } from '../components'
|
||||
import { infoMessage } from '../utils/utils'
|
||||
import { SvgXml } from 'react-native-svg'
|
||||
import { MintUnit, MintUnits } from '../services/wallet/currency'
|
||||
import { useStores } from '../models'
|
||||
import { MintHeader } from './Mints/MintHeader'
|
||||
import { verticalScale } from '@gocodingnow/rn-size-matters'
|
||||
import useIsInternetReachable from '../utils/useIsInternetReachable'
|
||||
import { translate } from '../i18n'
|
||||
import { StaticScreenProps, useNavigation } from '@react-navigation/native'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import { Mint, MintBalance } from '../models/Mint'
|
||||
import { TransactionTaskResult } from '../services'
|
||||
import { SendOption } from './SendScreen'
|
||||
import { TransferOption } from './TransferScreen'
|
||||
import { Transaction, TransactionStatus } from '../models/Transaction'
|
||||
import { Proof } from '../models/Proof'
|
||||
import { SEND_TASK } from '../services/wallet/sendTask'
|
||||
|
||||
type Props = StaticScreenProps<{
|
||||
unit: MintUnit
|
||||
}>
|
||||
|
||||
export const NfcPayScreen = observer(function NfcPayScreen({ route }: Props) {
|
||||
const navigation = useNavigation<any>()
|
||||
const { mintsStore, walletStore, proofsStore } = useStores()
|
||||
const unitRef = useRef<MintUnit>('sat')
|
||||
const isInternetReachable = useIsInternetReachable()
|
||||
|
||||
const [paymentOption, setPaymentOption] = useState<SendOption | TransferOption>(TransferOption.PASTE_OR_SCAN_INVOICE)
|
||||
const [encodedTokenToSend, setEncodedTokenToSend] = useState<string | undefined>()
|
||||
const [encodedCashuPaymentRequest, setEncodedCashuPaymentRequest] = useState<string | undefined>()
|
||||
const [decodedCashuPaymentRequest, setDecodedCashuPaymentRequest] = useState<CashuPaymentRequest | undefined>()
|
||||
const [memo, setMemo] = useState('')
|
||||
const [availableMintBalances, setAvailableMintBalances] = useState<MintBalance[]>([])
|
||||
const [mintBalanceToSendFrom, setMintBalanceToSendFrom] = useState<MintBalance | undefined>()
|
||||
const [selectedProofs, setSelectedProofs] = useState<Proof[]>([])
|
||||
const [transactionStatus, setTransactionStatus] = useState<TransactionStatus | undefined>()
|
||||
const [transaction, setTransaction] = useState<Transaction | undefined>()
|
||||
const [transactionId, setTransactionId] = useState<number | undefined>()
|
||||
const [resultModalInfo, setResultModalInfo] = useState<{status: TransactionStatus, title?: string, message: string} | undefined>()
|
||||
const [isLoading, setIsLoading] = useState(false)
|
||||
|
||||
const [isMintSelectorVisible, setIsMintSelectorVisible] = useState(false)
|
||||
const [isOfflineSend, setIsOfflineSend] = useState(false)
|
||||
const [isSendTaskSentToQueue, setIsSendTaskSentToQueue] = useState(false)
|
||||
const [isResultModalVisible, setIsResultModalVisible] = useState(false)
|
||||
// NFC state
|
||||
const [isNfcEnabled, setIsNfcEnabled] = useState(false)
|
||||
const [isNfcSupported, setIsNfcSupported] = useState(false)
|
||||
const [isProcessing, setIsProcessing] = useState(false)
|
||||
const [nfcInfo, setNfcInfo] = useState<string | undefined>()
|
||||
const [readNfcData, setReadNfcData] = useState<string | undefined>()
|
||||
const [mint, setMint] = useState<Mint | undefined>()
|
||||
|
||||
const [error, setError] = useState<AppError | undefined>()
|
||||
const [info, setInfo] = useState<string>('')
|
||||
|
||||
// Start NFC only when this screen is visible
|
||||
useEffect(() => {
|
||||
const initNfc = async () => {
|
||||
try {
|
||||
const supported = await NfcManager.isSupported()
|
||||
setIsNfcSupported(supported)
|
||||
if (!supported) {
|
||||
setNfcInfo('NFC is not supported on this device')
|
||||
return
|
||||
}
|
||||
|
||||
await NfcManager.start()
|
||||
|
||||
const enabled = await NfcManager.isEnabled()
|
||||
if (!enabled) {
|
||||
setNfcInfo('Please enable NFC in your device settings')
|
||||
return
|
||||
}
|
||||
|
||||
setIsNfcEnabled(true)
|
||||
|
||||
// Start listening for tags immediately
|
||||
startNfcSession()
|
||||
} catch (e: any) {
|
||||
log.error('Failed to initialize NFC', e.message)
|
||||
setNfcInfo('Failed to initialize NFC: ' + e.message)
|
||||
// setError(new AppError(Err.NFC_ERROR, 'Failed to initialize NFC', e.message))
|
||||
}
|
||||
}
|
||||
|
||||
initNfc()
|
||||
|
||||
return () => {
|
||||
NfcManager.cancelTechnologyRequest().catch(() => {})
|
||||
NfcManager.setEventListener(NfcEvents.DiscoverTag, null)
|
||||
}
|
||||
}, [])
|
||||
|
||||
// Auto-restart session when screen comes into focus
|
||||
useEffect(() => {
|
||||
const unsubscribe = navigation.addListener('focus', () => {
|
||||
if (isNfcEnabled && !isProcessing) {
|
||||
startNfcSession()
|
||||
}
|
||||
})
|
||||
return unsubscribe
|
||||
}, [navigation, isNfcEnabled, isProcessing])
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
const handleSendTaskResult = async (result: TransactionTaskResult) => {
|
||||
log.trace('handleSendTaskResult event handler triggered')
|
||||
|
||||
const {transaction} = result
|
||||
|
||||
setTransactionStatus(transaction?.status)
|
||||
setTransaction(transaction)
|
||||
setTransactionId(transaction?.id)
|
||||
|
||||
if (result.encodedTokenToSend) {
|
||||
setEncodedTokenToSend(result.encodedTokenToSend)
|
||||
}
|
||||
|
||||
if(paymentOption === SendOption.PAY_CASHU_PAYMENT_REQUEST) {
|
||||
if(decodedCashuPaymentRequest && decodedCashuPaymentRequest.id && transaction) {
|
||||
|
||||
transaction.update({
|
||||
paymentId: decodedCashuPaymentRequest.id,
|
||||
paymentRequest: encodedCashuPaymentRequest,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
if (result.error) {
|
||||
setResultModalInfo({
|
||||
status: result.transaction?.status as TransactionStatus,
|
||||
title: result.error.params?.message ? result.error.message : 'Payment failed',
|
||||
message: result.error.params?.message || result.error.message,
|
||||
})
|
||||
setIsResultModalVisible(true)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Subscribe to the 'sendCompleted' event
|
||||
if(isSendTaskSentToQueue) {
|
||||
EventEmitter.on(`ev_${SEND_TASK}_result`, handleSendTaskResult)
|
||||
}
|
||||
|
||||
// Unsubscribe from the 'sendCompleted' event on component unmount
|
||||
return () => {
|
||||
EventEmitter.off(`ev_${SEND_TASK}_result`, handleSendTaskResult)
|
||||
}
|
||||
}, [isSendTaskSentToQueue])
|
||||
|
||||
|
||||
const startNfcSession = async () => {
|
||||
try {
|
||||
await NfcManager.requestTechnology(NfcTech.Ndef, {
|
||||
alertMessage: 'Hold phone near the device...',
|
||||
//invalidateAfterFirstRead: false,
|
||||
})
|
||||
|
||||
// Listen for tag discovery
|
||||
NfcManager.setEventListener(NfcEvents.DiscoverTag, async (tag: any) => {
|
||||
if (isProcessing) return
|
||||
setIsProcessing(true)
|
||||
setNfcInfo('Reading payment request...')
|
||||
|
||||
try {
|
||||
const ndefMessage = tag.ndefMessage?.[0]
|
||||
if (!ndefMessage) {
|
||||
throw new AppError(Err.VALIDATION_ERROR, 'No NDEF message found')
|
||||
}
|
||||
|
||||
let payload: string
|
||||
|
||||
// Handle both Text and URI records
|
||||
if (ndefMessage.type === Ndef.RTD_TEXT) {
|
||||
const decoded = Ndef.text.decodePayload(ndefMessage.payload)
|
||||
payload = decoded
|
||||
} else if (ndefMessage.type === Ndef.RTD_URI) {
|
||||
const decoded = Ndef.uri.decodePayload(ndefMessage.payload)
|
||||
payload = decoded
|
||||
} else {
|
||||
payload = new TextDecoder().decode(ndefMessage.payload)
|
||||
}
|
||||
|
||||
log.trace('NFC tag read', { payload })
|
||||
setReadNfcData(payload)
|
||||
await handlePaymentRequest(payload)
|
||||
|
||||
} catch (e: any) {
|
||||
handleError(e)
|
||||
} finally {
|
||||
setIsProcessing(false)
|
||||
}
|
||||
})
|
||||
} catch (ex: any) {
|
||||
if (ex.message !== 'cancelled') {
|
||||
setInfo('Tap terminal to pay')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const handlePaymentRequest = async (data: string) => {
|
||||
try {
|
||||
Alert.alert(data)
|
||||
const result = IncomingParser.findAndExtract(data)
|
||||
|
||||
if (result.type === IncomingDataType.CASHU_PAYMENT_REQUEST) {
|
||||
const encodedCashuPaymentRequest = result.encoded
|
||||
const pr: CashuPaymentRequest = decodePaymentRequest(encodedCashuPaymentRequest)
|
||||
|
||||
log.trace('[handlePaymentRequest] decoded payment request', {pr})
|
||||
|
||||
//setDecodedCashuPaymentRequest(pr)
|
||||
//setEncodedCashuPaymentRequest(encodedCashuPaymentRequest)
|
||||
|
||||
if(pr.unit && !MintUnits.includes(pr.unit as MintUnit)) {
|
||||
throw new AppError(Err.VALIDATION_ERROR, `Wallet does not support ${pr.unit} unit.`)
|
||||
}
|
||||
|
||||
if(pr.unit) {
|
||||
unitRef.current = pr.unit as MintUnit
|
||||
}
|
||||
|
||||
/*if (pr.description && pr.description.length > 0) {
|
||||
setMemo(pr.description)
|
||||
setIsCashuPrWithDesc(true)
|
||||
}*/
|
||||
|
||||
if (!pr.amount || pr.amount <= 0) {
|
||||
throw new AppError(Err.VALIDATION_ERROR, 'Cashu payment request does not specify an amount to pay.')
|
||||
}
|
||||
|
||||
/*
|
||||
setAmountToSend(`${numbro(pr.amount / getCurrency(unitRef.current).precision)
|
||||
.format({
|
||||
thousandSeparated: true,
|
||||
mantissa: getCurrency(unitRef.current).mantissa
|
||||
})}`)
|
||||
|
||||
*/
|
||||
|
||||
let availableBalances: MintBalance[] = []
|
||||
|
||||
if (pr.mints && pr.mints.length > 0) {
|
||||
|
||||
for (const mint of pr.mints) {
|
||||
if (mintsStore.mintExists(mint)) {
|
||||
const mintBalance = proofsStore.getMintBalance(mint)
|
||||
availableBalances.push(mintBalance!)
|
||||
}
|
||||
}
|
||||
|
||||
if (availableBalances.length === 0) {
|
||||
throw new AppError(Err.NOTFOUND_ERROR, 'Wallet does not have any of the mints accepted by Cashu payment request.', {mints: pr.mints})
|
||||
}
|
||||
|
||||
const withEnoughBalance = availableBalances.filter(balance => {
|
||||
const unitBalance = balance.balances[unitRef.current]
|
||||
|
||||
if(unitBalance && unitBalance >= pr.amount!) {
|
||||
return balance
|
||||
}
|
||||
|
||||
return null
|
||||
})
|
||||
|
||||
if(withEnoughBalance.length === 0) {
|
||||
throw new AppError(Err.NOTFOUND_ERROR, `Wallet does not have enough balance to fulfill Cashu payment request of ${pr.amount} ${unitRef.current}.`, {availableBalances, amount: pr.amount, unit: unitRef.current})
|
||||
}
|
||||
|
||||
availableBalances = withEnoughBalance
|
||||
|
||||
// setAvailableMintBalances(withEnoughBalance)
|
||||
// setMintBalanceToSendFrom(withEnoughBalance[0])
|
||||
|
||||
} else {
|
||||
availableBalances = proofsStore.getMintBalancesWithEnoughBalance(pr.amount, unitRef.current)
|
||||
}
|
||||
|
||||
|
||||
|
||||
//setIsMintSelectorVisible(true)
|
||||
}
|
||||
|
||||
if (result.type === IncomingDataType.INVOICE) {
|
||||
Alert.alert(result.toString())
|
||||
}
|
||||
|
||||
} catch (e: any) {
|
||||
handleError(e)
|
||||
}
|
||||
}
|
||||
|
||||
const writeTokenToTag = async (token: string) => {
|
||||
try {
|
||||
// Re-request tech to write back
|
||||
await NfcManager.requestTechnology(NfcTech.Ndef)
|
||||
|
||||
const textRecord = Ndef.textRecord('en', token)
|
||||
const bytes = Ndef.encodeMessage([textRecord])
|
||||
|
||||
await NfcManager.ndefHandler.writeNdefMessage(bytes)
|
||||
setInfo('Payment sent!')
|
||||
} catch (e: any) {
|
||||
throw new AppError(Err.NFC_ERROR, 'Failed to send token', e.message)
|
||||
} finally {
|
||||
NfcManager.cancelTechnologyRequest().catch(() => {})
|
||||
}
|
||||
}
|
||||
|
||||
const handleError = (e: AppError) => {
|
||||
setError(e)
|
||||
setInfo('')
|
||||
setIsProcessing(false)
|
||||
}
|
||||
|
||||
const gotoScan = () => {
|
||||
navigation.navigate('Scan', { unit: unitRef.current })
|
||||
}
|
||||
|
||||
// Theme
|
||||
const hintText = useThemeColor('textDim')
|
||||
const headerBg = useThemeColor('header')
|
||||
const headerTitle = useThemeColor('headerTitle')
|
||||
const scanIcon = useThemeColor('text')
|
||||
const scanButtonColor = useThemeColor('card')
|
||||
|
||||
return (
|
||||
<Screen preset="fixed" contentContainerStyle={$screen}>
|
||||
<MintHeader mint={mint} unit={unitRef.current} />
|
||||
<View style={[$headerContainer, { backgroundColor: headerBg }]}>
|
||||
<Icon
|
||||
icon='faNfcSymbol'
|
||||
size={verticalScale(35)}
|
||||
color={headerTitle}
|
||||
/>
|
||||
</View>
|
||||
|
||||
<View style={$contentContainer}>
|
||||
<Card
|
||||
ContentComponent={
|
||||
<>
|
||||
<Icon
|
||||
icon='faWifi'
|
||||
size={verticalScale(80)}
|
||||
color={isNfcEnabled ? colors.palette.success200 : colors.palette.neutral400}
|
||||
containerStyle={{
|
||||
alignSelf: 'center',
|
||||
marginVertical: spacing.large,
|
||||
transform: [{ rotate: '-90deg' }]
|
||||
}}
|
||||
/>
|
||||
<Text
|
||||
text={
|
||||
nfcInfo ? nfcInfo : ''
|
||||
}
|
||||
style={{
|
||||
textAlign: 'center',
|
||||
marginBottom: spacing.medium,
|
||||
//fontFamily: typography.code,
|
||||
color: isNfcEnabled ? colors.palette.success200 : colors.palette.neutral500,
|
||||
fontSize: 18
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
|
||||
<View style={$bottomContainer}>
|
||||
<View style={$buttonContainer}>
|
||||
<Button
|
||||
preset='tertiary'
|
||||
LeftAccessory={() => (
|
||||
<SvgXml
|
||||
width={spacing.medium}
|
||||
height={spacing.medium}
|
||||
xml={ScanIcon}
|
||||
fill={scanIcon}
|
||||
style={{marginHorizontal: spacing.extraSmall}}
|
||||
/>
|
||||
)}
|
||||
onPress={gotoScan}
|
||||
//style={{backgroundColor: scanButtonColor}}
|
||||
text='Scan QR instead'
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
{info && !isProcessing && <InfoModal message={info} />}
|
||||
{error && <ErrorModal error={error} />}
|
||||
</Screen>
|
||||
)
|
||||
})
|
||||
|
||||
// Styles remain unchanged
|
||||
const $screen: ViewStyle = { flex: 1 }
|
||||
const $contentContainer: ViewStyle = { flex: 1, marginTop: -spacing.extraLarge * 2, padding: spacing.extraSmall }
|
||||
const $headerContainer: TextStyle = { alignItems: 'center', paddingBottom: spacing.medium, height: spacing.screenHeight * 0.15 }
|
||||
const $buttonContainer: ViewStyle = { marginTop: spacing.large, flexDirection: 'row', alignSelf: 'center' }
|
||||
const $bottomContainer: ViewStyle = {
|
||||
position: 'absolute',
|
||||
bottom: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
flex: 1,
|
||||
justifyContent: 'flex-end',
|
||||
marginBottom: spacing.medium,
|
||||
alignSelf: 'stretch',
|
||||
}
|
||||
@@ -445,6 +445,15 @@ export const WalletScreen = observer(function WalletScreen({ route }: Props) {
|
||||
}
|
||||
|
||||
|
||||
const gotoNfcPay = function () {
|
||||
setIsSendModalVisible(false)
|
||||
// @ts-ignore
|
||||
navigation.navigate('NfcPay', {
|
||||
unit: currentUnit
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
const gotoLightningPay = function (mintUrl?: string) {
|
||||
log.trace({mintUrl})
|
||||
if(mintUrl) {
|
||||
@@ -496,7 +505,8 @@ export const WalletScreen = observer(function WalletScreen({ route }: Props) {
|
||||
<View style={[
|
||||
$headerContainer, {
|
||||
backgroundColor: headerBg,
|
||||
paddingTop: spacing.small,
|
||||
//paddingTop: spacing.tiny,
|
||||
//borderWidth: 1
|
||||
}
|
||||
]}>
|
||||
<UnitBalanceBlock
|
||||
@@ -569,7 +579,11 @@ export const WalletScreen = observer(function WalletScreen({ route }: Props) {
|
||||
|
||||
const renderTabBar = (props: any) => {
|
||||
return(
|
||||
<View style={{backgroundColor: headerBg, marginTop: -spacing.small}}>
|
||||
<View style={{
|
||||
backgroundColor: headerBg,
|
||||
marginTop: -spacing.small,
|
||||
//borderWidth: 1,
|
||||
}}>
|
||||
<View style={{width: routes.length * tabWidth, alignSelf: 'center', backgroundColor: headerBg}}>
|
||||
<TabBar
|
||||
{...props}
|
||||
@@ -578,7 +592,7 @@ export const WalletScreen = observer(function WalletScreen({ route }: Props) {
|
||||
<CurrencySign
|
||||
mintUnit={route.key as MintUnit}
|
||||
textStyle={{color: 'white'}}
|
||||
containerStyle={{padding: spacing.medium, width: tabWidth}}
|
||||
containerStyle={{padding: spacing.small, width: tabWidth}}
|
||||
/>
|
||||
)}
|
||||
indicatorStyle={{backgroundColor: getActiveTabColor(props.navigationState)}}
|
||||
@@ -805,6 +819,12 @@ export const WalletScreen = observer(function WalletScreen({ route }: Props) {
|
||||
subTx="walletScreen_payWithLightningDesc"
|
||||
onPress={() => gotoLightningPay()}
|
||||
/>
|
||||
<ListItem
|
||||
leftIcon='faNfcSymbol'
|
||||
text="Pay with NFC"
|
||||
subText="Tap to pay using NFC-enabled wallets or POS"
|
||||
onPress={() => gotoNfcPay()}
|
||||
/>
|
||||
</>
|
||||
}
|
||||
onBackButtonPress={toggleSendModal}
|
||||
@@ -864,7 +884,7 @@ const UnitBalanceBlock = observer(function (props: {
|
||||
mintUnit={unitBalance.unit}
|
||||
symbolStyle={{display: 'none'}}
|
||||
amountStyle={[$unitBalance, {color: balanceColor}]}
|
||||
containerStyle={{marginTop: spacing.medium}}
|
||||
containerStyle={{marginTop: spacing.small}}
|
||||
/>
|
||||
<View style={{height: verticalScale(40)}}>
|
||||
{walletStore.exchangeRate
|
||||
@@ -1092,7 +1112,7 @@ const $screen: ViewStyle = {
|
||||
const $headerContainer: TextStyle = {
|
||||
alignItems: 'center',
|
||||
// padding: spacing.tiny,
|
||||
height: spacing.screenHeight * 0.27,
|
||||
height: spacing.screenHeight * 0.25,
|
||||
}
|
||||
|
||||
const $tabContainer: TextStyle = {
|
||||
|
||||
@@ -18,6 +18,7 @@ export * from './TopupScreen'
|
||||
export * from './LightningPayScreen'
|
||||
export * from './TokenReceiveScreen'
|
||||
export * from './CashuPaymentRequestScreen'
|
||||
export * from './NfcPayScreen'
|
||||
|
||||
// ContactsNavigator
|
||||
export * from './ContactsScreen'
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import {MMKV} from 'react-native-mmkv'
|
||||
import {createMMKV, type MMKV} from 'react-native-mmkv'
|
||||
import {log} from './logService'
|
||||
import AppError, {Err} from '../utils/AppError'
|
||||
|
||||
@@ -8,7 +8,7 @@ let _storage: MMKV | undefined
|
||||
const getInstance = function () {
|
||||
if (!_storage) {
|
||||
|
||||
_storage = new MMKV({
|
||||
_storage = createMMKV({
|
||||
id: STORAGE_KEY,
|
||||
})
|
||||
|
||||
@@ -135,7 +135,7 @@ const save = function (key: string, value: any): boolean {
|
||||
const remove = function (key: string): void {
|
||||
try {
|
||||
const storage = getInstance()
|
||||
storage.delete(key)
|
||||
storage.remove(key)
|
||||
} catch (e: any) {
|
||||
throw new AppError(Err.DATABASE_ERROR, e.message)
|
||||
}
|
||||
|
||||
@@ -20,7 +20,8 @@ export enum Err {
|
||||
SERVER_ERROR = 'SERVER_ERROR',
|
||||
LOCKED_ERROR = 'LOCKED_ERROR',
|
||||
SCAN_ERROR = 'SCAN_ERROR',
|
||||
AUTH_ERROR = "AUTH_ERROR"
|
||||
AUTH_ERROR = "AUTH_ERROR",
|
||||
NFC_ERROR = "NFC_ERROR",
|
||||
}
|
||||
|
||||
export interface IAppError {
|
||||
|
||||
Reference in New Issue
Block a user