From 2094623d8f4c2de0e4bd839e536e5aeab3de4d75 Mon Sep 17 00:00:00 2001 From: Vladyslav shepitko Date: Thu, 23 Sep 2021 17:54:30 +0300 Subject: [PATCH] Implement designed Prompts for EIP3085 wallet_addEthereumChain support #2908 --- AlphaWallet.xcodeproj/project.pbxproj | 8 + ...pRequestSwitchCustomChainCoordinator.swift | 100 +++++----- .../SwitchChainRequestViewController.swift | 180 ++++++++++++++++++ .../SwitchChainRequestViewModel.swift | 53 ++++++ .../Localization/en.lproj/Localizable.strings | 4 + .../Localization/es.lproj/Localizable.strings | 4 + .../Localization/ja.lproj/Localizable.strings | 4 + .../Localization/ko.lproj/Localizable.strings | 4 + .../zh-Hans.lproj/Localizable.strings | 4 + .../AddRPCServerCoordinator.swift | 2 +- 10 files changed, 312 insertions(+), 51 deletions(-) create mode 100644 AlphaWallet/Browser/ViewControllers/SwitchChainRequestViewController.swift create mode 100644 AlphaWallet/Browser/ViewModel/SwitchChainRequestViewModel.swift diff --git a/AlphaWallet.xcodeproj/project.pbxproj b/AlphaWallet.xcodeproj/project.pbxproj index 76877d4c3..8421027b4 100644 --- a/AlphaWallet.xcodeproj/project.pbxproj +++ b/AlphaWallet.xcodeproj/project.pbxproj @@ -841,6 +841,8 @@ 879F185C26E74507000602F2 /* ButtonsBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 879F185B26E74507000602F2 /* ButtonsBar.swift */; }; 879F185E26E74512000602F2 /* ButtonsBarBackgroundView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 879F185D26E74512000602F2 /* ButtonsBarBackgroundView.swift */; }; 879F186026E74543000602F2 /* ToolButtonsBarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 879F185F26E74543000602F2 /* ToolButtonsBarView.swift */; }; + 87A05C7526FCCA5C00AE26CA /* SwitchChainRequestViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 87A05C7426FCCA5C00AE26CA /* SwitchChainRequestViewController.swift */; }; + 87A05C7726FCCA8B00AE26CA /* SwitchChainRequestViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 87A05C7626FCCA8B00AE26CA /* SwitchChainRequestViewModel.swift */; }; 87A0C93225AEF1E400E73F60 /* EventInstanceValue.swift in Sources */ = {isa = PBXBuildFile; fileRef = 87A0C93125AEF1E400E73F60 /* EventInstanceValue.swift */; }; 87A3020924BEE243000DF32E /* TransactionInProgressViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 87A3020824BEE243000DF32E /* TransactionInProgressViewController.swift */; }; 87A3020B24BF04B6000DF32E /* TransactionInProgressViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 87A3020A24BF04B6000DF32E /* TransactionInProgressViewModel.swift */; }; @@ -1839,6 +1841,8 @@ 879F185B26E74507000602F2 /* ButtonsBar.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ButtonsBar.swift; sourceTree = ""; }; 879F185D26E74512000602F2 /* ButtonsBarBackgroundView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ButtonsBarBackgroundView.swift; sourceTree = ""; }; 879F185F26E74543000602F2 /* ToolButtonsBarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToolButtonsBarView.swift; sourceTree = ""; }; + 87A05C7426FCCA5C00AE26CA /* SwitchChainRequestViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwitchChainRequestViewController.swift; sourceTree = ""; }; + 87A05C7626FCCA8B00AE26CA /* SwitchChainRequestViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwitchChainRequestViewModel.swift; sourceTree = ""; }; 87A0C93125AEF1E400E73F60 /* EventInstanceValue.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EventInstanceValue.swift; sourceTree = ""; }; 87A3020824BEE243000DF32E /* TransactionInProgressViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionInProgressViewController.swift; sourceTree = ""; }; 87A3020A24BF04B6000DF32E /* TransactionInProgressViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionInProgressViewModel.swift; sourceTree = ""; }; @@ -3044,6 +3048,7 @@ 76F1DAFCBB43B6639472A229 /* BrowserHistoryViewController.swift */, 5E7C76EE22984D66A3C18E70 /* DappsAutoCompletionViewController.swift */, 5E7C7F55495A6095B3E86248 /* EditMyDappViewController.swift */, + 87A05C7426FCCA5C00AE26CA /* SwitchChainRequestViewController.swift */, ); path = ViewControllers; sourceTree = ""; @@ -4219,6 +4224,7 @@ 5E7C776B129861728FFB8CC8 /* EditMyDappViewControllerViewModel.swift */, 5E7C7D8D618A8A8D55479CDF /* Dapp.swift */, 5E7C7C0AC267283F3F2A6E37 /* EmptyDapps.swift */, + 87A05C7626FCCA8B00AE26CA /* SwitchChainRequestViewModel.swift */, ); path = ViewModel; sourceTree = ""; @@ -5541,6 +5547,7 @@ 5E7C7C98EAF40E8110241DBD /* NonFungibleTokenViewCell.swift in Sources */, 5E7C71B52A77008694BFA5D1 /* TokensDataStore.swift in Sources */, 87374A4325DFAF7800267160 /* HoneySwap.swift in Sources */, + 87A05C7526FCCA5C00AE26CA /* SwitchChainRequestViewController.swift in Sources */, 5E7C75C99B9F595F26EDC405 /* LockPasscodeViewController.swift in Sources */, 5E7C710331196CD591B51785 /* LockCreatePasscodeViewController.swift in Sources */, 87F4D41E26C26C3A00EFB9BC /* SortTokensParam.swift in Sources */, @@ -5578,6 +5585,7 @@ 5E7C7FCC321493B41C1083C1 /* EnterSellTokensCardPriceQuantityViewControllerViewModel.swift in Sources */, 5E7C7669BBE6255A2377E070 /* SetSellTokensCardExpiryDateViewController.swift in Sources */, 5E7C7A4384A8E3F22D3F8249 /* SetSellTokensCardExpiryDateViewControllerViewModel.swift in Sources */, + 87A05C7726FCCA8B00AE26CA /* SwitchChainRequestViewModel.swift in Sources */, 5E7C7B0367CFB413C6885474 /* GenerateSellMagicLinkViewControllerViewModel.swift in Sources */, 5E7C7692C981580CD32228EB /* ChooseTokenCardTransferModeViewController.swift in Sources */, 5E7C74DBAE43954C185057B3 /* ChooseTokenCardTransferModeViewControllerViewModel.swift in Sources */, diff --git a/AlphaWallet/Browser/Coordinators/DappRequestSwitchCustomChainCoordinator.swift b/AlphaWallet/Browser/Coordinators/DappRequestSwitchCustomChainCoordinator.swift index 00126f356..eebd7823b 100644 --- a/AlphaWallet/Browser/Coordinators/DappRequestSwitchCustomChainCoordinator.swift +++ b/AlphaWallet/Browser/Coordinators/DappRequestSwitchCustomChainCoordinator.swift @@ -66,62 +66,62 @@ class DappRequestSwitchCustomChainCoordinator: NSObject, Coordinator { } private func promptAndActivateExistingServer(existingServer: RPCServer, inViewController viewController: UIViewController, callbackID: Int) { - let title = R.string.localizable.addCustomChainEnableExisting(existingServer.displayName, existingServer.chainID) - UIAlertController.alert(title: title, - message: nil, - alertButtonTitles: [R.string.localizable.oK(), R.string.localizable.cancel()], - alertButtonStyles: [.destructive, .cancel], - viewController: viewController, - completion: { [self] choice in - if choice == 0 { - let enableChain = EnableChain(existingServer, restartQueue: self.restartQueue, url: self.currentUrl) - enableChain.delegate = self - enableChain.run() - } else { - self.delegate?.userCancelled(withCallbackId: callbackID, inCoordinator: self) - } - }) + func runEnableChain() { + let enableChain = EnableChain(existingServer, restartQueue: restartQueue, url: currentUrl) + enableChain.delegate = self + enableChain.run() + } + + let configuration: SwitchChainRequestConfiguration = .promptAndActivateExistingServer(existingServer: existingServer) + SwitchChainRequestViewController.promise(viewController, configuration: configuration).done { result in + // NOTE: here we pretty sure that there is only one action + switch result { + case .action: + runEnableChain() + case .canceled: + self.delegate?.userCancelled(withCallbackId: callbackID, inCoordinator: self) + } + }.cauterize() } private func promptAndAddAndActivateServer(customChain: WalletAddEthereumChainObject, customChainId: Int, inViewController viewController: UIViewController, callbackID: Int) { - let title = R.string.localizable.addCustomChainAddAndSwitch(customChain.chainName ?? R.string.localizable.addCustomChainUnnamed(), customChainId) - UIAlertController.alert(title: title, - message: nil, - alertButtonTitles: [R.string.localizable.settingsEnabledNetworksMainnet(), R.string.localizable.settingsEnabledNetworksTestnet(), R.string.localizable.cancel()], - alertButtonStyles: [.destructive, .destructive, .cancel], - viewController: viewController, - completion: { [self] choice in - func runAddCustomChain(isTestnet: Bool) { - let addCustomChain = AddCustomChain(customChain, isTestnet: isTestnet, restartQueue: self.restartQueue, url: self.currentUrl) - self.addCustomChain = (chain: addCustomChain, callbackId: callbackID) - addCustomChain.delegate = self - addCustomChain.run() - } - switch choice { - case 0: - runAddCustomChain(isTestnet: false) - case 1: - runAddCustomChain(isTestnet: true) - default: - self.delegate?.userCancelled(withCallbackId: callbackID, inCoordinator: self) - } - }) + func runAddCustomChain(isTestnet: Bool) { + let addCustomChain = AddCustomChain(customChain, isTestnet: isTestnet, restartQueue: restartQueue, url: currentUrl) + self.addCustomChain = (chain: addCustomChain, callbackId: callbackID) + addCustomChain.delegate = self + addCustomChain.run() + } + + let configuration: SwitchChainRequestConfiguration = .promptAndAddAndActivateServer(customChain: customChain, customChainId: customChainId) + SwitchChainRequestViewController.promise(viewController, configuration: configuration).done { result in + // NOTE: here we pretty sure that there is only one action + switch result { + case .action(let choice): + switch choice { + case 0: + runAddCustomChain(isTestnet: false) + case 1: + runAddCustomChain(isTestnet: true) + default: + self.delegate?.userCancelled(withCallbackId: callbackID, inCoordinator: self) + } + case .canceled: + self.delegate?.userCancelled(withCallbackId: callbackID, inCoordinator: self) + } + }.cauterize() } private func promptAndSwitchToExistingServerInBrowser(existingServer: RPCServer, viewController: UIViewController, callbackID: Int) { - let title = R.string.localizable.addCustomChainSwitchToExisting(existingServer.displayName, existingServer.chainID) - UIAlertController.alert(title: title, - message: nil, - alertButtonTitles: [R.string.localizable.oK(), R.string.localizable.cancel()], - alertButtonStyles: [.destructive, .cancel], - viewController: viewController, - completion: { [self] choice in - if choice == 0 { - self.delegate?.switchBrowserToExistingServer(existingServer, url: self.currentUrl, inCoordinator: self) - } else { - self.delegate?.userCancelled(withCallbackId: callbackID, inCoordinator: self) - } - }) + let configuration: SwitchChainRequestConfiguration = .promptAndSwitchToExistingServerInBrowser(existingServer: existingServer) + SwitchChainRequestViewController.promise(viewController, configuration: configuration).done { result in + // NOTE: here we pretty sure that there is only one action + switch result { + case .action: + self.delegate?.switchBrowserToExistingServer(existingServer, url: self.currentUrl, inCoordinator: self) + case .canceled: + self.delegate?.userCancelled(withCallbackId: callbackID, inCoordinator: self) + } + }.cauterize() } //This is really only (and should only be) fired when the chain is already enabled and activated in browser. i.e. we are not supposed to have restarted the app UI or browser. It's a no-op. If DApps detect that the browser is already connected to the right chain, they might not even trigger this diff --git a/AlphaWallet/Browser/ViewControllers/SwitchChainRequestViewController.swift b/AlphaWallet/Browser/ViewControllers/SwitchChainRequestViewController.swift new file mode 100644 index 000000000..da4301ec5 --- /dev/null +++ b/AlphaWallet/Browser/ViewControllers/SwitchChainRequestViewController.swift @@ -0,0 +1,180 @@ +// +// SwitchChainRequestViewController.swift +// AlphaWallet +// +// Created by Vladyslav Shepitko on 23.09.2021. +// + +import UIKit +import PromiseKit + +protocol SwitchChainRequestViewControllerDelegate: class { + func didClose(in viewController: SwitchChainRequestViewController) + func didSelectActionButton(in viewController: SwitchChainRequestViewController) + func didSelectAdditionalButton(in viewController: SwitchChainRequestViewController) +} + +class SwitchChainRequestViewController: ModalViewController { + weak var _delegate: SwitchChainRequestViewControllerDelegate? + + private var titleLabel: UILabel = { + let v = UILabel() + v.numberOfLines = 0 + v.textAlignment = .center + v.textColor = R.color.black() + v.font = Fonts.bold(size: 24) + + return v + }() + + private var descriptionLabel: UILabel = { + let v = UILabel() + v.numberOfLines = 0 + v.textAlignment = .center + v.textColor = R.color.mine() + v.font = Fonts.regular(size: 17) + + return v + }() + private lazy var enableTestnetButton: Button = { + let button = Button(size: .normal, style: .system) + button.setTitle(viewModel.additionalButtonTitle, for: .normal) + + return button + }() + + private lazy var buttonsBar: ButtonsBar = { + let buttonsBar = ButtonsBar(configuration: .green(buttons: 1)) + return buttonsBar + }() + + private var viewModel: SwitchChainRequestViewModel + + init(viewModel: SwitchChainRequestViewModel) { + self.viewModel = viewModel + super.init() + let footerView = ButtonsBarBackgroundView(buttonsBar: buttonsBar, separatorHeight: 0) + + footerStackView.addArrangedSubview(footerView) + generateSubviews() + presentationDelegate = self + + enableTestnetButton.addTarget(self, action: #selector(enableTestnetButtonSelected), for: .touchUpInside) + } + + required init?(coder aDecoder: NSCoder) { + return nil + } + + func configure(viewModel: SwitchChainRequestViewModel) { + self.viewModel = viewModel + generateSubviews() + + buttonsBar.configure() + buttonsBar.buttons[0].setTitle(viewModel.actionButtonTitle, for: .normal) + buttonsBar.buttons[0].addTarget(self, action: #selector(actionButtonSelected), for: .touchUpInside) + + titleLabel.text = viewModel.title + descriptionLabel.text = viewModel.description + } + + @objc private func actionButtonSelected(_ sender: UIButton) { + dismissViewAnimated(with: { + self._delegate?.didSelectActionButton(in: self) + }) + } + + @objc private func enableTestnetButtonSelected(_ sender: UIButton) { + dismissViewAnimated(with: { + self._delegate?.didSelectAdditionalButton(in: self) + }) + } +} + +extension SwitchChainRequestViewController: ModalViewControllerDelegate { + + func didDismiss(_ controller: ModalViewController) { + _delegate?.didClose(in: self) + dismiss(animated: false) + } + + func didClose(_ controller: ModalViewController) { + dismissViewAnimated(with: { + self._delegate?.didClose(in: self) + self.dismiss(animated: false) + }) + } +} + +extension SwitchChainRequestViewController { + private func generateSubviews() { + stackView.removeAllArrangedSubviews() + + var views: [UIView] = [ + [.spacerWidth(16), titleLabel, .spacerWidth(16)].asStackView(axis: .horizontal), + .spacer(height: 20), + [.spacerWidth(16), descriptionLabel, .spacerWidth(16)].asStackView(axis: .horizontal), + ] + + switch viewModel.configuration { + case .promptAndSwitchToExistingServerInBrowser, .promptAndActivateExistingServer: + break + case .promptAndAddAndActivateServer: + views += [ + .spacer(height: 20), + enableTestnetButton + ] + } + + stackView.addArrangedSubviews(views) + } +} + +private class SwitchChainRequestViewControllerBridgeToPromise: NSObject { + + private let (promiseToReturn, seal) = Promise.pending() + private var retainCycle: SwitchChainRequestViewControllerBridgeToPromise? + private let viewController: SwitchChainRequestViewController + + init(viewController target: UIViewController, configuration: SwitchChainRequestConfiguration) { + viewController = SwitchChainRequestViewController(viewModel: .init(configuration: configuration)) + viewController.configure(viewModel: .init(configuration: configuration)) + + super.init() + retainCycle = self + + viewController._delegate = self + promiseToReturn.ensure { + // ensure we break the retain cycle + self.retainCycle = nil + }.cauterize() + + target.present(viewController, animated: false) + } + + var promise: Promise { + return promiseToReturn + } +} + +extension SwitchChainRequestViewControllerBridgeToPromise: SwitchChainRequestViewControllerDelegate { + //NOTE: need to update it with more clear solution, passing button index isn't goo idea for that + func didSelectActionButton(in viewController: SwitchChainRequestViewController) { + seal.fulfill(.action(0)) + } + + func didSelectAdditionalButton(in viewController: SwitchChainRequestViewController) { + seal.fulfill(.action(1)) + } + + func didClose(in viewController: SwitchChainRequestViewController) { + seal.fulfill(.canceled) + } +} + +extension SwitchChainRequestViewController { + static func promise(_ viewController: UIViewController, configuration: SwitchChainRequestConfiguration) -> Promise { + return SwitchChainRequestViewControllerBridgeToPromise(viewController: viewController, configuration: configuration).promise + } +} + diff --git a/AlphaWallet/Browser/ViewModel/SwitchChainRequestViewModel.swift b/AlphaWallet/Browser/ViewModel/SwitchChainRequestViewModel.swift new file mode 100644 index 000000000..64bfd5469 --- /dev/null +++ b/AlphaWallet/Browser/ViewModel/SwitchChainRequestViewModel.swift @@ -0,0 +1,53 @@ +// +// SwitchChainRequestViewModel.swift +// AlphaWallet +// +// Created by Vladyslav Shepitko on 23.09.2021. +// + +import UIKit + +enum SwitchChainRequestConfiguration { + case promptAndSwitchToExistingServerInBrowser(existingServer: RPCServer) + case promptAndAddAndActivateServer(customChain: WalletAddEthereumChainObject, customChainId: Int) + case promptAndActivateExistingServer(existingServer: RPCServer) +} + +enum SwitchChainRequestResponse { + case action(Int) + case canceled +} + +struct SwitchChainRequestViewModel { + let title: String = R.string.localizable.switchChainRequestTitle() + let configuration: SwitchChainRequestConfiguration + + var description: String { + switch configuration { + case .promptAndSwitchToExistingServerInBrowser(let existingServer): + return R.string.localizable.addCustomChainSwitchToExisting(existingServer.displayName, existingServer.chainID) + case .promptAndAddAndActivateServer(let customChain, let customChainId): + return R.string.localizable.addCustomChainAddAndSwitch(customChain.chainName ?? R.string.localizable.addCustomChainUnnamed(), customChainId) + case .promptAndActivateExistingServer(let existingServer): + return R.string.localizable.addCustomChainEnableExisting(existingServer.displayName, existingServer.chainID) + } + } + + var actionButtonTitle: String { + switch configuration { + case .promptAndSwitchToExistingServerInBrowser: + // Switch & Reload + return R.string.localizable.switchChainRequestActionSwitchReload() + case .promptAndAddAndActivateServer: + // Add, Switch & Reload Mainnet + return R.string.localizable.switchChainRequestActionAddSwitchReload(R.string.localizable.settingsEnabledNetworksMainnet()) + case .promptAndActivateExistingServer: + // Enable, Switch & Reload + return R.string.localizable.switchChainRequestActionEnableSwitchReload() + } + } + + var additionalButtonTitle: String { + R.string.localizable.switchChainRequestActionAddSwitchReload(R.string.localizable.settingsEnabledNetworksTestnet()) + } +} diff --git a/AlphaWallet/Localization/en.lproj/Localizable.strings b/AlphaWallet/Localization/en.lproj/Localizable.strings index 38a30b274..c123207b5 100644 --- a/AlphaWallet/Localization/en.lproj/Localizable.strings +++ b/AlphaWallet/Localization/en.lproj/Localizable.strings @@ -674,3 +674,7 @@ You can check the latest gas price on gasnow.org"; "sortTokens.param.valueDescending" = "Value: Descending"; "sortTokens.param.mostUsed" = "Most Used"; "sortTokens.sortBy" = "Sort: By %@"; +"switchChainRequest.title" = "Switch Chain Request"; +"switchChainRequest.action.enableSwitchReload" = "Enable, Switch & Reload"; +"switchChainRequest.action.switchReload" = "Switch & Reload"; +"switchChainRequest.action.addSwitchReload" = "Add, Switch & Reload %@"; diff --git a/AlphaWallet/Localization/es.lproj/Localizable.strings b/AlphaWallet/Localization/es.lproj/Localizable.strings index 0a0bfe3db..135f9a19f 100644 --- a/AlphaWallet/Localization/es.lproj/Localizable.strings +++ b/AlphaWallet/Localization/es.lproj/Localizable.strings @@ -674,3 +674,7 @@ You can check the latest gas price on gasnow.org"; "sortTokens.param.valueDescending" = "Value: Descending"; "sortTokens.param.mostUsed" = "Most Used"; "sortTokens.sortBy" = "Sort: By %@"; +"switchChainRequest.title" = "Switch Chain Request"; +"switchChainRequest.action.enableSwitchReload" = "Enable, Switch & Reload"; +"switchChainRequest.action.switchReload" = "Switch & Reload"; +"switchChainRequest.action.addSwitchReload" = "Add, Switch & Reload %@"; diff --git a/AlphaWallet/Localization/ja.lproj/Localizable.strings b/AlphaWallet/Localization/ja.lproj/Localizable.strings index a01738d8a..5c011eb4d 100644 --- a/AlphaWallet/Localization/ja.lproj/Localizable.strings +++ b/AlphaWallet/Localization/ja.lproj/Localizable.strings @@ -674,3 +674,7 @@ You can check the latest gas price on gasnow.org"; "sortTokens.param.valueDescending" = "Value: Descending"; "sortTokens.param.mostUsed" = "Most Used"; "sortTokens.sortBy" = "Sort: By %@"; +"switchChainRequest.title" = "Switch Chain Request"; +"switchChainRequest.action.enableSwitchReload" = "Enable, Switch & Reload"; +"switchChainRequest.action.switchReload" = "Switch & Reload"; +"switchChainRequest.action.addSwitchReload" = "Add, Switch & Reload %@"; diff --git a/AlphaWallet/Localization/ko.lproj/Localizable.strings b/AlphaWallet/Localization/ko.lproj/Localizable.strings index a00195e97..faabea7b5 100644 --- a/AlphaWallet/Localization/ko.lproj/Localizable.strings +++ b/AlphaWallet/Localization/ko.lproj/Localizable.strings @@ -674,3 +674,7 @@ You can check the latest gas price on gasnow.org"; "sortTokens.param.valueDescending" = "Value: Descending"; "sortTokens.param.mostUsed" = "Most Used"; "sortTokens.sortBy" = "Sort: By %@"; +"switchChainRequest.title" = "Switch Chain Request"; +"switchChainRequest.action.enableSwitchReload" = "Enable, Switch & Reload"; +"switchChainRequest.action.switchReload" = "Switch & Reload"; +"switchChainRequest.action.addSwitchReload" = "Add, Switch & Reload %@"; diff --git a/AlphaWallet/Localization/zh-Hans.lproj/Localizable.strings b/AlphaWallet/Localization/zh-Hans.lproj/Localizable.strings index 15d154f7c..df33fa278 100644 --- a/AlphaWallet/Localization/zh-Hans.lproj/Localizable.strings +++ b/AlphaWallet/Localization/zh-Hans.lproj/Localizable.strings @@ -674,3 +674,7 @@ You can check the latest gas price on gasnow.org"; "sortTokens.param.valueDescending" = "Value: Descending"; "sortTokens.param.mostUsed" = "Most Used"; "sortTokens.sortBy" = "Sort: By %@"; +"switchChainRequest.title" = "Switch Chain Request"; +"switchChainRequest.action.enableSwitchReload" = "Enable, Switch & Reload"; +"switchChainRequest.action.switchReload" = "Switch & Reload"; +"switchChainRequest.action.addSwitchReload" = "Add, Switch & Reload %@"; diff --git a/AlphaWallet/Settings/Coordinators/AddRPCServerCoordinator.swift b/AlphaWallet/Settings/Coordinators/AddRPCServerCoordinator.swift index 46497c127..bbb3e8bee 100644 --- a/AlphaWallet/Settings/Coordinators/AddRPCServerCoordinator.swift +++ b/AlphaWallet/Settings/Coordinators/AddRPCServerCoordinator.swift @@ -87,7 +87,7 @@ extension AddRPCServerCoordinator: AddCustomChainDelegate { extension UIAlertController { static func promptToUseUnresolvedExplorerURL(customChain: WalletAddEthereumChainObject, chainId: Int, viewController: UIViewController) -> Promise { let (promise, seal) = Promise.pending() - let message = R.string.localizable.addCustomChainWarningNoBlockchainExplorerUrl(customChain.chainName ?? "-") + let message = R.string.localizable.addCustomChainWarningNoBlockchainExplorerUrl() let alertController = UIAlertController.alertController(title: R.string.localizable.warning(), message: message, style: .alert, in: viewController) let continueAction = UIAlertAction(title: R.string.localizable.continue(), style: .destructive, handler: { _ in seal.fulfill(true)