blockchainethereumblockchain-walleterc20erc721walletxdaidappdecentralizederc1155erc875iosswifttokens
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
280 lines
10 KiB
280 lines
10 KiB
// Copyright SIX DAY LLC. All rights reserved.
|
|
|
|
import Foundation
|
|
import TrustKeystore
|
|
import UIKit
|
|
import RealmSwift
|
|
|
|
protocol InCoordinatorDelegate: class {
|
|
func didCancel(in coordinator: InCoordinator)
|
|
func didUpdateAccounts(in coordinator: InCoordinator)
|
|
}
|
|
|
|
enum InCoordinatorError: LocalizedError {
|
|
case onlyWatchAccount
|
|
|
|
var errorDescription: String? {
|
|
return NSLocalizedString(
|
|
"InCoordinatorError.onlyWatchAccount",
|
|
value: "This wallet could be only used for watching. Import Private Key/Keystore to sign transactions",
|
|
comment: ""
|
|
)
|
|
}
|
|
}
|
|
|
|
class InCoordinator: Coordinator {
|
|
|
|
let navigationController: UINavigationController
|
|
var coordinators: [Coordinator] = []
|
|
let initialWallet: Wallet
|
|
var keystore: Keystore
|
|
var config: Config
|
|
let appTracker: AppTracker
|
|
weak var delegate: InCoordinatorDelegate?
|
|
var transactionCoordinator: TransactionCoordinator? {
|
|
return self.coordinators.flatMap { $0 as? TransactionCoordinator }.first
|
|
}
|
|
lazy var helpUsCoordinator: HelpUsCoordinator = {
|
|
return HelpUsCoordinator(
|
|
navigationController: navigationController,
|
|
appTracker: appTracker
|
|
)
|
|
}()
|
|
|
|
init(
|
|
navigationController: UINavigationController = NavigationController(),
|
|
wallet: Wallet,
|
|
keystore: Keystore,
|
|
config: Config = Config(),
|
|
appTracker: AppTracker = AppTracker()
|
|
) {
|
|
self.navigationController = navigationController
|
|
self.initialWallet = wallet
|
|
self.keystore = keystore
|
|
self.config = config
|
|
self.appTracker = appTracker
|
|
}
|
|
|
|
func start() {
|
|
showTabBar(for: initialWallet)
|
|
checkDevice()
|
|
|
|
helpUsCoordinator.start()
|
|
addCoordinator(helpUsCoordinator)
|
|
}
|
|
|
|
func showTabBar(for account: Wallet) {
|
|
|
|
let migration = MigrationInitializer(account: account, chainID: config.chainID)
|
|
migration.perform()
|
|
|
|
let web3 = self.web3(for: config.server)
|
|
let realm = self.realm(for: migration.config)
|
|
let tokensStorage = TokensDataStore(realm: realm, account: account, config: config, web3: web3)
|
|
let balance = BalanceCoordinator(account: account, storage: tokensStorage)
|
|
let session = WalletSession(
|
|
account: account,
|
|
config: config,
|
|
web3: web3,
|
|
balanceCoordinator: balance
|
|
)
|
|
let transactionsStorage = TransactionsStorage(
|
|
realm: realm
|
|
)
|
|
let inCoordinatorViewModel = InCoordinatorViewModel(config: config)
|
|
let transactionCoordinator = TransactionCoordinator(
|
|
session: session,
|
|
storage: transactionsStorage,
|
|
keystore: keystore,
|
|
tokensStorage: tokensStorage
|
|
)
|
|
transactionCoordinator.rootViewController.tabBarItem = UITabBarItem(title: NSLocalizedString("transactions.tabbar.item.title", value: "Transactions", comment: ""), image: R.image.feed(), selectedImage: nil)
|
|
transactionCoordinator.delegate = self
|
|
transactionCoordinator.start()
|
|
addCoordinator(transactionCoordinator)
|
|
|
|
let tabBarController = TabBarController()
|
|
tabBarController.viewControllers = [
|
|
transactionCoordinator.navigationController,
|
|
]
|
|
tabBarController.tabBar.isTranslucent = false
|
|
tabBarController.didShake = { [weak self] in
|
|
if inCoordinatorViewModel.canActivateDebugMode {
|
|
self?.activateDebug()
|
|
}
|
|
}
|
|
|
|
if inCoordinatorViewModel.browserAvailable {
|
|
let coordinator = BrowserCoordinator(session: session, keystore: keystore)
|
|
coordinator.delegate = self
|
|
coordinator.start()
|
|
coordinator.rootViewController.tabBarItem = UITabBarItem(
|
|
title: NSLocalizedString("browser.tabbar.item.title", value: "Browser", comment: ""),
|
|
image: R.image.coins(),
|
|
selectedImage: nil
|
|
)
|
|
addCoordinator(coordinator)
|
|
tabBarController.viewControllers?.insert(coordinator.navigationController, at: 0)
|
|
}
|
|
|
|
if inCoordinatorViewModel.tokensAvailable {
|
|
let tokenCoordinator = TokensCoordinator(
|
|
session: session,
|
|
keystore: keystore,
|
|
tokensStorage: tokensStorage
|
|
)
|
|
tokenCoordinator.rootViewController.tabBarItem = UITabBarItem(title: NSLocalizedString("tokens.tabbar.item.title", value: "Tokens", comment: ""), image: R.image.coins(), selectedImage: nil)
|
|
tokenCoordinator.delegate = self
|
|
tokenCoordinator.start()
|
|
addCoordinator(tokenCoordinator)
|
|
tabBarController.viewControllers?.append(tokenCoordinator.navigationController)
|
|
}
|
|
|
|
if inCoordinatorViewModel.exchangeAvailable {
|
|
let exchangeCoordinator = ExchangeCoordinator(session: session, keystore: keystore)
|
|
exchangeCoordinator.rootViewController.tabBarItem = UITabBarItem(title: NSLocalizedString("exchange.tabbar.item.title", value: "Exchange", comment: ""), image: R.image.exchange(), selectedImage: nil)
|
|
exchangeCoordinator.start()
|
|
addCoordinator(exchangeCoordinator)
|
|
tabBarController.viewControllers?.append(exchangeCoordinator.navigationController)
|
|
}
|
|
|
|
let settingsCoordinator = SettingsCoordinator(
|
|
keystore: keystore,
|
|
session: session,
|
|
storage: transactionsStorage
|
|
)
|
|
settingsCoordinator.rootViewController.tabBarItem = UITabBarItem(
|
|
title: NSLocalizedString("settings.navigation.title", value: "Settings", comment: ""),
|
|
image: R.image.settings_icon(),
|
|
selectedImage: nil
|
|
)
|
|
settingsCoordinator.delegate = self
|
|
settingsCoordinator.start()
|
|
addCoordinator(settingsCoordinator)
|
|
tabBarController.viewControllers?.append(settingsCoordinator.navigationController)
|
|
|
|
navigationController.setViewControllers(
|
|
[tabBarController],
|
|
animated: false
|
|
)
|
|
navigationController.setNavigationBarHidden(true, animated: false)
|
|
addCoordinator(transactionCoordinator)
|
|
|
|
// let coor = SignMessageCoordinator(navigationController: navigationController, keystore: keystore, account: Account(address: account.address))
|
|
// coor.start(with: "Hello")
|
|
|
|
keystore.recentlyUsedWallet = account
|
|
}
|
|
|
|
@objc func activateDebug() {
|
|
config.isDebugEnabled = !config.isDebugEnabled
|
|
|
|
guard let transactionCoordinator = transactionCoordinator else { return }
|
|
restart(for: transactionCoordinator.session.account, in: transactionCoordinator)
|
|
}
|
|
|
|
func restart(for account: Wallet, in coordinator: TransactionCoordinator) {
|
|
coordinator.navigationController.dismiss(animated: true, completion: nil)
|
|
coordinator.stop()
|
|
removeAllCoordinators()
|
|
showTabBar(for: account)
|
|
}
|
|
|
|
func checkDevice() {
|
|
let deviceChecker = CheckDeviceCoordinator(
|
|
navigationController: navigationController,
|
|
jailbreakChecker: DeviceChecker()
|
|
)
|
|
|
|
deviceChecker.start()
|
|
|
|
addCoordinator(deviceChecker)
|
|
}
|
|
|
|
func showPaymentFlow(for type: PaymentFlow) {
|
|
guard let transactionCoordinator = transactionCoordinator else { return }
|
|
let session = transactionCoordinator.session
|
|
let tokenStorage = transactionCoordinator.tokensStorage
|
|
|
|
switch session.account.type {
|
|
case .real(let account):
|
|
let coordinator = PaymentCoordinator(
|
|
flow: type,
|
|
session: session,
|
|
keystore: keystore,
|
|
storage: tokenStorage,
|
|
account: account
|
|
)
|
|
coordinator.delegate = self
|
|
navigationController.present(coordinator.navigationController, animated: true, completion: nil)
|
|
coordinator.start()
|
|
addCoordinator(coordinator)
|
|
case .watch: break
|
|
}
|
|
}
|
|
|
|
private func handlePendingTransaction(transaction: SentTransaction) {
|
|
transactionCoordinator?.dataCoordinator.add(transaction: transaction)
|
|
}
|
|
|
|
private func realm(for config: Realm.Configuration) -> Realm {
|
|
return try! Realm(configuration: config)
|
|
}
|
|
|
|
private func web3(for server: RPCServer) -> Web3Swift {
|
|
return Web3Swift(url: config.rpcURL)
|
|
}
|
|
}
|
|
|
|
extension InCoordinator: TransactionCoordinatorDelegate {
|
|
func didPress(for type: PaymentFlow, in coordinator: TransactionCoordinator) {
|
|
showPaymentFlow(for: type)
|
|
}
|
|
|
|
func didCancel(in coordinator: TransactionCoordinator) {
|
|
delegate?.didCancel(in: self)
|
|
coordinator.navigationController.dismiss(animated: true, completion: nil)
|
|
coordinator.stop()
|
|
removeAllCoordinators()
|
|
}
|
|
}
|
|
|
|
extension InCoordinator: SettingsCoordinatorDelegate {
|
|
func didCancel(in coordinator: SettingsCoordinator) {
|
|
removeCoordinator(coordinator)
|
|
coordinator.navigationController.dismiss(animated: true, completion: nil)
|
|
delegate?.didCancel(in: self)
|
|
}
|
|
|
|
func didRestart(with account: Wallet, in coordinator: SettingsCoordinator) {
|
|
guard let transactionCoordinator = transactionCoordinator else { return }
|
|
restart(for: account, in: transactionCoordinator)
|
|
}
|
|
|
|
func didUpdateAccounts(in coordinator: SettingsCoordinator) {
|
|
delegate?.didUpdateAccounts(in: self)
|
|
}
|
|
}
|
|
|
|
extension InCoordinator: TokensCoordinatorDelegate {
|
|
func didPress(for type: PaymentFlow, in coordinator: TokensCoordinator) {
|
|
showPaymentFlow(for: type)
|
|
}
|
|
}
|
|
|
|
extension InCoordinator: PaymentCoordinatorDelegate {
|
|
func didCreatePendingTransaction(transaction: SentTransaction, in coordinator: PaymentCoordinator) {
|
|
handlePendingTransaction(transaction: transaction)
|
|
}
|
|
|
|
func didCancel(in coordinator: PaymentCoordinator) {
|
|
coordinator.navigationController.dismiss(animated: true, completion: nil)
|
|
removeCoordinator(coordinator)
|
|
}
|
|
}
|
|
|
|
extension InCoordinator: BrowserCoordinatorDelegate {
|
|
func didSentTransaction(transaction: SentTransaction, in coordinator: BrowserCoordinator) {
|
|
handlePendingTransaction(transaction: transaction)
|
|
}
|
|
}
|
|
|