From 2817dee7d9b9a33ef51f9a7d87925d327fa91110 Mon Sep 17 00:00:00 2001 From: Kerry Washington Date: Wed, 18 Dec 2024 08:47:00 +0000 Subject: [PATCH] =?UTF-8?q?=E2=9A=A1=EF=B8=8F[Feature]=20Add=20remote=20co?= =?UTF-8?q?nfig=20[deconflicted]=20(#265)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Added the remote config components - Testing FB client - Confirmed Firebase registered for remote config - Checking all params Signed-off-by: kcw-grunt * Added tests Readd Remote Signed-off-by: kcw-grunt * updated gitignore Signed-off-by: kcw-grunt * update project version bump - Clean unused code - Readded test class Signed-off-by: kcw-grunt --------- Signed-off-by: kcw-grunt --- .gitignore | 2 + litewallet.xcodeproj/project.pbxproj | 50 +++++++++---- litewallet/AppDelegate.swift | 4 + litewallet/BRAPIClient+Wallet.swift | 5 +- litewallet/BuyView.swift | 2 +- litewallet/BuyWKWebViewController.swift | 2 +- litewallet/Constants/Constants+Events.swift | 14 +++- litewallet/Environment.swift | 1 + litewallet/RemoteConfigHelper.swift | 83 +++++++++++++++++++++ litewalletTests/APIManagerTests.swift | 24 ------ litewalletTests/APITests.swift | 43 +++++++++++ 11 files changed, 187 insertions(+), 43 deletions(-) create mode 100644 litewallet/RemoteConfigHelper.swift delete mode 100644 litewalletTests/APIManagerTests.swift create mode 100644 litewalletTests/APITests.swift diff --git a/.gitignore b/.gitignore index 28b294117..24ca1f81f 100644 --- a/.gitignore +++ b/.gitignore @@ -43,3 +43,5 @@ litewallet-partner-api-ios partner-keys.plist GoogleService-Info.plist *.gpx +litewallet/remote-config-defaults.plist +remote-config-defaults.plist diff --git a/litewallet.xcodeproj/project.pbxproj b/litewallet.xcodeproj/project.pbxproj index 577b14aff..4198fee9f 100644 --- a/litewallet.xcodeproj/project.pbxproj +++ b/litewallet.xcodeproj/project.pbxproj @@ -58,7 +58,6 @@ 24313CA523824F5800A83F69 /* Buy.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 24313C9823824F5800A83F69 /* Buy.storyboard */; }; 24313CAA23824F9800A83F69 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 24313CA823824F9800A83F69 /* Main.storyboard */; }; 24393B5C23C259400075218D /* Phrase.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 24393B5B23C259400075218D /* Phrase.storyboard */; }; - 24470E2123A5DA9700ADDA27 /* APIManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24470E2023A5DA9700ADDA27 /* APIManagerTests.swift */; }; 24470E2323A5DB7D00ADDA27 /* WalletManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24470E2223A5DB7D00ADDA27 /* WalletManagerTests.swift */; }; 24470E2A23A5F33000ADDA27 /* BRReplicatedKVStoreTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24470E2923A5F33000ADDA27 /* BRReplicatedKVStoreTests.swift */; }; 24470E2C23A5F43B00ADDA27 /* DefaultFiatCurrencyTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24470E2B23A5F43B00ADDA27 /* DefaultFiatCurrencyTests.swift */; }; @@ -240,7 +239,6 @@ C30029EB25D019BC00F08C2B /* CopyButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C30029EA25D019BC00F08C2B /* CopyButtonView.swift */; }; C3019EE32B8FEFED00FAF648 /* AssociatedObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3019EE22B8FEFED00FAF648 /* AssociatedObject.swift */; }; C30808A52D0A23530063E793 /* AppsFlyerLib-Static in Frameworks */ = {isa = PBXBuildFile; productRef = C30808A42D0A23530063E793 /* AppsFlyerLib-Static */; }; - C30808A72D0B70160063E793 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = C30808A62D0B70160063E793 /* GoogleService-Info.plist */; }; C316CF49261887FC00E4C09B /* UIApplication+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = C316CF48261887FC00E4C09B /* UIApplication+Extension.swift */; }; C31891C326733FD400ECE25C /* TabBarViewControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C31891C226733FD400ECE25C /* TabBarViewControllerTests.swift */; }; C32142EA25C97CD900BECCD0 /* TransactionCellView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C32142E925C97CD900BECCD0 /* TransactionCellView.swift */; }; @@ -274,6 +272,12 @@ C3423C4A2B796D820051BD6D /* It.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = C3423C3C2B796D820051BD6D /* It.mp3 */; settings = {ASSET_TAGS = (speakTag, ); }; }; C3423C4B2B796D820051BD6D /* Ru.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = C3423C3D2B796D820051BD6D /* Ru.mp3 */; settings = {ASSET_TAGS = (speakTag, ); }; }; C350788C27DCB10700A50819 /* TextView+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = C350788B27DCB10700A50819 /* TextView+Extension.swift */; }; + C353582B2D11D9B500395C45 /* RemoteConfigHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = C353582A2D11D9B500395C45 /* RemoteConfigHelper.swift */; }; + C353582D2D11DA4900395C45 /* FirebaseRemoteConfig in Frameworks */ = {isa = PBXBuildFile; productRef = C353582C2D11DA4900395C45 /* FirebaseRemoteConfig */; }; + C353582F2D11DA4900395C45 /* FirebaseRemoteConfigSwift in Frameworks */ = {isa = PBXBuildFile; productRef = C353582E2D11DA4900395C45 /* FirebaseRemoteConfigSwift */; }; + C35358332D11E7D100395C45 /* APITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C35358322D11E7D100395C45 /* APITests.swift */; }; + C35358372D11EB0600395C45 /* remote-config-defaults.plist in Resources */ = {isa = PBXBuildFile; fileRef = C35358362D11EB0600395C45 /* remote-config-defaults.plist */; settings = {ASSET_TAGS = ("initial-resources", ); }; }; + C35358392D11EB2F00395C45 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = C35358382D11EB2F00395C45 /* GoogleService-Info.plist */; settings = {ASSET_TAGS = ("initial-resources", ); }; }; C3543A27264AFE490005D17A /* LocaleChangeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3543A26264AFE490005D17A /* LocaleChangeView.swift */; }; C3543A29264AFE720005D17A /* LocaleChangeViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3543A28264AFE720005D17A /* LocaleChangeViewModel.swift */; }; C35ABD232574070A002BB9BB /* PartnersView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C35ABD222574070A002BB9BB /* PartnersView.swift */; }; @@ -287,7 +291,7 @@ C36375A528BD390C00CFB3D8 /* SendButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C36375A428BD390C00CFB3D8 /* SendButtonView.swift */; }; C36DBF5F28F18D2C00FBCB24 /* LocalWebView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C36DBF5E28F18D2C00FBCB24 /* LocalWebView.swift */; }; C36DBF6128F1988900FBCB24 /* LocalWebViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C36DBF6028F1988900FBCB24 /* LocalWebViewModel.swift */; }; - C37D51572CFBB5DB003E206E /* Debug-GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = C37D51562CFBB5DB003E206E /* Debug-GoogleService-Info.plist */; }; + C37D51572CFBB5DB003E206E /* Debug-GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = C37D51562CFBB5DB003E206E /* Debug-GoogleService-Info.plist */; settings = {ASSET_TAGS = ("initial-resources", ); }; }; C39443F9269DDAD3002703E9 /* LitewalletIconView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C39443F8269DDAD3002703E9 /* LitewalletIconView.swift */; }; C39A71472608CB4300E7B640 /* EmptyTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C39A71462608CB4300E7B640 /* EmptyTableViewCell.swift */; }; C3B419CB2BFCF14100EBD935 /* BuyHostingController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3B419CA2BFCF14100EBD935 /* BuyHostingController.swift */; }; @@ -321,7 +325,7 @@ C3F8F1442C04F6BE006C3211 /* Dakar, Senegal.gpx in Resources */ = {isa = PBXBuildFile; fileRef = C3F8F1432C04F6BE006C3211 /* Dakar, Senegal.gpx */; }; C3FF4D5F28AC5A5800713139 /* SendAddressCellView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3FF4D5E28AC5A5800713139 /* SendAddressCellView.swift */; }; C3FF4D6128AC5AC100713139 /* SendAddressCellViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3FF4D6028AC5AC100713139 /* SendAddressCellViewModel.swift */; }; - C7FD407F2C48FAF60010C0E6 /* partner-keys.plist in Resources */ = {isa = PBXBuildFile; fileRef = C7FD407E2C48FAF60010C0E6 /* partner-keys.plist */; }; + C7FD407F2C48FAF60010C0E6 /* partner-keys.plist in Resources */ = {isa = PBXBuildFile; fileRef = C7FD407E2C48FAF60010C0E6 /* partner-keys.plist */; settings = {ASSET_TAGS = ("initial-resources", ); }; }; CE03EC741EF256AC0038E3A8 /* SimpleUTXO.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE03EC731EF256AC0038E3A8 /* SimpleUTXO.swift */; }; CE0CD1591DBFBCF5004023DA /* ModalPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE0CD1581DBFBCF5004023DA /* ModalPresenter.swift */; }; CE124CF81E67A8E500DFA146 /* TransactionDirection.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE124CF71E67A8E500DFA146 /* TransactionDirection.swift */; }; @@ -731,7 +735,6 @@ 24375314238AE09700E1B2AE /* pt */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = pt; path = pt.lproj/BIP39Words.plist; sourceTree = ""; }; 24375315238AE09900E1B2AE /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = ru; path = ru.lproj/BIP39Words.plist; sourceTree = ""; }; 24393B5B23C259400075218D /* Phrase.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Phrase.storyboard; sourceTree = ""; }; - 24470E2023A5DA9700ADDA27 /* APIManagerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = APIManagerTests.swift; sourceTree = ""; }; 24470E2223A5DB7D00ADDA27 /* WalletManagerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletManagerTests.swift; sourceTree = ""; }; 24470E2923A5F33000ADDA27 /* BRReplicatedKVStoreTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRReplicatedKVStoreTests.swift; sourceTree = ""; }; 24470E2B23A5F43B00ADDA27 /* DefaultFiatCurrencyTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DefaultFiatCurrencyTests.swift; sourceTree = ""; }; @@ -1389,7 +1392,6 @@ C30029E125D0185500F08C2B /* StandardDividerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StandardDividerView.swift; sourceTree = ""; }; C30029EA25D019BC00F08C2B /* CopyButtonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CopyButtonView.swift; sourceTree = ""; }; C3019EE22B8FEFED00FAF648 /* AssociatedObject.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AssociatedObject.swift; sourceTree = ""; }; - C30808A62D0B70160063E793 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; C31045602CDBB94600C11FDE /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; C316CF48261887FC00E4C09B /* UIApplication+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIApplication+Extension.swift"; sourceTree = ""; }; C31891C226733FD400ECE25C /* TabBarViewControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabBarViewControllerTests.swift; sourceTree = ""; }; @@ -1428,6 +1430,10 @@ C350788927DCAAA000A50819 /* uk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = uk; path = uk.lproj/Localizable.strings; sourceTree = ""; }; C350788A27DCAAA100A50819 /* uk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = uk; path = uk.lproj/BIP39Words.plist; sourceTree = ""; }; C350788B27DCB10700A50819 /* TextView+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TextView+Extension.swift"; sourceTree = ""; }; + C353582A2D11D9B500395C45 /* RemoteConfigHelper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RemoteConfigHelper.swift; sourceTree = ""; }; + C35358322D11E7D100395C45 /* APITests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = APITests.swift; sourceTree = ""; }; + C35358362D11EB0600395C45 /* remote-config-defaults.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "remote-config-defaults.plist"; sourceTree = ""; }; + C35358382D11EB2F00395C45 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; C3543A26264AFE490005D17A /* LocaleChangeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocaleChangeView.swift; sourceTree = ""; }; C3543A28264AFE720005D17A /* LocaleChangeViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocaleChangeViewModel.swift; sourceTree = ""; }; C35ABD222574070A002BB9BB /* PartnersView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PartnersView.swift; sourceTree = ""; }; @@ -1662,6 +1668,7 @@ 24D91D0B2166923E0077A619 /* UserNotifications.framework in Frameworks */, C35C122A293D48340009022D /* KeychainAccess in Frameworks */, 22A9A9661DF61FEE000F0016 /* WebKit.framework in Frameworks */, + C353582D2D11DA4900395C45 /* FirebaseRemoteConfig in Frameworks */, 22A9A9641DF61FE7000F0016 /* Security.framework in Frameworks */, 22A9A9621DF61FE0000F0016 /* SystemConfiguration.framework in Frameworks */, 22A9A9601DF61FD8000F0016 /* CoreLocation.framework in Frameworks */, @@ -1670,6 +1677,7 @@ C3423C182B781C6B0051BD6D /* PushNotifications in Frameworks */, C35C1222293D464A0009022D /* FirebaseAuth in Frameworks */, C35C1224293D464A0009022D /* FirebaseCrashlytics in Frameworks */, + C353582F2D11DA4900395C45 /* FirebaseRemoteConfigSwift in Frameworks */, C35C1220293D464A0009022D /* FirebaseAnalytics in Frameworks */, 759DA0BE1DAC36A3008CC49B /* libBRCore.a in Frameworks */, ); @@ -2085,6 +2093,7 @@ 2465873723A5AAD100A32E9E /* litewalletTests */ = { isa = PBXGroup; children = ( + C35358322D11E7D100395C45 /* APITests.swift */, C3E587AD2CFC7C69000592D8 /* Seed Word Tests */, 584E24FF2951DA97005E0E8B /* Language Selection Tests */, C3EFA9A42651A7C4005C59B5 /* Lock Screen Tests */, @@ -2092,7 +2101,6 @@ 24470E3923A5FF5700ADDA27 /* TestHelpers.swift */, 24470E4323A6088700ADDA27 /* Class Tests */, 24470E2823A5F2C000ADDA27 /* Legacy BRTests */, - 24470E2023A5DA9700ADDA27 /* APIManagerTests.swift */, 24470E2223A5DB7D00ADDA27 /* WalletManagerTests.swift */, 2465873A23A5AAD100A32E9E /* Info.plist */, ); @@ -2984,7 +2992,8 @@ isa = PBXGroup; children = ( C7FD407E2C48FAF60010C0E6 /* partner-keys.plist */, - C30808A62D0B70160063E793 /* GoogleService-Info.plist */, + C35358382D11EB2F00395C45 /* GoogleService-Info.plist */, + C35358362D11EB0600395C45 /* remote-config-defaults.plist */, C37D51562CFBB5DB003E206E /* Debug-GoogleService-Info.plist */, ); name = LaunchDataResources; @@ -3341,6 +3350,7 @@ CE6D0E5A1E14BF8400137DF1 /* Models */ = { isa = PBXGroup; children = ( + C353582A2D11D9B500395C45 /* RemoteConfigHelper.swift */, CE20C8FF1DBBFFDD00C8397A /* SimpleRedux */, CE6D0E5B1E14BFA600137DF1 /* KeyboardNotificationInfo.swift */, CEE65DEF1E39056F0002994D /* Rate.swift */, @@ -3589,6 +3599,8 @@ C35C1229293D48340009022D /* KeychainAccess */, C3423C172B781C6B0051BD6D /* PushNotifications */, C30808A42D0A23530063E793 /* AppsFlyerLib-Static */, + C353582C2D11DA4900395C45 /* FirebaseRemoteConfig */, + C353582E2D11DA4900395C45 /* FirebaseRemoteConfigSwift */, ); productName = breadwallet; productReference = 75A2A7901DA5934300A983D8 /* Litewallet.app */; @@ -3749,6 +3761,7 @@ files = ( C3423C492B796D820051BD6D /* Ko.mp3 in Resources */, 75A2A79E1DA5934300A983D8 /* LaunchScreen.storyboard in Resources */, + C35358392D11EB2F00395C45 /* GoogleService-Info.plist in Resources */, C33685092BECE8B10069CBC7 /* PrivacyInfo.xcprivacy in Resources */, C3423C3F2B796D820051BD6D /* Pt.mp3 in Resources */, 24D5F23822599C0B00225462 /* BarlowSemiCondensed-Italic.ttf in Resources */, @@ -3784,11 +3797,11 @@ 24B523AD238A53DC0030594D /* BIP39Words.plist in Resources */, 24313CAA23824F9800A83F69 /* Main.storyboard in Resources */, 24D5F25F22599C0B00225462 /* BarlowSemiCondensed-Regular.ttf in Resources */, + C35358372D11EB0600395C45 /* remote-config-defaults.plist in Resources */, C3423C402B796D820051BD6D /* De.mp3 in Resources */, 24DFCE6823B89CDE001F17F8 /* Settings.storyboard in Resources */, C37D51572CFBB5DB003E206E /* Debug-GoogleService-Info.plist in Resources */, 24393B5C23C259400075218D /* Phrase.storyboard in Resources */, - C30808A72D0B70160063E793 /* GoogleService-Info.plist in Resources */, C3423C422B796D820051BD6D /* coinflip.aiff in Resources */, 75A2A79B1DA5934300A983D8 /* Assets.xcassets in Resources */, ); @@ -3901,8 +3914,8 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + C35358332D11E7D100395C45 /* APITests.swift in Sources */, 24470E4223A6007200ADDA27 /* WalletInfoTest.swift in Sources */, - 24470E2123A5DA9700ADDA27 /* APIManagerTests.swift in Sources */, 24470E3423A5F5E600ADDA27 /* PaymentRequestTests.swift in Sources */, 584E25012951DAAA005E0E8B /* LanguageSelectionTests.swift in Sources */, 24470E2E23A5F4FF00ADDA27 /* BRCoderTests.swift in Sources */, @@ -4265,6 +4278,7 @@ CE6D0F971DE8B73A00BD4BCF /* ModalTransitionDelegate.swift in Sources */, C3E751C82AF68AEB005571CA /* UnsafeMutablePointerExtension.swift in Sources */, C3BD4A5325975C6000D97079 /* View+Extension.swift in Sources */, + C353582B2D11D9B500395C45 /* RemoteConfigHelper.swift in Sources */, C3E5A9052BFDEEF1002FBE04 /* BuyViewModel.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -4524,7 +4538,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = litewallet/litewallet.entitlements; - CURRENT_PROJECT_VERSION = 241211.0; + CURRENT_PROJECT_VERSION = 241217.1; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = ZV7987N2ZC; EMBED_ASSET_PACKS_IN_PRODUCT_BUNDLE = YES; @@ -4882,7 +4896,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = litewallet/litewallet.entitlements; - CURRENT_PROJECT_VERSION = 241211.0; + CURRENT_PROJECT_VERSION = 241217.1; DEVELOPMENT_TEAM = ZV7987N2ZC; EMBED_ASSET_PACKS_IN_PRODUCT_BUNDLE = YES; FRAMEWORK_SEARCH_PATHS = ( @@ -5024,7 +5038,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = litewallet/litewallet.entitlements; - CURRENT_PROJECT_VERSION = 241211.0; + CURRENT_PROJECT_VERSION = 241217.1; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = ZV7987N2ZC; EMBED_ASSET_PACKS_IN_PRODUCT_BUNDLE = NO; @@ -5270,6 +5284,16 @@ package = C3423C162B7816EA0051BD6D /* XCRemoteSwiftPackageReference "push-notifications-swift" */; productName = PushNotifications; }; + C353582C2D11DA4900395C45 /* FirebaseRemoteConfig */ = { + isa = XCSwiftPackageProductDependency; + package = C35C121E293D464A0009022D /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */; + productName = FirebaseRemoteConfig; + }; + C353582E2D11DA4900395C45 /* FirebaseRemoteConfigSwift */ = { + isa = XCSwiftPackageProductDependency; + package = C35C121E293D464A0009022D /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */; + productName = FirebaseRemoteConfigSwift; + }; C35C121F293D464A0009022D /* FirebaseAnalytics */ = { isa = XCSwiftPackageProductDependency; package = C35C121E293D464A0009022D /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */; diff --git a/litewallet/AppDelegate.swift b/litewallet/AppDelegate.swift index c0dcdf701..5301d5526 100644 --- a/litewallet/AppDelegate.swift +++ b/litewallet/AppDelegate.swift @@ -10,6 +10,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? let applicationController = ApplicationController() let pushNotifications = PushNotifications.shared + var remoteConfigurationHelper: RemoteConfigHelper? var resourceRequest: NSBundleResourceRequest? @@ -33,6 +34,9 @@ class AppDelegate: UIResponder, UIApplicationDelegate { AppsFlyerLib.shared().appsFlyerDevKey = Partner.partnerKeyPath(name: .devAF) AppsFlyerLib.shared().appleAppID = "1119332592" + // Remote Config + self.remoteConfigurationHelper = RemoteConfigHelper.sharedInstance + // Pusher self.pushNotifications.start(instanceId: Partner.partnerKeyPath(name: .pusher)) let generalInterest = String.preferredLanguageInterest(currentId: UserDefaults.selectedLanguage) diff --git a/litewallet/BRAPIClient+Wallet.swift b/litewallet/BRAPIClient+Wallet.swift index 6204cf6bc..94d8071ec 100644 --- a/litewallet/BRAPIClient+Wallet.swift +++ b/litewallet/BRAPIClient+Wallet.swift @@ -1,7 +1,5 @@ import Foundation -private let fallbackRatesURL = "https://api-dev.lite-wallet.org/v1/rates" - extension BRAPIClient { func feePerKb(_ handler: @escaping (_ fees: Fees, _ error: String?) -> Void) { let req = URLRequest(url: url("/fee-per-kb")) @@ -13,7 +11,8 @@ extension BRAPIClient { } func exchangeRates(isFallback: Bool = false, _ handler: @escaping (_ rates: [Rate], _ error: String?) -> Void) { - let request = isFallback ? URLRequest(url: URL(string: fallbackRatesURL)!) : URLRequest(url: URL(string: APIServer.baseUrl + "v1/rates")!) + let request = isFallback ? URLRequest(url: URL(string: APIServer().devBaseUrl + "v1/rates")!) : URLRequest(url: URL(string: APIServer().baseUrl + "v1/rates")!) + dataTaskWithRequest(request) { data, _, error in if error == nil, let data = data, let parsedData = try? JSONSerialization.jsonObject(with: data, options: .allowFragments) diff --git a/litewallet/BuyView.swift b/litewallet/BuyView.swift index 2cbeec278..b1b8b9c05 100644 --- a/litewallet/BuyView.swift +++ b/litewallet/BuyView.swift @@ -103,7 +103,7 @@ struct BuyView: View { Button(action: { if viewModel.receivingAddress != "" { let timestamp = Int(Date().timeIntervalSince1970) - viewModel.urlString = APIServer.baseUrl + "moonpay/buy" + "?address=\(viewModel.receivingAddress)&idate=\(timestamp)&uid=\(viewModel.uuidString)&code=\(viewModel.selectedCode)" + viewModel.urlString = APIServer().baseUrl + "moonpay/buy" + "?address=\(viewModel.receivingAddress)&idate=\(timestamp)&uid=\(viewModel.uuidString)&code=\(viewModel.selectedCode)" self.shouldShowSafariVC = true } diff --git a/litewallet/BuyWKWebViewController.swift b/litewallet/BuyWKWebViewController.swift index 108b61b87..1548d835d 100644 --- a/litewallet/BuyWKWebViewController.swift +++ b/litewallet/BuyWKWebViewController.swift @@ -37,7 +37,7 @@ class BuyWKWebViewController: UIViewController, WKNavigationDelegate, WKScriptMe } func loadSimplexRequest() { - let urlString: String = APIServer.baseUrl + "?address=\(currentWalletAddress)&code=\(currencyCode)&idate=\(timestamp)&uid=\(uuidString)" + let urlString: String = APIServer().baseUrl + "?address=\(currentWalletAddress)&code=\(currencyCode)&idate=\(timestamp)&uid=\(uuidString)" guard let url = URL(string: urlString) else { diff --git a/litewallet/Constants/Constants+Events.swift b/litewallet/Constants/Constants+Events.swift index d600fc195..2bf985b14 100644 --- a/litewallet/Constants/Constants+Events.swift +++ b/litewallet/Constants/Constants+Events.swift @@ -1,3 +1,4 @@ +import SwiftUI import UIKit let π: CGFloat = .pi @@ -10,7 +11,15 @@ struct FoundationSupport { } struct APIServer { - static let baseUrl = "https://api-prod.lite-wallet.org/" + let appDelegate = UIApplication.shared.delegate as! AppDelegate + let baseUrl: String + let devBaseUrl: String + init() { + baseUrl = appDelegate.remoteConfigurationHelper? + .getString(key: RemoteConfigKeys.KEY_PROD_API_BASEURL.rawValue) ?? "" + devBaseUrl = appDelegate.remoteConfigurationHelper? + .getString(key: RemoteConfigKeys.KEY_DEV_API_BASEURL.rawValue) ?? "" + } } struct Padding { @@ -240,4 +249,7 @@ enum CustomEvent: String { /// Unsupported by Moonpay case _20240527_UBM = "unsupported_by_moonpay" + + /// Remote Config Changed + case _20241213_RCC = "remote_config_changed" } diff --git a/litewallet/Environment.swift b/litewallet/Environment.swift index 41b971fcf..159911f9b 100644 --- a/litewallet/Environment.swift +++ b/litewallet/Environment.swift @@ -1,3 +1,4 @@ +import Foundation import UIKit /// 14 Languages diff --git a/litewallet/RemoteConfigHelper.swift b/litewallet/RemoteConfigHelper.swift new file mode 100644 index 000000000..c8815bd3e --- /dev/null +++ b/litewallet/RemoteConfigHelper.swift @@ -0,0 +1,83 @@ +import FirebaseRemoteConfig +import Foundation +import KeychainAccess +import UIKit + +enum RemoteConfigKeys: String { + case KEY_FEATURE_MENU_HIDDEN_EXAMPLE = "feature_menu_hidden_example" + case KEY_API_BASEURL_PROD_NEW_ENABLED = "key_api_baseurl_prod_new_enabled" + case KEY_API_BASEURL_DEV_NEW_ENABLED = "key_api_baseurl_dev_new_enabled" + case KEY_KEYSTORE_MANAGER_ENABLED = "key_keystore_manager_enabled" + case KEY_PROD_API_BASEURL = "key_prod_api_baseurl" + case KEY_DEV_API_BASEURL = "key_dev_api_baseurl" +} + +class RemoteConfigHelper: NSObject { + static let sharedInstance = RemoteConfigHelper() + + private var remoteConfig: RemoteConfig! + private let settings = RemoteConfigSettings() + private let keychainEnvironment = Keychain(service: "litewallet.environment") + private let debugFetchInterval: TimeInterval = 0 // seconds + private let productionFetchInterval: TimeInterval = 60 * 180 // seconds; Fetch every 3 hours in production mode + override init() { + super.init() + remoteConfig = RemoteConfig.remoteConfig() + setupRemoteConfig() + } + + deinit {} + + private func setupRemoteConfig() { + remoteConfig.setDefaults(fromPlist: "remote-config-defaults") + #if DEBUG + settings.minimumFetchInterval = debugFetchInterval + #else + settings.minimumFetchInterval = productionFetchInterval + #endif + + remoteConfig.configSettings = settings + + /// Call the first time + fetchAndActivateRemoteConfig() + + /// Update based on remote changes + remoteConfig.addOnConfigUpdateListener { configUpdate, error in + guard let configUpdate, error == nil else { + let errorDict: [String: String] = ["error": error?.localizedDescription ?? ""] + LWAnalytics.logEventWithParameters(itemName: ._20200112_ERR, properties: errorDict) + return + } + + self.fetchAndActivateRemoteConfig() + } + } + + private func fetchAndActivateRemoteConfig() { + remoteConfig.fetch { status, error in + if status == .success { + self.remoteConfig.activate { _, error in + guard error == nil else { return } + DispatchQueue.main.async { + LWAnalytics.logEventWithParameters(itemName: ._20241213_RCC) + } + } + } else { + let errorDict: [String: String] = ["error": error?.localizedDescription ?? ""] + LWAnalytics.logEventWithParameters(itemName: ._20200112_ERR, properties: errorDict) + } + } + } + + func getString(key: String) -> String { + return remoteConfig[key].stringValue ?? "value_not_found" + } + + func getNumber(key: String) -> NSNumber { + return remoteConfig[key].numberValue + } + + func getBool(key: String) -> Bool { + return remoteConfig[key].boolValue + } +} diff --git a/litewalletTests/APIManagerTests.swift b/litewalletTests/APIManagerTests.swift deleted file mode 100644 index 353dad063..000000000 --- a/litewalletTests/APIManagerTests.swift +++ /dev/null @@ -1,24 +0,0 @@ -@testable import litewallet -import XCTest - -class APIManagerTests: XCTestCase { - override func setUp() { - // Put setup code here. This method is called before the invocation of each test method in the class. - } - - override func tearDown() { - // Put teardown code here. This method is called after the invocation of each test method in the class. - } - - func testConnectToSeed() { - // This is an example of a functional test case. - // Use XCTAssert and related functions to verify your tests produce the correct results. - - // Given: - // When: - // Then: - } - - func testFetchLitecoinRateData() - {} -} diff --git a/litewalletTests/APITests.swift b/litewalletTests/APITests.swift new file mode 100644 index 000000000..d1302c79e --- /dev/null +++ b/litewalletTests/APITests.swift @@ -0,0 +1,43 @@ +@testable import litewallet +import XCTest + +class APITests: XCTestCase { + var apiServer: APIServer! + var apiClient: BRAPIClient! + + override func setUpWithError() throws { + apiServer = APIServer() + apiClient = litewallet.BRAPIClient(authenticator: NoAuthAuthenticator()) + } + + override func tearDownWithError() throws { + apiServer = nil + } + + func testfetchExchangeRates() throws { + apiClient.exchangeRates { rates, _ in + for rate in rates { + if rate.code == "AFN" { + XCTAssertEqual(rate.name, "Afghan Afghani") + } + if rate.code == "GBP" { + XCTAssertEqual(rate.name, "British Pound Sterling") + } + if rate.code == "EUR" { + XCTAssertEqual(rate.name, "Euro") + } + if rate.code == "USD" { + XCTAssertEqual(rate.name, "US Dollar") + } + } + } + } + + func testfeePerKb() throws { + apiClient.feePerKb { fees, _ in + XCTAssertGreaterThan(fees.economy, 0) + XCTAssertGreaterThan(fees.regular, 0) + XCTAssertGreaterThan(fees.luxury, 0) + } + } +}