diff --git a/packages/examples/sdk-react-native/.gitignore b/packages/examples/sdk-react-native/.gitignore index 0cab2ac6f..ce53e3e2f 100644 --- a/packages/examples/sdk-react-native/.gitignore +++ b/packages/examples/sdk-react-native/.gitignore @@ -64,3 +64,8 @@ yarn-error.log # testing /coverage + +# Expo +.expo +dist/ +web-build/ \ No newline at end of file diff --git a/packages/examples/sdk-react-native/android/app/build.gradle b/packages/examples/sdk-react-native/android/app/build.gradle index 3e450ec37..93a743410 100644 --- a/packages/examples/sdk-react-native/android/app/build.gradle +++ b/packages/examples/sdk-react-native/android/app/build.gradle @@ -48,6 +48,11 @@ react { // // The list of flags to pass to the Hermes compiler. By default is "-O", "-output-source-map" // hermesFlags = ["-O", "-output-source-map"] + // + // Added by install-expo-modules + entryFile = file(["node", "-e", "require('expo/scripts/resolveAppEntry')", rootDir.getAbsoluteFile().getParentFile().getAbsolutePath(), "android", "absolute"].execute(null, rootDir).text.trim()) + cliFile = new File(["node", "--print", "require.resolve('@expo/cli')"].execute(null, rootDir).text.trim()) + bundleCommand = "export:embed" } /** diff --git a/packages/examples/sdk-react-native/android/app/src/main/AndroidManifest.xml b/packages/examples/sdk-react-native/android/app/src/main/AndroidManifest.xml index 4122f36a5..55d8a4015 100644 --- a/packages/examples/sdk-react-native/android/app/src/main/AndroidManifest.xml +++ b/packages/examples/sdk-react-native/android/app/src/main/AndroidManifest.xml @@ -2,6 +2,13 @@ + + + + + + + getPackages() { @Override protected String getJSMainModuleName() { - return "index"; + return ".expo/.virtual-metro-entry"; } @Override @@ -42,7 +45,7 @@ protected boolean isNewArchEnabled() { protected Boolean isHermesEnabled() { return BuildConfig.IS_HERMES_ENABLED; } - }; + }); @Override public ReactNativeHost getReactNativeHost() { @@ -58,5 +61,12 @@ public void onCreate() { DefaultNewArchitectureEntryPoint.load(); } ReactNativeFlipper.initializeFlipper(this, getReactNativeHost().getReactInstanceManager()); + ApplicationLifecycleDispatcher.onApplicationCreate(this); + } + + @Override + public void onConfigurationChanged(Configuration newConfig) { + super.onConfigurationChanged(newConfig); + ApplicationLifecycleDispatcher.onConfigurationChanged(this, newConfig); } } diff --git a/packages/examples/sdk-react-native/android/settings.gradle b/packages/examples/sdk-react-native/android/settings.gradle index 73697cabb..5a50dc11f 100644 --- a/packages/examples/sdk-react-native/android/settings.gradle +++ b/packages/examples/sdk-react-native/android/settings.gradle @@ -2,3 +2,6 @@ rootProject.name = 'rnsdktest' apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings) include ':app' includeBuild('../node_modules/@react-native/gradle-plugin') + +apply from: new File(["node", "--print", "require.resolve('expo/package.json')"].execute(null, rootDir).text.trim(), "../scripts/autolinking.gradle") +useExpoModules() \ No newline at end of file diff --git a/packages/examples/sdk-react-native/babel.config.js b/packages/examples/sdk-react-native/babel.config.js index f842b77fc..fcb34864d 100644 --- a/packages/examples/sdk-react-native/babel.config.js +++ b/packages/examples/sdk-react-native/babel.config.js @@ -1,3 +1,3 @@ module.exports = { - presets: ['module:metro-react-native-babel-preset'], + presets: ['babel-preset-expo'], }; diff --git a/packages/examples/sdk-react-native/ios/Podfile b/packages/examples/sdk-react-native/ios/Podfile index f4589eb87..7aae13edf 100644 --- a/packages/examples/sdk-react-native/ios/Podfile +++ b/packages/examples/sdk-react-native/ios/Podfile @@ -1,3 +1,4 @@ +require File.join(File.dirname(`node --print "require.resolve('expo/package.json')"`), "scripts/autolinking") # Resolve react_native_pods.rb with node to allow for hoisting require Pod::Executable.execute_command('node', ['-p', 'require.resolve( @@ -5,7 +6,7 @@ require Pod::Executable.execute_command('node', ['-p', {paths: [process.argv[1]]}, )', __dir__]).strip -platform :ios, min_ios_version_supported +platform :ios, '13.0' prepare_react_native_project! # If you are using a `react-native-flipper` your iOS build will fail when `NO_FLIPPER=1` is set. @@ -26,6 +27,14 @@ if linkage != nil end target 'rnsdktest' do + use_expo_modules! + post_integrate do |installer| + begin + expo_patch_react_imports!(installer) + rescue => e + Pod::UI.warn e + end + end config = use_native_modules! # Flags change depending on the env values. diff --git a/packages/examples/sdk-react-native/ios/Podfile.lock b/packages/examples/sdk-react-native/ios/Podfile.lock new file mode 100644 index 000000000..104a3d7e6 --- /dev/null +++ b/packages/examples/sdk-react-native/ios/Podfile.lock @@ -0,0 +1,809 @@ +PODS: + - boost (1.76.0) + - CocoaAsyncSocket (7.6.5) + - DoubleConversion (1.1.6) + - EXApplication (5.3.1): + - ExpoModulesCore + - EXAV (13.4.1): + - ExpoModulesCore + - ReactCommon/turbomodule/core + - EXConstants (14.4.2): + - ExpoModulesCore + - EXFileSystem (15.4.5): + - ExpoModulesCore + - EXFont (11.4.0): + - ExpoModulesCore + - Expo (49.0.21): + - ExpoModulesCore + - ExpoKeepAwake (12.3.0): + - ExpoModulesCore + - ExpoLinearGradient (12.3.0): + - ExpoModulesCore + - ExpoModulesCore (1.5.12): + - RCT-Folly (= 2021.07.22.00) + - React-Core + - React-NativeModulesApple + - React-RCTAppDelegate + - ReactCommon/turbomodule/core + - FBLazyVector (0.72.6) + - FBReactNativeSpec (0.72.6): + - RCT-Folly (= 2021.07.22.00) + - RCTRequired (= 0.72.6) + - RCTTypeSafety (= 0.72.6) + - React-Core (= 0.72.6) + - React-jsi (= 0.72.6) + - ReactCommon/turbomodule/core (= 0.72.6) + - Flipper (0.182.0): + - Flipper-Folly (~> 2.6) + - Flipper-Boost-iOSX (1.76.0.1.11) + - Flipper-DoubleConversion (3.2.0.1) + - Flipper-Fmt (7.1.7) + - Flipper-Folly (2.6.10): + - Flipper-Boost-iOSX + - Flipper-DoubleConversion + - Flipper-Fmt (= 7.1.7) + - Flipper-Glog + - libevent (~> 2.1.12) + - OpenSSL-Universal (= 1.1.1100) + - Flipper-Glog (0.5.0.5) + - Flipper-PeerTalk (0.0.4) + - FlipperKit (0.182.0): + - FlipperKit/Core (= 0.182.0) + - FlipperKit/Core (0.182.0): + - Flipper (~> 0.182.0) + - FlipperKit/CppBridge + - FlipperKit/FBCxxFollyDynamicConvert + - FlipperKit/FBDefines + - FlipperKit/FKPortForwarding + - SocketRocket (~> 0.6.0) + - FlipperKit/CppBridge (0.182.0): + - Flipper (~> 0.182.0) + - FlipperKit/FBCxxFollyDynamicConvert (0.182.0): + - Flipper-Folly (~> 2.6) + - FlipperKit/FBDefines (0.182.0) + - FlipperKit/FKPortForwarding (0.182.0): + - CocoaAsyncSocket (~> 7.6) + - Flipper-PeerTalk (~> 0.0.4) + - FlipperKit/FlipperKitHighlightOverlay (0.182.0) + - FlipperKit/FlipperKitLayoutHelpers (0.182.0): + - FlipperKit/Core + - FlipperKit/FlipperKitHighlightOverlay + - FlipperKit/FlipperKitLayoutTextSearchable + - FlipperKit/FlipperKitLayoutIOSDescriptors (0.182.0): + - FlipperKit/Core + - FlipperKit/FlipperKitHighlightOverlay + - FlipperKit/FlipperKitLayoutHelpers + - YogaKit (~> 1.18) + - FlipperKit/FlipperKitLayoutPlugin (0.182.0): + - FlipperKit/Core + - FlipperKit/FlipperKitHighlightOverlay + - FlipperKit/FlipperKitLayoutHelpers + - FlipperKit/FlipperKitLayoutIOSDescriptors + - FlipperKit/FlipperKitLayoutTextSearchable + - YogaKit (~> 1.18) + - FlipperKit/FlipperKitLayoutTextSearchable (0.182.0) + - FlipperKit/FlipperKitNetworkPlugin (0.182.0): + - FlipperKit/Core + - FlipperKit/FlipperKitReactPlugin (0.182.0): + - FlipperKit/Core + - FlipperKit/FlipperKitUserDefaultsPlugin (0.182.0): + - FlipperKit/Core + - FlipperKit/SKIOSNetworkPlugin (0.182.0): + - FlipperKit/Core + - FlipperKit/FlipperKitNetworkPlugin + - fmt (6.2.1) + - glog (0.3.5) + - hermes-engine (0.72.6): + - hermes-engine/Pre-built (= 0.72.6) + - hermes-engine/Pre-built (0.72.6) + - libevent (2.1.12) + - OpenSSL-Universal (1.1.1100) + - push-react-native-sdk (0.1.0): + - React-Core + - RCT-Folly (2021.07.22.00): + - boost + - DoubleConversion + - fmt (~> 6.2.1) + - glog + - RCT-Folly/Default (= 2021.07.22.00) + - RCT-Folly/Default (2021.07.22.00): + - boost + - DoubleConversion + - fmt (~> 6.2.1) + - glog + - RCT-Folly/Futures (2021.07.22.00): + - boost + - DoubleConversion + - fmt (~> 6.2.1) + - glog + - libevent + - RCTRequired (0.72.6) + - RCTTypeSafety (0.72.6): + - FBLazyVector (= 0.72.6) + - RCTRequired (= 0.72.6) + - React-Core (= 0.72.6) + - React (0.72.6): + - React-Core (= 0.72.6) + - React-Core/DevSupport (= 0.72.6) + - React-Core/RCTWebSocket (= 0.72.6) + - React-RCTActionSheet (= 0.72.6) + - React-RCTAnimation (= 0.72.6) + - React-RCTBlob (= 0.72.6) + - React-RCTImage (= 0.72.6) + - React-RCTLinking (= 0.72.6) + - React-RCTNetwork (= 0.72.6) + - React-RCTSettings (= 0.72.6) + - React-RCTText (= 0.72.6) + - React-RCTVibration (= 0.72.6) + - React-callinvoker (0.72.6) + - React-Codegen (0.72.6): + - DoubleConversion + - FBReactNativeSpec + - glog + - hermes-engine + - RCT-Folly + - RCTRequired + - RCTTypeSafety + - React-Core + - React-jsi + - React-jsiexecutor + - React-NativeModulesApple + - React-rncore + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - React-Core (0.72.6): + - glog + - hermes-engine + - RCT-Folly (= 2021.07.22.00) + - React-Core/Default (= 0.72.6) + - React-cxxreact + - React-hermes + - React-jsi + - React-jsiexecutor + - React-perflogger + - React-runtimeexecutor + - React-utils + - SocketRocket (= 0.6.1) + - Yoga + - React-Core/CoreModulesHeaders (0.72.6): + - glog + - hermes-engine + - RCT-Folly (= 2021.07.22.00) + - React-Core/Default + - React-cxxreact + - React-hermes + - React-jsi + - React-jsiexecutor + - React-perflogger + - React-runtimeexecutor + - React-utils + - SocketRocket (= 0.6.1) + - Yoga + - React-Core/Default (0.72.6): + - glog + - hermes-engine + - RCT-Folly (= 2021.07.22.00) + - React-cxxreact + - React-hermes + - React-jsi + - React-jsiexecutor + - React-perflogger + - React-runtimeexecutor + - React-utils + - SocketRocket (= 0.6.1) + - Yoga + - React-Core/DevSupport (0.72.6): + - glog + - hermes-engine + - RCT-Folly (= 2021.07.22.00) + - React-Core/Default (= 0.72.6) + - React-Core/RCTWebSocket (= 0.72.6) + - React-cxxreact + - React-hermes + - React-jsi + - React-jsiexecutor + - React-jsinspector (= 0.72.6) + - React-perflogger + - React-runtimeexecutor + - React-utils + - SocketRocket (= 0.6.1) + - Yoga + - React-Core/RCTActionSheetHeaders (0.72.6): + - glog + - hermes-engine + - RCT-Folly (= 2021.07.22.00) + - React-Core/Default + - React-cxxreact + - React-hermes + - React-jsi + - React-jsiexecutor + - React-perflogger + - React-runtimeexecutor + - React-utils + - SocketRocket (= 0.6.1) + - Yoga + - React-Core/RCTAnimationHeaders (0.72.6): + - glog + - hermes-engine + - RCT-Folly (= 2021.07.22.00) + - React-Core/Default + - React-cxxreact + - React-hermes + - React-jsi + - React-jsiexecutor + - React-perflogger + - React-runtimeexecutor + - React-utils + - SocketRocket (= 0.6.1) + - Yoga + - React-Core/RCTBlobHeaders (0.72.6): + - glog + - hermes-engine + - RCT-Folly (= 2021.07.22.00) + - React-Core/Default + - React-cxxreact + - React-hermes + - React-jsi + - React-jsiexecutor + - React-perflogger + - React-runtimeexecutor + - React-utils + - SocketRocket (= 0.6.1) + - Yoga + - React-Core/RCTImageHeaders (0.72.6): + - glog + - hermes-engine + - RCT-Folly (= 2021.07.22.00) + - React-Core/Default + - React-cxxreact + - React-hermes + - React-jsi + - React-jsiexecutor + - React-perflogger + - React-runtimeexecutor + - React-utils + - SocketRocket (= 0.6.1) + - Yoga + - React-Core/RCTLinkingHeaders (0.72.6): + - glog + - hermes-engine + - RCT-Folly (= 2021.07.22.00) + - React-Core/Default + - React-cxxreact + - React-hermes + - React-jsi + - React-jsiexecutor + - React-perflogger + - React-runtimeexecutor + - React-utils + - SocketRocket (= 0.6.1) + - Yoga + - React-Core/RCTNetworkHeaders (0.72.6): + - glog + - hermes-engine + - RCT-Folly (= 2021.07.22.00) + - React-Core/Default + - React-cxxreact + - React-hermes + - React-jsi + - React-jsiexecutor + - React-perflogger + - React-runtimeexecutor + - React-utils + - SocketRocket (= 0.6.1) + - Yoga + - React-Core/RCTSettingsHeaders (0.72.6): + - glog + - hermes-engine + - RCT-Folly (= 2021.07.22.00) + - React-Core/Default + - React-cxxreact + - React-hermes + - React-jsi + - React-jsiexecutor + - React-perflogger + - React-runtimeexecutor + - React-utils + - SocketRocket (= 0.6.1) + - Yoga + - React-Core/RCTTextHeaders (0.72.6): + - glog + - hermes-engine + - RCT-Folly (= 2021.07.22.00) + - React-Core/Default + - React-cxxreact + - React-hermes + - React-jsi + - React-jsiexecutor + - React-perflogger + - React-runtimeexecutor + - React-utils + - SocketRocket (= 0.6.1) + - Yoga + - React-Core/RCTVibrationHeaders (0.72.6): + - glog + - hermes-engine + - RCT-Folly (= 2021.07.22.00) + - React-Core/Default + - React-cxxreact + - React-hermes + - React-jsi + - React-jsiexecutor + - React-perflogger + - React-runtimeexecutor + - React-utils + - SocketRocket (= 0.6.1) + - Yoga + - React-Core/RCTWebSocket (0.72.6): + - glog + - hermes-engine + - RCT-Folly (= 2021.07.22.00) + - React-Core/Default (= 0.72.6) + - React-cxxreact + - React-hermes + - React-jsi + - React-jsiexecutor + - React-perflogger + - React-runtimeexecutor + - React-utils + - SocketRocket (= 0.6.1) + - Yoga + - React-CoreModules (0.72.6): + - RCT-Folly (= 2021.07.22.00) + - RCTTypeSafety (= 0.72.6) + - React-Codegen (= 0.72.6) + - React-Core/CoreModulesHeaders (= 0.72.6) + - React-jsi (= 0.72.6) + - React-RCTBlob + - React-RCTImage (= 0.72.6) + - ReactCommon/turbomodule/core (= 0.72.6) + - SocketRocket (= 0.6.1) + - React-cxxreact (0.72.6): + - boost (= 1.76.0) + - DoubleConversion + - glog + - hermes-engine + - RCT-Folly (= 2021.07.22.00) + - React-callinvoker (= 0.72.6) + - React-debug (= 0.72.6) + - React-jsi (= 0.72.6) + - React-jsinspector (= 0.72.6) + - React-logger (= 0.72.6) + - React-perflogger (= 0.72.6) + - React-runtimeexecutor (= 0.72.6) + - React-debug (0.72.6) + - React-hermes (0.72.6): + - DoubleConversion + - glog + - hermes-engine + - RCT-Folly (= 2021.07.22.00) + - RCT-Folly/Futures (= 2021.07.22.00) + - React-cxxreact (= 0.72.6) + - React-jsi + - React-jsiexecutor (= 0.72.6) + - React-jsinspector (= 0.72.6) + - React-perflogger (= 0.72.6) + - React-jsi (0.72.6): + - boost (= 1.76.0) + - DoubleConversion + - glog + - hermes-engine + - RCT-Folly (= 2021.07.22.00) + - React-jsiexecutor (0.72.6): + - DoubleConversion + - glog + - hermes-engine + - RCT-Folly (= 2021.07.22.00) + - React-cxxreact (= 0.72.6) + - React-jsi (= 0.72.6) + - React-perflogger (= 0.72.6) + - React-jsinspector (0.72.6) + - React-logger (0.72.6): + - glog + - react-native-fast-openpgp (2.7.0): + - RCT-Folly (= 2021.07.22.00) + - React-Core + - react-native-get-random-values (1.9.0): + - React-Core + - react-native-randombytes (3.6.1): + - React-Core + - react-native-webview (13.2.2): + - React-Core + - React-NativeModulesApple (0.72.6): + - hermes-engine + - React-callinvoker + - React-Core + - React-cxxreact + - React-jsi + - React-runtimeexecutor + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - React-perflogger (0.72.6) + - React-RCTActionSheet (0.72.6): + - React-Core/RCTActionSheetHeaders (= 0.72.6) + - React-RCTAnimation (0.72.6): + - RCT-Folly (= 2021.07.22.00) + - RCTTypeSafety (= 0.72.6) + - React-Codegen (= 0.72.6) + - React-Core/RCTAnimationHeaders (= 0.72.6) + - React-jsi (= 0.72.6) + - ReactCommon/turbomodule/core (= 0.72.6) + - React-RCTAppDelegate (0.72.6): + - RCT-Folly + - RCTRequired + - RCTTypeSafety + - React-Core + - React-CoreModules + - React-hermes + - React-NativeModulesApple + - React-RCTImage + - React-RCTNetwork + - React-runtimescheduler + - ReactCommon/turbomodule/core + - React-RCTBlob (0.72.6): + - hermes-engine + - RCT-Folly (= 2021.07.22.00) + - React-Codegen (= 0.72.6) + - React-Core/RCTBlobHeaders (= 0.72.6) + - React-Core/RCTWebSocket (= 0.72.6) + - React-jsi (= 0.72.6) + - React-RCTNetwork (= 0.72.6) + - ReactCommon/turbomodule/core (= 0.72.6) + - React-RCTImage (0.72.6): + - RCT-Folly (= 2021.07.22.00) + - RCTTypeSafety (= 0.72.6) + - React-Codegen (= 0.72.6) + - React-Core/RCTImageHeaders (= 0.72.6) + - React-jsi (= 0.72.6) + - React-RCTNetwork (= 0.72.6) + - ReactCommon/turbomodule/core (= 0.72.6) + - React-RCTLinking (0.72.6): + - React-Codegen (= 0.72.6) + - React-Core/RCTLinkingHeaders (= 0.72.6) + - React-jsi (= 0.72.6) + - ReactCommon/turbomodule/core (= 0.72.6) + - React-RCTNetwork (0.72.6): + - RCT-Folly (= 2021.07.22.00) + - RCTTypeSafety (= 0.72.6) + - React-Codegen (= 0.72.6) + - React-Core/RCTNetworkHeaders (= 0.72.6) + - React-jsi (= 0.72.6) + - ReactCommon/turbomodule/core (= 0.72.6) + - React-RCTSettings (0.72.6): + - RCT-Folly (= 2021.07.22.00) + - RCTTypeSafety (= 0.72.6) + - React-Codegen (= 0.72.6) + - React-Core/RCTSettingsHeaders (= 0.72.6) + - React-jsi (= 0.72.6) + - ReactCommon/turbomodule/core (= 0.72.6) + - React-RCTText (0.72.6): + - React-Core/RCTTextHeaders (= 0.72.6) + - React-RCTVibration (0.72.6): + - RCT-Folly (= 2021.07.22.00) + - React-Codegen (= 0.72.6) + - React-Core/RCTVibrationHeaders (= 0.72.6) + - React-jsi (= 0.72.6) + - ReactCommon/turbomodule/core (= 0.72.6) + - React-rncore (0.72.6) + - React-runtimeexecutor (0.72.6): + - React-jsi (= 0.72.6) + - React-runtimescheduler (0.72.6): + - glog + - hermes-engine + - RCT-Folly (= 2021.07.22.00) + - React-callinvoker + - React-debug + - React-jsi + - React-runtimeexecutor + - React-utils (0.72.6): + - glog + - RCT-Folly (= 2021.07.22.00) + - React-debug + - ReactCommon/turbomodule/bridging (0.72.6): + - DoubleConversion + - glog + - hermes-engine + - RCT-Folly (= 2021.07.22.00) + - React-callinvoker (= 0.72.6) + - React-cxxreact (= 0.72.6) + - React-jsi (= 0.72.6) + - React-logger (= 0.72.6) + - React-perflogger (= 0.72.6) + - ReactCommon/turbomodule/core (0.72.6): + - DoubleConversion + - glog + - hermes-engine + - RCT-Folly (= 2021.07.22.00) + - React-callinvoker (= 0.72.6) + - React-cxxreact (= 0.72.6) + - React-jsi (= 0.72.6) + - React-logger (= 0.72.6) + - React-perflogger (= 0.72.6) + - RNSVG (14.1.0): + - React-Core + - SocketRocket (0.6.1) + - Yoga (1.14.0) + - YogaKit (1.18.1): + - Yoga (~> 1.14) + +DEPENDENCIES: + - boost (from `../node_modules/react-native/third-party-podspecs/boost.podspec`) + - DoubleConversion (from `../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`) + - EXApplication (from `../node_modules/expo-application/ios`) + - EXAV (from `../node_modules/expo-av/ios`) + - EXConstants (from `../node_modules/expo-constants/ios`) + - EXFileSystem (from `../node_modules/expo-file-system/ios`) + - EXFont (from `../node_modules/expo-font/ios`) + - Expo (from `../node_modules/expo`) + - ExpoKeepAwake (from `../node_modules/expo-keep-awake/ios`) + - ExpoLinearGradient (from `../node_modules/expo-linear-gradient/ios`) + - ExpoModulesCore (from `../node_modules/expo-modules-core`) + - FBLazyVector (from `../node_modules/react-native/Libraries/FBLazyVector`) + - FBReactNativeSpec (from `../node_modules/react-native/React/FBReactNativeSpec`) + - Flipper (= 0.182.0) + - Flipper-Boost-iOSX (= 1.76.0.1.11) + - Flipper-DoubleConversion (= 3.2.0.1) + - Flipper-Fmt (= 7.1.7) + - Flipper-Folly (= 2.6.10) + - Flipper-Glog (= 0.5.0.5) + - Flipper-PeerTalk (= 0.0.4) + - FlipperKit (= 0.182.0) + - FlipperKit/Core (= 0.182.0) + - FlipperKit/CppBridge (= 0.182.0) + - FlipperKit/FBCxxFollyDynamicConvert (= 0.182.0) + - FlipperKit/FBDefines (= 0.182.0) + - FlipperKit/FKPortForwarding (= 0.182.0) + - FlipperKit/FlipperKitHighlightOverlay (= 0.182.0) + - FlipperKit/FlipperKitLayoutPlugin (= 0.182.0) + - FlipperKit/FlipperKitLayoutTextSearchable (= 0.182.0) + - FlipperKit/FlipperKitNetworkPlugin (= 0.182.0) + - FlipperKit/FlipperKitReactPlugin (= 0.182.0) + - FlipperKit/FlipperKitUserDefaultsPlugin (= 0.182.0) + - FlipperKit/SKIOSNetworkPlugin (= 0.182.0) + - glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`) + - hermes-engine (from `../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec`) + - libevent (~> 2.1.12) + - OpenSSL-Universal (= 1.1.1100) + - "push-react-native-sdk (from `../node_modules/@pushprotocol/react-native-sdk`)" + - RCT-Folly (from `../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec`) + - RCTRequired (from `../node_modules/react-native/Libraries/RCTRequired`) + - RCTTypeSafety (from `../node_modules/react-native/Libraries/TypeSafety`) + - React (from `../node_modules/react-native/`) + - React-callinvoker (from `../node_modules/react-native/ReactCommon/callinvoker`) + - React-Codegen (from `build/generated/ios`) + - React-Core (from `../node_modules/react-native/`) + - React-Core/DevSupport (from `../node_modules/react-native/`) + - React-Core/RCTWebSocket (from `../node_modules/react-native/`) + - React-CoreModules (from `../node_modules/react-native/React/CoreModules`) + - React-cxxreact (from `../node_modules/react-native/ReactCommon/cxxreact`) + - React-debug (from `../node_modules/react-native/ReactCommon/react/debug`) + - React-hermes (from `../node_modules/react-native/ReactCommon/hermes`) + - React-jsi (from `../node_modules/react-native/ReactCommon/jsi`) + - React-jsiexecutor (from `../node_modules/react-native/ReactCommon/jsiexecutor`) + - React-jsinspector (from `../node_modules/react-native/ReactCommon/jsinspector`) + - React-logger (from `../node_modules/react-native/ReactCommon/logger`) + - react-native-fast-openpgp (from `../node_modules/react-native-fast-openpgp`) + - react-native-get-random-values (from `../node_modules/react-native-get-random-values`) + - react-native-randombytes (from `../node_modules/react-native-randombytes`) + - react-native-webview (from `../node_modules/react-native-webview`) + - React-NativeModulesApple (from `../node_modules/react-native/ReactCommon/react/nativemodule/core/platform/ios`) + - React-perflogger (from `../node_modules/react-native/ReactCommon/reactperflogger`) + - React-RCTActionSheet (from `../node_modules/react-native/Libraries/ActionSheetIOS`) + - React-RCTAnimation (from `../node_modules/react-native/Libraries/NativeAnimation`) + - React-RCTAppDelegate (from `../node_modules/react-native/Libraries/AppDelegate`) + - React-RCTBlob (from `../node_modules/react-native/Libraries/Blob`) + - React-RCTImage (from `../node_modules/react-native/Libraries/Image`) + - React-RCTLinking (from `../node_modules/react-native/Libraries/LinkingIOS`) + - React-RCTNetwork (from `../node_modules/react-native/Libraries/Network`) + - React-RCTSettings (from `../node_modules/react-native/Libraries/Settings`) + - React-RCTText (from `../node_modules/react-native/Libraries/Text`) + - React-RCTVibration (from `../node_modules/react-native/Libraries/Vibration`) + - React-rncore (from `../node_modules/react-native/ReactCommon`) + - React-runtimeexecutor (from `../node_modules/react-native/ReactCommon/runtimeexecutor`) + - React-runtimescheduler (from `../node_modules/react-native/ReactCommon/react/renderer/runtimescheduler`) + - React-utils (from `../node_modules/react-native/ReactCommon/react/utils`) + - ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`) + - RNSVG (from `../node_modules/react-native-svg`) + - Yoga (from `../node_modules/react-native/ReactCommon/yoga`) + +SPEC REPOS: + trunk: + - CocoaAsyncSocket + - Flipper + - Flipper-Boost-iOSX + - Flipper-DoubleConversion + - Flipper-Fmt + - Flipper-Folly + - Flipper-Glog + - Flipper-PeerTalk + - FlipperKit + - fmt + - libevent + - OpenSSL-Universal + - SocketRocket + - YogaKit + +EXTERNAL SOURCES: + boost: + :podspec: "../node_modules/react-native/third-party-podspecs/boost.podspec" + DoubleConversion: + :podspec: "../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec" + EXApplication: + :path: "../node_modules/expo-application/ios" + EXAV: + :path: "../node_modules/expo-av/ios" + EXConstants: + :path: "../node_modules/expo-constants/ios" + EXFileSystem: + :path: "../node_modules/expo-file-system/ios" + EXFont: + :path: "../node_modules/expo-font/ios" + Expo: + :path: "../node_modules/expo" + ExpoKeepAwake: + :path: "../node_modules/expo-keep-awake/ios" + ExpoLinearGradient: + :path: "../node_modules/expo-linear-gradient/ios" + ExpoModulesCore: + :path: "../node_modules/expo-modules-core" + FBLazyVector: + :path: "../node_modules/react-native/Libraries/FBLazyVector" + FBReactNativeSpec: + :path: "../node_modules/react-native/React/FBReactNativeSpec" + glog: + :podspec: "../node_modules/react-native/third-party-podspecs/glog.podspec" + hermes-engine: + :podspec: "../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec" + :tag: hermes-2023-08-07-RNv0.72.4-813b2def12bc9df02654b3e3653ae4a68d0572e0 + push-react-native-sdk: + :path: "../node_modules/@pushprotocol/react-native-sdk" + RCT-Folly: + :podspec: "../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec" + RCTRequired: + :path: "../node_modules/react-native/Libraries/RCTRequired" + RCTTypeSafety: + :path: "../node_modules/react-native/Libraries/TypeSafety" + React: + :path: "../node_modules/react-native/" + React-callinvoker: + :path: "../node_modules/react-native/ReactCommon/callinvoker" + React-Codegen: + :path: build/generated/ios + React-Core: + :path: "../node_modules/react-native/" + React-CoreModules: + :path: "../node_modules/react-native/React/CoreModules" + React-cxxreact: + :path: "../node_modules/react-native/ReactCommon/cxxreact" + React-debug: + :path: "../node_modules/react-native/ReactCommon/react/debug" + React-hermes: + :path: "../node_modules/react-native/ReactCommon/hermes" + React-jsi: + :path: "../node_modules/react-native/ReactCommon/jsi" + React-jsiexecutor: + :path: "../node_modules/react-native/ReactCommon/jsiexecutor" + React-jsinspector: + :path: "../node_modules/react-native/ReactCommon/jsinspector" + React-logger: + :path: "../node_modules/react-native/ReactCommon/logger" + react-native-fast-openpgp: + :path: "../node_modules/react-native-fast-openpgp" + react-native-get-random-values: + :path: "../node_modules/react-native-get-random-values" + react-native-randombytes: + :path: "../node_modules/react-native-randombytes" + react-native-webview: + :path: "../node_modules/react-native-webview" + React-NativeModulesApple: + :path: "../node_modules/react-native/ReactCommon/react/nativemodule/core/platform/ios" + React-perflogger: + :path: "../node_modules/react-native/ReactCommon/reactperflogger" + React-RCTActionSheet: + :path: "../node_modules/react-native/Libraries/ActionSheetIOS" + React-RCTAnimation: + :path: "../node_modules/react-native/Libraries/NativeAnimation" + React-RCTAppDelegate: + :path: "../node_modules/react-native/Libraries/AppDelegate" + React-RCTBlob: + :path: "../node_modules/react-native/Libraries/Blob" + React-RCTImage: + :path: "../node_modules/react-native/Libraries/Image" + React-RCTLinking: + :path: "../node_modules/react-native/Libraries/LinkingIOS" + React-RCTNetwork: + :path: "../node_modules/react-native/Libraries/Network" + React-RCTSettings: + :path: "../node_modules/react-native/Libraries/Settings" + React-RCTText: + :path: "../node_modules/react-native/Libraries/Text" + React-RCTVibration: + :path: "../node_modules/react-native/Libraries/Vibration" + React-rncore: + :path: "../node_modules/react-native/ReactCommon" + React-runtimeexecutor: + :path: "../node_modules/react-native/ReactCommon/runtimeexecutor" + React-runtimescheduler: + :path: "../node_modules/react-native/ReactCommon/react/renderer/runtimescheduler" + React-utils: + :path: "../node_modules/react-native/ReactCommon/react/utils" + ReactCommon: + :path: "../node_modules/react-native/ReactCommon" + RNSVG: + :path: "../node_modules/react-native-svg" + Yoga: + :path: "../node_modules/react-native/ReactCommon/yoga" + +SPEC CHECKSUMS: + boost: 57d2868c099736d80fcd648bf211b4431e51a558 + CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99 + DoubleConversion: 5189b271737e1565bdce30deb4a08d647e3f5f54 + EXApplication: 042aa2e3f05258a16962ea1a9914bf288db9c9a1 + EXAV: f393dfc0b28214d62855a31e06eb21d426d6e2da + EXConstants: ce5bbea779da8031ac818c36bea41b10e14d04e1 + EXFileSystem: f8b838a880254de42a5a7da20ed5ce12e2697c1b + EXFont: 738c44c390953ebcbab075a4848bfbef025fd9ee + Expo: 61a8e1aa94311557c137c0a4dfd4fe78281cfbb4 + ExpoKeepAwake: be4cbd52d9b177cde0fd66daa1913afa3161fc1d + ExpoLinearGradient: 5966dd5d49872cc9c104fedc8bbc298b6049b2e8 + ExpoModulesCore: c480fd4e3c7c8e81f0a6ba3a7c56869f25fe016d + FBLazyVector: 748c0ef74f2bf4b36cfcccf37916806940a64c32 + FBReactNativeSpec: 966f29e4e697de53a3b366355e8f57375c856ad9 + Flipper: 6edb735e6c3e332975d1b17956bcc584eccf5818 + Flipper-Boost-iOSX: fd1e2b8cbef7e662a122412d7ac5f5bea715403c + Flipper-DoubleConversion: 2dc99b02f658daf147069aad9dbd29d8feb06d30 + Flipper-Fmt: 60cbdd92fc254826e61d669a5d87ef7015396a9b + Flipper-Folly: 584845625005ff068a6ebf41f857f468decd26b3 + Flipper-Glog: 70c50ce58ddaf67dc35180db05f191692570f446 + Flipper-PeerTalk: 116d8f857dc6ef55c7a5a75ea3ceaafe878aadc9 + FlipperKit: 2efad7007d6745a3f95e4034d547be637f89d3f6 + fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9 + glog: 04b94705f318337d7ead9e6d17c019bd9b1f6b1b + hermes-engine: 8057e75cfc1437b178ac86c8654b24e7fead7f60 + libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913 + OpenSSL-Universal: ebc357f1e6bc71fa463ccb2fe676756aff50e88c + push-react-native-sdk: d9d498989a0efa80523cfc7517ae24259d4a10f5 + RCT-Folly: 424b8c9a7a0b9ab2886ffe9c3b041ef628fd4fb1 + RCTRequired: 28469809442eb4eb5528462705f7d852948c8a74 + RCTTypeSafety: e9c6c409fca2cc584e5b086862d562540cb38d29 + React: 769f469909b18edfe934f0539fffb319c4c61043 + React-callinvoker: e48ce12c83706401251921896576710d81e54763 + React-Codegen: a136b8094d39fd071994eaa935366e6be2239cb1 + React-Core: e548a186fb01c3a78a9aeeffa212d625ca9511bf + React-CoreModules: d226b22d06ea1bc4e49d3c073b2c6cbb42265405 + React-cxxreact: 44a3560510ead6633b6e02f9fbbdd1772fb40f92 + React-debug: 238501490155574ae9f3f8dd1c74330eba30133e + React-hermes: 46e66dc854124d7645c20bfec0a6be9542826ecd + React-jsi: fbdaf4166bae60524b591b18c851b530c8cdb90c + React-jsiexecutor: 3bf18ff7cb03cd8dfdce08fbbc0d15058c1d71ae + React-jsinspector: 194e32c6aab382d88713ad3dd0025c5f5c4ee072 + React-logger: cebf22b6cf43434e471dc561e5911b40ac01d289 + react-native-fast-openpgp: f88473e308194d06f6601e322035836be5877bf0 + react-native-get-random-values: dee677497c6a740b71e5612e8dbd83e7539ed5bb + react-native-randombytes: 421f1c7d48c0af8dbcd471b0324393ebf8fe7846 + react-native-webview: b8ec89966713985111a14d6e4bf98d8b54bced0d + React-NativeModulesApple: 02e35e9a51e10c6422f04f5e4076a7c02243fff2 + React-perflogger: e3596db7e753f51766bceadc061936ef1472edc3 + React-RCTActionSheet: 17ab132c748b4471012abbcdcf5befe860660485 + React-RCTAnimation: c8bbaab62be5817d2a31c36d5f2571e3f7dcf099 + React-RCTAppDelegate: af1c7dace233deba4b933cd1d6491fe4e3584ad1 + React-RCTBlob: 1bcf3a0341eb8d6950009b1ddb8aefaf46996b8c + React-RCTImage: 670a3486b532292649b1aef3ffddd0b495a5cee4 + React-RCTLinking: bd7ab853144aed463903237e615fd91d11b4f659 + React-RCTNetwork: be86a621f3e4724758f23ad1fdce32474ab3d829 + React-RCTSettings: 4f3a29a6d23ffa639db9701bc29af43f30781058 + React-RCTText: adde32164a243103aaba0b1dc7b0a2599733873e + React-RCTVibration: 6bd85328388ac2e82ae0ca11afe48ad5555b483a + React-rncore: fda7b1ae5918fa7baa259105298a5487875a57c8 + React-runtimeexecutor: 57d85d942862b08f6d15441a0badff2542fd233c + React-runtimescheduler: f23e337008403341177fc52ee4ca94e442c17ede + React-utils: fa59c9a3375fb6f4aeb66714fd3f7f76b43a9f16 + ReactCommon: dd03c17275c200496f346af93a7b94c53f3093a4 + RNSVG: ba3e7232f45e34b7b47e74472386cf4e1a676d0a + SocketRocket: f32cd54efbe0f095c4d7594881e52619cfe80b17 + Yoga: b76f1acfda8212aa16b7e26bcce3983230c82603 + YogaKit: f782866e155069a2cca2517aafea43200b01fd5a + +PODFILE CHECKSUM: 1f558ed4affcd96124c5e0f5f09e499d67a1a465 + +COCOAPODS: 1.12.1 diff --git a/packages/examples/sdk-react-native/ios/rnsdktest.xcodeproj/project.pbxproj b/packages/examples/sdk-react-native/ios/rnsdktest.xcodeproj/project.pbxproj index 088c94e9f..e85666171 100644 --- a/packages/examples/sdk-react-native/ios/rnsdktest.xcodeproj/project.pbxproj +++ b/packages/examples/sdk-react-native/ios/rnsdktest.xcodeproj/project.pbxproj @@ -14,6 +14,8 @@ 13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; }; 7699B88040F8A987B510C191 /* libPods-rnsdktest-rnsdktestTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 19F6CBCC0A4E27FBF8BF4A61 /* libPods-rnsdktest-rnsdktestTests.a */; }; 81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */; }; + D3886B3EDFF56D08CE208F9D /* ExpoModulesProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AB96AA764B476307991EC5D /* ExpoModulesProvider.swift */; }; + FCDF00919D29F4508BA06765 /* ExpoModulesProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = FEF762D3DEECF3CF97206AA6 /* ExpoModulesProvider.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -41,9 +43,11 @@ 5709B34CF0A7D63546082F79 /* Pods-rnsdktest.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-rnsdktest.release.xcconfig"; path = "Target Support Files/Pods-rnsdktest/Pods-rnsdktest.release.xcconfig"; sourceTree = ""; }; 5B7EB9410499542E8C5724F5 /* Pods-rnsdktest-rnsdktestTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-rnsdktest-rnsdktestTests.debug.xcconfig"; path = "Target Support Files/Pods-rnsdktest-rnsdktestTests/Pods-rnsdktest-rnsdktestTests.debug.xcconfig"; sourceTree = ""; }; 5DCACB8F33CDC322A6C60F78 /* libPods-rnsdktest.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-rnsdktest.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 7AB96AA764B476307991EC5D /* ExpoModulesProvider.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ExpoModulesProvider.swift; path = "Pods/Target Support Files/Pods-rnsdktest-rnsdktestTests/ExpoModulesProvider.swift"; sourceTree = ""; }; 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = rnsdktest/LaunchScreen.storyboard; sourceTree = ""; }; 89C6BE57DB24E9ADA2F236DE /* Pods-rnsdktest-rnsdktestTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-rnsdktest-rnsdktestTests.release.xcconfig"; path = "Target Support Files/Pods-rnsdktest-rnsdktestTests/Pods-rnsdktest-rnsdktestTests.release.xcconfig"; sourceTree = ""; }; ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; }; + FEF762D3DEECF3CF97206AA6 /* ExpoModulesProvider.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ExpoModulesProvider.swift; path = "Pods/Target Support Files/Pods-rnsdktest/ExpoModulesProvider.swift"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -83,6 +87,14 @@ name = "Supporting Files"; sourceTree = ""; }; + 0B22B6BB14FC37A2AE8DB644 /* rnsdktest */ = { + isa = PBXGroup; + children = ( + FEF762D3DEECF3CF97206AA6 /* ExpoModulesProvider.swift */, + ); + name = rnsdktest; + sourceTree = ""; + }; 13B07FAE1A68108700A75B9A /* rnsdktest */ = { isa = PBXGroup; children = ( @@ -96,6 +108,15 @@ name = rnsdktest; sourceTree = ""; }; + 1B477E83BD2FC603B8A2F283 /* ExpoModulesProviders */ = { + isa = PBXGroup; + children = ( + 0B22B6BB14FC37A2AE8DB644 /* rnsdktest */, + 929C35D260F95369D5CD37ED /* rnsdktestTests */, + ); + name = ExpoModulesProviders; + sourceTree = ""; + }; 2D16E6871FA4F8E400B85C8A /* Frameworks */ = { isa = PBXGroup; children = ( @@ -122,6 +143,7 @@ 83CBBA001A601CBA00E9B192 /* Products */, 2D16E6871FA4F8E400B85C8A /* Frameworks */, BBD78D7AC51CEA395F1C20DB /* Pods */, + 1B477E83BD2FC603B8A2F283 /* ExpoModulesProviders */, ); indentWidth = 2; sourceTree = ""; @@ -137,6 +159,14 @@ name = Products; sourceTree = ""; }; + 929C35D260F95369D5CD37ED /* rnsdktestTests */ = { + isa = PBXGroup; + children = ( + 7AB96AA764B476307991EC5D /* ExpoModulesProvider.swift */, + ); + name = rnsdktestTests; + sourceTree = ""; + }; BBD78D7AC51CEA395F1C20DB /* Pods */ = { isa = PBXGroup; children = ( @@ -156,6 +186,7 @@ buildConfigurationList = 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "rnsdktestTests" */; buildPhases = ( A55EABD7B0C7F3A422A6CC61 /* [CP] Check Pods Manifest.lock */, + 43B2D184A39438D2BA631670 /* [Expo] Configure project */, 00E356EA1AD99517003FC87E /* Sources */, 00E356EB1AD99517003FC87E /* Frameworks */, 00E356EC1AD99517003FC87E /* Resources */, @@ -178,6 +209,7 @@ buildPhases = ( C38B50BA6285516D6DCD4F65 /* [CP] Check Pods Manifest.lock */, FD10A7F022414F080027D42C /* Start Packager */, + 6A3FB56600F3CEC5B20BA81E /* [Expo] Configure project */, 13B07F871A680F5B00A75B9A /* Sources */, 13B07F8C1A680F5B00A75B9A /* Frameworks */, 13B07F8E1A680F5B00A75B9A /* Resources */, @@ -264,7 +296,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "set -e\n\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"../node_modules/react-native/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT $REACT_NATIVE_XCODE\"\n"; + shellScript = "if [[ -f \"$PODS_ROOT/../.xcode.env\" ]]; then\n source \"$PODS_ROOT/../.xcode.env\"\nfi\nif [[ -f \"$PODS_ROOT/../.xcode.env.local\" ]]; then\n source \"$PODS_ROOT/../.xcode.env.local\"\nfi\n\n# The project root by default is one level up from the ios directory\nexport PROJECT_ROOT=\"$PROJECT_DIR\"/..\n\nif [[ \"$CONFIGURATION\" = *Debug* ]]; then\n export SKIP_BUNDLING=1\nfi\nif [[ -z \"$ENTRY_FILE\" ]]; then\n # Set the entry JS file using the bundler's entry resolution.\n export ENTRY_FILE=\"$(\"$NODE_BINARY\" -e \"require('expo/scripts/resolveAppEntry')\" \"$PROJECT_ROOT\" ios relative | tail -n 1)\"\nfi\n\nif [[ -z \"$CLI_PATH\" ]]; then\n # Use Expo CLI\n export CLI_PATH=\"$(\"$NODE_BINARY\" --print \"require.resolve('@expo/cli')\")\"\nfi\nif [[ -z \"$BUNDLE_COMMAND\" ]]; then\n # Default Expo CLI command for bundling\n export BUNDLE_COMMAND=\"export:embed\"\nfi\n\n`\"$NODE_BINARY\" --print \"require('path').dirname(require.resolve('react-native/package.json')) + '/scripts/react-native-xcode.sh'\"`\n"; }; 00EEFC60759A1932668264C0 /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; @@ -283,6 +315,44 @@ shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-rnsdktest/Pods-rnsdktest-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; + 43B2D184A39438D2BA631670 /* [Expo] Configure project */ = { + isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + name = "[Expo] Configure project"; + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "# This script configures Expo modules and generates the modules provider file.\nbash -l -c \"./Pods/Target\\ Support\\ Files/Pods-rnsdktest-rnsdktestTests/expo-configure-project.sh\"\n"; + }; + 6A3FB56600F3CEC5B20BA81E /* [Expo] Configure project */ = { + isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + name = "[Expo] Configure project"; + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "# This script configures Expo modules and generates the modules provider file.\nbash -l -c \"./Pods/Target\\ Support\\ Files/Pods-rnsdktest/expo-configure-project.sh\"\n"; + }; A55EABD7B0C7F3A422A6CC61 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -394,7 +464,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "export RCT_METRO_PORT=\"${RCT_METRO_PORT:=8081}\"\necho \"export RCT_METRO_PORT=${RCT_METRO_PORT}\" > \"${SRCROOT}/../node_modules/react-native/scripts/.packager.env\"\nif [ -z \"${RCT_NO_LAUNCH_PACKAGER+xxx}\" ] ; then\n if nc -w 5 -z localhost ${RCT_METRO_PORT} ; then\n if ! curl -s \"http://localhost:${RCT_METRO_PORT}/status\" | grep -q \"packager-status:running\" ; then\n echo \"Port ${RCT_METRO_PORT} already in use, packager is either not running or not running correctly\"\n exit 2\n fi\n else\n open \"$SRCROOT/../node_modules/react-native/scripts/launchPackager.command\" || echo \"Can't start packager automatically\"\n fi\nfi\n"; + shellScript = "if [[ -f \"$PODS_ROOT/../.xcode.env\" ]]; then\n source \"$PODS_ROOT/../.xcode.env\"\nfi\nif [[ -f \"$PODS_ROOT/../.xcode.env.local\" ]]; then\n source \"$PODS_ROOT/../.xcode.env.local\"\nfi\n\nexport RCT_METRO_PORT=\"${RCT_METRO_PORT:=8081}\"\necho \"export RCT_METRO_PORT=${RCT_METRO_PORT}\" > `$NODE_BINARY --print \"require('path').dirname(require.resolve('react-native/package.json')) + '/scripts/.packager.env'\"`\nif [ -z \"${RCT_NO_LAUNCH_PACKAGER+xxx}\" ] ; then\n if nc -w 5 -z localhost ${RCT_METRO_PORT} ; then\n if ! curl -s \"http://localhost:${RCT_METRO_PORT}/status\" | grep -q \"packager-status:running\" ; then\n echo \"Port ${RCT_METRO_PORT} already in use, packager is either not running or not running correctly\"\n exit 2\n fi\n else\n open `$NODE_BINARY --print \"require('path').dirname(require.resolve('expo/package.json')) + '/scripts/launchPackager.command'\"` || echo \"Can't start packager automatically\"\n fi\nfi\n"; showEnvVarsInLog = 0; }; /* End PBXShellScriptBuildPhase section */ @@ -405,6 +475,7 @@ buildActionMask = 2147483647; files = ( 00E356F31AD99517003FC87E /* rnsdktestTests.m in Sources */, + D3886B3EDFF56D08CE208F9D /* ExpoModulesProvider.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -414,6 +485,7 @@ files = ( 13B07FBC1A68108700A75B9A /* AppDelegate.mm in Sources */, 13B07FC11A68108700A75B9A /* main.m in Sources */, + FCDF00919D29F4508BA06765 /* ExpoModulesProvider.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -438,7 +510,7 @@ "$(inherited)", ); INFOPLIST_FILE = rnsdktestTests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 12.4; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -449,6 +521,7 @@ "-lc++", "$(inherited)", ); + OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_DEBUG"; PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/rnsdktest.app/rnsdktest"; @@ -462,7 +535,7 @@ BUNDLE_LOADER = "$(TEST_HOST)"; COPY_PHASE_STRIP = NO; INFOPLIST_FILE = rnsdktestTests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 12.4; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -473,6 +546,7 @@ "-lc++", "$(inherited)", ); + OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_RELEASE"; PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/rnsdktest.app/rnsdktest"; @@ -498,7 +572,9 @@ "-ObjC", "-lc++", ); + OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_DEBUG"; PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)"; + "PRODUCT_BUNDLE_IDENTIFIER[sdk=iphoneos*]" = org.reactjs.native.example.rnsdktesttrial; PRODUCT_NAME = rnsdktest; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; @@ -524,7 +600,9 @@ "-ObjC", "-lc++", ); + OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_RELEASE"; PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)"; + "PRODUCT_BUNDLE_IDENTIFIER[sdk=iphoneos*]" = org.reactjs.native.example.rnsdktesttrial; PRODUCT_NAME = rnsdktest; SWIFT_VERSION = 5.0; VERSIONING_SYSTEM = "apple-generic"; @@ -564,7 +642,7 @@ COPY_PHASE_STRIP = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; - "EXCLUDED_ARCHS[sdk=iphonesimulator*]" = ""; + "EXCLUDED_ARCHS[sdk=iphonesimulator*]" = i386; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; @@ -572,6 +650,7 @@ GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", "$(inherited)", + _LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION, ); GCC_SYMBOLS_PRIVATE_EXTERN = NO; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; @@ -580,7 +659,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 12.4; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; LD_RUNPATH_SEARCH_PATHS = ( /usr/lib/swift, "$(inherited)", @@ -592,12 +671,19 @@ ); MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; + OTHER_CFLAGS = "$(inherited)"; OTHER_CPLUSPLUSFLAGS = ( "$(OTHER_CFLAGS)", "-DFOLLY_NO_CONFIG", "-DFOLLY_MOBILE=1", "-DFOLLY_USE_LIBCPP=1", ); + OTHER_LDFLAGS = ( + "$(inherited)", + "-Wl", + "-ld_classic", + ); + REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native"; SDKROOT = iphoneos; }; name = Debug; @@ -635,16 +721,20 @@ COPY_PHASE_STRIP = YES; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; - "EXCLUDED_ARCHS[sdk=iphonesimulator*]" = ""; + "EXCLUDED_ARCHS[sdk=iphonesimulator*]" = i386; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_NO_COMMON_BLOCKS = YES; + GCC_PREPROCESSOR_DEFINITIONS = ( + "$(inherited)", + _LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION, + ); GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 12.4; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; LD_RUNPATH_SEARCH_PATHS = ( /usr/lib/swift, "$(inherited)", @@ -655,12 +745,19 @@ "\"$(inherited)\"", ); MTL_ENABLE_DEBUG_INFO = NO; + OTHER_CFLAGS = "$(inherited)"; OTHER_CPLUSPLUSFLAGS = ( "$(OTHER_CFLAGS)", "-DFOLLY_NO_CONFIG", "-DFOLLY_MOBILE=1", "-DFOLLY_USE_LIBCPP=1", ); + OTHER_LDFLAGS = ( + "$(inherited)", + "-Wl", + "-ld_classic", + ); + REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native"; SDKROOT = iphoneos; VALIDATE_PRODUCT = YES; }; diff --git a/packages/examples/sdk-react-native/ios/rnsdktest.xcworkspace/contents.xcworkspacedata b/packages/examples/sdk-react-native/ios/rnsdktest.xcworkspace/contents.xcworkspacedata new file mode 100644 index 000000000..22397b4b7 --- /dev/null +++ b/packages/examples/sdk-react-native/ios/rnsdktest.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/packages/examples/sdk-react-native/ios/rnsdktest/AppDelegate.h b/packages/examples/sdk-react-native/ios/rnsdktest/AppDelegate.h index 5d2808256..a7ebb518a 100644 --- a/packages/examples/sdk-react-native/ios/rnsdktest/AppDelegate.h +++ b/packages/examples/sdk-react-native/ios/rnsdktest/AppDelegate.h @@ -1,6 +1,7 @@ #import +#import #import -@interface AppDelegate : RCTAppDelegate +@interface AppDelegate : EXAppDelegateWrapper @end diff --git a/packages/examples/sdk-react-native/ios/rnsdktest/AppDelegate.mm b/packages/examples/sdk-react-native/ios/rnsdktest/AppDelegate.mm index 9e4bda8a3..df77f02bb 100644 --- a/packages/examples/sdk-react-native/ios/rnsdktest/AppDelegate.mm +++ b/packages/examples/sdk-react-native/ios/rnsdktest/AppDelegate.mm @@ -17,7 +17,7 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge { #if DEBUG - return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"]; + return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@".expo/.virtual-metro-entry"]; #else return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"]; #endif diff --git a/packages/examples/sdk-react-native/metro.config.js b/packages/examples/sdk-react-native/metro.config.js index ad8f87b6d..cf5fbe850 100644 --- a/packages/examples/sdk-react-native/metro.config.js +++ b/packages/examples/sdk-react-native/metro.config.js @@ -1,11 +1,28 @@ -const {getDefaultConfig, mergeConfig} = require('@react-native/metro-config'); +const path = require('path'); -/** - * Metro configuration - * https://facebook.github.io/metro/docs/configuration - * - * @type {import('metro-config').MetroConfig} - */ -const config = {}; +const reactnativesdkPath = path.resolve(__dirname, '../../reactnative'); +const uireactnativePath = path.resolve(__dirname, '../../uireactnative'); // Path of your local module -module.exports = mergeConfig(getDefaultConfig(__dirname), config); +const thirdPartyPackages = { + '@pushprotocol/uireactnative': uireactnativePath, + '@pushprotocol/react-native-sdk': reactnativesdkPath, +}; + +const {getDefaultConfig} = require('expo/metro-config'); + +const projectRoot = __dirname; + +const config = getDefaultConfig(projectRoot); + +config.resolver.nodeModulesPaths = [path.resolve(projectRoot, 'node_modules')]; +config.resolver.sourceExts = ['jsx', 'js', 'json', 'ts', 'tsx', 'mjs']; +config.resolver.thirdPartyPackages = thirdPartyPackages; +config.transformer.getTransformOptions = async () => ({ + transform: { + experimentalImportSupport: false, + inlineRequires: true, + }, +}); +config.watchFolders = [uireactnativePath, reactnativesdkPath]; + +module.exports = config; diff --git a/packages/examples/sdk-react-native/package.json b/packages/examples/sdk-react-native/package.json index a2612ef08..5412c7e08 100644 --- a/packages/examples/sdk-react-native/package.json +++ b/packages/examples/sdk-react-native/package.json @@ -11,15 +11,25 @@ "postinstall": "node_modules/.bin/rn-nodeify --install crypto,assert,url,stream,events,http,https,os,url,net,fs,zlib --hack && npx patch-package" }, "dependencies": { - "@push/react-native-sdk": "../../reactnative", + "@pushprotocol/react-native-sdk": "../../reactnative", + "@pushprotocol/uireactnative": "../../uireactnative", + "@react-navigation/native": "^6.1.9", + "@react-navigation/native-stack": "^6.9.17", "browserify-zlib": "^0.1.4", "events": "^1.1.1", + "expo": "^49.0.0", + "expo-av": "~13.4.1", + "expo-linear-gradient": "~12.3.0", + "expo-modules-core": "~1.5.12", "react": "18.2.0", "react-native": "0.72.6", "react-native-fast-openpgp": "^2.6.0", "react-native-get-random-values": "^1.9.0", "react-native-randombytes": "3.6.1", - "react-native-webview": "^13.2.2", + "react-native-safe-area-context": "4.6.3", + "react-native-screens": "~3.22.0", + "react-native-svg": "^14.1.0", + "react-native-webview": "13.2.2", "react-native-webview-crypto": "^0.0.25", "readable-stream": "^1.0.33" }, @@ -39,7 +49,8 @@ "patch-package": "^8.0.0", "prettier": "^2.4.1", "react-test-renderer": "18.2.0", - "typescript": "4.8.4" + "rn-nodeify": "^10.3.0", + "typescript": "^5.1.3" }, "engines": { "node": ">=16" diff --git a/packages/examples/sdk-react-native/patches/@kalashshah+restapi+0.1.2.patch b/packages/examples/sdk-react-native/patches/@kalashshah+restapi+0.1.2.patch deleted file mode 100644 index 4de4642f9..000000000 --- a/packages/examples/sdk-react-native/patches/@kalashshah+restapi+0.1.2.patch +++ /dev/null @@ -1,52 +0,0 @@ -diff --git a/node_modules/@kalashshah/restapi/src/lib/chat/helpers/payloadHelper.ts b/node_modules/@kalashshah/restapi/src/lib/chat/helpers/payloadHelper.ts -index b322a8e..e3ed682 100644 ---- a/node_modules/@kalashshah/restapi/src/lib/chat/helpers/payloadHelper.ts -+++ b/node_modules/@kalashshah/restapi/src/lib/chat/helpers/payloadHelper.ts -@@ -377,8 +377,8 @@ export const getAdminsList = ( - ) - : []; - -- const adminList = [...adminsFromMembers, ...adminsFromPendingMembers]; -- return adminList; -+ // const adminList = [...adminsFromMembers, ...adminsFromPendingMembers]; -+ return []; - }; - - export const getSpaceAdminsList = ( -@@ -405,14 +405,15 @@ export const getSpaceAdminsList = ( - ) - : []; - -- const adminList = [...adminsFromMembers, ...adminsFromPendingMembers]; -- return adminList; -+ // const adminList = [...adminsFromMembers, ...adminsFromPendingMembers]; -+ return []; - }; - - export const convertToWalletAddressList = ( - memberList: { wallet: string }[] - ): string[] => { -- return memberList ? memberList.map((member) => member.wallet) : []; -+ // return memberList ? memberList.map((member) => member.wallet) : []; -+ return []; - }; - - export const getMembersList = ( -@@ -430,7 +431,8 @@ export const getMembersList = ( - }[] - ): Array => { - const allMembers = [...(members || []), ...(pendingMembers || [])]; -- return convertToWalletAddressList(allMembers); -+ // return convertToWalletAddressList(allMembers); -+ return []; - }; - - export const getSpacesMembersList = ( -@@ -448,5 +450,6 @@ export const getSpacesMembersList = ( - }[] - ): Array => { - const allMembers = [...(members || []), ...(pendingMembers || [])]; -- return convertToWalletAddressList(allMembers); -+ // return convertToWalletAddressList(allMembers); -+ return []; - }; diff --git a/packages/examples/sdk-react-native/src/App.tsx b/packages/examples/sdk-react-native/src/App.tsx index 86cf72614..8dc5884ed 100644 --- a/packages/examples/sdk-react-native/src/App.tsx +++ b/packages/examples/sdk-react-native/src/App.tsx @@ -1,340 +1,51 @@ import React from 'react'; -import { ethers } from 'ethers'; - import WebViewCrypto from 'react-native-webview-crypto'; -import { ScrollView, StyleSheet, Text } from 'react-native'; -import OpenPGP from 'react-native-fast-openpgp'; - +import {NavigationContainer} from '@react-navigation/native'; +import {createNativeStackNavigator} from '@react-navigation/native-stack'; import { - PGPHelper, - genRandomAddress, - createUser, - ENV, - conversationHash, - latest, - createGroup, - updateGroup, - chats, - PushApi, - get, - profileUpdate, - decryptPGPKey, - profileUpgrade, - send, - Constants, - approve, -} from '@push/react-native-sdk/src'; - -function generatePrivateKey() { - // Define the set of characters for private key generation - var characters = '0123456789abcdef'; + HighLevelFnsScreen, + Index, + LowLevelFnsScreen, + NotificationScreen, +} from './screens'; - // Set the length of the private key (64 characters for 256 bits) - var keyLength = 64; +export type RootStackParamList = { + Index: undefined; + LowLevelFns: undefined; + Notification: undefined; + HighLevelFns: undefined; +}; - // Generate the private key - var privateKey = ''; - for (var i = 0; i < keyLength; i++) { - var randomIndex = Math.floor(Math.random() * characters.length); - privateKey += characters.charAt(randomIndex); - } - - // Return the private key - return privateKey; -} - -function generateRandomString() { - var characters = '0123456789abcdef'; - var keyLength = 40; - var randomString = ''; - for (var i = 0; i < keyLength; i++) { - var randomIndex = Math.floor(Math.random() * characters.length); - randomString += characters.charAt(randomIndex); - } - return randomString; -} +const Stack = createNativeStackNavigator(); export default function App() { - const handlePgp = async () => { - let res = await PGPHelper.generateKeyPair(); - console.log(res); - }; - - const handleEthers = async () => { - let res = await genRandomAddress(); - console.log(res); - }; - - const handleUserCreate = async () => { - const pk = generatePrivateKey(); - - const signer = new ethers.Wallet(pk); - const walletAddress = signer.address; - const account = `eip155:${walletAddress}`; - - const options: PushApi.user.CreateUserProps = { - account: account, - signer: signer, - env: Constants.ENV.DEV, - }; - - console.log('create user', account); - - const res = await createUser(options); - console.log('success', res.did); - }; - - const handleUserMsgs = async () => { - const signer = new ethers.Wallet( - '07da77f7471e5cf046ea3793421cbce90fd42a4cfcf520046a490ca1a9b636e0' - ); - const walletAddress = signer.address; - const account = `eip155:${walletAddress}`; - console.log(signer); - - const res = await PushApi.chat.conversationHash({ - account: account, - conversationId: - 'b353220b812bdb707bd93529aac6fac893438e5db791d7c9e6aab6773aaff90b', - env: ENV.STAGING, - }); - - const res2 = await latest({ - threadhash: res.threadHash, - toDecrypt: true, - account: account, - env: ENV.STAGING, - }); - - const user = await PushApi.user.get({ - account: account, - env: ENV.STAGING, - }); - - const pgpDecryptedPvtKey = await PushApi.chat.decryptPGPKey({ - encryptedPGPPrivateKey: user.encryptedPrivateKey, - signer: signer, - }); - - const chatList = await chats({ - account: account, - pgpPrivateKey: pgpDecryptedPvtKey, - toDecrypt: true, - env: ENV.STAGING, - }); - console.log(user, 'user'); - console.log(pgpDecryptedPvtKey, 'key'); - console.log(chatList, 'Chatlist'); - }; - - const handleCreateGroup = async () => { - const pk = generatePrivateKey(); - const signer = new ethers.Wallet(pk); - const walletAddress = signer.address; - const account = `eip155:${walletAddress}`; - console.log(signer); - - const groupName = generateRandomString(); - - const res = await createGroup({ - groupName: groupName, - groupDescription: 'satyamstesing', - groupImage: 'https://github.com', - account: account, - signer: signer, - members: [ - '0x83d4c16b15F7BBA501Ca1057364a1F502d1c34D5', - '0x6Ff7DF70cAACAd6B35d2d30eca6bbb4E86fEE62f', - ], - admins: [], - isPublic: true, - env: ENV.DEV, - }); - console.log(res, 'res'); - - return { - chatId: res.chatId, - groupName, - signer, - }; - }; - - const handleUpdateGroup = async () => { - const { signer, chatId, groupName } = await handleCreateGroup(); - const walletAddress = signer.address; - const account = `eip155:${walletAddress}`; - - const res = await updateGroup({ - groupName, - groupDescription: 'satyamstesing', - groupImage: 'https://github.com', - chatId, - account: account, - signer: signer, - admins: ['0x83d4c16b15F7BBA501Ca1057364a1F502d1c34D5'], - members: [ - '0x6Ff7DF70cAACAd6B35d2d30eca6bbb4E86fEE62f', - '0x6d118b28ebd82635A30b142D11B9eEEa2c0bea26', - '0x83d4c16b15F7BBA501Ca1057364a1F502d1c34D5', - ], - env: ENV.DEV, - }); - console.log(res, 'ress'); - }; - - const handleGetUser = async () => { - const options: PushApi.AccountEnvOptionsType = { - account: '0xACEe0D180d0118FD4F3027Ab801cc862520570d1', - env: Constants.ENV.DEV, - }; - - const res = await get(options); - console.log('successfully got user', res); - }; - - const handleProfileUpdate = async () => { - console.log('updating profile...'); - const pk = generatePrivateKey(); - - const signer = new ethers.Wallet(pk); - const walletAddress = signer.address; - const account = `eip155:${walletAddress}`; - - console.log('creating user...'); - const user = await createUser({ - account: account, - signer: signer, - env: Constants.ENV.DEV, - }); - - console.log('decrypting pgp key...'); - const pgpPK = await decryptPGPKey({ - account: user.did, - encryptedPGPPrivateKey: user.encryptedPrivateKey, - env: Constants.ENV.DEV, - signer: signer, - }); - - console.log('updating profile...'); - await profileUpdate({ - account: account, - env: Constants.ENV.DEV, - pgpPrivateKey: pgpPK, - profile: { - name: 'Updated Name', - desc: 'Updated Desc', - }, - }); - console.log('successfully updated profile'); - }; - - const handleProfileUpgrade = async () => { - console.log('upgrading profile...'); - const pk = generatePrivateKey(); - const signer = new ethers.Wallet(pk); - const walletAddress = signer.address; - const account = `eip155:${walletAddress}`; - - const user = await createUser({ - account: account, - signer: signer, - env: Constants.ENV.DEV, - }); - - const pgpPK = await decryptPGPKey({ - account: user.did, - encryptedPGPPrivateKey: user.encryptedPrivateKey, - env: Constants.ENV.DEV, - signer: signer, - }); - - const pgpPubKey = await OpenPGP.convertPrivateKeyToPublicKey(pgpPK); - - const upgradedProfile = await profileUpgrade({ - signer: signer, - pgpPrivateKey: pgpPK, - pgpPublicKey: pgpPubKey, - pgpEncryptionVersion: Constants.ENCRYPTION_TYPE.NFTPGP_V1, - account: account, - env: Constants.ENV.DEV, - additionalMeta: { - NFTPGP_V1: { - password: '0x@1jdw89Amcedk', //new nft profile password - }, - }, - }); - - console.log('successfully upgraded profile'); - return upgradedProfile; - }; - - const handleInbox = async () => { - // - }; - - const handleSend = async () => { - console.log('sent message!'); - }; - - const handleApproveRequest = async () => { - console.log('successfully approved request!'); - }; - return ( - + <> - - Inbox - - - New User - - - Generate PGP Pair - - - Log Address - - - Create Group - - - update group - - - ConversationHash - - - Get user - - - Update Profile - - - Upgrade Profile - - - Send Message - - - Approve Request - - + + + + + + + + + ); } - -const styles = StyleSheet.create({ - container: { - flex: 1, - }, - box: { - width: 60, - height: 60, - marginVertical: 20, - }, - button: { - padding: 10, - fontSize: 32, - margin: 10, - }, -}); diff --git a/packages/examples/sdk-react-native/src/components/CustomButton.tsx b/packages/examples/sdk-react-native/src/components/CustomButton.tsx new file mode 100644 index 000000000..47e35166c --- /dev/null +++ b/packages/examples/sdk-react-native/src/components/CustomButton.tsx @@ -0,0 +1,31 @@ +import React from 'react'; +import {StyleSheet, Text, TouchableOpacity} from 'react-native'; + +interface CustomButtonProps { + title: string; + onPress: () => void; +} + +export const CustomButton = ({title, onPress}: CustomButtonProps) => { + return ( + + {title} + + ); +}; + +const styles = StyleSheet.create({ + button: { + padding: 10, + fontSize: 32, + margin: 10, + backgroundColor: '#D53A94', + borderRadius: 10, + width: '50%', + }, + text: { + fontSize: 14, + color: '#fff', + textAlign: 'center', + }, +}); diff --git a/packages/examples/sdk-react-native/src/components/index.ts b/packages/examples/sdk-react-native/src/components/index.ts new file mode 100644 index 000000000..d255a80eb --- /dev/null +++ b/packages/examples/sdk-react-native/src/components/index.ts @@ -0,0 +1 @@ +export * from './CustomButton'; diff --git a/packages/examples/sdk-react-native/src/helpers/LowLevelFnsHelper.ts b/packages/examples/sdk-react-native/src/helpers/LowLevelFnsHelper.ts new file mode 100644 index 000000000..07a3ea477 --- /dev/null +++ b/packages/examples/sdk-react-native/src/helpers/LowLevelFnsHelper.ts @@ -0,0 +1,331 @@ +import * as PushAPI from '@pushprotocol/react-native-sdk'; +import {ethers} from 'ethers'; + +export const generatePrivateKey = () => { + // Define the set of characters for private key generation + var characters = '0123456789abcdef'; + + // Set the length of the private key (64 characters for 256 bits) + var keyLength = 64; + + // Generate the private key + var privateKey = ''; + for (var i = 0; i < keyLength; i++) { + var randomIndex = Math.floor(Math.random() * characters.length); + privateKey += characters.charAt(randomIndex); + } + + // Return the private key + return privateKey; +}; + +export const generateRandomString = (keyLen = 40) => { + var characters = '0123456789abcdef'; + var keyLength = keyLen; + var randomString = ''; + for (var i = 0; i < keyLength; i++) { + var randomIndex = Math.floor(Math.random() * characters.length); + randomString += characters.charAt(randomIndex); + } + return randomString; +}; + +export const handleUserCreate = async () => { + const pk = generatePrivateKey(); + + const signer = new ethers.Wallet(pk); + const walletAddress = signer.address; + const account = `eip155:${walletAddress}`; + + const options: PushAPI.user.CreateUserProps = { + account: account, + signer: signer, + env: PushAPI.CONSTANTS.ENV.DEV, + }; + + console.log('creating user with account: ', account, '...'); + + const res = await PushAPI.user.create(options); + console.log('✅ successfully created user: ', res.did); +}; + +export const handleLatestMsg = async () => { + const signer = new ethers.Wallet( + '07da77f7471e5cf046ea3793421cbce90fd42a4cfcf520046a490ca1a9b636e0', + ); + const walletAddress = signer.address; + const account = `eip155:${walletAddress}`; + console.log(signer); + + const res = await PushAPI.chat.conversationHash({ + account: account, + conversationId: + 'b353220b812bdb707bd93529aac6fac893438e5db791d7c9e6aab6773aaff90b', + env: PushAPI.CONSTANTS.ENV.STAGING, + }); + + const user = await PushAPI.user.get({ + account, + env: PushAPI.CONSTANTS.ENV.STAGING, + }); + + const pgpDecryptedPvtKey = await PushAPI.chat.decryptPGPKey({ + encryptedPGPPrivateKey: user.encryptedPrivateKey, + signer: signer, + env: PushAPI.CONSTANTS.ENV.STAGING, + }); + + const msg = await PushAPI.chat.latest({ + threadhash: res.threadHash, + toDecrypt: true, + account: account, + env: PushAPI.CONSTANTS.ENV.STAGING, + pgpPrivateKey: pgpDecryptedPvtKey, + }); + + console.log('✅ Got Latest message: ', msg); +}; + +export const handleCreateGroup = async () => { + const pk = generatePrivateKey(); + const signer = new ethers.Wallet(pk); + const walletAddress = signer.address; + const account = `eip155:${walletAddress}`; + console.log(signer); + + const groupName = generateRandomString(); + + const res = await PushAPI.chat.createGroup({ + groupName: groupName, + groupDescription: 'satyamstesing', + groupImage: 'https://github.com', + account: account, + signer: signer, + members: [ + '0x83d4c16b15F7BBA501Ca1057364a1F502d1c34D5', + '0x6Ff7DF70cAACAd6B35d2d30eca6bbb4E86fEE62f', + ], + admins: [], + isPublic: true, + env: PushAPI.CONSTANTS.ENV.DEV, + }); + console.log('✅ successfully created group: ', res); + + return { + chatId: res.chatId, + groupName, + signer, + }; +}; + +export const handleUpdateGroup = async () => { + const {signer, chatId, groupName} = await handleCreateGroup(); + const walletAddress = signer.address; + const account = `eip155:${walletAddress}`; + + const res = await PushAPI.chat.updateGroup({ + groupName, + groupDescription: 'satyamstesing', + groupImage: 'https://github.com', + chatId, + account: account, + signer: signer, + admins: ['0x83d4c16b15F7BBA501Ca1057364a1F502d1c34D5'], + members: [ + '0x6Ff7DF70cAACAd6B35d2d30eca6bbb4E86fEE62f', + '0x6d118b28ebd82635A30b142D11B9eEEa2c0bea26', + '0x83d4c16b15F7BBA501Ca1057364a1F502d1c34D5', + ], + env: PushAPI.CONSTANTS.ENV.DEV, + }); + console.log('✅ successfully updated group: ', res); +}; + +export const handleGetUser = async () => { + const options: PushAPI.AccountEnvOptionsType = { + account: '0xACEe0D180d0118FD4F3027Ab801cc862520570d1', + env: PushAPI.CONSTANTS.ENV.DEV, + }; + + const res = await PushAPI.user.get(options); + console.log('✅ successfully got user', res); +}; + +export const handleProfileUpdate = async () => { + console.log('updating profile...'); + const pk = generatePrivateKey(); + + const signer = new ethers.Wallet(pk); + const walletAddress = signer.address; + const account = `eip155:${walletAddress}`; + + console.log('creating user...'); + const user = await PushAPI.user.create({ + account: account, + signer: signer, + env: PushAPI.CONSTANTS.ENV.DEV, + }); + + console.log('decrypting pgp key...'); + const pgpPK = await PushAPI.chat.decryptPGPKey({ + account: user.did, + encryptedPGPPrivateKey: user.encryptedPrivateKey, + env: PushAPI.CONSTANTS.ENV.DEV, + signer: signer, + }); + + console.log('updating profile...'); + await PushAPI.user.profile.update({ + account: account, + env: PushAPI.CONSTANTS.ENV.DEV, + pgpPrivateKey: pgpPK, + profile: { + name: 'Updated Name', + desc: 'Updated Desc', + }, + }); + console.log('✅ successfully updated profile'); +}; + +export const handleProfileUpgrade = async () => { + console.log('upgrading profile...'); + const pk = generatePrivateKey(); + const signer = new ethers.Wallet(pk); + const walletAddress = signer.address; + const account = `eip155:${walletAddress}`; + + await PushAPI.user.create({ + account, + env: PushAPI.CONSTANTS.ENV.DEV, + signer, + }); + + const upgradedProfile = await PushAPI.user.upgrade({ + signer: signer, + account: account, + env: PushAPI.CONSTANTS.ENV.DEV, + additionalMeta: { + NFTPGP_V1: { + password: '0x@1jdw89Amcedk', //new nft profile password + }, + }, + }); + + console.log('✅ successfully upgraded profile', upgradedProfile); + return upgradedProfile; +}; + +export const handleInbox = async () => { + const signer = new ethers.Wallet( + '07da77f7471e5cf046ea3793421cbce90fd42a4cfcf520046a490ca1a9b636e0', + ); + const walletAddress = signer.address; + const account = `eip155:${walletAddress}`; + + const user = await PushAPI.user.get({ + account: account, + env: PushAPI.CONSTANTS.ENV.DEV, + }); + + const pgpDecryptedPvtKey = await PushAPI.chat.decryptPGPKey({ + encryptedPGPPrivateKey: user.encryptedPrivateKey, + signer: signer, + }); + + const chatList = await PushAPI.chat.chats({ + account: account, + pgpPrivateKey: pgpDecryptedPvtKey, + toDecrypt: true, + env: PushAPI.CONSTANTS.ENV.DEV, + }); + + const requestList = await PushAPI.chat.requests({ + account: account, + pgpPrivateKey: pgpDecryptedPvtKey, + toDecrypt: true, + env: PushAPI.CONSTANTS.ENV.DEV, + }); + + console.log('✅ Got chats: ', chatList); + console.log('-'.repeat(30)); + console.log('✅ Got requests: ', requestList); +}; + +export const handleSend = async () => { + const signer = new ethers.Wallet( + '07da77f7471e5cf046ea3793421cbce90fd42a4cfcf520046a490ca1a9b636e0', + ); + const account = `eip155:${signer.address}`; + + const user = await PushAPI.user.get({ + account, + env: PushAPI.CONSTANTS.ENV.DEV, + }); + + const pgpDecryptedPvtKey = await PushAPI.chat.decryptPGPKey({ + encryptedPGPPrivateKey: user.encryptedPrivateKey, + signer: signer, + env: PushAPI.CONSTANTS.ENV.DEV, + }); + + const MESSAGE_TYPE = PushAPI.CONSTANTS.CHAT.MESSAGE_TYPE.MEDIA_EMBED; + const MESSAGE = + 'ttps://media1.giphy.com/media/FtlUfrq3pVZXVNjoxf/giphy360p.mp4?cid=ecf05e47jk317254v9hbdjrknemduocie4pf54wtsir98xsx&ep=v1_videos_search&rid=giphy360p.mp4&ct=v'; + + const messageSent = await PushAPI.chat.send({ + account, + env: PushAPI.CONSTANTS.ENV.DEV, + messageContent: MESSAGE, + messageType: MESSAGE_TYPE, + to: '0xACEe0D180d0118FD4F3027Ab801cc862520570d1', + pgpPrivateKey: pgpDecryptedPvtKey, + }); + + console.log('✅ successfully sent message: ', messageSent); +}; + +export const handleApproveRequest = async () => { + const signer = new ethers.Wallet( + '07da77f7471e5cf046ea3793421cbce90fd42a4cfcf520046a490ca1a9b636e0', + ); + const walletAddress = signer.address; + const account = `eip155:${walletAddress}`; + + const user = await PushAPI.user.get({ + account, + env: PushAPI.CONSTANTS.ENV.DEV, + }); + + const pgpDecryptedPvtKey = await PushAPI.chat.decryptPGPKey({ + encryptedPGPPrivateKey: user.encryptedPrivateKey, + signer: signer, + env: PushAPI.CONSTANTS.ENV.DEV, + }); + + const senderAddress = '0xACEe0D180d0118FD4F3027Ab801cc862520570d1'; + + const res = await PushAPI.chat.approve({ + senderAddress, + account: account, + env: PushAPI.CONSTANTS.ENV.DEV, + pgpPrivateKey: pgpDecryptedPvtKey, + status: 'Approved', + }); + + console.log('✅ successfully approved request: ', res); +}; + +export const handleConversationHash = async () => { + const signer = new ethers.Wallet( + '07da77f7471e5cf046ea3793421cbce90fd42a4cfcf520046a490ca1a9b636e0', + ); + const account = `eip155:${signer.address}`; + + const hash = await PushAPI.chat.conversationHash({ + account, + conversationId: + 'b353220b812bdb707bd93529aac6fac893438e5db791d7c9e6aab6773aaff90b', + env: PushAPI.CONSTANTS.ENV.STAGING, + }); + console.log('✅ successfully got conversation hash: ', hash); +}; diff --git a/packages/examples/sdk-react-native/src/helpers/index.ts b/packages/examples/sdk-react-native/src/helpers/index.ts new file mode 100644 index 000000000..0e78913c8 --- /dev/null +++ b/packages/examples/sdk-react-native/src/helpers/index.ts @@ -0,0 +1 @@ +export * from './LowLevelFnsHelper'; diff --git a/packages/examples/sdk-react-native/src/screens/HighLevelFnsScreen.tsx b/packages/examples/sdk-react-native/src/screens/HighLevelFnsScreen.tsx new file mode 100644 index 000000000..732e546a4 --- /dev/null +++ b/packages/examples/sdk-react-native/src/screens/HighLevelFnsScreen.tsx @@ -0,0 +1,56 @@ +import {PushAPI, CONSTANTS} from '@pushprotocol/react-native-sdk'; +import {FlatList, View} from 'react-native'; +import React, {useEffect, useState} from 'react'; +import {ethers} from 'ethers'; +import {NotificationItem} from '@pushprotocol/uireactnative'; + +export const HighLevelFnsScreen = () => { + const [notifications, setNotifications] = useState(); + + useEffect(() => { + (async () => { + const signer = new ethers.Wallet( + '07da77f7471e5cf046ea3793421cbce90fd42a4cfcf520046a490ca1a9b636e0', + ); + const account = `eip155:${signer.address}`; + + const alice = await PushAPI.initialize(signer, { + account, + env: CONSTANTS.ENV.DEV, + }); + + const spam = await alice.notification.list('SPAM', { + limit: 10, + page: 1, + }); + setNotifications(spam); + })(); + }, []); + + return ( + + ( + + )} + keyExtractor={item => item.sid} + /> + + ); +}; diff --git a/packages/examples/sdk-react-native/src/screens/IndexScreen.tsx b/packages/examples/sdk-react-native/src/screens/IndexScreen.tsx new file mode 100644 index 000000000..b43f512ad --- /dev/null +++ b/packages/examples/sdk-react-native/src/screens/IndexScreen.tsx @@ -0,0 +1,47 @@ +import {ScrollView, StyleSheet} from 'react-native'; +import React from 'react'; +import {NativeStackScreenProps} from '@react-navigation/native-stack'; +import {RootStackParamList} from '../App'; +import {CustomButton} from '../components'; + +type IndexScreenProps = NativeStackScreenProps; + +export const Index = ({navigation}: IndexScreenProps) => { + const navigateToLowLvlFnsScreen = () => { + navigation.navigate('LowLevelFns'); + }; + const navigateToHighLvlFnsScreen = () => { + navigation.navigate('HighLevelFns'); + }; + const navigateToNotificationScreen = () => { + navigation.navigate('Notification'); + }; + + return ( + + + + + + ); +}; + +const styles = StyleSheet.create({ + container: { + flex: 1, + }, + button: { + padding: 10, + fontSize: 32, + margin: 10, + }, +}); diff --git a/packages/examples/sdk-react-native/src/screens/LowLevelFnsScreen.tsx b/packages/examples/sdk-react-native/src/screens/LowLevelFnsScreen.tsx new file mode 100644 index 000000000..52f64f9a0 --- /dev/null +++ b/packages/examples/sdk-react-native/src/screens/LowLevelFnsScreen.tsx @@ -0,0 +1,40 @@ +import React from 'react'; +import {StyleSheet, ScrollView} from 'react-native'; +import {CustomButton} from '../components'; +import { + handleApproveRequest, + handleConversationHash, + handleCreateGroup, + handleGetUser, + handleInbox, + handleLatestMsg, + handleProfileUpdate, + handleProfileUpgrade, + handleSend, + handleUpdateGroup, + handleUserCreate, +} from '../helpers'; + +export const LowLevelFnsScreen = () => { + return ( + + + + + + + + + + + + + + ); +}; + +const styles = StyleSheet.create({ + container: { + flex: 1, + }, +}); diff --git a/packages/examples/sdk-react-native/src/screens/NotificationScreen.tsx b/packages/examples/sdk-react-native/src/screens/NotificationScreen.tsx new file mode 100644 index 000000000..c8fdd5533 --- /dev/null +++ b/packages/examples/sdk-react-native/src/screens/NotificationScreen.tsx @@ -0,0 +1,97 @@ +import {FlatList, ScrollView, StyleSheet, View} from 'react-native'; +import React from 'react'; +import { + NotificationItem, + NotificationItemProps, +} from '@pushprotocol/uireactnative'; + +export const NotificationScreen = () => { + const notificationItems: NotificationItemProps[] = [ + { + notificationTitle: 'Notification with styled content', + notificationBody: + "[Hello World](https://github1.com) ***Bold&Italic*** \n **Bold** \n *Italic* \n green text \n [PUSH website](https://push.org) \n [timestamp: 1699347011]", + app: 'Push', + icon: 'https://picsum.photos/200', + image: undefined, + url: 'https://push.org/', + theme: 'light', + chainName: 'POLYGON_TEST_MUMBAI', + cta: 'https://github.com/ethereum-push-notification-service/', + }, + { + notificationTitle: 'Notification with image', + notificationBody: + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit', + app: 'Push', + icon: 'https://picsum.photos/200', + image: 'https://picsum.photos/200', + url: undefined, + theme: 'dark', + chainName: 'ETH_TEST_SEPOLIA', + cta: undefined, + }, + { + notificationTitle: 'Notification with video', + notificationBody: + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit', + app: 'Push', + icon: 'https://picsum.photos/200', + image: + 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/Sintel.mp4', + url: undefined, + theme: 'dark', + chainName: 'BSC_TESTNET', + cta: undefined, + }, + { + notificationTitle: 'Notification with youtube video', + notificationBody: + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit', + app: 'Push', + icon: 'https://picsum.photos/200', + image: 'https://www.youtube.com/watch?v=R8nsAhyrvTI', + url: undefined, + theme: 'light', + chainName: 'ARBITRUM_TESTNET', + cta: undefined, + }, + ]; + + return ( + + index.toString()} + renderItem={({item}) => ( + + + + )} + /> + + ); +}; + +const styles = StyleSheet.create({ + container: { + flex: 1, + }, + nfItemContainer: { + margin: 10, + }, +}); diff --git a/packages/examples/sdk-react-native/src/screens/index.ts b/packages/examples/sdk-react-native/src/screens/index.ts new file mode 100644 index 000000000..60070a699 --- /dev/null +++ b/packages/examples/sdk-react-native/src/screens/index.ts @@ -0,0 +1,4 @@ +export * from './IndexScreen'; +export * from './LowLevelFnsScreen'; +export * from './NotificationScreen'; +export * from './HighLevelFnsScreen'; diff --git a/packages/examples/sdk-react-native/tsconfig.json b/packages/examples/sdk-react-native/tsconfig.json index 45a6c7072..dba4910d2 100644 --- a/packages/examples/sdk-react-native/tsconfig.json +++ b/packages/examples/sdk-react-native/tsconfig.json @@ -1,3 +1,9 @@ { - "extends": "@tsconfig/react-native/tsconfig.json" + "extends": "@tsconfig/react-native/tsconfig.json", + "compilerOptions": { + "paths": { + "react": ["./node_modules/react"], + "react-native": ["./node_modules/react-native"], + } + } } diff --git a/packages/reactnative/README.md b/packages/reactnative/README.md index e01511f45..2c6644462 100644 --- a/packages/reactnative/README.md +++ b/packages/reactnative/README.md @@ -35,7 +35,7 @@ src="https://res.cloudinary.com/drdjegqln/image/upload/v1686227558/Push-Logo-Sta - [Install the SDK](#install-the-sdk) - [Install the peer dependencies](#install-the-peer-dependencies) - [Nodeify the crypto packages](#nodeify-the-crypto-packages) - - [Wrap your app with the PushRNWrapper](#wrap-your-app-with-the-pushrnwrapper) + - [Add the WebViewCrypto component in your app root](#add-the-webviewcrypto-component-in-your-app-root) - [Start using the Push SDK in your app](#start-using-the-push-sdk-in-your-app) - [React Native SDK Features](#react-native-sdk-features) @@ -79,13 +79,13 @@ without having to write a lot of boilerplate code. All the heavy lifting is done #### Install the SDK ```bash -yarn add @push/react-native-sdk +yarn add @pushprotocol/react-native-sdk ``` or ```bash -npm install @push/react-native-sdk +npm install @pushprotocol/react-native-sdk ``` #### Install the peer dependencies @@ -108,22 +108,23 @@ Add postinstall script in your `package.json` file if `node_modules` are not nod "postinstall": "node_modules/.bin/rn-nodeify --install crypto,assert,url,stream,events,http,https,os,url,net,fs --hack" ``` -#### Wrap your app with the PushRNWrapper +#### Add the WebViewCrypto component in your app root ```jsx -import { PushRNWrapper } from '@push/react-native-sdk'; +import WebViewCrypto from 'react-native-webview-crypto'; return ( - + <> + - + ); ``` #### Start using the Push SDK in your app ```jsx -import { createUser, Constants } from '@push/react-native-sdk'; +import { createUser, Constants } from '@pushprotocol/react-native-sdk'; const user = await createUser({ account: account, @@ -139,7 +140,7 @@ const user = await createUser({ #### Create User ```jsx -import { createUser, Constants } from '@push/react-native-sdk'; +import { createUser, Constants } from '@pushprotocol/react-native-sdk'; const user = await createUser({ account: 'eip155:0xACEe0D180d0118FD4F3027Ab801cc862520570d1', @@ -151,7 +152,7 @@ const user = await createUser({ #### Get User ```jsx -import { get, Constants } from '@push/react-native-sdk'; +import { get, Constants } from '@pushprotocol/react-native-sdk'; const user = await get({ account: 'eip155:0xACEe0D180d0118FD4F3027Ab801cc862520570d1', @@ -162,7 +163,7 @@ const user = await get({ #### Profile Update ```jsx -import { profileUpdate, Constants } from '@push/react-native-sdk'; +import { profileUpdate, Constants } from '@pushprotocol/react-native-sdk'; await profileUpdate({ account: 'eip155:0xACEe0D180d0118FD4F3027Ab801cc862520570d1', @@ -178,7 +179,7 @@ await profileUpdate({ #### Profile Upgrade ```jsx -import { profileUpgrade, Constants } from '@push/react-native-sdk'; +import { profileUpgrade, Constants } from '@pushprotocol/react-native-sdk'; const upgradedProfile = await profileUpgrade({ signer: signer, @@ -200,7 +201,7 @@ const upgradedProfile = await profileUpgrade({ #### Decrypt PGP key ```jsx -import { PushApi } from '@push/react-native-sdk'; +import { PushApi } from '@pushprotocol/react-native-sdk'; const user = await get({ account: 'eip155:0xACEe0D180d0118FD4F3027Ab801cc862520570d1', @@ -216,7 +217,7 @@ const pgpDecryptedPvtKey = await PushApi.chat.decryptPGPKey({ #### Chats ```jsx -import { chats, Constants } from '@push/react-native-sdk'; +import { chats, Constants } from '@pushprotocol/react-native-sdk'; const chatList = await chats({ account: 'eip155:0xACEe0D180d0118FD4F3027Ab801cc862520570d1', @@ -229,7 +230,7 @@ const chatList = await chats({ #### Conversation Hash ```jsx -import { PushApi, Constants } from '@push/react-native-sdk'; +import { PushApi, Constants } from '@pushprotocol/react-native-sdk'; const hash = await PushApi.chat.conversationHash({ account: 'eip155:0xACEe0D180d0118FD4F3027Ab801cc862520570d1', @@ -241,7 +242,7 @@ const hash = await PushApi.chat.conversationHash({ #### Latest Chat message ```jsx -import { latest, Constants } from '@push/react-native-sdk'; +import { latest, Constants } from '@pushprotocol/react-native-sdk'; const msg = await latest({ threadhash: hash, @@ -254,7 +255,7 @@ const msg = await latest({ #### Create Group ```jsx -import { createGroup, Constants } from '@push/react-native-sdk'; +import { createGroup, Constants } from '@pushprotocol/react-native-sdk'; const res = await createGroup({ groupName: groupName, @@ -275,7 +276,7 @@ const res = await createGroup({ #### Update Group ```jsx -import { updateGroup, Constants } from '@push/react-native-sdk'; +import { updateGroup, Constants } from '@pushprotocol/react-native-sdk'; const res = await updateGroup({ groupName, @@ -298,10 +299,10 @@ const res = await updateGroup({ All the remaining features of the `restapi` SDK are available in a similar manner to the `restapi` package. You can read more about them HERE -These functions can be accessed by simply importing the `PushApi` object from the `@push/react-native-sdk` package. +These functions can be accessed by simply importing the `PushApi` object from the `@pushprotocol/react-native-sdk` package. ```jsx -import { PushApi } from '@push/react-native-sdk'; +import { PushApi } from '@pushprotocol/react-native-sdk'; const response = await PushApi.chat.getGroupByName({ groupName: 'Push Group Chat 3', diff --git a/packages/reactnative/package.json b/packages/reactnative/package.json index 64a44772c..d919016d6 100644 --- a/packages/reactnative/package.json +++ b/packages/reactnative/package.json @@ -1,12 +1,11 @@ { - "name": "@push/react-native-sdk", + "name": "@pushprotocol/react-native-sdk", "version": "0.1.0", "description": "test", "main": "lib/commonjs/index", "module": "lib/module/index", "types": "lib/typescript/index.d.ts", "react-native": { - "lib/commonjs/index": "src/index", "crypto": "react-native-crypto", "net": "react-native-tcp", "http": "@tradle/react-native-http", @@ -20,13 +19,13 @@ "_stream_passthrough": "readable-stream/passthrough", "stream": "stream-browserify" }, - "source": "src/index", "files": [ - "src", "lib", + "patches", "android", "ios", "cpp", + "shim.js", "*.podspec", "!lib/typescript/example", "!ios/build", @@ -44,10 +43,9 @@ "test": "jest", "typecheck": "tsc --noEmit", "lint": "eslint \"**/*.{js,ts,tsx}\"", - "prepack": "bob build", + "prepare": "bob build", "release": "release-it", - "example": "yarn --cwd example", - "bootstrap": "yarn example && yarn install", + "bootstrap": "yarn install", "clean": "del-cli android/build example/android/build example/android/app/build example/ios/build", "postinstall": "node_modules/.bin/rn-nodeify --install crypto,assert,url,stream,events,http,https,os,url,net,fs --hack && npx patch-package" }, @@ -67,7 +65,7 @@ "registry": "https://registry.npmjs.org/" }, "dependencies": { - "@kalashshah/restapi": "0.1.2", + "@pushprotocol/restapi": "1.6.3", "@tradle/react-native-http": "^2.0.1", "assert": "^1.5.0", "axios": "^0.27.2", @@ -84,7 +82,7 @@ "react-native-os": "^1.2.6", "react-native-randombytes": "^3.6.1", "react-native-tcp": "^3.3.2", - "react-native-webview": "^13.2.2", + "react-native-webview": "13.2.2", "react-native-webview-crypto": "^0.0.25", "readable-stream": "^1.0.33", "rn-nodeify": "^10.3.0", @@ -92,8 +90,7 @@ "stream-browserify": "^1.0.0", "text-encoding": "0.7.0", "url": "^0.10.3", - "uuid": "^9.0.0", - "viem": "^1.3.0" + "uuid": "^9.0.0" }, "devDependencies": { "@commitlint/config-conventional": "^17.0.2", @@ -101,8 +98,8 @@ "@react-native-community/eslint-config": "^3.0.2", "@release-it/conventional-changelog": "^5.0.0", "@types/jest": "^28.1.2", - "@types/react": "~17.0.21", - "@types/react-native": "0.70.0", + "@types/react": "~18.2.25", + "@types/react-native": "0.72.6", "commitlint": "^17.0.2", "del-cli": "^5.0.0", "eslint": "^8.4.1", @@ -113,14 +110,12 @@ "pod-install": "^0.1.0", "postinstall-postinstall": "^2.1.0", "prettier": "^2.0.5", - "react": "18.2.0", - "react-native": "0.71.11", "react-native-builder-bob": "^0.20.4", "release-it": "^15.0.0", - "typescript": "^4.5.2" + "typescript": "^5.1.3" }, "resolutions": { - "@types/react": "17.0.21" + "@types/react": "18.2.25" }, "peerDependencies": { "react": "*", @@ -205,7 +200,6 @@ ] }, "browser": { - "lib/commonjs/index": "src/index", "crypto": "react-native-crypto", "net": "react-native-tcp", "http": "@tradle/react-native-http", diff --git a/packages/reactnative/patches/@pushprotocol+restapi+1.6.3.patch b/packages/reactnative/patches/@pushprotocol+restapi+1.6.3.patch new file mode 100644 index 000000000..c703c5990 --- /dev/null +++ b/packages/reactnative/patches/@pushprotocol+restapi+1.6.3.patch @@ -0,0 +1,156 @@ +diff --git a/node_modules/@pushprotocol/restapi/src/lib/chat/helpers/pgp.js b/node_modules/@pushprotocol/restapi/src/lib/chat/helpers/pgp.js +index 161c76b..beca4e6 100644 +--- a/node_modules/@pushprotocol/restapi/src/lib/chat/helpers/pgp.js ++++ b/node_modules/@pushprotocol/restapi/src/lib/chat/helpers/pgp.js +@@ -2,135 +2,45 @@ + Object.defineProperty(exports, "__esModule", { value: true }); + exports.pgpDecrypt = exports.verifySignature = exports.sign = exports.pgpEncrypt = exports.generateKeyPair = exports.PGPHelper = void 0; + const tslib_1 = require("tslib"); +-const openpgp = require("openpgp"); ++const openpgp = require("react-native-fast-openpgp"); + const PGPHelper = { + generateKeyPair() { + return tslib_1.__awaiter(this, void 0, void 0, function* () { +- const keys = yield openpgp.generateKey({ +- type: 'rsa', +- rsaBits: 2048, +- userIDs: [{ name: '', email: '' }] +- }); ++ const keys = yield openpgp.default.generate({keyOptions: {rsaBits: 2048}}); + return { + privateKeyArmored: keys.privateKey, +- publicKeyArmored: keys.publicKey ++ publicKeyArmored: keys.publicKey, + }; + }); + }, + sign({ message, signingKey }) { + return tslib_1.__awaiter(this, void 0, void 0, function* () { +- const messageObject = yield openpgp.createMessage({ text: message }); +- const privateKey = yield openpgp.readPrivateKey({ armoredKey: signingKey }); +- return yield openpgp.sign({ message: messageObject, signingKeys: privateKey, detached: true }); ++ const signature = yield openpgp.default.sign(message, signingKey, ''); ++ return signature.replace('\nVersion: openpgp-mobile', ''); + }); + }, + pgpEncrypt({ plainText, keys }) { + return tslib_1.__awaiter(this, void 0, void 0, function* () { +- const pgpKeys = []; +- for (let i = 0; i < keys.length; i++) { +- pgpKeys.push(yield openpgp.readKey({ armoredKey: keys[i] })); +- } +- const message = yield openpgp.createMessage({ text: plainText }); +- const encrypted = yield openpgp.encrypt({ +- message: message, +- encryptionKeys: pgpKeys, +- }); +- return encrypted; ++ return yield openpgp.default.encrypt(plainText, keys.join('\n')); + }); + }, + pgpDecrypt({ cipherText, toPrivateKeyArmored }) { + return tslib_1.__awaiter(this, void 0, void 0, function* () { +- const message = yield openpgp.readMessage({ armoredMessage: cipherText }); +- const privateKey = yield openpgp.readPrivateKey({ armoredKey: toPrivateKeyArmored }); +- const { data: decrypted } = yield openpgp.decrypt({ +- message, +- decryptionKeys: privateKey +- }); +- return decrypted; ++ return yield openpgp.default.decrypt(cipherText, toPrivateKeyArmored, ''); + }); + }, + verifySignature({ messageContent, signatureArmored, publicKeyArmored, }) { + return tslib_1.__awaiter(this, void 0, void 0, function* () { +- const message = yield openpgp.createMessage({ text: messageContent }); +- const signature = yield openpgp.readSignature({ +- armoredSignature: signatureArmored +- }); +- const publicKey = yield openpgp.readKey({ armoredKey: publicKeyArmored }); +- const verificationResult = yield openpgp.verify({ +- message, +- signature, +- verificationKeys: publicKey +- }); +- const { verified } = verificationResult.signatures[0]; +- try { +- yield verified; +- } +- catch (e) { +- throw new Error('Signature could not be verified: ' + e); +- } ++ const verified = yield openpgp.default.verify(signatureArmored, messageContent, publicKeyArmored); ++ if(!verified) throw new Error('Signature could not be verified'); + }); + } + }; + exports.PGPHelper = PGPHelper; +-const generateKeyPair = () => tslib_1.__awaiter(void 0, void 0, void 0, function* () { +- const keys = yield openpgp.generateKey({ +- type: 'rsa', +- rsaBits: 2048, +- userIDs: [{ name: '', email: '' }] +- }); +- return { +- privateKeyArmored: keys.privateKey, +- publicKeyArmored: keys.publicKey +- }; +-}); +-exports.generateKeyPair = generateKeyPair; +-const pgpEncrypt = ({ plainText, keys, }) => tslib_1.__awaiter(void 0, void 0, void 0, function* () { +- const pgpKeys = []; +- for (let i = 0; i < keys.length; i++) { +- pgpKeys.push(yield openpgp.readKey({ armoredKey: keys[i] })); +- } +- const message = yield openpgp.createMessage({ text: plainText }); +- const encrypted = yield openpgp.encrypt({ +- message: message, +- encryptionKeys: pgpKeys +- }); +- return encrypted; +-}); +-exports.pgpEncrypt = pgpEncrypt; +-const sign = ({ message, signingKey }) => tslib_1.__awaiter(void 0, void 0, void 0, function* () { +- const messageObject = yield openpgp.createMessage({ text: message }); +- const privateKey = yield openpgp.readPrivateKey({ armoredKey: signingKey }); +- return yield openpgp.sign({ message: messageObject, signingKeys: privateKey, detached: true }); +-}); +-exports.sign = sign; +-const verifySignature = ({ messageContent, signatureArmored, publicKeyArmored, }) => tslib_1.__awaiter(void 0, void 0, void 0, function* () { +- const message = yield openpgp.createMessage({ text: messageContent }); +- const signature = yield openpgp.readSignature({ +- armoredSignature: signatureArmored +- }); +- const publicKey = yield openpgp.readKey({ armoredKey: publicKeyArmored }); +- const verificationResult = yield openpgp.verify({ +- message, +- signature, +- verificationKeys: publicKey +- }); +- const { verified } = verificationResult.signatures[0]; +- try { +- yield verified; +- } +- catch (e) { +- throw new Error('Signature could not be verified: ' + e); +- } +-}); +-exports.verifySignature = verifySignature; +-const pgpDecrypt = ({ cipherText, toPrivateKeyArmored }) => tslib_1.__awaiter(void 0, void 0, void 0, function* () { +- const message = yield openpgp.readMessage({ armoredMessage: cipherText }); +- const privateKey = yield openpgp.readPrivateKey({ armoredKey: toPrivateKeyArmored }); +- const { data: decrypted } = yield openpgp.decrypt({ +- message, +- decryptionKeys: privateKey +- }); +- return decrypted; +-}); +-exports.pgpDecrypt = pgpDecrypt; ++ ++exports.generateKeyPair = PGPHelper.generateKeyPair; ++exports.pgpEncrypt = PGPHelper.pgpEncrypt; ++exports.sign = PGPHelper.sign; ++exports.verifySignature = PGPHelper.verifySignature; ++exports.pgpDecrypt = PGPHelper.pgpDecrypt; + //# sourceMappingURL=pgp.js.map +\ No newline at end of file diff --git a/packages/examples/sdk-react-native/patches/react-native-get-random-values+1.9.0.patch b/packages/reactnative/patches/react-native-get-random-values+1.9.0.patch similarity index 100% rename from packages/examples/sdk-react-native/patches/react-native-get-random-values+1.9.0.patch rename to packages/reactnative/patches/react-native-get-random-values+1.9.0.patch diff --git a/packages/reactnative/src/__tests__/index.test.tsx b/packages/reactnative/src/__tests__/index.test.tsx index 92643deb6..aa3ef72ad 100644 --- a/packages/reactnative/src/__tests__/index.test.tsx +++ b/packages/reactnative/src/__tests__/index.test.tsx @@ -1,4 +1 @@ -import { PushApi } from '../index'; -it('write a test', async () => { - console.log(PushApi); -}); +it('todo: write a test', async () => {}); diff --git a/packages/reactnative/src/index.tsx b/packages/reactnative/src/index.tsx index fe9c11cc0..a8ba17943 100644 --- a/packages/reactnative/src/index.tsx +++ b/packages/reactnative/src/index.tsx @@ -1,155 +1,7 @@ -import '../shim.js'; +import '../../shim.js'; +import 'crypto'; import 'text-encoding'; import 'react-native-crypto'; import 'react-native-get-random-values'; -import React from 'react'; -import OpenPGP from 'react-native-fast-openpgp'; -import WebViewCrypto from 'react-native-webview-crypto'; -import { ethers } from 'ethers'; - -import * as PushApi from '@pushprotocol/restapi'; -import { IPGPHelper } from '@pushprotocol/restapi/src/lib/chat/helpers/pgp.js'; -import { ENV } from '@pushprotocol/restapi/src/lib/constants.js'; -import { LatestMessagesOptionsType } from '@pushprotocol/restapi/src/lib/chat/latestMessage.js'; -import { HistoricalMessagesOptionsType } from '@pushprotocol/restapi/src/lib/chat/historicalMessages.js'; -import { ChatCreateGroupType } from '@pushprotocol/restapi/src/lib/chat/createGroup.js'; -import { ChatUpdateGroupType } from '@pushprotocol/restapi/src/lib/chat/updateGroup.js'; -import { ChatsOptionsType } from '@pushprotocol/restapi/src/lib/chat/chats.js'; -import Constants from '@pushprotocol/restapi/src/lib/constants.js'; -import { decryptPGPKey } from '@pushprotocol/restapi/src/lib/helpers/crypto.js'; - -const PGPHelper: IPGPHelper = { - async generateKeyPair() { - let keys = await OpenPGP.generate({ keyOptions: { rsaBits: 2048 } }); - return { - privateKeyArmored: keys.privateKey, - publicKeyArmored: keys.publicKey, - }; - }, - - async sign({ message, signingKey }) { - const signature = await OpenPGP.sign(message, signingKey, ''); - return signature.replace('\nVersion: openpgp-mobile', ''); - }, - - async pgpEncrypt({ keys, plainText }) { - const encryptedSecret = await OpenPGP.encrypt(plainText, keys.join('\n')); - return encryptedSecret; - }, - - async pgpDecrypt({ - cipherText, - toPrivateKeyArmored, - }: { - cipherText: any; - toPrivateKeyArmored: string; - }): Promise { - return await OpenPGP.decrypt(cipherText, toPrivateKeyArmored, ''); - }, - - async verifySignature({}: { - messageContent: string; - signatureArmored: string; - publicKeyArmored: string; - }): Promise { - // TODO: add verification - }, -}; - -const createUser = async (options: PushApi.user.CreateUserProps) => { - return await PushApi.user.createUserCore(options, PGPHelper); -}; - -const get = async (options: PushApi.AccountEnvOptionsType) => { - return await PushApi.user.get(options); -}; - -const profileUpdate = async (options: PushApi.user.ProfileUpdateProps) => { - return await PushApi.user.profile.updateCore(options, PGPHelper); -}; - -const send = async (options: PushApi.ChatSendOptionsType) => { - return await PushApi.chat.sendCore(options, PGPHelper); -}; - -const approve = async (options: PushApi.chat.ApproveRequestOptionsType) => { - return await PushApi.chat.approveCore(options, PGPHelper); -}; - -const conversationHash = async ( - options: PushApi.ConversationHashOptionsType -) => { - let hash = await PushApi.chat.conversationHash(options); - return hash; -}; - -const chats = async (options: ChatsOptionsType) => { - let chatsList = await PushApi.chat.chatsCore(options, PGPHelper); - return chatsList; -}; - -const requests = async (options: ChatsOptionsType) => { - return await PushApi.chat.requestsCore(options, PGPHelper); -}; - -const latest = async (options: LatestMessagesOptionsType) => { - let latestMsg = await PushApi.chat.latestCore(options, PGPHelper); - return latestMsg; -}; - -const history = async (options: HistoricalMessagesOptionsType) => { - let msg = await PushApi.chat.historyCore(options, PGPHelper); - return msg; -}; - -const createGroup = async (options: ChatCreateGroupType) => { - let group = await PushApi.chat.createGroupCore(options, PGPHelper); - return group; -}; - -const updateGroup = async (options: ChatUpdateGroupType) => { - let updatedGroup = await PushApi.chat.updateGroupCore(options, PGPHelper); - return updatedGroup; -}; - -// checking if ethers works -const genRandomAddress = () => { - const wallet = ethers.Wallet.createRandom(); - const address = wallet.address; - return address; -}; - -const profileUpgrade = PushApi.user.auth.update; - -const PushRNWrapper = ({ children }: { children: React.ReactNode }) => { - return ( - - - {children} - - ); -}; - -export { - PGPHelper, - genRandomAddress, - createUser, - get, - profileUpdate, - PushApi, - ENV, - conversationHash, - latest, - history, - createGroup, - updateGroup, - chats, - requests, - decryptPGPKey, - profileUpgrade, - send, - approve, - Constants, - PushRNWrapper, -}; +export * from '@pushprotocol/restapi'; diff --git a/packages/reactnative/tsconfig.json b/packages/reactnative/tsconfig.json index 392fa464b..c04f33534 100644 --- a/packages/reactnative/tsconfig.json +++ b/packages/reactnative/tsconfig.json @@ -2,7 +2,7 @@ "compilerOptions": { "baseUrl": "./", "paths": { - "@push/react-native-sdk": ["./src/index"] + "@pushprotocol/react-native-sdk": ["./src/index"] }, "allowUnreachableCode": false, "allowUnusedLabels": false, diff --git a/packages/uireactnative/.gitignore b/packages/uireactnative/.gitignore new file mode 100644 index 000000000..42bee8de0 --- /dev/null +++ b/packages/uireactnative/.gitignore @@ -0,0 +1,79 @@ +# OSX +# +.DS_Store + +# XDE +.expo/ + +# VSCode +.vscode/ +jsconfig.json + +# Xcode +# +build/ +*.pbxuser +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 +*.perspectivev3 +!default.perspectivev3 +xcuserdata +*.xccheckout +*.moved-aside +DerivedData +*.hmap +*.ipa +*.xcuserstate +project.xcworkspace + +# Android/IJ +# +.classpath +.cxx +.gradle +.idea +.project +.settings +local.properties +android.iml + +# Cocoapods +# +example/ios/Pods + +# Ruby +example/vendor/ + +# node.js +# +node_modules/ +npm-debug.log +yarn-debug.log +yarn-error.log + +# BUCK +buck-out/ +\.buckd/ +android/app/libs +android/keystores/debug.keystore + +# Yarn +.yarn +!.yarn/patches +!.yarn/plugins +!.yarn/releases +!.yarn/sdks +!.yarn/versions +.yarnrc.yml + +# Expo +.expo/ + +# Turborepo +.turbo/ + +# generated by bob +/lib diff --git a/packages/uireactnative/.watchmanconfig b/packages/uireactnative/.watchmanconfig new file mode 100644 index 000000000..9e26dfeeb --- /dev/null +++ b/packages/uireactnative/.watchmanconfig @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/packages/uireactnative/README.md b/packages/uireactnative/README.md new file mode 100644 index 000000000..abe73ab51 --- /dev/null +++ b/packages/uireactnative/README.md @@ -0,0 +1,31 @@ +# @pushprotocol/uireactnative + +Package for UI components for Push Protocol in React Native + +## Installation + +```sh +npm install @pushprotocol/uireactnative +``` + +## Usage + +```js +import { multiply } from '@pushprotocol/uireactnative'; + +// ... + +const result = await multiply(3, 7); +``` + +## Contributing + +See the [contributing guide](CONTRIBUTING.md) to learn how to contribute to the repository and the development workflow. + +## License + +MIT + +--- + +Made with [create-react-native-library](https://github.com/callstack/react-native-builder-bob) diff --git a/packages/uireactnative/babel.config.js b/packages/uireactnative/babel.config.js new file mode 100644 index 000000000..f7b3da3b3 --- /dev/null +++ b/packages/uireactnative/babel.config.js @@ -0,0 +1,3 @@ +module.exports = { + presets: ['module:@react-native/babel-preset'], +}; diff --git a/packages/uireactnative/package.json b/packages/uireactnative/package.json new file mode 100644 index 000000000..678a03dee --- /dev/null +++ b/packages/uireactnative/package.json @@ -0,0 +1,154 @@ +{ + "name": "@pushprotocol/uireactnative", + "version": "0.1.0", + "main": "lib/commonjs/index", + "module": "lib/module/index", + "types": "lib/typescript/src/index.d.ts", + "react-native": "src/index", + "source": "src/index", + "files": [ + "src", + "lib", + "android", + "ios", + "cpp", + "*.podspec", + "!ios/build", + "!android/build", + "!android/gradle", + "!android/gradlew", + "!android/gradlew.bat", + "!android/local.properties", + "!**/__tests__", + "!**/__fixtures__", + "!**/__mocks__", + "!**/.*" + ], + "scripts": { + "test": "jest", + "typecheck": "tsc --noEmit", + "lint": "eslint \"**/*.{js,ts,tsx}\"", + "prepare": "bob build", + "release": "release-it" + }, + "keywords": [ + "react-native", + "ios", + "android" + ], + "publishConfig": { + "registry": "https://registry.npmjs.org/" + }, + "devDependencies": { + "@react-native/eslint-config": "^0.72.2", + "@release-it/conventional-changelog": "^5.0.0", + "@types/jest": "^28.1.2", + "@types/react": "~18.2.25", + "@types/react-native": "0.72.6", + "eslint": "^8.4.1", + "eslint-config-prettier": "^8.5.0", + "eslint-plugin-prettier": "^4.0.0", + "expo-av": "13.6.0", + "expo-file-system": "15.6.0", + "expo-linear-gradient": "12.5.0", + "jest": "^28.1.1", + "prettier": "^2.0.5", + "react-native-builder-bob": "^0.20.0", + "release-it": "^15.0.0", + "typescript": "^5.3.3" + }, + "resolutions": { + "@types/react": "18.2.25" + }, + "peerDependencies": { + "expo": "*", + "expo-av": "*", + "expo-linear-gradient": "*", + "react": "*", + "react-native": "*" + }, + "dependencies": { + "@react-native-community/masked-view": "^0.1.11", + "react-native-parsed-text": "^0.0.22", + "react-native-progress-circle": "^2.1.0", + "react-native-svg": "^14.1.0", + "react-native-youtube-iframe": "^2.3.0" + }, + "packageManager": "yarn@4.0.2", + "engines": { + "node": ">= 18.0.0" + }, + "jest": { + "preset": "react-native", + "modulePathIgnorePatterns": [ + "/example/node_modules", + "/lib/" + ] + }, + "commitlint": { + "extends": [ + "@commitlint/config-conventional" + ] + }, + "release-it": { + "git": { + "commitMessage": "chore: release ${version}", + "tagName": "v${version}" + }, + "npm": { + "publish": true + }, + "github": { + "release": true + }, + "plugins": { + "@release-it/conventional-changelog": { + "preset": "angular" + } + } + }, + "eslintConfig": { + "root": true, + "extends": [ + "@react-native", + "prettier" + ], + "rules": { + "prettier/prettier": [ + "error", + { + "quoteProps": "consistent", + "singleQuote": true, + "tabWidth": 2, + "trailingComma": "es5", + "useTabs": false + } + ] + } + }, + "eslintIgnore": [ + "node_modules/", + "/lib" + ], + "prettier": { + "quoteProps": "consistent", + "singleQuote": true, + "tabWidth": 2, + "trailingComma": "es5", + "useTabs": false + }, + "react-native-builder-bob": { + "source": "src", + "output": "lib", + "targets": [ + "commonjs", + "module", + [ + "typescript", + { + "project": "tsconfig.build.json" + } + ] + ] + } +} diff --git a/packages/uireactnative/src/index.ts b/packages/uireactnative/src/index.ts new file mode 100644 index 000000000..f41a696fd --- /dev/null +++ b/packages/uireactnative/src/index.ts @@ -0,0 +1 @@ +export * from './lib'; diff --git a/packages/uireactnative/src/lib/assets/icons/ArbitriumSVG.tsx b/packages/uireactnative/src/lib/assets/icons/ArbitriumSVG.tsx new file mode 100644 index 000000000..ac6832fdd --- /dev/null +++ b/packages/uireactnative/src/lib/assets/icons/ArbitriumSVG.tsx @@ -0,0 +1,38 @@ +import * as React from 'react'; +import Svg, { + type SvgProps, + Path, + ClipPath, + Defs, + Circle, + G, +} from 'react-native-svg'; + +export const ArbitrumSVG = (props: SvgProps) => ( + + + + + + + + + + + + + + +); diff --git a/packages/uireactnative/src/lib/assets/icons/BscSVG.tsx b/packages/uireactnative/src/lib/assets/icons/BscSVG.tsx new file mode 100644 index 000000000..cd3bc12c1 --- /dev/null +++ b/packages/uireactnative/src/lib/assets/icons/BscSVG.tsx @@ -0,0 +1,12 @@ +import * as React from 'react'; +import Svg, { type SvgProps, Circle, Path } from 'react-native-svg'; + +export const BscSVG = (props: SvgProps) => ( + + + + +); diff --git a/packages/uireactnative/src/lib/assets/icons/EthereumSVG.tsx b/packages/uireactnative/src/lib/assets/icons/EthereumSVG.tsx new file mode 100644 index 000000000..98fd6607a --- /dev/null +++ b/packages/uireactnative/src/lib/assets/icons/EthereumSVG.tsx @@ -0,0 +1,33 @@ +import * as React from 'react'; +import Svg, { type SvgProps, Path } from 'react-native-svg'; + +export const EthereumSVG = (props: SvgProps) => ( + + + + + + + + + +); diff --git a/packages/uireactnative/src/lib/assets/icons/GraphSVG.tsx b/packages/uireactnative/src/lib/assets/icons/GraphSVG.tsx new file mode 100644 index 000000000..f527ecee9 --- /dev/null +++ b/packages/uireactnative/src/lib/assets/icons/GraphSVG.tsx @@ -0,0 +1,24 @@ +import * as React from 'react'; +import Svg, { type SvgProps, G, Path, Defs, ClipPath } from 'react-native-svg'; + +export const GraphSVG = (props: SvgProps) => ( + + + + + + + + + + + +); diff --git a/packages/uireactnative/src/lib/assets/icons/Link.tsx b/packages/uireactnative/src/lib/assets/icons/Link.tsx new file mode 100644 index 000000000..b620dd615 --- /dev/null +++ b/packages/uireactnative/src/lib/assets/icons/Link.tsx @@ -0,0 +1,11 @@ +import * as React from 'react'; +import Svg, { G, Path, type SvgProps } from 'react-native-svg'; + +export const Link = (props: SvgProps) => ( + + + + + + +); diff --git a/packages/uireactnative/src/lib/assets/icons/OptimismSVG.tsx b/packages/uireactnative/src/lib/assets/icons/OptimismSVG.tsx new file mode 100644 index 000000000..4e5731e5b --- /dev/null +++ b/packages/uireactnative/src/lib/assets/icons/OptimismSVG.tsx @@ -0,0 +1,22 @@ +import * as React from 'react'; +import Svg, { type SvgProps, G, Path, Defs, ClipPath } from 'react-native-svg'; + +export const OptimismSVG = (props: SvgProps) => ( + + + + + + + + + + + +); diff --git a/packages/uireactnative/src/lib/assets/icons/PolygonSVG.tsx b/packages/uireactnative/src/lib/assets/icons/PolygonSVG.tsx new file mode 100644 index 000000000..e3dadd2c6 --- /dev/null +++ b/packages/uireactnative/src/lib/assets/icons/PolygonSVG.tsx @@ -0,0 +1,22 @@ +import * as React from 'react'; +import Svg, { type SvgProps, G, Path, Defs, ClipPath } from 'react-native-svg'; + +export const PolygonSVG = (props: SvgProps) => ( + + + + + + + + + + + +); diff --git a/packages/uireactnative/src/lib/assets/icons/PolygonZkevmSVG.tsx b/packages/uireactnative/src/lib/assets/icons/PolygonZkevmSVG.tsx new file mode 100644 index 000000000..b00e90ef4 --- /dev/null +++ b/packages/uireactnative/src/lib/assets/icons/PolygonZkevmSVG.tsx @@ -0,0 +1,26 @@ +import * as React from 'react'; +import Svg, { type SvgProps, G, Path, Defs, ClipPath } from 'react-native-svg'; + +export const PolygonZkevmSVG = (props: SvgProps) => ( + + + + + + + + + + + + +); diff --git a/packages/uireactnative/src/lib/assets/icons/index.ts b/packages/uireactnative/src/lib/assets/icons/index.ts new file mode 100644 index 000000000..4c0313e82 --- /dev/null +++ b/packages/uireactnative/src/lib/assets/icons/index.ts @@ -0,0 +1,8 @@ +export * from './EthereumSVG'; +export * from './PolygonSVG'; +export * from './BscSVG'; +export * from './OptimismSVG'; +export * from './PolygonZkevmSVG'; +export * from './ArbitriumSVG'; +export * from './GraphSVG'; +export * from './Link'; diff --git a/packages/uireactnative/src/lib/assets/index.ts b/packages/uireactnative/src/lib/assets/index.ts new file mode 100644 index 000000000..838008a0b --- /dev/null +++ b/packages/uireactnative/src/lib/assets/index.ts @@ -0,0 +1 @@ +export * from './icons'; diff --git a/packages/uireactnative/src/lib/components/index.ts b/packages/uireactnative/src/lib/components/index.ts new file mode 100644 index 000000000..fc944913c --- /dev/null +++ b/packages/uireactnative/src/lib/components/index.ts @@ -0,0 +1,3 @@ +export * from './notification'; +export * from './loaders'; +export * from './labels'; diff --git a/packages/uireactnative/src/lib/components/labels/StylishLabel.tsx b/packages/uireactnative/src/lib/components/labels/StylishLabel.tsx new file mode 100644 index 000000000..5370bb232 --- /dev/null +++ b/packages/uireactnative/src/lib/components/labels/StylishLabel.tsx @@ -0,0 +1,419 @@ +import React from 'react'; +import { + Linking, + Platform, + StyleSheet, + Text, + View, + type StyleProp, + type TextStyle, + type ViewStyle, +} from 'react-native'; +import ParsedText from 'react-native-parsed-text'; +import { GLOBALS } from '../../constants'; + +interface StylishLabelProps { + textStyle?: StyleProp; + style?: StyleProp; + title: string; + fontSize: number; +} + +export const StylishLabel = ({ + style, + title, + fontSize, + textStyle, +}: StylishLabelProps) => { + const openLink = (url: string | undefined) => { + if (!url) return; + Linking.canOpenURL(url).then((supported) => { + if (supported) Linking.openURL(url); + else console.log("Don't know how to open URI: " + url); + }); + }; + + const handleUrlPress = (matchingString: string) => { + let pattern = /\[([^:]+):([^\]]+)\]/i; + let match = matchingString.match(pattern); + + if (match && match[2]) { + const midComponent = `${match[2]}`; + const url = midComponent.substr(midComponent.indexOf('||') + 2); + openLink(url); + } + }; + + const handlePhonePress = (phone: string) => { + if (Platform.OS !== 'android') { + phone = `telprompt:${phone}`; + } else { + phone = `tel:${phone}`; + } + openLink(phone); + }; + + const handleEmailPress = (email: string) => { + openLink(`mailto:${email}`); + }; + + const handleAppSettings = () => { + if (Platform.OS === 'ios') { + Linking.openURL('app-settings:'); + } + }; + + const renderStyles = (matchingString: string) => { + let pattern = /\[([^:]+):([^\]]+)\]/i; + let match = matchingString.match(pattern); + + if (match && match[2]) return `${match[2]}`; + return ''; + }; + + const renderThreeStyles = (matchingString: string) => { + // matches => ["[@michel:5455345]", "@michel", "5455345"] + let pattern = /\[([^:]+):([^\]]+)\]/i; + let match = matchingString.match(pattern); + + if (match && match[2]) { + let midComponent = `${match[2]}`; + const midText = midComponent.substr(0, midComponent.indexOf('||')); + return midText; + } else { + return ''; + } + }; + + const handleAnchorRender = (matchingString: string) => { + let renderString = matchingString; + renderString = renderString.replace(/]*>/, ''); + renderString = renderString.replace('', ''); + return renderString; + }; + + const handelAnchorClick = (matchingString: string) => { + let url = matchingString; + const match = url.match(/]*?\s+)?href=(["'])(.*?)\1/); + if (match) url = match[0]; + url = url.replace(' { + return '\n'; + }; + + const renderTextStyles = (matchingString: string) => { + const pattern = + /(.*?)<\/span>/i; + const match = matchingString.match(pattern); + + if (match && match[1]) { + const colorName = match[1].toLowerCase(); + let color; + switch (colorName) { + case 'primary': + color = GLOBALS.COLORS.PRIMARY; + break; + case 'secondary': + color = GLOBALS.COLORS.GRADIENT_SECONDARY; + break; + case 'white': + color = GLOBALS.COLORS.WHITE; + break; + default: + color = colorName; + } + let textContent = match[2]; + return {textContent}; + } + + return matchingString; + }; + + const renderLinkWithColor = (matchingString: string) => { + const pattern = + /(.*?)<\/PUSHText>/i; + const linkPattern = /\[([^\]]+)]\((https?:\/\/[^)]+)/; + const match = matchingString.match(pattern); + const markdownLinkPattern = matchingString.match(linkPattern); + + if (match && match[1]) { + const colorName = match[1].toLowerCase(); + let color; + // Map custom color names to specific values + switch (colorName) { + case 'primary': + color = GLOBALS.COLORS.PRIMARY; + break; + case 'secondary': + color = GLOBALS.COLORS.GRADIENT_SECONDARY; + break; + case 'tertiary': + color = GLOBALS.COLORS.GRADIENT_THIRD; + break; + case 'white': + color = GLOBALS.COLORS.WHITE; + break; + // Add more custom color names if needed + default: + color = colorName; + } + + const link = match[2]; + let textContent = match[3]; + return ( + openLink(link)}> + {textContent} + + ); + } else if (markdownLinkPattern) { + const linkText = markdownLinkPattern[1]; + const linkUrl = markdownLinkPattern[2]; + return ( + openLink(linkUrl)} style={styles.linkText}> + {linkText} + + ); + } + + return matchingString; + }; + + let TextUpdatedStyle = { + fontSize: fontSize, + }; + + let parseSettings = [ + { + type: 'email', + style: [styles.link, styles.underline], + onPress: handleEmailPress, + }, + { + type: 'phone', + style: [styles.link, styles.underline], + onPress: handlePhonePress, + }, + { + pattern: /\[([^\]]+)]\((https?:\/\/[^)]+)\)/g, + style: {}, + renderText: renderLinkWithColor, + }, + { + pattern: /\[(u):([^\]]+)\]/i, // url + style: [styles.primary, styles.bold, styles.italics, styles.underline], + onPress: handleUrlPress, + renderText: renderThreeStyles, + }, + { + pattern: /\[(ub):([^\]]+)\]/i, // urli + style: [styles.secondary, styles.bold, styles.italics, styles.underline], + onPress: handleUrlPress, + renderText: renderThreeStyles, + }, + { + pattern: /\[(ut):([^\]]+)\]/i, // url + style: [styles.third, styles.bold, styles.italics, styles.underline], + onPress: handleUrlPress, + renderText: renderThreeStyles, + }, + { + pattern: /]*>([^<]+)<\/a>/, // for anchor tage + style: [styles.third, styles.bold, styles.italics, styles.underline], + onPress: handelAnchorClick, + renderText: handleAnchorRender, + }, + { + pattern: /\[(up):([^\]]+)\]/i, // url + style: [styles.primary, styles.italics, styles.underline], + onPress: handleUrlPress, + renderText: renderThreeStyles, + }, + { + pattern: + /(.*?)<\/span>/gi, + style: {}, // we can add aditional styles here if needed + renderText: renderTextStyles, + }, + { + pattern: /\[(d):([^\]]+)\]/i, // default or primary gradient color + style: [styles.primary, styles.bold], + renderText: renderStyles, + }, + { + pattern: /\[(s):([^\]]+)\]/i, // secondary gradient color + style: [styles.secondary, styles.bold], + renderText: renderStyles, + }, + { + pattern: /\[(t):([^\]]+)\]/i, // third gradient color + style: [styles.third, styles.bold], + renderText: renderStyles, + }, + { + pattern: /\[(e):([^\]]+)\]/i, // error + style: [styles.error, styles.bold], + renderText: renderStyles, + }, + { + pattern: /\[(bi):([^\]]+)\]/i, // bolditalics + style: [styles.bold, styles.italics], + renderText: renderStyles, + }, + { + pattern: /\*\*\*(.*?)\*\*\*/g, // bolditalics ***text*** + style: { + ...styles.bold, + ...styles.italics, + }, + renderText: (matchingString: string) => + matchingString.replace(/\*\*\*(.*?)\*\*\*/g, '$1'), + }, + { + pattern: /\[(b):([^\]]+)\]/i, // bold + style: styles.bold, + renderText: renderStyles, + }, + { + pattern: /\*\*(.*?)\*\*/g, // bold **text** + style: styles.bold, + renderText: (matchingString: string) => + matchingString.replace(/\*\*(.*?)\*\*/g, '$1'), + }, + { + pattern: /\[(i):([^\]]+)\]/i, // italics + style: styles.italics, + renderText: renderStyles, + }, + { + pattern: /\*(.*?)\*/g, // italic *some text* + style: { + ...styles.italics, + }, + renderText: (matchingString: string) => + matchingString.replace(/\*(.*?)\*/g, '$1'), + }, + { + pattern: /\[(w):([^\]]+)\]/i, // white + style: [styles.white], + renderText: renderStyles, + }, + { + pattern: /\[(wb):([^\]]+)\]/i, // whitebold + style: [styles.white, styles.bold], + renderText: renderStyles, + }, + { + pattern: /\[(mg):([^\]]+)\]/i, // midgray + style: [styles.midgray], + renderText: renderStyles, + }, + { + pattern: /\[(dg):([^\]]+)\]/i, // darkgray + style: [styles.darkgray], + renderText: renderStyles, + }, + { + pattern: /\[(ddg):([^\]]+)\]/i, // darker gray + style: [styles.darkergray], + renderText: renderStyles, + }, + { + type: 'url', + style: [styles.link, styles.underline], + onPress: handleUrlPress, + }, + { + pattern: /\\n/g, + style: {}, + renderText: newLineStyles, + }, + ]; + + if (Platform.OS === 'ios') { + parseSettings.push({ + pattern: /\[(appsettings):([^\]]+)\]/i, + style: [styles.link, styles.bold, styles.italics, styles.underline], + onPress: handleAppSettings, + renderText: renderStyles, + }); + } else if (Platform.OS === 'android') { + parseSettings.push({ + pattern: /\[(appsettings):([^\]]+)\]/i, + style: [styles.bold], + renderText: renderStyles, + }); + } + + return ( + + + {title} + + + ); +}; + +// Styling +const styles = StyleSheet.create({ + container: {}, + name: { + color: GLOBALS.COLORS.SUBLIME_RED, + }, + username: { + color: GLOBALS.COLORS.GRADIENT_SECONDARY, + }, + text: { + color: GLOBALS.COLORS.BLACK, + }, + primary: { + color: GLOBALS.COLORS.GRADIENT_PRIMARY, + }, + secondary: { + color: GLOBALS.COLORS.GRADIENT_SECONDARY, + }, + third: { + color: GLOBALS.COLORS.GRADIENT_THIRD, + }, + error: { + color: GLOBALS.COLORS.SUBLIME_RED, + }, + white: { + color: GLOBALS.COLORS.WHITE, + }, + midgray: { + color: GLOBALS.COLORS.MID_GRAY, + }, + darkgray: { + color: GLOBALS.COLORS.DARK_GRAY, + }, + darkergray: { + color: GLOBALS.COLORS.DARKER_GRAY, + }, + link: { + color: GLOBALS.COLORS.GRADIENT_PRIMARY, + }, + underline: { + textDecorationLine: 'underline', + }, + bold: { + fontWeight: 'bold', + }, + italics: { + fontStyle: 'italic', + }, + linkText: { + color: GLOBALS.COLORS.PINK, + flex: 0, + }, +}); diff --git a/packages/uireactnative/src/lib/components/labels/index.ts b/packages/uireactnative/src/lib/components/labels/index.ts new file mode 100644 index 000000000..4a5a1ef04 --- /dev/null +++ b/packages/uireactnative/src/lib/components/labels/index.ts @@ -0,0 +1 @@ +export * from './StylishLabel'; diff --git a/packages/uireactnative/src/lib/components/loaders/ImageLoader.tsx b/packages/uireactnative/src/lib/components/loaders/ImageLoader.tsx new file mode 100644 index 000000000..8cec7107d --- /dev/null +++ b/packages/uireactnative/src/lib/components/loaders/ImageLoader.tsx @@ -0,0 +1,50 @@ +import { ActivityIndicator, Image, StyleSheet, View } from 'react-native'; +import React, { useState } from 'react'; +import { GLOBALS } from '../../constants'; + +interface ImageLoaderProps { + imageUri: string; +} + +export const ImageLoader = ({ imageUri }: ImageLoaderProps) => { + const [isLoading, setIsLoading] = useState(true); + + const onLoadEnd = () => { + setIsLoading(false); + }; + + return ( + + + + + ); +}; + +const styles = StyleSheet.create({ + container: { + flex: 1, + }, + activity: { + position: 'absolute', + left: 0, + right: 0, + top: 0, + bottom: 0, + }, + img: { + borderColor: GLOBALS.COLORS.SLIGHT_GRAY, + backgroundColor: GLOBALS.COLORS.SLIGHTER_GRAY, + borderBottomWidth: 1, + flex: 1, + resizeMode: 'cover', + width: '100%', + height: '100%', + overflow: 'hidden', + }, +}); diff --git a/packages/uireactnative/src/lib/components/loaders/VideoLoader.tsx b/packages/uireactnative/src/lib/components/loaders/VideoLoader.tsx new file mode 100644 index 000000000..ce7fa1164 --- /dev/null +++ b/packages/uireactnative/src/lib/components/loaders/VideoLoader.tsx @@ -0,0 +1,66 @@ +import { AppState, StyleSheet } from 'react-native'; +import React, { useCallback, useEffect, useRef, useState } from 'react'; +import { MediaHelper } from '../../helpers'; +import YoutubeIframe, { + PLAYER_STATES, + type YoutubeIframeRef, +} from 'react-native-youtube-iframe'; +import { ResizeMode, Video } from 'expo-av'; + +interface VideoLoaderProps { + videoUri: string; +} + +export const VideoLoader = ({ videoUri }: VideoLoaderProps) => { + const videoRef = useRef