ZcashLightClientKit/Example/ZcashLightClientSample/ZcashLightClientSample/Derivation Tool/DerivationToolViewControlle...

185 lines
6.3 KiB
Swift

//
// DerivationToolViewController.swift
// ZcashLightClientSample
//
// Created by Francisco Gindre on 12/9/20.
// Copyright © 2020 Electric Coin Company. All rights reserved.
//
import UIKit
import ZcashLightClientKit
import MnemonicSwift
class DerivationToolViewController: UIViewController {
enum DerivationErrors: Error {
case couldNotDeriveSpendingKeys(underlyingError: Error)
case couldNotDeriveViewingKeys(underlyingError: Error)
case unknown
}
@IBOutlet weak var seedTextView: UITextView!
@IBOutlet weak var seedTextLabel: UILabel!
@IBOutlet weak var shieldedAddressLabel: UILabel!
@IBOutlet weak var transparentAddressLabel: UILabel!
@IBOutlet weak var spendingKeyLabel: UILabel!
@IBOutlet weak var extendedFullViewingKeyLabel: UILabel!
@IBOutlet weak var deriveButton: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
deriveButton.isEnabled = isValidSeed(seedTextView.text)
updateValidationUI()
}
@IBAction func spendingKeyTapped(_ gesture: UIGestureRecognizer) {
loggerProxy.event("spending key copied to clipboard")
UIPasteboard.general.string = self.spendingKeyLabel.text
let alert = UIAlertController(
title: "",
message: "Spending Key Copied to clipboard",
preferredStyle: UIAlertController.Style.alert
)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertAction.Style.default, handler: nil))
self.present(alert, animated: true, completion: nil)
}
@IBAction func viewingKeyTapped(_ gesture: UIGestureRecognizer) {
loggerProxy.event("extended full viewing key copied to clipboard")
UIPasteboard.general.string = self.extendedFullViewingKeyLabel.text
let alert = UIAlertController(
title: "",
message: "extended full viewing key copied to clipboard",
preferredStyle: UIAlertController.Style.alert
)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertAction.Style.default, handler: nil))
self.present(alert, animated: true, completion: nil)
}
@IBAction func zAddressTapped(_ gesture: UIGestureRecognizer) {
loggerProxy.event("zAddress copied to clipboard")
UIPasteboard.general.string = self.shieldedAddressLabel.text
let alert = UIAlertController(
title: "",
message: "zAddress Copied to clipboard",
preferredStyle: UIAlertController.Style.alert
)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertAction.Style.default, handler: nil))
self.present(alert, animated: true, completion: nil)
}
@IBAction func tAddressTapped(_ gesture: UIGestureRecognizer) {
loggerProxy.event("tAddress copied to clipboard")
UIPasteboard.general.string = self.transparentAddressLabel.text
let alert = UIAlertController(
title: "",
message: "tAddress Copied to clipboard",
preferredStyle: UIAlertController.Style.alert
)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertAction.Style.default, handler: nil))
self.present(alert, animated: true, completion: nil)
}
@IBAction func deriveButtonTapped(_ sender: Any) {
do {
try deriveFrom(seedPhrase: seedTextView.text)
} catch {
fail(error)
clearLabels()
}
}
func deriveFrom(seedPhrase: String) throws {
let seedBytes = try Mnemonic.deterministicSeedBytes(from: seedPhrase)
let derivationTool = DerivationTool(networkType: kZcashNetwork.networkType)
guard let spendingKey = try derivationTool.deriveSpendingKeys(seed: seedBytes, numberOfAccounts: 1).first else {
throw DerivationErrors.couldNotDeriveSpendingKeys(underlyingError: DerivationErrors.unknown)
}
guard let viewingKey = try derivationTool.deriveUnifiedFullViewingKeysFromSeed(seedBytes, numberOfAccounts: 1).first else {
throw DerivationErrors.couldNotDeriveViewingKeys(underlyingError: DerivationErrors.unknown)
}
let unifiedAddress = try derivationTool.deriveUnifiedAddress(from: viewingKey)
let transparentAddress = try derivationTool.deriveTransparentAddress(seed: seedBytes)
updateLabels(
spendingKey: spendingKey.stringEncoded,
viewingKey: viewingKey.stringEncoded,
shieldedAddress: unifiedAddress.stringEncoded,
transaparentAddress: transparentAddress.stringEncoded
)
}
func updateLabels(
spendingKey: String = "",
viewingKey: String = "",
shieldedAddress: String = "",
transaparentAddress: String = ""
) {
spendingKeyLabel.text = spendingKey
extendedFullViewingKeyLabel.text = viewingKey
shieldedAddressLabel.text = shieldedAddress
transparentAddressLabel.text = transaparentAddress
}
func clearLabels() {
updateLabels()
}
func fail(_ error: Error) {
let alert = UIAlertController(title: "Error", message: "\(error)", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertAction.Style.default, handler: nil))
self.present(alert, animated: true, completion: nil)
}
func setValidSeed() {
seedTextLabel.text = "This is a valid seed phrase"
seedTextLabel.textColor = UIColor.systemGreen
}
func setInvalidSeed() {
seedTextLabel.text = "Invalid seed phrase"
seedTextLabel.textColor = UIColor.red
}
func isValidSeed(_ seed: String) -> Bool {
do {
try Mnemonic.validate(mnemonic: seed)
} catch {
return false
}
return true
}
func updateValidationUI() {
guard isValidSeed(seedTextView.text) else {
setInvalidSeed()
return
}
setValidSeed()
}
}
extension DerivationToolViewController: UITextViewDelegate {
func textViewDidEndEditing(_ textView: UITextView) {
updateValidationUI()
}
func textViewDidChange(_ textView: UITextView) {
deriveButton.isEnabled = isValidSeed(textView.text)
}
}