mirror of
https://github.com/luxfi/safe-ios.git
synced 2026-10-30 15:19:20 +00:00
192 lines
6.4 KiB
Swift
192 lines
6.4 KiB
Swift
//
|
|
// GenerateKeyFlow.swift
|
|
// Multisig
|
|
//
|
|
// Created by Dmitry Bespalov on 04.05.22.
|
|
// Copyright © 2022 Gnosis Ltd. All rights reserved.
|
|
//
|
|
|
|
import Foundation
|
|
import UIKit
|
|
|
|
/// Flow for generating a new private key
|
|
///
|
|
/// Screen sequence:
|
|
///
|
|
/// 1. Intro (in superclass)
|
|
/// 2. Key is generated
|
|
/// 3. Enter Name (in superclass)
|
|
/// 4. Create Passcode (in superclass)
|
|
/// 5. Backup Key
|
|
/// 6. Add Key as Safe Owner
|
|
/// 6.1. Add as new owner OR
|
|
/// 6.2. Replace existing owner
|
|
/// 7. If user selected 'open tx details' then flow closes.
|
|
/// 7.1. Otherwise, Key Details screen
|
|
class GenerateKeyFlow: AddKeyFlow {
|
|
var flowFactory: GenerateKeyFactory {
|
|
factory as! GenerateKeyFactory
|
|
}
|
|
|
|
var safe: Safe?
|
|
|
|
var backupFlow: BackupFlow!
|
|
var addOwnerFlow: AddOwnerFlow!
|
|
var replaceOwnerFlow: ReplaceOwnerFlow!
|
|
|
|
var parameters: GenerateKeyParameters? {
|
|
keyParameters as? GenerateKeyParameters
|
|
}
|
|
|
|
init(completion: @escaping (Bool) -> Void) {
|
|
super.init(factory: GenerateKeyFactory(), completion: completion)
|
|
}
|
|
|
|
override func didIntro() {
|
|
let privateKey = OwnerKeyController.generate()
|
|
keyParameters = GenerateKeyParameters(address: privateKey.address, keyName: nil, privateKey: privateKey)
|
|
didGetKey()
|
|
}
|
|
|
|
override func doImport() -> Bool {
|
|
guard let privateKey = parameters?.privateKey,
|
|
let name = parameters?.name else {
|
|
assertionFailure("Missing key arguments")
|
|
return false
|
|
}
|
|
|
|
return OwnerKeyController.importKey(privateKey, name: name, type: .deviceGenerated, isDerivedFromSeedPhrase: true)
|
|
}
|
|
|
|
func backup() {
|
|
guard let mnemonic = parameters?.privateKey?.mnemonic else {
|
|
assertionFailure("No mnemonic found")
|
|
return
|
|
}
|
|
|
|
backupFlow = BackupFlow(mnemonic: mnemonic) { [unowned self] _ in
|
|
backupFlow = nil
|
|
addKeyAsOwner()
|
|
}
|
|
push(flow: backupFlow)
|
|
}
|
|
|
|
func addKeyAsOwner() {
|
|
safe = try? Safe.getSelected()
|
|
didAddKeyAsOwner()
|
|
}
|
|
|
|
func addOwner() {
|
|
guard let address = parameters?.address else {
|
|
assertionFailure("Missing key arguments")
|
|
return
|
|
}
|
|
addOwnerFlow = AddOwnerFlow(newOwner: address, safe: safe!) { [unowned self] skippedTxDetails in
|
|
addOwnerFlow = nil
|
|
didAddKeyAsOwner(openKeyDetails: skippedTxDetails)
|
|
}
|
|
push(flow: addOwnerFlow)
|
|
}
|
|
|
|
func replaceOwner() {
|
|
replaceOwnerFlow = ReplaceOwnerFlow(newOwner: parameters!.address, safe: safe!) { [unowned self] skippedTxDetails in
|
|
replaceOwnerFlow = nil
|
|
didReplaceKeyAsOwner(openKeyDetails: skippedTxDetails)
|
|
}
|
|
push(flow: replaceOwnerFlow)
|
|
}
|
|
|
|
func didAddKeyAsOwner(openKeyDetails: Bool = true) {
|
|
guard openKeyDetails else {
|
|
stop(success: true)
|
|
return
|
|
}
|
|
details()
|
|
}
|
|
|
|
func didReplaceKeyAsOwner(openKeyDetails: Bool = true) {
|
|
guard openKeyDetails else {
|
|
stop(success: true)
|
|
return
|
|
}
|
|
details()
|
|
}
|
|
|
|
func details() {
|
|
guard let address = parameters?.address else {
|
|
assertionFailure("Missing key arguments")
|
|
return
|
|
}
|
|
|
|
navigationController.setNavigationBarHidden(false, animated: true)
|
|
let key = try? KeyInfo.firstKey(address: address)
|
|
assert(key != nil)
|
|
let keyVC = flowFactory.details(keyInfo: key!) { [unowned self] in
|
|
stop(success: true)
|
|
}
|
|
show(keyVC)
|
|
}
|
|
|
|
override func didDelegateKeySetup() {
|
|
backup()
|
|
}
|
|
}
|
|
|
|
class GenerateKeyFactory: AddKeyFlowFactory {
|
|
override func intro(completion: @escaping () -> Void) -> AddKeyOnboardingViewController {
|
|
let introVC = super.intro(completion: completion)
|
|
introVC.cards = [
|
|
.init(image: UIImage(named: "ico-onboarding-import-key-1"),
|
|
title: "How does it work?",
|
|
body: "To use this app as an owner in the Safe Account, you can create a key and add it as an owner of your Safe Account. When you tap Next, the app will create a new private key from a new unique seed phrase."),
|
|
|
|
.init(image: UIImage(named: "ico-onboarding-import-key-2"),
|
|
title: "How secure is that?",
|
|
body: "The owner key and the seed phrase are stored in the device's secure store - iOS Keychain.",
|
|
link: .init(title: "How is a private key stored on mobile?", url: App.configuration.help.keySecurityURL)),
|
|
|
|
.init(image: UIImage(named: "ico-onboarding-import-key-3"),
|
|
title: "How to export?",
|
|
body: "To export your owner key or seed phrase, navigate to the key details.")]
|
|
introVC.viewTrackingEvent = .generateOwnerOnboarding
|
|
introVC.navigationItem.title = "Create Owner Key"
|
|
introVC.navigationItem.largeTitleDisplayMode = .never
|
|
return introVC
|
|
}
|
|
|
|
func inviteToAddOwner(share: @escaping () -> Void, onSkip: @escaping () -> ()) -> CreateInviteOwnerIntroViewController {
|
|
let introVC = CreateInviteOwnerIntroViewController(onShare: share, onSkip: onSkip)
|
|
ViewControllerFactory.makeTransparentNavigationBar(introVC)
|
|
return introVC
|
|
}
|
|
|
|
func shareAddKeyAsOwnerLink(owner: Address, safe: Safe, onFinish: @escaping () -> Void) -> UIViewController {
|
|
let vc = ShareAddOwnerLinkViewController(owner: owner,
|
|
safe: safe,
|
|
onFinish: onFinish)
|
|
|
|
ViewControllerFactory.makeTransparentNavigationBar(vc)
|
|
ViewControllerFactory.addCloseButton(vc)
|
|
|
|
return vc
|
|
}
|
|
|
|
func addAsOwner(added: @escaping () -> Void, replaced: @escaping () -> Void, skipped: @escaping () -> Void) -> AddKeyAsOwnerIntroViewController {
|
|
let introVC = AddKeyAsOwnerIntroViewController()
|
|
ViewControllerFactory.makeTransparentNavigationBar(introVC)
|
|
introVC.onAdd = added
|
|
introVC.onReplace = replaced
|
|
introVC.onSkip = skipped
|
|
return introVC
|
|
}
|
|
}
|
|
|
|
class GenerateKeyParameters: AddKeyParameters {
|
|
var privateKey: PrivateKey?
|
|
|
|
init(address: Address, keyName: String?, privateKey: PrivateKey?) {
|
|
self.privateKey = privateKey
|
|
super.init(address: address, name: keyName, type: KeyType.deviceGenerated)
|
|
}
|
|
}
|