Skip to content

Commit

Permalink
Add 'referral' deeplinks handler
Browse files Browse the repository at this point in the history
  • Loading branch information
esen committed Aug 15, 2024
1 parent a011fea commit 85d0963
Show file tree
Hide file tree
Showing 15 changed files with 141 additions and 3 deletions.
1 change: 1 addition & 0 deletions .github/workflows/deploy_appstore.yml
Original file line number Diff line number Diff line change
Expand Up @@ -70,3 +70,4 @@ jobs:
XCCONFIG_PROD_ONE_INCH_API_KEY: ${{ secrets.XCCONFIG_PROD_ONE_INCH_API_KEY }}
XCCONFIG_PROD_ONE_INCH_COMMISSION: ${{ secrets.XCCONFIG_PROD_ONE_INCH_COMMISSION }}
XCCONFIG_PROD_ONE_INCH_COMMISSION_ADDRESS: ${{ secrets.XCCONFIG_PROD_ONE_INCH_COMMISSION_ADDRESS }}
XCCONFIG_PROD_REFERRAL_APP_SERVER_URL: ${{ secrets.XCCONFIG_PROD_REFERRAL_APP_SERVER_URL }}
1 change: 1 addition & 0 deletions .github/workflows/deploy_dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -71,3 +71,4 @@ jobs:
XCCONFIG_DEV_ONE_INCH_API_KEY: ${{ secrets.XCCONFIG_DEV_ONE_INCH_API_KEY }}
XCCONFIG_DEV_ONE_INCH_COMMISSION: ${{ secrets.XCCONFIG_DEV_ONE_INCH_COMMISSION }}
XCCONFIG_DEV_ONE_INCH_COMMISSION_ADDRESS: ${{ secrets.XCCONFIG_DEV_ONE_INCH_COMMISSION_ADDRESS }}
XCCONFIG_DEV_REFERRAL_APP_SERVER_URL: ${{ secrets.XCCONFIG_DEV_REFERRAL_APP_SERVER_URL }}
12 changes: 12 additions & 0 deletions UnstoppableWallet/UnstoppableWallet.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -2680,6 +2680,10 @@
D061A5332AA846FA009AAD57 /* SecuritySettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D061A5312AA846FA009AAD57 /* SecuritySettingsView.swift */; };
D06669022A31B559004B048D /* TronRecipientAddressViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D06669012A31B559004B048D /* TronRecipientAddressViewModel.swift */; };
D06669032A31B559004B048D /* TronRecipientAddressViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D06669012A31B559004B048D /* TronRecipientAddressViewModel.swift */; };
D066A45C2C6CB2E100074E35 /* TelegramUserHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = D066A45B2C6CB2E100074E35 /* TelegramUserHandler.swift */; };
D066A45D2C6CB2E100074E35 /* TelegramUserHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = D066A45B2C6CB2E100074E35 /* TelegramUserHandler.swift */; };
D066A45F2C6CC7E200074E35 /* WelcomeScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D066A45E2C6CC7E200074E35 /* WelcomeScreenViewModel.swift */; };
D066A4602C6CC7E200074E35 /* WelcomeScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D066A45E2C6CC7E200074E35 /* WelcomeScreenViewModel.swift */; };
D06A171B2BA1B1BC0081E312 /* FeeSettingsViewHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = D06A171A2BA1B1BC0081E312 /* FeeSettingsViewHelper.swift */; };
D06A171C2BA1B1BC0081E312 /* FeeSettingsViewHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = D06A171A2BA1B1BC0081E312 /* FeeSettingsViewHelper.swift */; };
D06B302C2B6A120E0012A161 /* LegacyFeeSettingsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D06B302B2B6A120E0012A161 /* LegacyFeeSettingsViewModel.swift */; };
Expand Down Expand Up @@ -4607,6 +4611,8 @@
D05F132D2A31FE0D00C3193F /* AddTronTokenBlockchainService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddTronTokenBlockchainService.swift; sourceTree = "<group>"; };
D061A5312AA846FA009AAD57 /* SecuritySettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecuritySettingsView.swift; sourceTree = "<group>"; };
D06669012A31B559004B048D /* TronRecipientAddressViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TronRecipientAddressViewModel.swift; sourceTree = "<group>"; };
D066A45B2C6CB2E100074E35 /* TelegramUserHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TelegramUserHandler.swift; sourceTree = "<group>"; };
D066A45E2C6CC7E200074E35 /* WelcomeScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WelcomeScreenViewModel.swift; sourceTree = "<group>"; };
D06A171A2BA1B1BC0081E312 /* FeeSettingsViewHelper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FeeSettingsViewHelper.swift; sourceTree = "<group>"; };
D06B302B2B6A120E0012A161 /* LegacyFeeSettingsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LegacyFeeSettingsViewModel.swift; sourceTree = "<group>"; };
D07157DA2A2DD968006F141F /* SendTronModule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SendTronModule.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -7069,6 +7075,7 @@
children = (
3C7B956E27165EB2D682C2D7 /* WelcomeScreenViewController.swift */,
11B35A05B93CB243B6404C4A /* WelcomeTextView.swift */,
D066A45E2C6CC7E200074E35 /* WelcomeScreenViewModel.swift */,
);
path = Welcome;
sourceTree = "<group>";
Expand Down Expand Up @@ -7432,6 +7439,7 @@
6B29071C2AF0CB8A006157D6 /* WidgetCoinAppShowWorker */,
6B29071E2AF0CB8A006157D6 /* EventHandler.swift */,
ABC9A72A3AB621DE379754C8 /* SendAppShowWorker */,
D066A45B2C6CB2E100074E35 /* TelegramUserHandler.swift */,
);
path = Workers;
sourceTree = "<group>";
Expand Down Expand Up @@ -9786,6 +9794,7 @@
11B355E3AC79508BEDA18CAE /* BirthdayInputViewController.swift in Sources */,
1A5643BCDAD7CB0230CBB513 /* GradientClippingView.swift in Sources */,
11B3558898EE33B8D6E571CE /* MnemonicPhraseCell.swift in Sources */,
D066A4602C6CC7E200074E35 /* WelcomeScreenViewModel.swift in Sources */,
11B35A33CB6CA5C4A25ECFC9 /* MnemonicWordCell.swift in Sources */,
1A564B1D457A23C7732B76DF /* ReleaseNotesService.swift in Sources */,
1A5642F3BA1892109A596B61 /* MarkdownContentProvider.swift in Sources */,
Expand Down Expand Up @@ -10202,6 +10211,7 @@
11B35DBD3329CD28158E4D6A /* NftHeaderViewModel.swift in Sources */,
11B35B36FB559CDEB1B496EC /* NftHeaderView.swift in Sources */,
11B358F2CD17616038016E59 /* NftRecord.swift in Sources */,
D066A45D2C6CB2E100074E35 /* TelegramUserHandler.swift in Sources */,
11B35480CA91E0A62617B83A /* EvmNftRecord.swift in Sources */,
11B35D3102B803096B6EE5B6 /* NftMetadataManager.swift in Sources */,
11B35E34B9E95819B9EA1764 /* OpenSeaNftProvider.swift in Sources */,
Expand Down Expand Up @@ -11276,6 +11286,7 @@
11B3553ED96875D0B6E5B5C4 /* BirthdayInputViewController.swift in Sources */,
1A564A2FCE3C764029FECB7B /* GradientClippingView.swift in Sources */,
11B35E67CDA98E004C9C2011 /* MnemonicPhraseCell.swift in Sources */,
D066A45F2C6CC7E200074E35 /* WelcomeScreenViewModel.swift in Sources */,
11B35C22A15045197D511BB2 /* MnemonicWordCell.swift in Sources */,
1A564C10B9782D53375736C8 /* ReleaseNotesService.swift in Sources */,
1A56451ADE50B86E21814347 /* MarkdownContentProvider.swift in Sources */,
Expand Down Expand Up @@ -11692,6 +11703,7 @@
11B353A07F9259765D90F3BA /* NftService.swift in Sources */,
11B35D6C50BA6E928A54EDAC /* NftModule.swift in Sources */,
11B356D6A39A05C101B0CB9D /* NftViewModel.swift in Sources */,
D066A45C2C6CB2E100074E35 /* TelegramUserHandler.swift in Sources */,
11B35AF308141DC4CFA45918 /* NftHeaderViewModel.swift in Sources */,
11B351F991634E3E6A0846EF /* NftHeaderView.swift in Sources */,
11B35F2F1770FB757E6FDCD8 /* NftRecord.swift in Sources */,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,4 @@ swap_enabled = true
donate_enabled = true

default_words =
referral_app_server_url =
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,4 @@ one_inch_commission =
one_inch_commission_address =
swap_enabled = true
donate_enabled = true
referral_app_server_url =
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import BigInt
import ComponentKit
import Foundation
import RxRelay
Expand Down Expand Up @@ -37,6 +38,7 @@ extension DeepLinkManager {
do {
let address = try parser.parse(url: url.absoluteString)
newSchemeRelay.accept(.transfer(addressUri: address))
return true
} catch {
HudHelper.instance.show(banner: .error(string: error.localizedDescription))
}
Expand All @@ -49,14 +51,31 @@ extension DeepLinkManager {
return true
}

if (scheme == DeepLinkManager.deepLinkScheme && host == "referral") || (scheme == "https" && host == DeepLinkManager.deepLinkScheme && path == "/referral") {
guard let queryItems, queryItems.count == 2,
let userId = queryItems[0].value,
let referralCode = queryItems[1].value
else {
return false
}

newSchemeRelay.accept(.referral(telegramUserId: userId, referralCode: referralCode))
return true
}

return false
}

func setDeepLinkShown() {
newSchemeRelay.accept(nil)
}
}

extension DeepLinkManager {
enum DeepLink {
case walletConnect(url: String)
case coin(uid: String)
case transfer(addressUri: AddressUri)
case referral(telegramUserId: String, referralCode: String)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,10 @@ enum AppConfig {
(Bundle.main.object(forInfoDictionaryKey: "OneInchCommissionAddress") as? String).flatMap { $0.isEmpty ? nil : $0 }
}

static var referralAppServerUrl: String {
(Bundle.main.object(forInfoDictionaryKey: "ReferralAppServerUrl") as? String) ?? ""
}

static var defaultWords: String {
Bundle.main.object(forInfoDictionaryKey: "DefaultWords") as? String ?? ""
}
Expand Down
2 changes: 2 additions & 0 deletions UnstoppableWallet/UnstoppableWallet/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -164,5 +164,7 @@
<string>${unstoppable_domains_api_key}</string>
<key>WallectConnectV2ProjectKey</key>
<string>${wallet_connect_v2_project_key}</string>
<key>ReferralAppServerUrl</key>
<string>${referral_app_server_url}</string>
</dict>
</plist>
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ enum LaunchModule {
switch service.launchMode {
case .passcodeNotSet: return NoPasscodeViewController(mode: .noPasscode)
case .cannotCheckPasscode: return NoPasscodeViewController(mode: .cannotCheckPasscode)
case .intro: return WelcomeScreenViewController()
case .intro: return WelcomeScreenViewController.instance()
case .unlock: return UnlockModule.appUnlockView(appStart: true).toViewController()
case .main: return MainModule.instance()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,6 @@ class DeepLinkService {
}

func setDeepLinkShown() {
deepLink = nil
deepLinkManager.setDeepLinkShown()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,11 @@ enum MainModule {
let deepLinkHandler = WalletConnectAppShowModule.handler(parentViewController: viewController)
let widgetCoinHandler = WidgetCoinAppShowModule.handler(parentViewController: viewController)
let sendAddressHandler = AddressAppShowModule.handler(parentViewController: viewController)
let telegramUserHandler = TelegramUserHandler.handler(parentViewController: viewController)
eventHandler.append(handler: deepLinkHandler)
eventHandler.append(handler: widgetCoinHandler)
eventHandler.append(handler: sendAddressHandler)
eventHandler.append(handler: telegramUserHandler)

App.shared.lockDelegate.viewController = viewController

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import MarketKit
import ObjectMapper
import RxSwift
import UIKit

class TelegramUserHandler {
private let disposeBag = DisposeBag()
private let parentViewController: UIViewController?
private let marketKit = App.shared.marketKit
private let baseUrl = AppConfig.referralAppServerUrl

init(parentViewController: UIViewController?) {
self.parentViewController = parentViewController
}
}

extension TelegramUserHandler: IEventHandler {
@MainActor
func handle(source: StatPage, event: Any, eventType: EventHandler.EventType) async throws {
if eventType.contains(.deepLink), let event = event as? DeepLinkManager.DeepLink {
guard case let .referral(userId, referralCode) = event else {
throw EventHandler.HandleError.noSuitableHandler
}
let urlString = "\(baseUrl)/v1/tasks/registerApp?userId=\(userId)&referralCode=\(referralCode)"
print("Requesting: \(urlString)")
guard let url = URL(string: urlString) else {
return
}

let _: EmptyResponse = try await App.shared.networkManager.fetch(url: url)
}
}
}

extension TelegramUserHandler {
static func handler(parentViewController: UIViewController? = nil) -> IEventHandler {
TelegramUserHandler(parentViewController: parentViewController)
}
}

struct EmptyResponse: ImmutableMappable {
init(map: Map) throws {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import ThemeKit
import UIKit

class WelcomeScreenViewController: ThemeViewController {
private let viewModel: WelcomeScreenViewModel
private let scrollView = UIScrollView()
private var textViews = [WelcomeTextView]()
private let pageControl: BarPageControl
Expand All @@ -19,7 +20,8 @@ class WelcomeScreenViewController: ThemeViewController {
Slide(title: "intro.stay_private.title".localized, description: "intro.stay_private.description".localized, image: "Intro - Stay Private"),
]

override init() {
init(viewModel: WelcomeScreenViewModel) {
self.viewModel = viewModel
pageControl = BarPageControl(barCount: slides.count)

super.init()
Expand Down Expand Up @@ -191,6 +193,12 @@ class WelcomeScreenViewController: ThemeViewController {
logoTitleLabel.font = .title2
logoTitleLabel.textColor = .themeLeah
logoTitleLabel.text = AppConfig.appName

NotificationCenter.default.addObserver(self, selector: #selector(appDidBecomeActive), name: UIApplication.didBecomeActiveNotification, object: nil)
}

@objc func appDidBecomeActive() {
viewModel.handleDeepLink()
}

override func viewDidAppear(_ animated: Bool) {
Expand All @@ -205,6 +213,7 @@ class WelcomeScreenViewController: ThemeViewController {
self?.logoWrapperView.removeFromSuperview()
})
})
viewModel.handleDeepLink()
}

@objc private func onTapStart() {
Expand Down Expand Up @@ -245,6 +254,21 @@ extension WelcomeScreenViewController: UIScrollViewDelegate {
}
}

extension WelcomeScreenViewController {
static func instance() -> UIViewController {
let eventHandler = EventHandler()
let deepLinkService = DeepLinkService(deepLinkManager: App.shared.deepLinkManager)
let viewModel = WelcomeScreenViewModel(deepLinkService: deepLinkService, eventHandler: eventHandler)

let viewController = WelcomeScreenViewController(viewModel: viewModel)
let telegramUserHandler = TelegramUserHandler.handler(parentViewController: viewController)

eventHandler.append(handler: telegramUserHandler)

return viewController
}
}

extension WelcomeScreenViewController {
private struct Slide {
let title: String
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
class WelcomeScreenViewModel {
private let deepLinkService: DeepLinkService
private let eventHandler: EventHandler

init(deepLinkService: DeepLinkService, eventHandler: EventHandler) {
self.deepLinkService = deepLinkService
self.eventHandler = eventHandler
}

func handleDeepLink() {
guard let deepLink = deepLinkService.deepLink else {
return
}

Task {
do {
try await eventHandler.handle(source: .main, event: deepLink, eventType: .deepLink)
deepLinkService.setDeepLinkShown()
} catch {
print("Can't handle Deep Link \(error)")
}
}
}
}
4 changes: 4 additions & 0 deletions fastlane/Fastfile
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ XCCONFIG_DEV_UNSTOPPABLE_DOMAINS_API_KEY = ENV["XCCONFIG_DEV_UNSTOPPABLE_DOMAINS
XCCONFIG_DEV_ONE_INCH_API_KEY = ENV["XCCONFIG_DEV_ONE_INCH_API_KEY"]
XCCONFIG_DEV_ONE_INCH_COMMISSION = ENV["XCCONFIG_DEV_ONE_INCH_COMMISSION"]
XCCONFIG_DEV_ONE_INCH_COMMISSION_ADDRESS = ENV["XCCONFIG_DEV_ONE_INCH_COMMISSION_ADDRESS"]
XCCONFIG_DEV_REFERRAL_APP_SERVER_URL = ENV["XCCONFIG_DEV_REFERRAL_APP_SERVER_URL"]

XCCONFIG_PROD_ETHERSCAN_API_KEY = ENV["XCCONFIG_PROD_ETHERSCAN_API_KEY"]
XCCONFIG_PROD_ARBISCAN_API_KEY = ENV["XCCONFIG_PROD_ARBISCAN_API_KEY"]
Expand All @@ -46,6 +47,7 @@ XCCONFIG_PROD_UNSTOPPABLE_DOMAINS_API_KEY = ENV["XCCONFIG_PROD_UNSTOPPABLE_DOMAI
XCCONFIG_PROD_ONE_INCH_API_KEY = ENV["XCCONFIG_PROD_ONE_INCH_API_KEY"]
XCCONFIG_PROD_ONE_INCH_COMMISSION = ENV["XCCONFIG_PROD_ONE_INCH_COMMISSION"]
XCCONFIG_PROD_ONE_INCH_COMMISSION_ADDRESS = ENV["XCCONFIG_PROD_ONE_INCH_COMMISSION_ADDRESS"]
XCCONFIG_PROD_REFERRAL_APP_SERVER_URL = ENV["XCCONFIG_PROD_REFERRAL_APP_SERVER_URL"]

def delete_temp_keychain(name)
delete_keychain(
Expand Down Expand Up @@ -127,6 +129,7 @@ def apply_dev_xcconfig
update_dev_xcconfig('one_inch_api_key', XCCONFIG_DEV_ONE_INCH_API_KEY)
update_dev_xcconfig('one_inch_commission', XCCONFIG_DEV_ONE_INCH_COMMISSION)
update_dev_xcconfig('one_inch_commission_address', XCCONFIG_DEV_ONE_INCH_COMMISSION_ADDRESS)
update_dev_xcconfig('referral_app_server_url', XCCONFIG_DEV_REFERRAL_APP_SERVER_URL)
end

def apply_prod_xcconfig(swap_enabled, donate_enabled)
Expand All @@ -150,6 +153,7 @@ def apply_prod_xcconfig(swap_enabled, donate_enabled)
update_prod_xcconfig('one_inch_api_key', XCCONFIG_PROD_ONE_INCH_API_KEY)
update_prod_xcconfig('one_inch_commission', XCCONFIG_PROD_ONE_INCH_COMMISSION)
update_prod_xcconfig('one_inch_commission_address', XCCONFIG_PROD_ONE_INCH_COMMISSION_ADDRESS)
update_prod_xcconfig('referral_app_server_url', XCCONFIG_PROD_REFERRAL_APP_SERVER_URL)
end

def deploy_production
Expand Down

0 comments on commit 85d0963

Please sign in to comment.