Skip to content

Commit

Permalink
MOB-2167 - Fix UI when user's PK is unavailable (#644)
Browse files Browse the repository at this point in the history
* MOB-2167 - Fix UI when user's PK is unavailable

* Adjusted copies
  • Loading branch information
Oleg-Pecheneg authored Aug 16, 2024
1 parent ee3ec96 commit aceb462
Show file tree
Hide file tree
Showing 7 changed files with 93 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,18 @@ struct UDWallet: Codable, Hashable {
}
}

func getMnemonicsThrowing() throws -> String {
guard let mnemonics = getMnemonics() else { throw Error.failedToRetrieveSP }

return mnemonics
}

func getPrivateKeyThrowing() throws -> String {
guard let privateKey = getPrivateKey() else { throw Error.failedToRetrievePK }

return privateKey
}

private var walletConnectionInfo: WalletConnectionInfo?

func getExternalWallet() -> WCWalletsProvider.WalletRecord? {
Expand Down Expand Up @@ -96,6 +108,8 @@ struct UDWallet: Codable, Hashable {
enum Error: String, Swift.Error, RawValueLocalizable {
case failedSignature
case failedToFindMPCMetadata
case failedToRetrieveSP
case failedToRetrievePK
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ struct UDWallet: Codable, @unchecked Sendable {
case failedToFindWallet = "Failed to Find a Wallet"
case failedSignature
case failedToFindMPCMetadata
case failedToRetrievePK
case failedToRetrieveSP
}

struct WalletConnectionInfo: Codable {
Expand Down Expand Up @@ -72,6 +74,12 @@ struct UDWallet: Codable, @unchecked Sendable {
}
}

func getPrivateKeyThrowing() throws -> String {
guard let privateKey = getPrivateKey() else { throw Error.failedToRetrievePK }

return privateKey
}

func getPrivateKey() -> String? {
guard let ethWallet = self.ethWallet else { return nil }
switch ethWallet.securityType {
Expand All @@ -86,6 +94,12 @@ struct UDWallet: Codable, @unchecked Sendable {
}
}

func getMnemonicsThrowing() throws -> String {
guard let mnemonics = getMnemonics() else { throw Error.failedToRetrieveSP }

return mnemonics
}

func getMnemonics() -> String? {
guard let ethWallet = self.ethWallet else { return nil }
switch ethWallet.securityType {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,8 @@ extension String {
static let recoveryPhraseHelpText = "RECOVERY_PHRASE_HELP_TEXT"
static let recoveryPhraseHelpTextHighlighted = "RECOVERY_PHRASE_HELP_TEXT_HIGHLIGHTED"
static let recoveryPhraseHelpTextBullets = "RECOVERY_PHRASE_HELP_TEXT_BULLETS"
static let recoveryPhraseNotAvailableTitle = "RECOVERY_PHRASE_NOT_AVAILABLE_TITLE"
static let recoveryPhraseNotAvailableMessage = "RECOVERY_PHRASE_NOT_AVAILABLE_MESSAGE"

static let confirmYourWords = "CONFIRM_YOUR_WORDS"
static let iForgotMyWords = "I_FORGOT_MY_WORDS"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,22 +88,30 @@ extension BaseRecoveryPhrasePresenter: RecoveryPhrasePresenterProtocol {
// MARK: - Private methods
private extension BaseRecoveryPhrasePresenter {
func configureMnem() {
guard let wallet = self.wallet else { return }

switch recoveryType {
case .privateKey:
guard let privateKey = wallet.getPrivateKey() else { return }

self.privateKey = privateKey
view?.setPrivateKey(privateKey)
case .recoveryPhrase:
guard let mnem = wallet.getMnemonics()?.mnemonicsArray else { return }
do {
guard let wallet = self.wallet else {
throw BaseRecoveryPhrasePresenterError.failedToGetPK
}

configure(with: mnem)
switch recoveryType {
case .privateKey:
let privateKey = try wallet.getPrivateKeyThrowing()
self.privateKey = privateKey
view?.setPrivateKey(privateKey)
case .recoveryPhrase:
let seedPhrase = try wallet.getMnemonicsThrowing()
let mnem = seedPhrase.mnemonicsArray

try configure(with: mnem)
}
} catch {
view?.setRecoveryPhraseUnavailable()
}
}

func configure(with mnem: [String]) {

func configure(with mnem: [String]) throws {
guard mnem.count == 12 else { throw BaseRecoveryPhrasePresenterError.incorrectMnemonicsCount }

self.mnems = mnem

let leftMnems = Array(mnem[0...5])
Expand All @@ -119,4 +127,13 @@ private extension BaseRecoveryPhrasePresenter {
self?.view?.setCopiedToClipboardButtonForState(false)
}
}

enum BaseRecoveryPhrasePresenterError: String, LocalizedError {
case failedToGetPK
case incorrectMnemonicsCount

public var errorDescription: String? {
return rawValue
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,13 @@ protocol RecoveryPhraseViewControllerProtocol: BaseViewControllerProtocol & View
func setDoneButtonTitle(_ title: String)
func setDoneButtonHidden(_ isHidden: Bool)
func setSubtitleHidden(_ isHidden: Bool)
func setRecoveryPhraseUnavailable()
}

final class RecoveryPhraseViewController: BaseViewController, TitleVisibilityAfterLimitNavBarScrollingBehaviour, BlurVisibilityAfterLimitNavBarScrollingBehaviour {

@IBOutlet private weak var titleLabel: UDTitleLabel!
@IBOutlet private weak var subtitleLabel: UILabel!
@IBOutlet private weak var subTitleButton: UIButton!
@IBOutlet private weak var mnemonicsContainerView: UIView!
@IBOutlet private weak var copyToClipboardButton: TextButton!
Expand Down Expand Up @@ -127,6 +129,17 @@ extension RecoveryPhraseViewController: RecoveryPhraseViewControllerProtocol {
func setSubtitleHidden(_ isHidden: Bool) {
subTitleButton.isHidden = isHidden
}

func setRecoveryPhraseUnavailable() {
mnemonicsContainerView.isHidden = true
subtitleLabel.isHidden = false
subtitleLabel.setAttributedTextWith(text: String.Constants.recoveryPhraseNotAvailableMessage.localized(),
font: .currentFont(withSize: 17, weight: .regular),
textColor: .foregroundDefault,
alignment: .center)
titleLabel.setTitle(String.Constants.recoveryPhraseNotAvailableTitle.localized())
setExplanationText("")
}
}

// MARK: - UIScrollViewDelegate
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="20037" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="32700.99.1234" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<device id="retina6_1" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="20020"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22685"/>
<capability name="Named colors" minToolsVersion="9.0"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="System colors in document resources" minToolsVersion="11.0"/>
Expand All @@ -23,6 +23,7 @@
<outlet property="rightMnemonicsStackView" destination="C11-lc-vJS" id="zkY-NN-np0"/>
<outlet property="scrollView" destination="oC6-m2-C7e" id="2i9-mY-YDj"/>
<outlet property="subTitleButton" destination="bTU-8r-Yhd" id="FnT-db-JQa"/>
<outlet property="subtitleLabel" destination="46e-pQ-bnf" id="K7m-eb-Ptk"/>
<outlet property="titleLabel" destination="e1C-oj-gDw" id="drZ-KB-Tzf"/>
<outlet property="view" destination="d7V-7Z-4i9" id="eTd-bL-ibX"/>
<outletCollection property="blurCoverViews" destination="wUh-Vu-LXP" collectionClass="NSMutableArray" id="VrF-Xa-wRx"/>
Expand All @@ -35,7 +36,7 @@
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="oC6-m2-C7e">
<rect key="frame" x="0.0" y="44" width="414" height="818"/>
<rect key="frame" x="0.0" y="48" width="414" height="814"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="1Ca-eN-xu2">
<rect key="frame" x="0.0" y="0.0" width="414" height="1"/>
Expand All @@ -45,19 +46,25 @@
</constraints>
</view>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" alignment="center" spacing="32" translatesAutoresizingMaskIntoConstraints="NO" id="KYo-Fj-F2E">
<rect key="frame" x="16" y="60" width="382" height="1108.5"/>
<rect key="frame" x="16" y="60" width="382" height="1145.5"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" alignment="center" spacing="16" translatesAutoresizingMaskIntoConstraints="NO" id="PVW-Lw-nI0">
<rect key="frame" x="81.5" y="0.0" width="219.5" height="83.5"/>
<rect key="frame" x="70.5" y="0.0" width="241.5" height="120.5"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Recovery phrase" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="e1C-oj-gDw" customClass="UDTitleLabel" customModule="domains_manager_ios" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="219.5" height="33.5"/>
<rect key="frame" x="11" y="0.0" width="219.5" height="33.5"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="28"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<label hidden="YES" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="46e-pQ-bnf">
<rect key="frame" x="100" y="41.5" width="41.5" height="0.0"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="bTU-8r-Yhd">
<rect key="frame" x="19" y="49.5" width="181.5" height="34"/>
<rect key="frame" x="0.0" y="49.5" width="241.5" height="71"/>
<accessibility key="accessibilityConfiguration">
<accessibilityTraits key="traits" button="YES" notEnabled="YES"/>
<bool key="isElement" value="NO"/>
Expand All @@ -70,7 +77,7 @@
</subviews>
</stackView>
<view clipsSubviews="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="av9-7g-LPy">
<rect key="frame" x="43" y="115.5" width="296" height="894"/>
<rect key="frame" x="43" y="152.5" width="296" height="894"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" translatesAutoresizingMaskIntoConstraints="NO" id="MFp-xX-3FX">
<rect key="frame" x="0.0" y="0.0" width="296" height="894"/>
Expand Down Expand Up @@ -488,7 +495,7 @@
</userDefinedRuntimeAttributes>
</view>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="t4J-o6-fm7">
<rect key="frame" x="3" y="1041.5" width="376.5" height="67"/>
<rect key="frame" x="3" y="1078.5" width="376.5" height="67"/>
<string key="text">For your eyes only! Anyone who has access to your 12 word recovery phrase can access your entire wallet. Store your recovery phrase somewhere safe.
Learn more</string>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
Expand Down Expand Up @@ -544,7 +551,7 @@ Learn more</string>
</view>
</objects>
<resources>
<image name="checkCircle" width="20" height="20"/>
<image name="checkCircle" width="56" height="57"/>
<namedColor name="backgroundOverlay">
<color red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</namedColor>
Expand All @@ -555,7 +562,7 @@ Learn more</string>
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</systemColor>
<systemColor name="systemGreenColor">
<color red="0.20392156862745098" green="0.7803921568627451" blue="0.34901960784313724" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color red="0.20392156859999999" green="0.78039215689999997" blue="0.34901960780000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
</resources>
</document>
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,8 @@
"RECOVERY_PHRASE_HELP_TEXT" = "A recovery phrase is the human-readable form of your wallet private key — the unique, secret passcode used to authenticate and encrypt your wallet access. This phrase allows you to sign transactions, confirm ownership of your Web3 domains, and recover them in the event that your mobile device is lost, stolen, or becomes inaccessible.\n\nHowever you choose to store your recovery phrase, you should consider two things:\n\n• Your 12 word recovery phrase should be safe from other people.\n• Your 12 word recovery phrase should be in a reliable location that you’ll always have access to.\n\nNote: Unstoppable Domains cannot recover your 12 word recovery phrase for you.";
"RECOVERY_PHRASE_HELP_TEXT_HIGHLIGHTED" = "Note: Unstoppable Domains cannot recover your 12 word recovery phrase for you.";
"RECOVERY_PHRASE_HELP_TEXT_BULLETS" = "• Your 12 word recovery phrase should be safe from other people.\n• Your 12 word recovery phrase should be in a reliable location that you’ll always have access to.";
"RECOVERY_PHRASE_NOT_AVAILABLE_TITLE" = "Wallet not available";
"RECOVERY_PHRASE_NOT_AVAILABLE_MESSAGE" = "The app doesn't have access to the secure storage with private keys. If this is a new phone please remove this wallet and import it manually, using the private key or a recovery phrase from your old phone / manually recorded keys.";

// Confirm words screen
"CONFIRM_YOUR_WORDS" = "Confirm your words";
Expand Down

0 comments on commit aceb462

Please sign in to comment.