Skip to content

Commit

Permalink
Added the remote config components
Browse files Browse the repository at this point in the history
- Testing  FB client
- Confirmed Firebase registered for remote config
- Checking all params
  • Loading branch information
kcw-grunt committed Dec 13, 2024
1 parent 38fdab3 commit a9cf77d
Show file tree
Hide file tree
Showing 10 changed files with 161 additions and 15 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,4 @@ litewallet-partner-api-ios
partner-keys.plist
GoogleService-Info.plist
*.gpx
litewallet/remote-config-defaults.plist
22 changes: 19 additions & 3 deletions litewallet.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,9 @@
C30029E225D0185500F08C2B /* StandardDividerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C30029E125D0185500F08C2B /* StandardDividerView.swift */; };
C30029EB25D019BC00F08C2B /* CopyButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C30029EA25D019BC00F08C2B /* CopyButtonView.swift */; };
C3019EE32B8FEFED00FAF648 /* AssociatedObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3019EE22B8FEFED00FAF648 /* AssociatedObject.swift */; };
C30808A92D0B758B0063E793 /* RemoteConfigHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = C30808A82D0B758B0063E793 /* RemoteConfigHelper.swift */; };
C30808AB2D0B77F80063E793 /* FirebaseRemoteConfigSwift in Frameworks */ = {isa = PBXBuildFile; productRef = C30808AA2D0B77F80063E793 /* FirebaseRemoteConfigSwift */; };
C30808AD2D0C399D0063E793 /* remote-config-defaults.plist in Resources */ = {isa = PBXBuildFile; fileRef = C30808AC2D0C399D0063E793 /* remote-config-defaults.plist */; settings = {ASSET_TAGS = ("initial-resources", ); }; };
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 */; };
Expand Down Expand Up @@ -285,8 +288,8 @@
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 */; };
C37D51592CFBB5E4003E206E /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = C37D51582CFBB5E4003E206E /* GoogleService-Info.plist */; };
C37D51572CFBB5DB003E206E /* Debug-GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = C37D51562CFBB5DB003E206E /* Debug-GoogleService-Info.plist */; settings = {ASSET_TAGS = ("initial-resources", ); }; };
C37D51592CFBB5E4003E206E /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = C37D51582CFBB5E4003E206E /* 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 */; };
Expand Down Expand Up @@ -320,7 +323,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 */; };
Expand Down Expand Up @@ -1388,6 +1391,8 @@
C30029E125D0185500F08C2B /* StandardDividerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StandardDividerView.swift; sourceTree = "<group>"; };
C30029EA25D019BC00F08C2B /* CopyButtonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CopyButtonView.swift; sourceTree = "<group>"; };
C3019EE22B8FEFED00FAF648 /* AssociatedObject.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AssociatedObject.swift; sourceTree = "<group>"; };
C30808A82D0B758B0063E793 /* RemoteConfigHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RemoteConfigHelper.swift; sourceTree = "<group>"; };
C30808AC2D0C399D0063E793 /* remote-config-defaults.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "remote-config-defaults.plist"; sourceTree = "<group>"; };
C31045602CDBB94600C11FDE /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = "<group>"; };
C316CF48261887FC00E4C09B /* UIApplication+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIApplication+Extension.swift"; sourceTree = "<group>"; };
C31891C226733FD400ECE25C /* TabBarViewControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabBarViewControllerTests.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1670,6 +1675,7 @@
C35C1224293D464A0009022D /* FirebaseCrashlytics in Frameworks */,
C35C1220293D464A0009022D /* FirebaseAnalytics in Frameworks */,
759DA0BE1DAC36A3008CC49B /* libBRCore.a in Frameworks */,
C30808AB2D0B77F80063E793 /* FirebaseRemoteConfigSwift in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -2984,6 +2990,7 @@
C7FD407E2C48FAF60010C0E6 /* partner-keys.plist */,
C37D51582CFBB5E4003E206E /* GoogleService-Info.plist */,
C37D51562CFBB5DB003E206E /* Debug-GoogleService-Info.plist */,
C30808AC2D0C399D0063E793 /* remote-config-defaults.plist */,
);
name = LaunchDataResources;
sourceTree = "<group>";
Expand Down Expand Up @@ -3353,6 +3360,7 @@
24B8FADE2163C4D400A155B1 /* Currency.swift */,
24313C732381E73200A83F69 /* TransactionManager.swift */,
24470E4623A6B6E900ADDA27 /* MockSeeds.swift */,
C30808A82D0B758B0063E793 /* RemoteConfigHelper.swift */,
584E24F22951C119005E0E8B /* Localization.swift */,
);
name = Models;
Expand Down Expand Up @@ -3586,6 +3594,7 @@
C35C1223293D464A0009022D /* FirebaseCrashlytics */,
C35C1229293D48340009022D /* KeychainAccess */,
C3423C172B781C6B0051BD6D /* PushNotifications */,
C30808AA2D0B77F80063E793 /* FirebaseRemoteConfigSwift */,
);
productName = breadwallet;
productReference = 75A2A7901DA5934300A983D8 /* Litewallet.app */;
Expand Down Expand Up @@ -3780,6 +3789,7 @@
2485F7D023728C19005962F1 /* RELEASE_NOTES.md in Resources */,
24B523AD238A53DC0030594D /* BIP39Words.plist in Resources */,
24313CAA23824F9800A83F69 /* Main.storyboard in Resources */,
C30808AD2D0C399D0063E793 /* remote-config-defaults.plist in Resources */,
24D5F25F22599C0B00225462 /* BarlowSemiCondensed-Regular.ttf in Resources */,
C3423C402B796D820051BD6D /* De.mp3 in Resources */,
24DFCE6823B89CDE001F17F8 /* Settings.storyboard in Resources */,
Expand Down Expand Up @@ -4261,6 +4271,7 @@
CE6D0F971DE8B73A00BD4BCF /* ModalTransitionDelegate.swift in Sources */,
C3E751C82AF68AEB005571CA /* UnsafeMutablePointerExtension.swift in Sources */,
C3BD4A5325975C6000D97079 /* View+Extension.swift in Sources */,
C30808A92D0B758B0063E793 /* RemoteConfigHelper.swift in Sources */,
C3E5A9052BFDEEF1002FBE04 /* BuyViewModel.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down Expand Up @@ -5248,6 +5259,11 @@
/* End XCRemoteSwiftPackageReference section */

/* Begin XCSwiftPackageProductDependency section */
C30808AA2D0B77F80063E793 /* FirebaseRemoteConfigSwift */ = {
isa = XCSwiftPackageProductDependency;
package = C35C121E293D464A0009022D /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */;
productName = FirebaseRemoteConfigSwift;
};
C3423C172B781C6B0051BD6D /* PushNotifications */ = {
isa = XCSwiftPackageProductDependency;
package = C3423C162B7816EA0051BD6D /* XCRemoteSwiftPackageReference "push-notifications-swift" */;
Expand Down
4 changes: 4 additions & 0 deletions litewallet/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
let applicationController = ApplicationController()
let pushNotifications = PushNotifications.shared
var remoteConfigurationHelper: RemoteConfigHelper?

var resourceRequest: NSBundleResourceRequest?

Expand All @@ -28,6 +29,9 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
// Firebase
self.setFirebaseConfiguration()

// Remote Config
self.remoteConfigurationHelper = RemoteConfigHelper.sharedInstance

// Pusher
self.pushNotifications.start(instanceId: Partner.partnerKeyPath(name: .pusher))
let generalInterest = String.preferredLanguageInterest(currentId: UserDefaults.selectedLanguage)
Expand Down
4 changes: 1 addition & 3 deletions litewallet/BRAPIClient+Wallet.swift
Original file line number Diff line number Diff line change
@@ -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"))
Expand All @@ -13,7 +11,7 @@ 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)
Expand Down
2 changes: 1 addition & 1 deletion litewallet/BuyView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

Expand Down
2 changes: 1 addition & 1 deletion litewallet/BuyWKWebViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
15 changes: 14 additions & 1 deletion litewallet/Constants/Constants+Events.swift
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import SwiftUI
import UIKit

let π: CGFloat = .pi
Expand All @@ -10,7 +11,16 @@ 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 {
Expand Down Expand Up @@ -240,4 +250,7 @@ enum CustomEvent: String {

/// Unsupported by Moonpay
case _20240527_UBM = "unsupported_by_moonpay"

/// Remote Config Changed
case _20241213_RCC = "remote_config_changed"
}
21 changes: 21 additions & 0 deletions litewallet/Environment.swift
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import Foundation
import UIKit

/// 14 Languages
Expand Down Expand Up @@ -143,3 +144,23 @@ struct E {
return UIScreen.main.bounds.size.height
}
}

/// Remote Config
enum EnvironmentRemoteConfigKey: String, Equatable {
case k20241212_API_1
case k20241212_API_2

var key: String {
switch self {
case .k20241212_API_1: return "key_api_baseurl_dev_new_enabled"
case .k20241212_API_2: return "key_api_baseurl_prod_new_enabled"
}
}

// var type: Any {
// switch self {
// case .k20241212_API_1: return Bool
// case .k20241212_API_2: return bool
// }
// }
}
20 changes: 14 additions & 6 deletions litewallet/GoogleService-Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,24 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CLIENT_ID</key>
<string>230187998656-s6tf5antivdoid0pmbt6qkmo5lnipiq3.apps.googleusercontent.com</string>
<key>REVERSED_CLIENT_ID</key>
<string>com.googleusercontent.apps.230187998656-s6tf5antivdoid0pmbt6qkmo5lnipiq3</string>
<key>ANDROID_CLIENT_ID</key>
<string>230187998656-mvo0eadvv8cu98vhdtkku72olhvdjgao.apps.googleusercontent.com</string>
<key>API_KEY</key>
<string>AIzaSyC58u1MhxC27M-eWBHO60czLz08f4rrAMw</string>
<string>AIzaSyDsR9RB5n7G_6xXxhNsYrfy00bUFE0pB8M</string>
<key>GCM_SENDER_ID</key>
<string>969229325957</string>
<string>230187998656</string>
<key>PLIST_VERSION</key>
<string>1</string>
<key>BUNDLE_ID</key>
<string>com.litewallet.newborn</string>
<string>com.litecoin.loafwallet</string>
<key>PROJECT_ID</key>
<string>litewallet-newborn-alpha</string>
<string>litewallet-beta</string>
<key>STORAGE_BUCKET</key>
<string>litewallet-newborn-alpha.appspot.com</string>
<string>litewallet-beta.appspot.com</string>
<key>IS_ADS_ENABLED</key>
<false></false>
<key>IS_ANALYTICS_ENABLED</key>
Expand All @@ -25,6 +31,8 @@
<key>IS_SIGNIN_ENABLED</key>
<true></true>
<key>GOOGLE_APP_ID</key>
<string>1:969229325957:ios:b96117f47e5a662f41bbec</string>
<string>1:230187998656:ios:2437e5740a4cb54570bc25</string>
<key>DATABASE_URL</key>
<string>https://litewallet-beta.firebaseio.com</string>
</dict>
</plist>
85 changes: 85 additions & 0 deletions litewallet/RemoteConfigHelper.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
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
}

print("::: Updated keys: \(configUpdate.updatedKeys)")

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
}
}

0 comments on commit a9cf77d

Please sign in to comment.