diff --git a/AlphaWallet/Browser/Coordinators/DappBrowserCoordinator.swift b/AlphaWallet/Browser/Coordinators/DappBrowserCoordinator.swift index c964fd4d3..468f61747 100644 --- a/AlphaWallet/Browser/Coordinators/DappBrowserCoordinator.swift +++ b/AlphaWallet/Browser/Coordinators/DappBrowserCoordinator.swift @@ -517,11 +517,15 @@ extension DappBrowserCoordinator: BrowserViewControllerDelegate { case .real(let account): return performDappAction(account: account) case .watch(let account): - switch action { - case .signTransaction, .sendTransaction, .signMessage, .signPersonalMessage, .signTypedMessage, .signTypedMessageV3, .unknown, .sendRawTransaction: - return rejectDappAction() - case .walletAddEthereumChain, .walletSwitchEthereumChain, .ethCall: + if config.development.shouldPretendIsRealWallet { return performDappAction(account: account) + } else { + switch action { + case .signTransaction, .sendTransaction, .signMessage, .signPersonalMessage, .signTypedMessage, .signTypedMessageV3, .unknown, .sendRawTransaction: + return rejectDappAction() + case .walletAddEthereumChain, .walletSwitchEthereumChain, .ethCall: + return performDappAction(account: account) + } } } } diff --git a/AlphaWallet/Redeem/ViewControllers/TokenCardRedemptionViewController.swift b/AlphaWallet/Redeem/ViewControllers/TokenCardRedemptionViewController.swift index 37c7980e3..def11d14f 100644 --- a/AlphaWallet/Redeem/ViewControllers/TokenCardRedemptionViewController.swift +++ b/AlphaWallet/Redeem/ViewControllers/TokenCardRedemptionViewController.swift @@ -114,16 +114,25 @@ class TokenCardRedemptionViewController: UIViewController, TokenVerifiableStatus case .erc721, .erc721ForTickets: redeemData = redeem.redeemMessage(tokenIds: viewModel.tokenHolder.tokens.map({ $0.id })) } - switch session.account.type { - case .real(let account): + func _generateQr(account: AlphaWallet.Address) { do { - guard let decimalSignature = try SignatureHelper.signatureAsDecimal(for: redeemData.message, account: account, analyticsCoordinator: analyticsCoordinator) else { break } + guard let decimalSignature = try SignatureHelper.signatureAsDecimal(for: redeemData.message, account: account, analyticsCoordinator: analyticsCoordinator) else { return } let qrCodeInfo = redeemData.qrCode + decimalSignature imageView.image = qrCodeInfo.toQRCode() } catch { - break + //no-op + } + } + switch session.account.type { + case .real(let account): + _generateQr(account: account) + case .watch(let account): + //TODO should pass in a Config instance instead + if Config().development.shouldPretendIsRealWallet { + _generateQr(account: account) + } else { + //no-op } - case .watch: break } } diff --git a/AlphaWallet/Settings/Types/Config.swift b/AlphaWallet/Settings/Types/Config.swift index 23077ddce..f912c7885 100644 --- a/AlphaWallet/Settings/Types/Config.swift +++ b/AlphaWallet/Settings/Types/Config.swift @@ -9,6 +9,8 @@ struct Config { let shouldReadClipboardForWalletConnectUrl = false ///Useful to reduce network calls let isAutoFetchingDisabled = false + ///Should only be used to allow users to take paths where the current wallet is real, not watched, e.g sign buttons are enabled. Some of those actions will fail, understandably. Should not display a watch wallet as if it is a real wallet though + let shouldPretendIsRealWallet = false } let development = Development() diff --git a/AlphaWallet/Tokens/Collectibles/Coordinators/TokensCardCollectionCoordinator.swift b/AlphaWallet/Tokens/Collectibles/Coordinators/TokensCardCollectionCoordinator.swift index d19fe1a79..316731bda 100644 --- a/AlphaWallet/Tokens/Collectibles/Coordinators/TokensCardCollectionCoordinator.swift +++ b/AlphaWallet/Tokens/Collectibles/Coordinators/TokensCardCollectionCoordinator.swift @@ -74,7 +74,7 @@ class TokensCardCollectionCoordinator: NSObject, Coordinator { navigationController.pushViewController(rootViewController, animated: true) refreshUponAssetDefinitionChanges() refreshUponEthereumEventChanges() - } + } private func makeCoordinatorReadOnlyIfNotSupportedByOpenSeaERC1155(type: PaymentFlow, target: IsReadOnlyViewController) { switch (type, session.account.type) { @@ -194,7 +194,7 @@ extension TokensCardCollectionCoordinator: TokensCardCollectionViewControllerDel private func showTokenInstanceActionView(forAction action: TokenInstanceAction, tokenHolder: TokenHolder, viewController: UIViewController) { delegate?.didTap(for: .send(type: .tokenScript(action: action, tokenObject: token, tokenHolder: tokenHolder)), in: self, viewController: viewController) } - + func didSelectTokenHolder(in viewController: TokensCardCollectionViewController, didSelectTokenHolder tokenHolder: TokenHolder) { switch tokenHolder.type { case .collectible: @@ -232,7 +232,7 @@ extension TokensCardCollectionCoordinator: TokensCardCollectionViewControllerDel viewController.navigationItem.leftBarButtonItem = .backBarButton(self, selector: #selector(didCloseTokenInstanceSelected)) navigationController.pushViewController(viewController, animated: true) } - + @objc private func didCloseTokenInstanceSelected(_ sender: UIBarButtonItem) { navigationController.popViewController(animated: true) } diff --git a/AlphaWallet/Tokens/Collectibles/ViewControllers/TokensCardCollectionViewController.swift b/AlphaWallet/Tokens/Collectibles/ViewControllers/TokensCardCollectionViewController.swift index 666133983..210ffd0a4 100644 --- a/AlphaWallet/Tokens/Collectibles/ViewControllers/TokensCardCollectionViewController.swift +++ b/AlphaWallet/Tokens/Collectibles/ViewControllers/TokensCardCollectionViewController.swift @@ -151,18 +151,27 @@ class TokensCardCollectionViewController: UIViewController { buttonsBar.configure(.combined(buttons: viewModel.actions.count)) buttonsBar.viewController = self + func _configButton(action: TokenInstanceAction, button: BarButton) { + if let selection = action.activeExcludingSelection(selectedTokenHolder: viewModel.tokenHolders[0], tokenId: viewModel.tokenHolders[0].tokenId, forWalletAddress: session.account.address, fungibleBalance: viewModel.fungibleBalance) { + if selection.denial == nil { + button.displayButton = false + } + } + } + for (action, button) in zip(actions, buttonsBar.buttons) { button.setTitle(action.name, for: .normal) button.addTarget(self, action: #selector(actionButtonTapped), for: .touchUpInside) switch session.account.type { case .real: - if let selection = action.activeExcludingSelection(selectedTokenHolder: viewModel.tokenHolders[0], tokenId: viewModel.tokenHolders[0].tokenId, forWalletAddress: session.account.address, fungibleBalance: viewModel.fungibleBalance) { - if selection.denial == nil { - button.displayButton = false - } - } + _configButton(action: action, button: button) case .watch: - button.isEnabled = false + //TODO pass in Config instance instead + if Config().development.shouldPretendIsRealWallet { + _configButton(action: action, button: button) + } else { + button.isEnabled = false + } } } } diff --git a/AlphaWallet/Tokens/ViewControllers/TokenInstanceViewController.swift b/AlphaWallet/Tokens/ViewControllers/TokenInstanceViewController.swift index 0949bb16c..0aab7938a 100644 --- a/AlphaWallet/Tokens/ViewControllers/TokenInstanceViewController.swift +++ b/AlphaWallet/Tokens/ViewControllers/TokenInstanceViewController.swift @@ -134,19 +134,28 @@ class TokenInstanceViewController: UIViewController, TokenVerifiableStatusViewCo buttonsBar.configure(.combined(buttons: viewModel.actions.count)) buttonsBar.viewController = self + func _configButton(action: TokenInstanceAction, button: BarButton) { + if let selection = action.activeExcludingSelection(selectedTokenHolders: [tokenHolder], forWalletAddress: account.address) { + if selection.denial == nil { + button.displayButton = false + } + } + } + for (index, button) in buttonsBar.buttons.enumerated() { let action = viewModel.actions[index] button.setTitle(action.name, for: .normal) button.addTarget(self, action: #selector(actionButtonTapped), for: .touchUpInside) switch account.type { case .real: - if let selection = action.activeExcludingSelection(selectedTokenHolders: [tokenHolder], forWalletAddress: account.address) { - if selection.denial == nil { - button.displayButton = false - } - } + _configButton(action: action, button: button) case .watch: - button.isEnabled = false + //TODO pass in a Config instance instead + if Config().development.shouldPretendIsRealWallet { + _configButton(action: action, button: button) + } else { + button.isEnabled = false + } } } } @@ -231,7 +240,7 @@ extension TokenInstanceViewController: VerifiableStatusViewController { func open(url: URL) { delegate?.didPressViewContractWebPage(url, in: self) } -} +} extension TokenInstanceViewController: TokenInstanceAttributeViewDelegate { func didSelect(in view: TokenInstanceAttributeView) { diff --git a/AlphaWallet/Tokens/ViewControllers/TokenViewController.swift b/AlphaWallet/Tokens/ViewControllers/TokenViewController.swift index 24777ce92..8c5228b47 100644 --- a/AlphaWallet/Tokens/ViewControllers/TokenViewController.swift +++ b/AlphaWallet/Tokens/ViewControllers/TokenViewController.swift @@ -137,18 +137,27 @@ class TokenViewController: UIViewController { buttonsBar.configure(.combined(buttons: viewModel.actions.count)) buttonsBar.viewController = self + func _configButton(action: TokenInstanceAction, viewModel: TokenViewControllerViewModel, button: BarButton) { + if let tokenHolder = generateTokenHolder(), let selection = action.activeExcludingSelection(selectedTokenHolders: [tokenHolder], forWalletAddress: session.account.address, fungibleBalance: viewModel.fungibleBalance) { + if selection.denial == nil { + button.displayButton = false + } + } + } + for (action, button) in zip(actions, buttonsBar.buttons) { button.setTitle(action.name, for: .normal) button.addTarget(self, action: #selector(actionButtonTapped), for: .touchUpInside) switch session.account.type { case .real: - if let tokenHolder = generateTokenHolder(), let selection = action.activeExcludingSelection(selectedTokenHolders: [tokenHolder], forWalletAddress: session.account.address, fungibleBalance: viewModel.fungibleBalance) { - if selection.denial == nil { - button.displayButton = false - } - } + _configButton(action: action, viewModel: viewModel, button: button) case .watch: - button.isEnabled = false + //TODO pass in Config instance instead + if Config().development.shouldPretendIsRealWallet { + _configButton(action: action, viewModel: viewModel, button: button) + } else { + button.isEnabled = false + } } } } diff --git a/AlphaWallet/Tokens/ViewControllers/TokensCardViewController.swift b/AlphaWallet/Tokens/ViewControllers/TokensCardViewController.swift index 0639fa3c1..5307ba558 100644 --- a/AlphaWallet/Tokens/ViewControllers/TokensCardViewController.swift +++ b/AlphaWallet/Tokens/ViewControllers/TokensCardViewController.swift @@ -98,7 +98,7 @@ class TokensCardViewController: UIViewController { assetsPageView.searchBar.delegate = self assetsPageView.collectionView.refreshControl = refreshControl keyboardChecker.constraints = containerView.bottomAnchorConstraints - } + } required init?(coder aDecoder: NSCoder) { return nil @@ -156,18 +156,27 @@ class TokensCardViewController: UIViewController { buttonsBar.configure(.combined(buttons: viewModel.actions.count)) buttonsBar.viewController = self + func _configButton(action: TokenInstanceAction, button: BarButton) { + if let selection = action.activeExcludingSelection(selectedTokenHolder: viewModel.tokenHolders[0], tokenId: viewModel.tokenHolders[0].tokenId, forWalletAddress: session.account.address, fungibleBalance: viewModel.fungibleBalance) { + if selection.denial == nil { + button.displayButton = false + } + } + } + for (action, button) in zip(actions, buttonsBar.buttons) { button.setTitle(action.name, for: .normal) button.addTarget(self, action: #selector(actionButtonTapped), for: .touchUpInside) switch session.account.type { case .real: - if let selection = action.activeExcludingSelection(selectedTokenHolder: viewModel.tokenHolders[0], tokenId: viewModel.tokenHolders[0].tokenId, forWalletAddress: session.account.address, fungibleBalance: viewModel.fungibleBalance) { - if selection.denial == nil { - button.displayButton = false - } - } + _configButton(action: action, button: button) case .watch: - button.isEnabled = false + //TODO pass in a Config instance instead + if Config().development.shouldPretendIsRealWallet { + _configButton(action: action, button: button) + } else { + button.isEnabled = false + } } } } @@ -208,7 +217,7 @@ class TokensCardViewController: UIViewController { viewModel.markHolderSelected() guard let tokenHolder = selectedTokenHolder else { return } - + switch action.type { case .erc20Send, .erc20Receive, .swap, .buy, .bridge: break diff --git a/AlphaWallet/Tokens/Views/TokenInstanceWebView.swift b/AlphaWallet/Tokens/Views/TokenInstanceWebView.swift index b3c29ab52..6c9f6a791 100644 --- a/AlphaWallet/Tokens/Views/TokenInstanceWebView.swift +++ b/AlphaWallet/Tokens/Views/TokenInstanceWebView.swift @@ -444,18 +444,27 @@ extension TokenInstanceWebView: WKScriptMessageHandler { let token = TokensDataStore.token(forServer: server) let action = DappAction.fromCommand(.eth(command), server: server, transactionType: .dapp(token, requester)) - switch wallet.type { - case .real(let account): + func _sign(action: DappAction, command: DappCommand, account: AlphaWallet.Address) { switch action { case .signPersonalMessage(let hexMessage): let msg = convertMessageToHex(msg: hexMessage) let callbackID = command.id signMessage(with: .personalMessage(Data(_hex: msg)), account: account, callbackID: callbackID) case .signTransaction, .sendTransaction, .signMessage, .signTypedMessage, .unknown, .sendRawTransaction, .signTypedMessageV3, .ethCall, .walletAddEthereumChain, .walletSwitchEthereumChain: - return + break + } + } + + switch wallet.type { + case .real(let account): + _sign(action: action, command: command, account: account) + case .watch(let account): + //TODO pass in Config instance instead + if Config().development.shouldPretendIsRealWallet { + _sign(action: action, command: command, account: account) + } else { + //no-op } - case .watch: - break } } } diff --git a/AlphaWallet/Transactions/Coordinators/TokensCardCoordinator.swift b/AlphaWallet/Transactions/Coordinators/TokensCardCoordinator.swift index 311ba30de..14b381b00 100644 --- a/AlphaWallet/Transactions/Coordinators/TokensCardCoordinator.swift +++ b/AlphaWallet/Transactions/Coordinators/TokensCardCoordinator.swift @@ -62,7 +62,7 @@ class TokensCardCoordinator: NSObject, Coordinator { self.eventsDataStore = eventsDataStore self.analyticsCoordinator = analyticsCoordinator navigationController.navigationBar.isTranslucent = false - } + } func start() { rootViewController.configure() @@ -431,7 +431,7 @@ class TokensCardCoordinator: NSObject, Coordinator { } extension TokensCardCoordinator: TokensCardViewControllerDelegate { - + func didTap(transaction: TransactionInstance, in viewController: TokensCardViewController) { delegate?.didTap(transaction: transaction, in: self) } diff --git a/AlphaWallet/Transfer/Coordinators/PaymentCoordinator.swift b/AlphaWallet/Transfer/Coordinators/PaymentCoordinator.swift index 051f579ab..347d2a989 100644 --- a/AlphaWallet/Transfer/Coordinators/PaymentCoordinator.swift +++ b/AlphaWallet/Transfer/Coordinators/PaymentCoordinator.swift @@ -94,8 +94,7 @@ class PaymentCoordinator: Coordinator { self.navigationController.setNavigationBarHidden(false, animated: true) } - switch (flow, session.account.type) { - case (.send(let transactionType), .real): + func _startPaymentFlow(transactionType: PaymentFlowType) { switch transactionType { case .transaction(let transactionType): switch transactionType { @@ -111,14 +110,23 @@ class PaymentCoordinator: Coordinator { case .tokenScript(let action, let tokenObject, let tokenHolder): startWithTokenScriptCoordinator(action: action, tokenObject: tokenObject, tokenHolder: tokenHolder) } + } + + switch (flow, session.account.type) { + case (.send(let transactionType), .real): + _startPaymentFlow(transactionType: transactionType) case (.request, _): let coordinator = RequestCoordinator(navigationController: navigationController, account: session.account) coordinator.delegate = self coordinator.start() addCoordinator(coordinator) - case (.send, .watch): - //TODO: This case should be returning an error inCoordinator. Improve this logic into single piece. - break + case (.send(let transactionType), .watch): + //TODO pass in a config instance instead + if Config().development.shouldPretendIsRealWallet { + _startPaymentFlow(transactionType: transactionType) + } else { + //TODO: This case should be returning an error inCoordinator. Improve this logic into single piece. + } } } diff --git a/AlphaWallet/WalletConnect/Coordinator/WalletConnectCoordinator.swift b/AlphaWallet/WalletConnect/Coordinator/WalletConnectCoordinator.swift index 895d04857..a0b19c216 100644 --- a/AlphaWallet/WalletConnect/Coordinator/WalletConnectCoordinator.swift +++ b/AlphaWallet/WalletConnect/Coordinator/WalletConnectCoordinator.swift @@ -202,7 +202,12 @@ private extension WalletType { case .real: return .value(()) case .watch: - return .init(error: WalletConnectCoordinator.RequestCanceledDueToWatchWalletError()) + //TODO pass in Config instance instead + if Config().development.shouldPretendIsRealWallet { + return .value(()) + } else { + return .init(error: WalletConnectCoordinator.RequestCanceledDueToWatchWalletError()) + } } } }