diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6297ef1..1c9f5c8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -99,7 +99,7 @@ jobs: - name: Build example for Android env: - JAVA_OPTS: "-XX:MaxHeapSize=6g" + JAVA_OPTS: '-XX:MaxHeapSize=6g' run: | yarn turbo run build:android --cache-dir="${{ env.TURBO_CACHE_DIR }}" @@ -142,7 +142,7 @@ jobs: ${{ runner.os }}-cocoapods- - name: Install cocoapods - if: env.turbo_cache_hit != 1 && steps.cocoapods-cache.outputs.cache-hit != 'true' + # if: env.turbo_cache_hit != 1 && steps.cocoapods-cache.outputs.cache-hit != 'true' run: | cd example/ios pod install diff --git a/android/build.gradle b/android/build.gradle index 383fae9..ba525d0 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -100,6 +100,7 @@ repositories { mavenCentral() google() + // Sandbox: maven { url = "https://maven.fireblocks.io/android-sdk/maven" name = "android-sdk" @@ -109,6 +110,17 @@ repositories { } authentication { header(HttpHeaderAuthentication) } } + + // //dev9: + // maven { + // url = "https://gitlab.com/api/v4/projects/42877710/packages/maven" + // name = "android-sdk" + // credentials(HttpHeaderCredentials) { + // name = "Deploy-Token" + // value = "vq2yuSp4Vxu5tzyExoXt" + // } + // authentication { header(HttpHeaderAuthentication) } + // } } def kotlin_version = getExtOrDefault("kotlinVersion") @@ -119,7 +131,9 @@ dependencies { //noinspection GradleDynamicVersion implementation "com.facebook.react:react-native:+" implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" - implementation "com.fireblocks.sdk:ncw:2.5.0" + // implementation "com.fireblocks.sdk:ncw-dev:2.5.0" //dev9 + implementation "com.fireblocks.sdk:ncw:2.5.0" //sandbox + } if (isNewArchitectureEnabled()) { diff --git a/example/Gemfile.lock b/example/Gemfile.lock index 03a1548..6b25385 100644 --- a/example/Gemfile.lock +++ b/example/Gemfile.lock @@ -5,11 +5,12 @@ GEM base64 nkf rexml - activesupport (7.0.8.1) + activesupport (6.1.7.7) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 1.6, < 2) minitest (>= 5.1) tzinfo (~> 2.0) + zeitwerk (~> 2.3) addressable (2.8.6) public_suffix (>= 2.0.2, < 6.0) algoliasearch (1.27.5) @@ -88,6 +89,7 @@ GEM colored2 (~> 3.1) nanaimo (~> 0.3.0) rexml (~> 3.2.4) + zeitwerk (2.6.15) PLATFORMS ruby diff --git a/example/README.md b/example/README.md index 12470c3..8bd066d 100644 --- a/example/README.md +++ b/example/README.md @@ -2,7 +2,7 @@ This is a new [**React Native**](https://reactnative.dev) project, bootstrapped # Getting Started ->**Note**: Make sure you have completed the [React Native - Environment Setup](https://reactnative.dev/docs/environment-setup) instructions till "Creating a new application" step, before proceeding. +> **Note**: Make sure you have completed the [React Native - Environment Setup](https://reactnative.dev/docs/environment-setup) instructions till "Creating a new application" step, before proceeding. ## Step 1: Start the Metro Server diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle index 43352ca..5c05c75 100644 --- a/example/android/app/build.gradle +++ b/example/android/app/build.gradle @@ -106,22 +106,36 @@ android { } repositories { - maven { - url = "https://maven.fireblocks.io/android-sdk/maven" - name = "android-sdk" - credentials(HttpHeaderCredentials) { - name = "Deploy-Token" - value = "-fU8ijmuPohHaqDBgpaT" - } - authentication { header(HttpHeaderAuthentication) } +// Sandbox: + maven { + url = "https://maven.fireblocks.io/android-sdk/maven" + name = "android-sdk" + credentials(HttpHeaderCredentials) { + name = "Deploy-Token" + value = "-fU8ijmuPohHaqDBgpaT" + } + authentication { header(HttpHeaderAuthentication) } } + +// //dev9: +// maven { +// url = "https://gitlab.com/api/v4/projects/42877710/packages/maven" +// name = "android-sdk" +// credentials(HttpHeaderCredentials) { +// name = "Deploy-Token" +// value = "vq2yuSp4Vxu5tzyExoXt" +// } +// authentication { header(HttpHeaderAuthentication) } +// } } dependencies { // The version of react-native is set by the React Native Gradle Plugin implementation("com.facebook.react:react-android") implementation("com.facebook.react:flipper-integration") - implementation("com.fireblocks.sdk:ncw:2.5.0") + implementation("com.fireblocks.sdk:ncw:2.5.0") //sandbox + // implementation("com.fireblocks.sdk:ncw-dev:2.5.0") //dev9 + if (hermesEnabled.toBoolean()) { implementation("com.facebook.react:hermes-android") diff --git a/example/ios/.xcode.env.local b/example/ios/.xcode.env.local new file mode 100644 index 0000000..c380e43 --- /dev/null +++ b/example/ios/.xcode.env.local @@ -0,0 +1,2 @@ +export NODE_BINARY=/opt/homebrew/bin/node + diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index b4deac0..8aa4317 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -63,7 +63,7 @@ PODS: - GoogleUtilities/Environment (~> 7.8) - GoogleUtilities/UserDefaults (~> 7.8) - PromisesObjC (~> 2.1) - - fireblocks-react-native-ncw-sdk (1.0.0): + - fireblocks-react-native-ncw-sdk (1.0.1): - glog - RCT-Folly (= 2022.05.16.00) - React-Core @@ -1545,7 +1545,7 @@ SPEC CHECKSUMS: FirebaseCore: 28045c1560a2600d284b9c45a904fe322dc890b6 FirebaseCoreInternal: bca337352024b18424a61e478460547d46c4c753 FirebaseInstallations: 763814908793c0da14c18b3dcffdec71e29ed55e - fireblocks-react-native-ncw-sdk: 867882b558c0a3ef1c7a79d2e21af7db40a5a88e + fireblocks-react-native-ncw-sdk: 2d2ea406e10daf0bb129212af21ae94e858a039c Flipper: c7a0093234c4bdd456e363f2f19b2e4b27652d44 Flipper-Boost-iOSX: fd1e2b8cbef7e662a122412d7ac5f5bea715403c Flipper-DoubleConversion: 2dc99b02f658daf147069aad9dbd29d8feb06d30 diff --git a/example/ios/ReactNativeNcwSdkExample.xcodeproj/project.pbxproj b/example/ios/ReactNativeNcwSdkExample.xcodeproj/project.pbxproj index e8f124a..a4b1ecd 100644 --- a/example/ios/ReactNativeNcwSdkExample.xcodeproj/project.pbxproj +++ b/example/ios/ReactNativeNcwSdkExample.xcodeproj/project.pbxproj @@ -7,19 +7,19 @@ objects = { /* Begin PBXBuildFile section */ - 00E356F31AD99517003FC87E /* ReactNativeNcwSdkExampleTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 00E356F21AD99517003FC87E /* ReactNativeNcwSdkExampleTests.m */; }; 0C80B921A6F3F58F76C31292 /* libPods-ReactNativeNcwSdkExample.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5DCACB8F33CDC322A6C60F78 /* libPods-ReactNativeNcwSdkExample.a */; }; 13B07FBC1A68108700A75B9A /* AppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.mm */; }; 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; }; 13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; }; 2923859A2BD18D1D00BDE940 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 292385992BD18D1D00BDE940 /* GoogleService-Info.plist */; }; - 292385A62BD19B6100BDE940 /* FireblocksSDK in Frameworks */ = {isa = PBXBuildFile; productRef = 292385A52BD19B6100BDE940 /* FireblocksSDK */; }; - 7699B88040F8A987B510C191 /* libPods-ReactNativeNcwSdkExample-ReactNativeNcwSdkExampleTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 19F6CBCC0A4E27FBF8BF4A61 /* libPods-ReactNativeNcwSdkExample-ReactNativeNcwSdkExampleTests.a */; }; + 399C8E7E2C10A0B10060CF72 /* ReactNativeNcwSdkExampleTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 399C8E7D2C10A0B10060CF72 /* ReactNativeNcwSdkExampleTests.swift */; }; + 39ACB3E62C43D47600B7B859 /* FireblocksSDK in Frameworks */ = {isa = PBXBuildFile; productRef = 39ACB3E52C43D47600B7B859 /* FireblocksSDK */; }; + 6168BB22004ADA806847E0C1 /* libPods-ReactNativeNcwSdkExample-ReactNativeNcwSdkExampleTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 19F6CBCC0A4E27FBF8BF4A61 /* libPods-ReactNativeNcwSdkExample-ReactNativeNcwSdkExampleTests.a */; }; 81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ - 00E356F41AD99517003FC87E /* PBXContainerItemProxy */ = { + 399C8E7F2C10A0B10060CF72 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 83CBB9F71A601CBA00E9B192 /* Project object */; proxyType = 1; @@ -29,7 +29,6 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ - 00E356EE1AD99517003FC87E /* ReactNativeNcwSdkExampleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ReactNativeNcwSdkExampleTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 00E356F11AD99517003FC87E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 00E356F21AD99517003FC87E /* ReactNativeNcwSdkExampleTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ReactNativeNcwSdkExampleTests.m; sourceTree = ""; }; 13B07F961A680F5B00A75B9A /* ReactNativeNcwSdkExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ReactNativeNcwSdkExample.app; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -40,6 +39,8 @@ 13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = ReactNativeNcwSdkExample/main.m; sourceTree = ""; }; 19F6CBCC0A4E27FBF8BF4A61 /* libPods-ReactNativeNcwSdkExample-ReactNativeNcwSdkExampleTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ReactNativeNcwSdkExample-ReactNativeNcwSdkExampleTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 292385992BD18D1D00BDE940 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = "GoogleService-Info.plist"; path = "ReactNativeNcwSdkExample/GoogleService-Info.plist"; sourceTree = ""; }; + 399C8E7B2C10A0B10060CF72 /* ReactNativeNcwSdkExampleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ReactNativeNcwSdkExampleTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 399C8E7D2C10A0B10060CF72 /* ReactNativeNcwSdkExampleTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReactNativeNcwSdkExampleTests.swift; sourceTree = ""; }; 3B4392A12AC88292D35C810B /* Pods-ReactNativeNcwSdkExample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ReactNativeNcwSdkExample.debug.xcconfig"; path = "Target Support Files/Pods-ReactNativeNcwSdkExample/Pods-ReactNativeNcwSdkExample.debug.xcconfig"; sourceTree = ""; }; 5709B34CF0A7D63546082F79 /* Pods-ReactNativeNcwSdkExample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ReactNativeNcwSdkExample.release.xcconfig"; path = "Target Support Files/Pods-ReactNativeNcwSdkExample/Pods-ReactNativeNcwSdkExample.release.xcconfig"; sourceTree = ""; }; 5B7EB9410499542E8C5724F5 /* Pods-ReactNativeNcwSdkExample-ReactNativeNcwSdkExampleTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ReactNativeNcwSdkExample-ReactNativeNcwSdkExampleTests.debug.xcconfig"; path = "Target Support Files/Pods-ReactNativeNcwSdkExample-ReactNativeNcwSdkExampleTests/Pods-ReactNativeNcwSdkExample-ReactNativeNcwSdkExampleTests.debug.xcconfig"; sourceTree = ""; }; @@ -50,20 +51,20 @@ /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ - 00E356EB1AD99517003FC87E /* Frameworks */ = { + 13B07F8C1A680F5B00A75B9A /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 7699B88040F8A987B510C191 /* libPods-ReactNativeNcwSdkExample-ReactNativeNcwSdkExampleTests.a in Frameworks */, + 0C80B921A6F3F58F76C31292 /* libPods-ReactNativeNcwSdkExample.a in Frameworks */, + 39ACB3E62C43D47600B7B859 /* FireblocksSDK in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; - 13B07F8C1A680F5B00A75B9A /* Frameworks */ = { + 399C8E782C10A0B10060CF72 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 0C80B921A6F3F58F76C31292 /* libPods-ReactNativeNcwSdkExample.a in Frameworks */, - 292385A62BD19B6100BDE940 /* FireblocksSDK in Frameworks */, + 6168BB22004ADA806847E0C1 /* libPods-ReactNativeNcwSdkExample-ReactNativeNcwSdkExampleTests.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -111,6 +112,14 @@ name = Frameworks; sourceTree = ""; }; + 399C8E7C2C10A0B10060CF72 /* ReactNativeNcwSdkExampleTests */ = { + isa = PBXGroup; + children = ( + 399C8E7D2C10A0B10060CF72 /* ReactNativeNcwSdkExampleTests.swift */, + ); + path = ReactNativeNcwSdkExampleTests; + sourceTree = ""; + }; 832341AE1AAA6A7D00B99B32 /* Libraries */ = { isa = PBXGroup; children = ( @@ -124,6 +133,7 @@ 13B07FAE1A68108700A75B9A /* ReactNativeNcwSdkExample */, 832341AE1AAA6A7D00B99B32 /* Libraries */, 00E356EF1AD99517003FC87E /* ReactNativeNcwSdkExampleTests */, + 399C8E7C2C10A0B10060CF72 /* ReactNativeNcwSdkExampleTests */, 83CBBA001A601CBA00E9B192 /* Products */, 2D16E6871FA4F8E400B85C8A /* Frameworks */, BBD78D7AC51CEA395F1C20DB /* Pods */, @@ -137,7 +147,7 @@ isa = PBXGroup; children = ( 13B07F961A680F5B00A75B9A /* ReactNativeNcwSdkExample.app */, - 00E356EE1AD99517003FC87E /* ReactNativeNcwSdkExampleTests.xctest */, + 399C8E7B2C10A0B10060CF72 /* ReactNativeNcwSdkExampleTests.xctest */, ); name = Products; sourceTree = ""; @@ -156,27 +166,6 @@ /* End PBXGroup section */ /* Begin PBXNativeTarget section */ - 00E356ED1AD99517003FC87E /* ReactNativeNcwSdkExampleTests */ = { - isa = PBXNativeTarget; - buildConfigurationList = 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "ReactNativeNcwSdkExampleTests" */; - buildPhases = ( - A55EABD7B0C7F3A422A6CC61 /* [CP] Check Pods Manifest.lock */, - 00E356EA1AD99517003FC87E /* Sources */, - 00E356EB1AD99517003FC87E /* Frameworks */, - 00E356EC1AD99517003FC87E /* Resources */, - C59DA0FBD6956966B86A3779 /* [CP] Embed Pods Frameworks */, - F6A41C54EA430FDDC6A6ED99 /* [CP] Copy Pods Resources */, - ); - buildRules = ( - ); - dependencies = ( - 00E356F51AD99517003FC87E /* PBXTargetDependency */, - ); - name = ReactNativeNcwSdkExampleTests; - productName = ReactNativeNcwSdkExampleTests; - productReference = 00E356EE1AD99517003FC87E /* ReactNativeNcwSdkExampleTests.xctest */; - productType = "com.apple.product-type.bundle.unit-test"; - }; 13B07F861A680F5B00A75B9A /* ReactNativeNcwSdkExample */ = { isa = PBXNativeTarget; buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "ReactNativeNcwSdkExample" */; @@ -196,27 +185,49 @@ ); name = ReactNativeNcwSdkExample; packageProductDependencies = ( - 292385A52BD19B6100BDE940 /* FireblocksSDK */, + 39ACB3E52C43D47600B7B859 /* FireblocksSDK */, ); productName = ReactNativeNcwSdkExample; productReference = 13B07F961A680F5B00A75B9A /* ReactNativeNcwSdkExample.app */; productType = "com.apple.product-type.application"; }; + 399C8E7A2C10A0B10060CF72 /* ReactNativeNcwSdkExampleTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 399C8E832C10A0B10060CF72 /* Build configuration list for PBXNativeTarget "ReactNativeNcwSdkExampleTests" */; + buildPhases = ( + B1C70E1ED9CE65D666AE6C3E /* [CP] Check Pods Manifest.lock */, + 399C8E772C10A0B10060CF72 /* Sources */, + 399C8E782C10A0B10060CF72 /* Frameworks */, + 399C8E792C10A0B10060CF72 /* Resources */, + 5ED04ED7AEA51A6BACCC954D /* [CP] Embed Pods Frameworks */, + D9F41F911B6E71EEDE72AD6D /* [CP] Copy Pods Resources */, + ); + buildRules = ( + ); + dependencies = ( + 399C8E802C10A0B10060CF72 /* PBXTargetDependency */, + ); + name = ReactNativeNcwSdkExampleTests; + productName = ReactNativeNcwSdkExampleTests; + productReference = 399C8E7B2C10A0B10060CF72 /* ReactNativeNcwSdkExampleTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ 83CBB9F71A601CBA00E9B192 /* Project object */ = { isa = PBXProject; attributes = { + LastSwiftUpdateCheck = 1540; LastUpgradeCheck = 1210; TargetAttributes = { - 00E356ED1AD99517003FC87E = { - CreatedOnToolsVersion = 6.2; - TestTargetID = 13B07F861A680F5B00A75B9A; - }; 13B07F861A680F5B00A75B9A = { LastSwiftMigration = 1120; }; + 399C8E7A2C10A0B10060CF72 = { + CreatedOnToolsVersion = 15.4; + TestTargetID = 13B07F861A680F5B00A75B9A; + }; }; }; buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "ReactNativeNcwSdkExample" */; @@ -229,33 +240,33 @@ ); mainGroup = 83CBB9F61A601CBA00E9B192; packageReferences = ( - 292385A42BD19B6100BDE940 /* XCRemoteSwiftPackageReference "ncw-ios-sdk" */, + 39BD110A2C24198B0035EF26 /* XCRemoteSwiftPackageReference "ncw-ios-sdk" */, ); productRefGroup = 83CBBA001A601CBA00E9B192 /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( 13B07F861A680F5B00A75B9A /* ReactNativeNcwSdkExample */, - 00E356ED1AD99517003FC87E /* ReactNativeNcwSdkExampleTests */, + 399C8E7A2C10A0B10060CF72 /* ReactNativeNcwSdkExampleTests */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ - 00E356EC1AD99517003FC87E /* Resources */ = { + 13B07F8E1A680F5B00A75B9A /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */, + 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */, + 2923859A2BD18D1D00BDE940 /* GoogleService-Info.plist in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 13B07F8E1A680F5B00A75B9A /* Resources */ = { + 399C8E792C10A0B10060CF72 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */, - 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */, - 2923859A2BD18D1D00BDE940 /* GoogleService-Info.plist in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -295,7 +306,24 @@ shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ReactNativeNcwSdkExample/Pods-ReactNativeNcwSdkExample-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; - A55EABD7B0C7F3A422A6CC61 /* [CP] Check Pods Manifest.lock */ = { + 5ED04ED7AEA51A6BACCC954D /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-ReactNativeNcwSdkExample-ReactNativeNcwSdkExampleTests/Pods-ReactNativeNcwSdkExample-ReactNativeNcwSdkExampleTests-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-ReactNativeNcwSdkExample-ReactNativeNcwSdkExampleTests/Pods-ReactNativeNcwSdkExample-ReactNativeNcwSdkExampleTests-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ReactNativeNcwSdkExample-ReactNativeNcwSdkExampleTests/Pods-ReactNativeNcwSdkExample-ReactNativeNcwSdkExampleTests-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + B1C70E1ED9CE65D666AE6C3E /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -339,21 +367,21 @@ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - C59DA0FBD6956966B86A3779 /* [CP] Embed Pods Frameworks */ = { + D9F41F911B6E71EEDE72AD6D /* [CP] Copy Pods Resources */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-ReactNativeNcwSdkExample-ReactNativeNcwSdkExampleTests/Pods-ReactNativeNcwSdkExample-ReactNativeNcwSdkExampleTests-frameworks-${CONFIGURATION}-input-files.xcfilelist", + "${PODS_ROOT}/Target Support Files/Pods-ReactNativeNcwSdkExample-ReactNativeNcwSdkExampleTests/Pods-ReactNativeNcwSdkExample-ReactNativeNcwSdkExampleTests-resources-${CONFIGURATION}-input-files.xcfilelist", ); - name = "[CP] Embed Pods Frameworks"; + name = "[CP] Copy Pods Resources"; outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-ReactNativeNcwSdkExample-ReactNativeNcwSdkExampleTests/Pods-ReactNativeNcwSdkExample-ReactNativeNcwSdkExampleTests-frameworks-${CONFIGURATION}-output-files.xcfilelist", + "${PODS_ROOT}/Target Support Files/Pods-ReactNativeNcwSdkExample-ReactNativeNcwSdkExampleTests/Pods-ReactNativeNcwSdkExample-ReactNativeNcwSdkExampleTests-resources-${CONFIGURATION}-output-files.xcfilelist", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ReactNativeNcwSdkExample-ReactNativeNcwSdkExampleTests/Pods-ReactNativeNcwSdkExample-ReactNativeNcwSdkExampleTests-frameworks.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ReactNativeNcwSdkExample-ReactNativeNcwSdkExampleTests/Pods-ReactNativeNcwSdkExample-ReactNativeNcwSdkExampleTests-resources.sh\"\n"; showEnvVarsInLog = 0; }; DA9AB9D205C5E4152F4BBCE5 /* [CP-User] [RNFB] Core Configuration */ = { @@ -386,112 +414,47 @@ shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ReactNativeNcwSdkExample/Pods-ReactNativeNcwSdkExample-resources.sh\"\n"; showEnvVarsInLog = 0; }; - F6A41C54EA430FDDC6A6ED99 /* [CP] Copy Pods Resources */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-ReactNativeNcwSdkExample-ReactNativeNcwSdkExampleTests/Pods-ReactNativeNcwSdkExample-ReactNativeNcwSdkExampleTests-resources-${CONFIGURATION}-input-files.xcfilelist", - ); - name = "[CP] Copy Pods Resources"; - outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-ReactNativeNcwSdkExample-ReactNativeNcwSdkExampleTests/Pods-ReactNativeNcwSdkExample-ReactNativeNcwSdkExampleTests-resources-${CONFIGURATION}-output-files.xcfilelist", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ReactNativeNcwSdkExample-ReactNativeNcwSdkExampleTests/Pods-ReactNativeNcwSdkExample-ReactNativeNcwSdkExampleTests-resources.sh\"\n"; - showEnvVarsInLog = 0; - }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ - 00E356EA1AD99517003FC87E /* Sources */ = { + 13B07F871A680F5B00A75B9A /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 00E356F31AD99517003FC87E /* ReactNativeNcwSdkExampleTests.m in Sources */, + 13B07FBC1A68108700A75B9A /* AppDelegate.mm in Sources */, + 13B07FC11A68108700A75B9A /* main.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 13B07F871A680F5B00A75B9A /* Sources */ = { + 399C8E772C10A0B10060CF72 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 13B07FBC1A68108700A75B9A /* AppDelegate.mm in Sources */, - 13B07FC11A68108700A75B9A /* main.m in Sources */, + 399C8E7E2C10A0B10060CF72 /* ReactNativeNcwSdkExampleTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ - 00E356F51AD99517003FC87E /* PBXTargetDependency */ = { + 399C8E802C10A0B10060CF72 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 13B07F861A680F5B00A75B9A /* ReactNativeNcwSdkExample */; - targetProxy = 00E356F41AD99517003FC87E /* PBXContainerItemProxy */; + targetProxy = 399C8E7F2C10A0B10060CF72 /* PBXContainerItemProxy */; }; /* End PBXTargetDependency section */ /* Begin XCBuildConfiguration section */ - 00E356F61AD99517003FC87E /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 5B7EB9410499542E8C5724F5 /* Pods-ReactNativeNcwSdkExample-ReactNativeNcwSdkExampleTests.debug.xcconfig */; - buildSettings = { - BUNDLE_LOADER = "$(TEST_HOST)"; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - INFOPLIST_FILE = ReactNativeNcwSdkExampleTests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 13.4; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - "@loader_path/Frameworks", - ); - OTHER_LDFLAGS = ( - "-ObjC", - "-lc++", - "$(inherited)", - ); - PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)"; - PRODUCT_NAME = "$(TARGET_NAME)"; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/ReactNativeNcwSdkExample.app/ReactNativeNcwSdkExample"; - }; - name = Debug; - }; - 00E356F71AD99517003FC87E /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 89C6BE57DB24E9ADA2F236DE /* Pods-ReactNativeNcwSdkExample-ReactNativeNcwSdkExampleTests.release.xcconfig */; - buildSettings = { - BUNDLE_LOADER = "$(TEST_HOST)"; - COPY_PHASE_STRIP = NO; - INFOPLIST_FILE = ReactNativeNcwSdkExampleTests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 13.4; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - "@loader_path/Frameworks", - ); - OTHER_LDFLAGS = ( - "-ObjC", - "-lc++", - "$(inherited)", - ); - PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)"; - PRODUCT_NAME = "$(TARGET_NAME)"; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/ReactNativeNcwSdkExample.app/ReactNativeNcwSdkExample"; - }; - name = Release; - }; 13B07F941A680F5B00A75B9A /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = 3B4392A12AC88292D35C810B /* Pods-ReactNativeNcwSdkExample.debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; + CODE_SIGN_STYLE = Manual; CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = ""; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = 2HS962GC9R; ENABLE_BITCODE = NO; INFOPLIST_FILE = ReactNativeNcwSdkExample/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( @@ -504,8 +467,10 @@ "-ObjC", "-lc++", ); - PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)"; + PRODUCT_BUNDLE_IDENTIFIER = com.fireblocks.ncw.demo.reactNative; PRODUCT_NAME = ReactNativeNcwSdkExample; + PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "NCW ReactNative Demo"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; VERSIONING_SYSTEM = "apple-generic"; @@ -518,7 +483,10 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; + CODE_SIGN_STYLE = Manual; CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = ""; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = 2HS962GC9R; INFOPLIST_FILE = ReactNativeNcwSdkExample/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", @@ -530,13 +498,84 @@ "-ObjC", "-lc++", ); - PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)"; + PRODUCT_BUNDLE_IDENTIFIER = com.fireblocks.ncw.demo.reactNative; PRODUCT_NAME = ReactNativeNcwSdkExample; + PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "NCW ReactNative Demo"; SWIFT_VERSION = 5.0; VERSIONING_SYSTEM = "apple-generic"; }; name = Release; }; + 399C8E812C10A0B10060CF72 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 5B7EB9410499542E8C5724F5 /* Pods-ReactNativeNcwSdkExample-ReactNativeNcwSdkExampleTests.debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + BUNDLE_LOADER = "$(TEST_HOST)"; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + DEVELOPMENT_TEAM = 2HS962GC9R; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 17.5; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MARKETING_VERSION = 1.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = Fireblocks.ReactNativeNcwSdkExampleTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/ReactNativeNcwSdkExample.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/ReactNativeNcwSdkExample"; + }; + name = Debug; + }; + 399C8E822C10A0B10060CF72 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 89C6BE57DB24E9ADA2F236DE /* Pods-ReactNativeNcwSdkExample-ReactNativeNcwSdkExampleTests.release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + BUNDLE_LOADER = "$(TEST_HOST)"; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_STYLE = Automatic; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEVELOPMENT_TEAM = 2HS962GC9R; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 17.5; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MARKETING_VERSION = 1.0; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = Fireblocks.ReactNativeNcwSdkExampleTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/ReactNativeNcwSdkExample.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/ReactNativeNcwSdkExample"; + }; + name = Release; + }; 83CBBA201A601CBA00E9B192 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -606,7 +645,10 @@ "-DFOLLY_USE_LIBCPP=1", "-DFOLLY_CFG_NO_COROUTINES=1", ); - OTHER_LDFLAGS = "$(inherited) "; + OTHER_LDFLAGS = ( + "$(inherited)", + " ", + ); REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native"; SDKROOT = iphoneos; USE_HERMES = true; @@ -674,7 +716,10 @@ "-DFOLLY_USE_LIBCPP=1", "-DFOLLY_CFG_NO_COROUTINES=1", ); - OTHER_LDFLAGS = "$(inherited) "; + OTHER_LDFLAGS = ( + "$(inherited)", + " ", + ); REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native"; SDKROOT = iphoneos; USE_HERMES = true; @@ -685,20 +730,20 @@ /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ - 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "ReactNativeNcwSdkExampleTests" */ = { + 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "ReactNativeNcwSdkExample" */ = { isa = XCConfigurationList; buildConfigurations = ( - 00E356F61AD99517003FC87E /* Debug */, - 00E356F71AD99517003FC87E /* Release */, + 13B07F941A680F5B00A75B9A /* Debug */, + 13B07F951A680F5B00A75B9A /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "ReactNativeNcwSdkExample" */ = { + 399C8E832C10A0B10060CF72 /* Build configuration list for PBXNativeTarget "ReactNativeNcwSdkExampleTests" */ = { isa = XCConfigurationList; buildConfigurations = ( - 13B07F941A680F5B00A75B9A /* Debug */, - 13B07F951A680F5B00A75B9A /* Release */, + 399C8E812C10A0B10060CF72 /* Debug */, + 399C8E822C10A0B10060CF72 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -715,20 +760,20 @@ /* End XCConfigurationList section */ /* Begin XCRemoteSwiftPackageReference section */ - 292385A42BD19B6100BDE940 /* XCRemoteSwiftPackageReference "ncw-ios-sdk" */ = { + 39BD110A2C24198B0035EF26 /* XCRemoteSwiftPackageReference "ncw-ios-sdk" */ = { isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/fireblocks/ncw-ios-sdk"; requirement = { kind = upToNextMajorVersion; - minimumVersion = 2.4.0; + minimumVersion = 2.5.1; }; }; /* End XCRemoteSwiftPackageReference section */ /* Begin XCSwiftPackageProductDependency section */ - 292385A52BD19B6100BDE940 /* FireblocksSDK */ = { + 39ACB3E52C43D47600B7B859 /* FireblocksSDK */ = { isa = XCSwiftPackageProductDependency; - package = 292385A42BD19B6100BDE940 /* XCRemoteSwiftPackageReference "ncw-ios-sdk" */; + package = 39BD110A2C24198B0035EF26 /* XCRemoteSwiftPackageReference "ncw-ios-sdk" */; productName = FireblocksSDK; }; /* End XCSwiftPackageProductDependency section */ diff --git a/example/ios/ReactNativeNcwSdkExample/Info.plist b/example/ios/ReactNativeNcwSdkExample/Info.plist index 191ba0c..2b464cb 100644 --- a/example/ios/ReactNativeNcwSdkExample/Info.plist +++ b/example/ios/ReactNativeNcwSdkExample/Info.plist @@ -44,6 +44,10 @@ NSLocationWhenInUseUsageDescription + NSFileProviderPresenceUsageDescription + App needs File Provider +App needs File Provider + UILaunchStoryboardName LaunchScreen UIRequiredDeviceCapabilities diff --git a/example/ios/ReactNativeNcwSdkExampleTests/ReactNativeNcwSdkExampleTests.swift b/example/ios/ReactNativeNcwSdkExampleTests/ReactNativeNcwSdkExampleTests.swift new file mode 100644 index 0000000..b19aad1 --- /dev/null +++ b/example/ios/ReactNativeNcwSdkExampleTests/ReactNativeNcwSdkExampleTests.swift @@ -0,0 +1,35 @@ +// +// ReactNativeNcwSdkExampleTests.swift +// ReactNativeNcwSdkExampleTests +// +// Created by Valeria Haberman on 05/06/2024. +// + +import XCTest + +final class ReactNativeNcwSdkExampleTests: XCTestCase { + + override func setUpWithError() throws { + // Put setup code here. This method is called before the invocation of each test method in the class. + } + + override func tearDownWithError() throws { + // Put teardown code here. This method is called after the invocation of each test method in the class. + } + + func testExample() throws { + // This is an example of a functional test case. + // Use XCTAssert and related functions to verify your tests produce the correct results. + // Any test you write for XCTest can be annotated as throws and async. + // Mark your test throws to produce an unexpected failure when your test encounters an uncaught error. + // Mark your test async to allow awaiting for asynchronous code to complete. Check the results with assertions afterwards. + } + + func testPerformanceExample() throws { + // This is an example of a performance test case. + measure { + // Put the code you want to measure the time of here. + } + } + +} diff --git a/example/package.json b/example/package.json index 936ce66..6f14760 100644 --- a/example/package.json +++ b/example/package.json @@ -32,6 +32,7 @@ "react-qr-code": "^2.0.12", "rn-secure-storage": "^3.0.1", "socket.io-client": "^4.7.4", + "tsl-apple-cloudkit": "^0.2.31", "zustand": "^4.5.0" }, "devDependencies": { diff --git a/example/src/App.tsx b/example/src/App.tsx index d8ffb74..e09c7bf 100644 --- a/example/src/App.tsx +++ b/example/src/App.tsx @@ -1,14 +1,20 @@ -import React from "react"; +import React from 'react'; // import { useAppStore } from "./AppStore"; // import { Login } from "./auth/Login"; // import { AppContent } from "./components/AppContent"; // import { NavBar } from "./components/ui/NavBar"; -import { SafeAreaView, ScrollView, StatusBar, StyleSheet, useColorScheme } from "react-native"; -import { useAppStore } from "./AppStore"; -import { AppContent } from "./components/AppContent"; -import { Login } from "./auth/Login"; -import { AutocompleteDropdownContextProvider } from "react-native-autocomplete-dropdown"; -import { NavBar } from "./components/ui/NavBar"; +import { + SafeAreaView, + ScrollView, + StatusBar, + StyleSheet, + useColorScheme, +} from 'react-native'; +import { useAppStore } from './AppStore'; +import { AppContent } from './components/AppContent'; +import { Login } from './auth/Login'; +import { AutocompleteDropdownContextProvider } from 'react-native-autocomplete-dropdown'; +import { NavBar } from './components/ui/NavBar'; export function App(): React.JSX.Element { const isDarkMode = useColorScheme() === 'dark'; @@ -16,17 +22,16 @@ export function App(): React.JSX.Element { return ( - + - - {loggedUser ? - - - : - - } + + {loggedUser ? ( + + + + ) : ( + + )} ); diff --git a/example/src/AppStore.ts b/example/src/AppStore.ts index 385af62..f91c837 100644 --- a/example/src/AppStore.ts +++ b/example/src/AppStore.ts @@ -1,22 +1,67 @@ - -import { create } from "zustand"; -import type { IAppState, IPassphraseInfo, TPassphrases, TAppMode, INewTransactionData } from "./IAppState"; -import { generateDeviceId, getOrCreateDeviceId, storeDeviceId } from "./deviceId"; -import { ENV_CONFIG } from "./env_config"; -import { ApiService, type ITransactionData, type IWalletAsset, type TPassphraseLocation } from "./services/ApiService"; -import { PasswordEncryptedLocalStorage } from "./services/PasswordEncryptedLocalStorage"; -import type { IAuthManager } from "./auth/IAuthManager"; -import { FirebaseAuthManager } from "./auth/FirebaseAuthManager"; -import { decode, version } from "js-base64"; -import type { IEventsHandler, IFireblocksNCW, IJoinWalletEvent, IKeyBackupEvent, IKeyDescriptor, IKeyRecoveryEvent, IMessagesHandler } from "@fireblocks/react-native-ncw-sdk"; -import type { TEvent, TMPCAlgorithm, TEnv } from "@fireblocks/react-native-ncw-sdk"; -import { FireblocksNCWFactory } from "@fireblocks/react-native-ncw-sdk"; -import { ACCESSIBLE, ACCESS_CONTROL, type Options, getGenericPassword, setGenericPassword } from "react-native-keychain"; -import { randomPassPhrase } from "./services/randomPassPhrase"; - -export type TAsyncActionStatus = "not_started" | "started" | "success" | "failed"; -export type TFireblocksNCWStatus = "sdk_not_ready" | "initializing_sdk" | "sdk_available" | "sdk_initialization_failed"; -export type TRequestDecodedData = { email: string; requestId: string; platform: string }; +import { create } from 'zustand'; +import type { + IAppState, + IPassphraseInfo, + TPassphrases, + TAppMode, + INewTransactionData, + TAccount, +} from './IAppState'; +import { + generateDeviceId, + getOrCreateDeviceId, + storeDeviceId, +} from './deviceId'; +import { ENV_CONFIG } from './env_config'; +import { + ApiService, + type ITransactionData, + type IWalletAsset, + type TPassphraseLocation, +} from './services/ApiService'; +import { PasswordEncryptedLocalStorage } from './services/PasswordEncryptedLocalStorage'; +import type { IAuthManager } from './auth/IAuthManager'; +import { FirebaseAuthManager } from './auth/FirebaseAuthManager'; +import { decode, version } from 'js-base64'; +import type { + IEventsHandler, + IFireblocksNCW, + IJoinWalletEvent, + IKeyBackupEvent, + IKeyDescriptor, + IKeyRecoveryEvent, + IMessagesHandler, +} from '@fireblocks/react-native-ncw-sdk'; +import type { + TEvent, + TMPCAlgorithm, + TEnv, +} from '@fireblocks/react-native-ncw-sdk'; +import { FireblocksNCWFactory } from '@fireblocks/react-native-ncw-sdk'; +import { + ACCESSIBLE, + ACCESS_CONTROL, + type Options, + getGenericPassword, + setGenericPassword, +} from 'react-native-keychain'; +import { randomPassPhrase } from './services/randomPassPhrase'; + +export type TAsyncActionStatus = + | 'not_started' + | 'started' + | 'success' + | 'failed'; +export type TFireblocksNCWStatus = + | 'sdk_not_ready' + | 'initializing_sdk' + | 'sdk_available' + | 'sdk_initialization_failed'; +export type TRequestDecodedData = { + email: string; + requestId: string; + platform: string; +}; export const useAppStore = create()((set, get) => { let apiService: ApiService | null = null; @@ -27,14 +72,19 @@ export const useAppStore = create()((set, get) => { set({ loggedUser: user }); }); - const updateOrAddTx = (existingTxs: ITransactionData[], newTx: ITransactionData): ITransactionData[] => { + const updateOrAddTx = ( + existingTxs: ITransactionData[], + newTx: ITransactionData + ): ITransactionData[] => { const index = existingTxs.findIndex((tx) => tx.id === newTx.id); if (index === -1) { return [...existingTxs, newTx]; } const result = [...existingTxs]; result[index] = newTx; - return result.sort((t1, t2) => (t2.lastUpdated ?? 0) - (t1.lastUpdated ?? 0)); + return result.sort( + (t1, t2) => (t2.lastUpdated ?? 0) - (t1.lastUpdated ?? 0) + ); }; return { @@ -51,15 +101,15 @@ export const useAppStore = create()((set, get) => { txs: [], appStoreInitialized: false, deviceId: null, - loginToDemoAppServerStatus: "not_started", - assignDeviceStatus: "not_started", - joinWalletStatus: "not_started", - fireblocksNCWStatus: "sdk_not_ready", + loginToDemoAppServerStatus: 'not_started', + assignDeviceStatus: 'not_started', + joinWalletStatus: 'not_started', + fireblocksNCWStatus: 'sdk_not_ready', addDeviceRequestId: null, keysStatus: null, passphrase: null, passphrases: null, - regeneratePassphrase: () => { }, + regeneratePassphrase: () => {}, accounts: [], supportedAssets: {}, initAppStore: () => { @@ -81,7 +131,7 @@ export const useAppStore = create()((set, get) => { async getGoogleDriveCredentials(): Promise { return await authManager.getGoogleDriveCredentials(); }, - async login(provider: "GOOGLE" | "APPLE"): Promise { + async login(provider: 'GOOGLE' | 'APPLE'): Promise { await authManager.login(provider); set({ loggedUser: authManager.loggedUser, @@ -102,42 +152,50 @@ export const useAppStore = create()((set, get) => { web3Connections: [], txs: [], appStoreInitialized: false, - loginToDemoAppServerStatus: "not_started", - assignDeviceStatus: "not_started", - joinWalletStatus: "not_started", - fireblocksNCWStatus: "sdk_not_ready", + loginToDemoAppServerStatus: 'not_started', + assignDeviceStatus: 'not_started', + joinWalletStatus: 'not_started', + fireblocksNCWStatus: 'sdk_not_ready', keysStatus: null, accounts: [], supportedAssets: {}, }); }, assignCurrentDevice: async () => { - set((state) => ({ ...state, walletId: null, assignDeviceStatus: "started" })); + set((state) => ({ + ...state, + walletId: null, + assignDeviceStatus: 'started', + })); if (!apiService) { - throw new Error("apiService is not initialized"); + throw new Error('apiService is not initialized'); } const { deviceId } = get(); if (!deviceId) { - throw new Error("deviceId is not set"); + throw new Error('deviceId is not set'); } try { const walletId = await apiService.assignDevice(deviceId); - set((state) => ({ ...state, walletId, assignDeviceStatus: "success" })); + set((state) => ({ ...state, walletId, assignDeviceStatus: 'success' })); } catch (e) { - set((state) => ({ ...state, walletId: null, assignDeviceStatus: "failed" })); + set((state) => ({ + ...state, + walletId: null, + assignDeviceStatus: 'failed', + })); } }, askToJoinWalletExisting: async () => { - set((state) => ({ ...state, joinWalletStatus: "started" })); + set((state) => ({ ...state, joinWalletStatus: 'started' })); if (!apiService) { - throw new Error("apiService is not initialized"); + throw new Error('apiService is not initialized'); } const { walletId, deviceId } = get(); if (!walletId) { - throw new Error("walletId is not set"); + throw new Error('walletId is not set'); } if (!deviceId) { - throw new Error("deviceId is not set"); + throw new Error('deviceId is not set'); } try { @@ -146,8 +204,8 @@ export const useAppStore = create()((set, get) => { ...state, deviceId, walletId, - assignDeviceStatus: "success", - joinWalletStatus: "success", + assignDeviceStatus: 'success', + joinWalletStatus: 'success', joinExistingWalletMode: true, })); } catch (e) { @@ -155,27 +213,36 @@ export const useAppStore = create()((set, get) => { ...state, deviceId: null, walletId: null, - assignDeviceStatus: "failed", - joinWalletStatus: "failed", + assignDeviceStatus: 'failed', + joinWalletStatus: 'failed', })); } }, generateNewDeviceId: async () => { const { userId } = get(); if (!userId) { - throw new Error("First login to demo app server"); + throw new Error('First login to demo app server'); } const deviceId = generateDeviceId(); - set((state) => ({ ...state, deviceId, walletId: null, assignDeviceStatus: "not_started" })); + set((state) => ({ + ...state, + deviceId, + walletId: null, + assignDeviceStatus: 'not_started', + })); storeDeviceId(deviceId, userId); }, setAppMode: (appMode: TAppMode) => { - set((state) => ({ ...state, appMode, assignDeviceStatus: "not_started" })); + set((state) => ({ + ...state, + appMode, + assignDeviceStatus: 'not_started', + })); }, setDeviceId: (deviceId: string) => { const { userId } = get(); if (!userId) { - throw new Error("First login to demo app server"); + throw new Error('First login to demo app server'); } storeDeviceId(deviceId, userId); set((state) => ({ ...state, deviceId })); @@ -183,44 +250,48 @@ export const useAppStore = create()((set, get) => { setWalletId: (walletId: string) => { set((state) => ({ ...state, walletId })); }, - setPassphrase: (passphrase: string) => { + setPassphrase: (_passphrase: string) => { const { userId } = get(); if (!userId) { - throw new Error("First login to demo app server"); + throw new Error('First login to demo app server'); } }, getLatestBackup: async () => { if (!apiService) { - throw new Error("apiService is not initialized"); + throw new Error('apiService is not initialized'); } const { walletId } = get(); if (!walletId) { - throw new Error("No wallet set"); + throw new Error('No wallet set'); } const latestBackup = await apiService.getLatestBackup(walletId); set((state) => ({ ...state, latestBackup })); }, approveJoinWallet: async (requestData?: string) => { if (!fireblocksNCW) { - throw new Error("fireblocksNCW is not initialized"); + throw new Error('fireblocksNCW is not initialized'); } if (requestData) { try { - const decodedData: TRequestDecodedData = JSON.parse(decode(requestData)); - const result = await fireblocksNCW.approveJoinWalletRequest(decodedData.requestId); - console.log("approveJoinWallet result:", result); + const decodedData: TRequestDecodedData = JSON.parse( + decode(requestData) + ); + const result = await fireblocksNCW.approveJoinWalletRequest( + decodedData.requestId + ); + console.log('approveJoinWallet result:', result); } catch (e) { console.error(e); } // set((state) => ({ ...state, passphrase })); } else { - console.log("approveJoinWallet cancelled"); + console.log('approveJoinWallet cancelled'); } }, joinExistingWallet: async () => { if (!fireblocksNCW) { - throw new Error("fireblocksNCW is not initialized"); + throw new Error('fireblocksNCW is not initialized'); } await fireblocksNCW.requestJoinExistingWallet({ onRequestId(requestId: string) { @@ -230,13 +301,13 @@ export const useAppStore = create()((set, get) => { }, stopJoinExistingWallet: () => { if (!fireblocksNCW) { - throw new Error("fireblocksNCW is not initialized"); + throw new Error('fireblocksNCW is not initialized'); } fireblocksNCW.stopJoinWallet(); }, getPassphraseInfos: async () => { if (!apiService) { - throw new Error("apiService is not initialized"); + throw new Error('apiService is not initialized'); } const { passphrases } = await apiService.getPassphraseInfos(); const reduced = passphrases.reduce((p, v) => { @@ -245,68 +316,84 @@ export const useAppStore = create()((set, get) => { }, {}); set((state) => ({ ...state, passphrases: reduced })); }, - createPassphraseInfo: async (passphraseId: string, location: TPassphraseLocation) => { + createPassphraseInfo: async ( + passphraseId: string, + location: TPassphraseLocation + ) => { if (!apiService) { - throw new Error("apiService is not initialized"); + throw new Error('apiService is not initialized'); } await apiService.createPassphraseInfo(passphraseId, location); const passphraseInfo: IPassphraseInfo = { passphraseId, location }; - set((state) => ({ ...state, passphrases: { ...state.passphrases, [passphraseId]: passphraseInfo } })); + set((state) => ({ + ...state, + passphrases: { ...state.passphrases, [passphraseId]: passphraseInfo }, + })); }, backupKeys: async (passphrase: string, passphraseId: string) => { if (!fireblocksNCW) { - throw new Error("fireblocksNCW is not initialized"); + throw new Error('fireblocksNCW is not initialized'); } if (!passphrase) { - throw new Error("passphrase is not set"); + throw new Error('passphrase is not set'); } if (!passphraseId) { - throw new Error("passphraseId is not set"); + throw new Error('passphraseId is not set'); } await fireblocksNCW.backupKeys(passphrase, passphraseId); }, - recoverKeys: async (passphraseResolver: (passphraseId: string) => Promise) => { + recoverKeys: async ( + passphraseResolver: (passphraseId: string) => Promise + ) => { if (!fireblocksNCW) { - throw new Error("fireblocksNCW is not initialized"); + throw new Error('fireblocksNCW is not initialized'); } await fireblocksNCW.recoverKeys(passphraseResolver); const keysStatus = await fireblocksNCW.getKeysStatus(); set((state) => ({ ...state, keysStatus })); }, loginToDemoAppServer: async () => { - set((state) => ({ ...state, userId: null, loginToDemoAppServerStatus: "started" })); + set((state) => ({ + ...state, + userId: null, + loginToDemoAppServerStatus: 'started', + })); if (!apiService) { - throw new Error("apiService is not initialized"); + throw new Error('apiService is not initialized'); } try { const userId = await apiService.login(); set((state) => ({ ...state, userId, - loginToDemoAppServerStatus: "success", + loginToDemoAppServerStatus: 'success', deviceId: getOrCreateDeviceId(userId), })); } catch (e) { - console.error("xxx", e); - set((state) => ({ ...state, userId: null, loginToDemoAppServerStatus: "failed" })); + console.error('xxx', e); + set((state) => ({ + ...state, + userId: null, + loginToDemoAppServerStatus: 'failed', + })); } }, initFireblocksNCW: async () => { if (!apiService) { - throw new Error("apiService is not initialized"); + throw new Error('apiService is not initialized'); } fireblocksNCW = null; - set((state) => ({ ...state, fireblocksNCWStatus: "initializing_sdk" })); + set((state) => ({ ...state, fireblocksNCWStatus: 'initializing_sdk' })); try { const messagesHandler: IMessagesHandler = { handleOutgoingMessage: (message: string) => { if (!apiService) { - throw new Error("apiService is not initialized"); + throw new Error('apiService is not initialized'); } const { deviceId } = get(); if (!deviceId) { - throw new Error("deviceId is not set"); + throw new Error('deviceId is not set'); } return apiService.sendMessage(deviceId, message); }, @@ -315,27 +402,36 @@ export const useAppStore = create()((set, get) => { const eventsHandler: IEventsHandler = { handleEvent: (event: TEvent) => { switch (event.type) { - case "key_descriptor_changed": + case 'key_descriptor_changed': const keysStatus: Record = - get().keysStatus ?? ({} as Record); + get().keysStatus ?? + ({} as Record); keysStatus[event.keyDescriptor.algorithm] = event.keyDescriptor; set((state) => ({ ...state, keysStatus })); break; - case "transaction_signature_changed": - console.log(`Transaction signature status: ${event.transactionSignature.transactionSignatureStatus}`); + case 'transaction_signature_changed': + console.log( + `Transaction signature status: ${event.transactionSignature.transactionSignatureStatus}` + ); break; - case "keys_backup": - console.log(`Key backup status: ${JSON.stringify((event as IKeyBackupEvent).keysBackup)}`); + case 'keys_backup': + console.log( + `Key backup status: ${JSON.stringify((event as IKeyBackupEvent).keysBackup)}` + ); break; - case "keys_recovery": - console.log(`Key recover status: ${JSON.stringify((event as IKeyRecoveryEvent).keyDescriptor)}`); + case 'keys_recovery': + console.log( + `Key recover status: ${JSON.stringify((event as IKeyRecoveryEvent).keyDescriptor)}` + ); break; - case "join_wallet_descriptor": - console.log(`join wallet event: ${JSON.stringify((event as IJoinWalletEvent).joinWalletDescriptor)}`); + case 'join_wallet_descriptor': + console.log( + `join wallet event: ${JSON.stringify((event as IJoinWalletEvent).joinWalletDescriptor)}` + ); break; } }, @@ -343,7 +439,7 @@ export const useAppStore = create()((set, get) => { const { deviceId } = get(); if (!deviceId) { - throw new Error("deviceId is not set"); + throw new Error('deviceId is not set'); } const secureStorageProvider = new PasswordEncryptedLocalStorage( async () => { @@ -362,12 +458,13 @@ export const useAppStore = create()((set, get) => { } } - return Promise.reject(new Error("Rejected by user")); - }); + return Promise.reject(new Error('Rejected by user')); + } + ); fireblocksNCW = await FireblocksNCWFactory({ env: ENV_CONFIG.NCW_SDK_ENV as TEnv, - logLevel: "INFO", + logLevel: 'INFO', deviceId, messagesHandler, eventsHandler, @@ -375,25 +472,32 @@ export const useAppStore = create()((set, get) => { // logger: await IndexedDBLoggerFactory({ deviceId, logger: ConsoleLoggerFactory() }), }); - txsUnsubscriber = apiService.listenToTxs(deviceId, (tx: ITransactionData) => { - const txs = updateOrAddTx(get().txs, tx); - set((state) => ({ ...state, txs })); - }); + txsUnsubscriber = apiService.listenToTxs( + deviceId, + (tx: ITransactionData) => { + const txs = updateOrAddTx(get().txs, tx); + set((state) => ({ ...state, txs })); + } + ); const keysStatus = await fireblocksNCW.getKeysStatus(); - set((state) => ({ ...state, keysStatus, fireblocksNCWStatus: "sdk_available" })); + set((state) => ({ + ...state, + keysStatus, + fireblocksNCWStatus: 'sdk_available', + })); } catch (e) { console.error(e); fireblocksNCW = null; set((state) => ({ ...state, keysStatus: null, - fireblocksNCWStatus: "sdk_initialization_failed", + fireblocksNCWStatus: 'sdk_initialization_failed', })); } }, clearSDKStorage: async () => { if (!fireblocksNCW) { - throw new Error("fireblocksNCW is not initialized"); + throw new Error('fireblocksNCW is not initialized'); } await fireblocksNCW.clearAllStorage(); const keysStatus = await fireblocksNCW.getKeysStatus(); @@ -401,23 +505,26 @@ export const useAppStore = create()((set, get) => { }, createTransaction: async (dataToSend?: INewTransactionData) => { if (!apiService) { - throw new Error("apiService is not initialized"); + throw new Error('apiService is not initialized'); } const { deviceId } = get(); if (!deviceId) { - throw new Error("deviceId is not set"); + throw new Error('deviceId is not set'); } - const newTxData = await apiService.createTransaction(deviceId, dataToSend); + const newTxData = await apiService.createTransaction( + deviceId, + dataToSend + ); const txs = updateOrAddTx(get().txs, newTxData); set((state) => ({ ...state, txs })); }, cancelTransaction: async (txId: string) => { if (!apiService) { - throw new Error("apiService is not initialized"); + throw new Error('apiService is not initialized'); } const { deviceId } = get(); if (!deviceId) { - throw new Error("deviceId is not set"); + throw new Error('deviceId is not set'); } await apiService.cancelTransaction(deviceId, txId); set((state) => { @@ -429,7 +536,7 @@ export const useAppStore = create()((set, get) => { ...state, txs: [ ...state.txs.slice(0, index), - { ...state.txs[index], status: "CANCELLING" }, + { ...state.txs[index], status: 'CANCELLING', id: txId }, //TODO: check this ...state.txs.slice(index + 1), ], }; @@ -437,11 +544,11 @@ export const useAppStore = create()((set, get) => { }, signTransaction: async (txId: string) => { if (!apiService) { - throw new Error("apiService is not initialized"); + throw new Error('apiService is not initialized'); } - const { signTransaction } = get(); + // const { signTransaction } = get(); if (!fireblocksNCW) { - throw new Error("fireblocksNCW is not initialized"); + throw new Error('fireblocksNCW is not initialized'); } try { @@ -461,100 +568,131 @@ export const useAppStore = create()((set, get) => { }, getWeb3Connections: async () => { if (!apiService) { - throw new Error("apiService is not initialized"); + throw new Error('apiService is not initialized'); } const { deviceId } = get(); if (!deviceId) { - throw new Error("deviceId is not set"); + throw new Error('deviceId is not set'); } const connections = await apiService.getWeb3Connections(deviceId); set((state) => ({ ...state, web3Connections: connections })); }, createWeb3Connection: async (uri: string) => { if (!apiService) { - throw new Error("apiService is not initialized"); + throw new Error('apiService is not initialized'); } const { deviceId } = get(); if (!deviceId) { - throw new Error("deviceId is not set"); + throw new Error('deviceId is not set'); } const response = await apiService.createWeb3Connection(deviceId, uri); set((state) => ({ ...state, pendingWeb3Connection: response })); }, approveWeb3Connection: async () => { if (!apiService) { - throw new Error("apiService is not initialized"); + throw new Error('apiService is not initialized'); } const { deviceId, pendingWeb3Connection } = get(); if (!pendingWeb3Connection) { - throw new Error("no pending connection"); + throw new Error('no pending connection'); } if (!deviceId) { - throw new Error("deviceId is not set"); + throw new Error('deviceId is not set'); } - await apiService.approveWeb3Connection(deviceId, pendingWeb3Connection.id); + await apiService.approveWeb3Connection( + deviceId, + pendingWeb3Connection.id + ); set((state) => ({ ...state, pendingWeb3Connection: null })); }, denyWeb3Connection: async () => { if (!apiService) { - throw new Error("apiService is not initialized"); + throw new Error('apiService is not initialized'); } const { deviceId, pendingWeb3Connection } = get(); if (!pendingWeb3Connection) { - throw new Error("no pending connection"); + throw new Error('no pending connection'); } if (!deviceId) { - throw new Error("deviceId is not set"); + throw new Error('deviceId is not set'); } await apiService.denyWeb3Connection(deviceId, pendingWeb3Connection.id); set((state) => ({ ...state, pendingWeb3Connection: null })); }, removeWeb3Connection: async (sessionId: string) => { if (!apiService) { - throw new Error("apiService is not initialized"); + throw new Error('apiService is not initialized'); } const { deviceId } = get(); if (!deviceId) { - throw new Error("deviceId is not set"); + throw new Error('deviceId is not set'); } await apiService.removeWeb3Connection(deviceId, sessionId); - set((state) => ({ ...state, web3Connections: state.web3Connections.filter((s) => s.id !== sessionId) })); + set((state) => ({ + ...state, + web3Connections: state.web3Connections.filter( + (s) => s.id !== sessionId + ), + })); }, - generateMPCKeys: async () => { + generateMPCKeys: async (algorithms: Set) => { if (!fireblocksNCW) { - throw new Error("fireblocksNCW is not initialized"); + throw new Error('fireblocksNCW is not initialized'); } // TODO: consolidate - // const ALGORITHMS = new Set(["MPC_CMP_ECDSA_SECP256K1"]); - const ALGORITHMS = new Set(["MPC_ECDSA_SECP256K1"]); - await fireblocksNCW.generateMPCKeys(ALGORITHMS); + + if (algorithms) { + await fireblocksNCW.generateMPCKeys(algorithms); + } else { + const ALGORITHMS = new Set([ + 'MPC_ECDSA_SECP256K1', + 'MPC_EDDSA_ED25519', + ]); + + await fireblocksNCW.generateMPCKeys(ALGORITHMS); + } }, stopMpcDeviceSetup: async () => { if (!fireblocksNCW) { - throw new Error("fireblocksNCW is not initialized"); + throw new Error('fireblocksNCW is not initialized'); } await fireblocksNCW.stopMpcDeviceSetup(); }, takeover: async () => { if (!fireblocksNCW) { - throw new Error("fireblocksNCW is not initialized"); + throw new Error('fireblocksNCW is not initialized'); } return fireblocksNCW.takeover(); }, - exportFullKeys: (chainCode: string, cloudKeyShares: Map) => { + exportFullKeys: ( + chainCode: string, + cloudKeyShares: Map + ) => { if (!fireblocksNCW) { - throw new Error("fireblocksNCW is not initialized"); + throw new Error('fireblocksNCW is not initialized'); } return fireblocksNCW.exportFullKeys(chainCode, cloudKeyShares); }, - deriveAssetKey: (extendedPrivateKey: string, coinType: number, account: number, change: number, index: number) => { + deriveAssetKey: ( + extendedPrivateKey: string, + coinType: number, + account: number, + change: number, + index: number + ) => { if (!fireblocksNCW) { - throw new Error("fireblocksNCW is not initialized"); + throw new Error('fireblocksNCW is not initialized'); } - return fireblocksNCW.deriveAssetKey(extendedPrivateKey, coinType, account, change, index); + return fireblocksNCW.deriveAssetKey( + extendedPrivateKey, + coinType, + account, + change, + index + ); }, disposeFireblocksNCW: () => { if (!fireblocksNCW) { @@ -568,84 +706,100 @@ export const useAppStore = create()((set, get) => { fireblocksNCW.dispose(); fireblocksNCW = null; - set((state) => ({ ...state, fireblocksNCWStatus: "sdk_not_ready" })); + set((state) => ({ ...state, fireblocksNCWStatus: 'sdk_not_ready' })); }, addAsset: async (accountId: number, assetId: string) => { if (!apiService) { - throw new Error("apiService is not initialized"); + throw new Error('apiService is not initialized'); } const { deviceId } = get(); if (!deviceId) { - throw new Error("deviceId is not set"); + throw new Error('deviceId is not set'); } const address = await apiService.addAsset(deviceId, accountId, assetId); const asset = await apiService.getAsset(deviceId, accountId, assetId); set((state) => ({ ...state, accounts: state.accounts.map((assets, index) => - index === accountId ? { ...assets, ...{ [assetId]: { asset, address } } } : assets, + index === accountId + ? { ...assets, ...{ [assetId]: { asset, address } } } + : assets ), })); }, refreshAccounts: async () => { if (!apiService) { - throw new Error("apiService is not initialized"); + throw new Error('apiService is not initialized'); } const { deviceId } = get(); if (!deviceId) { - throw new Error("deviceId is not set"); + throw new Error('deviceId is not set'); } const allAccounts = await apiService.getAccounts(deviceId); set((state) => ({ ...state, - accounts: Array.from({ length: allAccounts.length }, (_v, i) => ({ ...state.accounts[i] })), + accounts: Array.from({ length: allAccounts.length }, (_v, i) => ({ + ...state.accounts[i], + })), })); // refresh all const { refreshAssets, refreshAddress, refreshBalance } = get(); await Promise.all(get().accounts.map((_v, id) => refreshAssets(id))); await Promise.all([ - ...get().accounts.flatMap((v, id) => Object.keys(v).map((assetId) => refreshAddress(id, assetId))), - ...get().accounts.flatMap((v, id) => Object.keys(v).map((assetId) => refreshBalance(id, assetId))), + ...get().accounts.flatMap((v, id) => + Object.keys(v).map((assetId) => refreshAddress(id, assetId)) + ), + ...get().accounts.flatMap((v, id) => + Object.keys(v).map((assetId) => refreshBalance(id, assetId)) + ), ]); }, refreshAssets: async (accountId: number) => { if (!apiService) { - throw new Error("apiService is not initialized"); + throw new Error('apiService is not initialized'); } const { deviceId } = get(); if (!deviceId) { - throw new Error("deviceId is not set"); + throw new Error('deviceId is not set'); } const assets = await apiService.getAssets(deviceId, accountId); - const reduced = assets.reduce>((acc, asset) => { - acc[asset.id] = { asset }; - return acc; - }, {}); + const reduced = assets.reduce>( + (acc, asset) => { + acc[asset.id] = { asset }; + return acc; + }, + {} + ); set((state) => ({ ...state, - accounts: state.accounts.map((v, i) => (i === accountId ? { ...reduced, ...v } : v)), + accounts: state.accounts.map((v, i) => + i === accountId ? { ...reduced, ...v } : v + ), })); }, refreshSupportedAssets: async (accountId: number) => { if (!apiService) { - throw new Error("apiService is not initialized"); + throw new Error('apiService is not initialized'); } const { deviceId } = get(); if (!deviceId) { - throw new Error("deviceId is not set"); + throw new Error('deviceId is not set'); } const assets = await apiService.getSupportedAssets(deviceId, accountId); - const reduced = assets.reduce>((acc, asset) => { - acc[asset.id] = asset; - return acc; - }, {}); + const reduced = assets.reduce>( + (acc, asset) => { + acc[asset.id] = asset; + return acc; + }, + {} + ); set((state) => ({ ...state, @@ -658,36 +812,46 @@ export const useAppStore = create()((set, get) => { refreshBalance: async (accountId: number, assetId: string) => { if (!apiService) { - throw new Error("apiService is not initialized"); + throw new Error('apiService is not initialized'); } const { deviceId } = get(); if (!deviceId) { - throw new Error("deviceId is not set"); + throw new Error('deviceId is not set'); } const balance = await apiService.getBalance(deviceId, accountId, assetId); set((state) => ({ ...state, accounts: state.accounts.map((v, i) => - i === accountId ? { ...v, ...{ [assetId]: { ...v[assetId], balance } } } : v, + i === accountId + ? { + ...v, + ...({ [assetId]: { ...v[assetId], balance } } as TAccount), + } + : v ), })); }, refreshAddress: async (accountId: number, assetId: string) => { if (!apiService) { - throw new Error("apiService is not initialized"); + throw new Error('apiService is not initialized'); } const { deviceId } = get(); if (!deviceId) { - throw new Error("deviceId is not set"); + throw new Error('deviceId is not set'); } const address = await apiService.getAddress(deviceId, accountId, assetId); set((state) => ({ ...state, accounts: state.accounts.map((v, i) => - i === accountId ? { ...v, ...{ [assetId]: { ...v[assetId], address } } } : v, + i === accountId + ? ({ + ...v, + ...{ [assetId]: { ...v[assetId], address } }, + } as TAccount) + : v ), })); }, diff --git a/example/src/IAppState.ts b/example/src/IAppState.ts index 8cd4749..fe3d51a 100644 --- a/example/src/IAppState.ts +++ b/example/src/IAppState.ts @@ -1,5 +1,5 @@ -import { TAsyncActionStatus, TFireblocksNCWStatus } from "./AppStore"; -import { +import type { TAsyncActionStatus, TFireblocksNCWStatus } from './AppStore'; +import type { IAssetAddress, IAssetBalance, ICreateWeb3ConnectionResponse, @@ -7,10 +7,14 @@ import { IWalletAsset, IWeb3Session, TPassphraseLocation, -} from "./services/ApiService"; -import { IUser } from "./auth/IAuthManager"; +} from './services/ApiService'; +import type { IUser } from './auth/IAuthManager'; -import type { TMPCAlgorithm, IFullKey, IKeyDescriptor } from "@fireblocks/react-native-ncw-sdk"; +import type { + TMPCAlgorithm, + IFullKey, + IKeyDescriptor, +} from '@fireblocks/react-native-ncw-sdk'; export interface IAssetInfo { asset: IWalletAsset; @@ -23,9 +27,9 @@ export interface IPassphraseInfo { location: TPassphraseLocation; } -type TAccount = Record; -type TSupportedAssets = Record; -export type TAppMode = "SIGN_IN" | "JOIN" | null; +export type TAccount = Record; +export type TSupportedAssets = Record; +export type TAppMode = 'SIGN_IN' | 'JOIN' | null; export type TPassphrases = Record; export interface IBackupInfo { @@ -40,7 +44,7 @@ export interface INewTransactionData { assetId: string; amount?: string; destAddress?: string; - feeLevel?: "LOW" | "MEDIUM" | "HIGH"; + feeLevel?: 'LOW' | 'MEDIUM' | 'HIGH'; estimateFee?: boolean; } @@ -71,7 +75,7 @@ export interface IAppState { initAppStore: () => void; disposeAppStore: () => void; getGoogleDriveCredentials: () => Promise; - login(provider: "GOOGLE" | "APPLE"): Promise; + login(provider: 'GOOGLE' | 'APPLE'): Promise; setAppMode: (mode: TAppMode) => void; logout: () => Promise; clearSDKStorage: () => Promise; @@ -81,19 +85,22 @@ export interface IAppState { assignCurrentDevice: () => Promise; askToJoinWalletExisting: () => Promise; generateNewDeviceId: () => Promise; - generateMPCKeys: () => Promise; + generateMPCKeys: (algorithms: Set) => Promise; stopMpcDeviceSetup: () => Promise; createTransaction: (dataToSend?: INewTransactionData) => Promise; cancelTransaction: (txId: string) => Promise; signTransaction: (txId: string) => Promise; takeover: () => Promise; - exportFullKeys: (chainCode: string, cloudKeyShares: Map) => Promise; + exportFullKeys: ( + chainCode: string, + cloudKeyShares: Map + ) => Promise; deriveAssetKey: ( extendedPrivateKey: string, coinType: number, account: number, change: number, - index: number, + index: number ) => string; setPassphrase: (passphrase: string) => void; approveJoinWallet: (requestData?: string) => Promise; @@ -102,8 +109,13 @@ export interface IAppState { regeneratePassphrase: () => void; getPassphraseInfos: () => Promise; getLatestBackup: () => Promise; - createPassphraseInfo: (passphraseId: string, location: TPassphraseLocation) => Promise; - recoverKeys: (passphraseResolver: (passphraseId: string) => Promise) => Promise; + createPassphraseInfo: ( + passphraseId: string, + location: TPassphraseLocation + ) => Promise; + recoverKeys: ( + passphraseResolver: (passphraseId: string) => Promise + ) => Promise; backupKeys: (passhrase: string, passphraseId: string) => Promise; initFireblocksNCW: () => Promise; disposeFireblocksNCW: () => void; diff --git a/example/src/auth/FirebaseAuthManager.ts b/example/src/auth/FirebaseAuthManager.ts index 2b1a6a0..939862f 100644 --- a/example/src/auth/FirebaseAuthManager.ts +++ b/example/src/auth/FirebaseAuthManager.ts @@ -1,6 +1,10 @@ -import auth, { FirebaseAuthTypes } from "@react-native-firebase/auth"; -import { IAuthManager, IUser } from "./IAuthManager"; -import { getGoogleDriveCredentials, onGoogleButtonPress, onGoogleSignout } from "./GoogleSignIn"; +import auth, { FirebaseAuthTypes } from '@react-native-firebase/auth'; +import type { IAuthManager, IUser } from './IAuthManager'; +import { + getGoogleDriveCredentials, + onGoogleButtonPress, + onGoogleSignout, +} from './GoogleSignIn'; export class FirebaseAuthManager implements IAuthManager { private _loggedUser: FirebaseAuthTypes.User | null = null; @@ -16,17 +20,17 @@ export class FirebaseAuthManager implements IAuthManager { return getGoogleDriveCredentials(); } - public async login(provider: "GOOGLE" | "APPLE"): Promise { + public async login(provider: 'GOOGLE' | 'APPLE'): Promise { // let authProvider: AuthProvider; switch (provider) { - case "GOOGLE": + case 'GOOGLE': await onGoogleButtonPress(); break; - case "APPLE": + case 'APPLE': // TODO: @invertase/react-native-apple-authentication - // break; + break; default: - throw new Error("Unsupported provider"); + throw new Error('Unsupported provider'); } // const unsubscribe = this._auth.onAuthStateChanged((user) => { @@ -45,7 +49,7 @@ export class FirebaseAuthManager implements IAuthManager { public getAccessToken(): Promise { if (!this._loggedUser) { - throw new Error("User is not logged in"); + throw new Error('User is not logged in'); } return this._loggedUser.getIdToken(); diff --git a/example/src/auth/GoogleSignIn.tsx b/example/src/auth/GoogleSignIn.tsx index ef0b514..7b419ff 100644 --- a/example/src/auth/GoogleSignIn.tsx +++ b/example/src/auth/GoogleSignIn.tsx @@ -1,30 +1,35 @@ -import { Button } from "react-native" +import { Button } from 'react-native'; import { GoogleSignin } from '@react-native-google-signin/google-signin'; import auth from '@react-native-firebase/auth'; +import React from 'react'; -const DRIVE_APPDATA = "https://www.googleapis.com/auth/drive.appdata"; +const DRIVE_APPDATA = 'https://www.googleapis.com/auth/drive.appdata'; GoogleSignin.configure({ - webClientId: '127498444203-cpgvmmrd4mu697kgtkjvi4ef0tn01gha.apps.googleusercontent.com', // client ID of type WEB for your server. Required to get the `idToken` on the user object, and for offline access. + webClientId: + '127498444203-cpgvmmrd4mu697kgtkjvi4ef0tn01gha.apps.googleusercontent.com', // client ID of type WEB for your server. Required to get the `idToken` on the user object, and for offline access. // scopes: [DRIVE_APPDATA], // what API you want to access on behalf of the user, default is email and profile // offlineAccess: true, // if you want to access Google API on behalf of the user FROM YOUR SERVER // hostedDomain: '', // specifies a hosted domain restriction // forceCodeForRefreshToken: true, // [Android] related to `serverAuthCode`, read the docs link below *. // accountName: '', // [Android] specifies an account name on the device that should be used - iosClientId: '127498444203-ovplbl75l57llur20n12lai8gij50594.apps.googleusercontent.com', // [iOS] if you want to specify the client ID of type iOS (otherwise, it is taken from GoogleService-Info.plist) + iosClientId: + '127498444203-ovplbl75l57llur20n12lai8gij50594.apps.googleusercontent.com', // [iOS] if you want to specify the client ID of type iOS (otherwise, it is taken from GoogleService-Info.plist) // googleServicePlistPath: '', // [iOS] if you renamed your GoogleService-Info file, new name here, e.g. GoogleService-Info-Staging // openIdRealm: '', // [iOS] The OpenID2 realm of the home web server. This allows Google to include the user's OpenID Identifier in the OpenID Connect ID token. // profileImageSize: 120, // [iOS] The desired height (and width) of the profile image. Defaults to 120px }); export function GoogleSignIn() { - return ( - + - @@ -94,7 +101,7 @@ export const Web3: React.FC = () => { Description Url Icon - + diff --git a/example/src/components/Web3ConnectionRow.tsx b/example/src/components/Web3ConnectionRow.tsx index e58f497..f3894f1 100644 --- a/example/src/components/Web3ConnectionRow.tsx +++ b/example/src/components/Web3ConnectionRow.tsx @@ -1,6 +1,6 @@ -import React from "react"; -import { useAppStore } from "../AppStore"; -import { IWeb3Session } from "../services/ApiService"; +import React from 'react'; +import { useAppStore } from '../AppStore'; +import type { IWeb3Session } from '../services/ApiService'; interface IProps { session: IWeb3Session; @@ -41,7 +41,11 @@ export const Web3ConnectionRow: React.FC = ({ session }) => { {appUrl} {appIcon && } - diff --git a/example/src/components/ui/ActionButton.tsx b/example/src/components/ui/ActionButton.tsx index 38d8be1..e95cd29 100644 --- a/example/src/components/ui/ActionButton.tsx +++ b/example/src/components/ui/ActionButton.tsx @@ -1,10 +1,10 @@ -import React from "react"; +import React from 'react'; export interface IActionButtonProps { action?: () => void; isDisabled?: boolean; isInProgress?: boolean; - buttonVariant?: "primary" | "accent"; + buttonVariant?: 'primary' | 'accent'; label: string; } @@ -12,10 +12,11 @@ export const ActionButton: React.FC = ({ action, isDisabled = false, isInProgress = false, - buttonVariant = "primary", + buttonVariant = 'primary', label, }) => { - const buttonClassName = buttonVariant === "primary" ? "btn btn-primary" : "btn btn-accent"; + const buttonClassName = + buttonVariant === 'primary' ? 'btn btn-primary' : 'btn btn-accent'; return (

{title}

diff --git a/example/src/components/ui/ArrayOfBytes.tsx b/example/src/components/ui/ArrayOfBytes.tsx index 0908225..6dc16e9 100644 --- a/example/src/components/ui/ArrayOfBytes.tsx +++ b/example/src/components/ui/ArrayOfBytes.tsx @@ -1,4 +1,4 @@ -import React from "react"; +import React from 'react'; export const ArrayOfBytes: React.FC<{ arr: string }> = ({ arr }) => { const items = arr.toUpperCase(); diff --git a/example/src/components/ui/Autocomplete.tsx b/example/src/components/ui/Autocomplete.tsx index 00d3d5e..feafb34 100644 --- a/example/src/components/ui/Autocomplete.tsx +++ b/example/src/components/ui/Autocomplete.tsx @@ -1,5 +1,6 @@ -import classNames from "classnames"; -import { memo, useRef, useState } from "react"; +// import classNames from 'classnames'; +// import React from 'react'; +// import { memo, useRef, useState } from 'react'; export interface IAutoCompleteItem { id: string; @@ -8,68 +9,69 @@ export interface IAutoCompleteItem { balance?: string; } -type Props = { - items: IAutoCompleteItem[]; - value: string; - onChange(val: string): void; - disabled?: boolean; - placeholder?: string; -}; +// type Props = { +// items: IAutoCompleteItem[]; +// value: string; +// onChange(val: string): void; +// disabled?: boolean; +// placeholder?: string; +// }; //we are using dropdown, input and menu component from daisyui -export const Autocomplete = memo((props: Props) => { - const { items, value, onChange, disabled, placeholder } = props; - const ref = useRef(null); - const [open, setOpen] = useState(false); +// export const Autocomplete = memo((props: Props) => { +// const { items, value, onChange, disabled, placeholder } = props; +// const ref = useRef(null); +// const [open, setOpen] = useState(false); - const regex = RegExp(value, "gi"); +// const regex = RegExp(value, 'gi'); - return ( -
- onChange(e.target.value)} - placeholder={placeholder ?? "Type something..."} - tabIndex={0} - /> -
-
    - {items - .filter((item) => regex.test(item.name) || regex.test(item.id)) - .map((item, index) => { - return ( -
  • { - onChange(item.id); - setOpen(false); - }} - className="border-b border-b-base-content/10 w-full" - > - -
  • - ); - })} -
-
-
- ); -}); +// return ( +//
+// onChange(e.target.value)} +// placeholder={placeholder ?? 'Type something...'} +// tabIndex={0} +// /> +//
+//
    +// {items +// .filter((item) => regex.test(item.name) || regex.test(item.id)) +// .map((item, index) => { +// return ( +//
  • { +// onChange(item.id); +// setOpen(false); +// }} +// className="border-b border-b-base-content/10 w-full" +// > +// +//
  • +// ); +// })} +//
+//
+//
+// ); +// }); diff --git a/example/src/components/ui/Card.tsx b/example/src/components/ui/Card.tsx index 9b61417..4f9eee8 100644 --- a/example/src/components/ui/Card.tsx +++ b/example/src/components/ui/Card.tsx @@ -1,11 +1,11 @@ -import React from "react"; -import { Button, StyleSheet, Text, View } from "react-native"; +import React from 'react'; +import { Button, StyleSheet, Text, View } from 'react-native'; export interface ICardAction { action?: () => void; isDisabled?: boolean; isInProgress?: boolean; - buttonVariant?: "primary" | "accent"; + buttonVariant?: 'primary' | 'accent'; label: string; } @@ -18,15 +18,20 @@ interface IProps { const CardActionButton: React.FC = ({ action, isDisabled = false, - isInProgress = false, - buttonVariant = "primary", + // isInProgress = false, + // buttonVariant = 'primary', label, }) => { - const buttonClassName = buttonVariant === "primary" ? "btn btn-primary" : "btn btn-accent"; + // const buttonClassName = + // buttonVariant === 'primary' ? 'btn btn-primary' : 'btn btn-accent'; return ( - +