mirror of
https://github.com/luxfi/safe-ios.git
synced 2026-10-30 15:19:20 +00:00
128 lines
5.0 KiB
Swift
128 lines
5.0 KiB
Swift
//
|
|
// StartWalletConnectionViewController.swift
|
|
// Multisig
|
|
//
|
|
// Created by Dmitry Bespalov on 21.03.22.
|
|
// Copyright © 2022 Gnosis Ltd. All rights reserved.
|
|
//
|
|
|
|
import Foundation
|
|
import UIKit
|
|
|
|
class StartWalletConnectionViewController: PendingWalletActionViewController {
|
|
var onSuccess: (_ connection: WebConnection) -> Void = { _ in }
|
|
|
|
var qrCodeController: QRCodeShareViewController!
|
|
|
|
/// Constructor of a new WalletConnect connection request (session request) screen
|
|
/// - Parameters:
|
|
/// - wallet: if nil then will display qr code; otherwise will try to open the wallet
|
|
/// - chain: required chain for the account to be in
|
|
/// - keyInfo: if nil then will create new connection; otherwise will restrict the connection to pre-existing account
|
|
convenience init(wallet: WCAppRegistryEntry?, chain: Chain, keyInfo: KeyInfo? = nil) {
|
|
self.init(namedClass: PendingWalletActionViewController.self)
|
|
self.wallet = wallet
|
|
self.chain = chain
|
|
self.keyInfo = keyInfo
|
|
}
|
|
|
|
override func viewDidLoad() {
|
|
super.viewDidLoad()
|
|
if let wallet = wallet {
|
|
titleLabel.text = "Connecting to \(wallet.name)..."
|
|
} else {
|
|
titleLabel.text = "Scan QR code in your wallet"
|
|
qrCodeController = QRCodeShareViewController()
|
|
viewControllers = [qrCodeController]
|
|
activityIndicator.isHidden = true
|
|
}
|
|
}
|
|
|
|
|
|
override func main() {
|
|
Task { @MainActor in
|
|
guard connection == nil, let chainIdStr = chain?.id, let chainId = Int(chainIdStr) else { return }
|
|
do {
|
|
connection = try await WebConnectionController.shared.connect(wallet: wallet, chainId: chainId)
|
|
WebConnectionController.shared.attach(observer: self, to: connection)
|
|
if wallet != nil {
|
|
openWallet()
|
|
} else {
|
|
displayChild(at: 0, in: contentView)
|
|
qrCodeController.value = connection.connectionURL.absoluteString
|
|
}
|
|
} catch {
|
|
App.shared.snackbar.show(message: error.localizedDescription)
|
|
doCancel()
|
|
}
|
|
}
|
|
}
|
|
|
|
override func didUpdate(connection: WebConnection) {
|
|
self.connection = connection
|
|
switch connection.status {
|
|
case .opened:
|
|
guard checkCorrectAccount() else { return }
|
|
guard checkCorrectChain() else { return }
|
|
|
|
if let keyInfo = keyInfo, OwnerKeyController.updateKey(keyInfo, connection: connection, wallet: wallet) {
|
|
App.shared.snackbar.show(message: "Key connected successfully")
|
|
}
|
|
|
|
self.dismiss(animated: true) { [weak self] in
|
|
self?.onSuccess(connection)
|
|
}
|
|
case .final:
|
|
if let string = connection.lastError {
|
|
App.shared.snackbar.show(message: string)
|
|
}
|
|
doCancel()
|
|
default:
|
|
// do nothing
|
|
break
|
|
}
|
|
}
|
|
|
|
func checkCorrectAccount() -> Bool {
|
|
if let keyInfo = keyInfo, !connection.accounts.contains(keyInfo.address) {
|
|
App.shared.snackbar.show(message: "Unexpected address. Please connnect to account \(keyInfo.address.ellipsized()).")
|
|
WebConnectionController.shared.userDidDisconnect(connection)
|
|
return false
|
|
} else if keyInfo == nil, let account = connection.accounts.first, let existing = (try? KeyInfo.firstKey(address: account)) {
|
|
let name = existing.displayName.prefix(30)
|
|
App.shared.snackbar.show(message: "Address '\(account.ellipsized())' already exists with name '\(name)'. Please connect another account.")
|
|
WebConnectionController.shared.userDidDisconnect(connection)
|
|
return false
|
|
} else {
|
|
return true
|
|
}
|
|
}
|
|
|
|
func checkCorrectChain() -> Bool {
|
|
// always succeeds, but shows warning message in case networks are different.
|
|
|
|
if let chain = chain,
|
|
let connectedChainId = connection.chainId,
|
|
let selectedChainId = chain.id,
|
|
String(connectedChainId) != selectedChainId {
|
|
let connectedChain = Chain.by(String(connectedChainId))
|
|
let selectedName = chain.name ?? "Chain Id \(selectedChainId)"
|
|
let connectedName = connectedChain?.name ?? "Chain Id \(connectedChainId)"
|
|
let icon = UIImage(systemName: "exclamationmark.triangle.fill")!.withTintColor(.systemYellow, renderingMode: .alwaysOriginal)
|
|
App.shared.snackbar.show(
|
|
message: "Selected Safe's network '\(selectedName)' is different from the network in the wallet: '\(connectedName)'.",
|
|
icon: SnackbarViewController.IconSource.image(icon)
|
|
)
|
|
}
|
|
return true
|
|
}
|
|
|
|
override func didTapCancel(_ sender: Any) {
|
|
if let connection = connection {
|
|
WebConnectionController.shared.userDidCancel(connection)
|
|
} else {
|
|
doCancel()
|
|
}
|
|
}
|
|
}
|