diff --git a/AlphaWallet.xcodeproj/project.pbxproj b/AlphaWallet.xcodeproj/project.pbxproj index a698141a3..74986ea11 100644 --- a/AlphaWallet.xcodeproj/project.pbxproj +++ b/AlphaWallet.xcodeproj/project.pbxproj @@ -806,6 +806,7 @@ 87A3020924BEE243000DF32E /* TransactionInProgressViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 87A3020824BEE243000DF32E /* TransactionInProgressViewController.swift */; }; 87A3020B24BF04B6000DF32E /* TransactionInProgressViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 87A3020A24BF04B6000DF32E /* TransactionInProgressViewModel.swift */; }; 87A3022724C02212000DF32E /* TransactionConfirmationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 87A3022624C02212000DF32E /* TransactionConfirmationViewController.swift */; }; + 87A5D53E26B9767300856995 /* QuickSwap.swift in Sources */ = {isa = PBXBuildFile; fileRef = 87A5D53D26B9767300856995 /* QuickSwap.swift */; }; 87B651F7256D4BFE000EF927 /* ClaimPaidOrderCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 87B651F6256D4BFE000EF927 /* ClaimPaidOrderCoordinator.swift */; }; 87B6526A256FBF36000EF927 /* SwapTokenService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 87B65269256FBF36000EF927 /* SwapTokenService.swift */; }; 87BB63DC265CFF2700FF702A /* WalletBalanceCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 87BB63DB265CFF2700FF702A /* WalletBalanceCoordinator.swift */; }; @@ -1757,6 +1758,7 @@ 87A3020824BEE243000DF32E /* TransactionInProgressViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionInProgressViewController.swift; sourceTree = ""; }; 87A3020A24BF04B6000DF32E /* TransactionInProgressViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionInProgressViewModel.swift; sourceTree = ""; }; 87A3022624C02212000DF32E /* TransactionConfirmationViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TransactionConfirmationViewController.swift; sourceTree = ""; }; + 87A5D53D26B9767300856995 /* QuickSwap.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuickSwap.swift; sourceTree = ""; }; 87B651F6256D4BFE000EF927 /* ClaimPaidOrderCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ClaimPaidOrderCoordinator.swift; sourceTree = ""; }; 87B65269256FBF36000EF927 /* SwapTokenService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwapTokenService.swift; sourceTree = ""; }; 87BB63DB265CFF2700FF702A /* WalletBalanceCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletBalanceCoordinator.swift; sourceTree = ""; }; @@ -4202,9 +4204,18 @@ path = CoinTicker; sourceTree = ""; }; + 87A5D53C26B9765000856995 /* QuickSwap */ = { + isa = PBXGroup; + children = ( + 87A5D53D26B9767300856995 /* QuickSwap.swift */, + ); + path = QuickSwap; + sourceTree = ""; + }; 87B65268256FBF22000EF927 /* SwapToken */ = { isa = PBXGroup; children = ( + 87A5D53C26B9765000856995 /* QuickSwap */, 87374A4125DFAEF200267160 /* HoneySwap */, 8731E6DD2565269400A6A7DA /* Oneinch */, 8731E6DA2565269400A6A7DA /* Uniswap */, @@ -5029,6 +5040,7 @@ 7721A6BE202A5677004DB16C /* DecryptError.swift in Sources */, 87BBF9982563DD7600FF4846 /* TransactionConfirmationCoordinatorBridgeToPromise.swift in Sources */, 61FC5ECF1FCFBAE500CCB12A /* EtherNumberFormatter.swift in Sources */, + 87A5D53E26B9767300856995 /* QuickSwap.swift in Sources */, 29DBF2A71F9F145900327C60 /* StateViewModel.swift in Sources */, 2923D9B31FDA49F8000CF3F8 /* SkipBackupFilesInitializer.swift in Sources */, 29C80D4B1FB51C460037B1E0 /* Decimal.swift in Sources */, diff --git a/AlphaWallet/Core/SwapToken/QuickSwap/QuickSwap.swift b/AlphaWallet/Core/SwapToken/QuickSwap/QuickSwap.swift new file mode 100644 index 000000000..23f2b7528 --- /dev/null +++ b/AlphaWallet/Core/SwapToken/QuickSwap/QuickSwap.swift @@ -0,0 +1,108 @@ +// +// QuickSwap.swift +// AlphaWallet +// +// Created by Vladyslav Shepitko on 21.08.2020. +// + +import UIKit + +struct QuickSwap: TokenActionsProvider, SwapTokenURLProviderType { + + var action: String { + return R.string.localizable.aWalletTokenErc20ExchangeOnQuickSwapButtonTitle() + } + var rpcServer: RPCServer? { + .polygon + } + + var analyticsName: String { + "QuickSwap" + } + + private static let baseURL = "https://quickswap.exchange/#" + + var version: Version = .v2 + var theme: Uniswap.Theme = .dark + var method: Method = .swap + + func url(token: TokenActionsServiceKey) -> URL? { + let input = Input.input(token.contractAddress) + var components = URLComponents() + components.path = method.rawValue + components.queryItems = [ + URLQueryItem(name: Version.key, value: version.rawValue), + URLQueryItem(name: Uniswap.Theme.key, value: theme.rawValue) + ] + input.urlQueryItems + + //NOTE: URLComponents doesn't allow path to contain # symbol + guard let pathWithQueryItems = components.url?.absoluteString else { return nil } + + return URL(string: QuickSwap.baseURL + pathWithQueryItems) + } + + enum Version: String { + static let key = "use" + + case v1 + case v2 + } + + enum Method: String { + case swap = "/swap" + case use + } + + enum Input { + enum Keys { + static let input = "inputCurrency" + static let output = "outputCurrency" + } + + case inputOutput(from: AlphaWallet.Address, to: AddressOrEnsName) + case input(AlphaWallet.Address) + case none + + var urlQueryItems: [URLQueryItem] { + switch self { + case .inputOutput(let inputAddress, let outputAddress): + return [ + .init(name: Keys.input, value: functional.rewriteContractInput(inputAddress)), + .init(name: Keys.output, value: outputAddress.stringValue), + ] + case .input(let address): + return [ + .init(name: Keys.input, value: functional.rewriteContractInput(address)) + ] + case .none: + return [] + } + } + + class functional { + static func rewriteContractInput(_ address: AlphaWallet.Address) -> String { + if address.sameContract(as: Constants.nativeCryptoAddressInDatabase) { + //QuickSwap (forked from Uniswap) likes it this way + return "ETH" + } else { + return address.eip55String + } + } + } + } + + func actions(token: TokenActionsServiceKey) -> [TokenInstanceAction] { + return [ + .init(type: .swap(service: self)) + ] + } + + func isSupport(token: TokenActionsServiceKey) -> Bool { + switch token.server { + case .polygon: + return true + case .main, .kovan, .ropsten, .rinkeby, .poa, .sokol, .classic, .callisto, .goerli, .artis_sigma1, .artis_tau1, .binance_smart_chain, .binance_smart_chain_testnet, .heco, .heco_testnet, .custom, .fantom, .fantom_testnet, .avalanche, .avalanche_testnet, .xDai, .mumbai_testnet, .optimistic, .optimisticKovan, .cronosTestnet: + return false + } + } +} diff --git a/AlphaWallet/InCoordinator.swift b/AlphaWallet/InCoordinator.swift index 88617a157..d16aae454 100644 --- a/AlphaWallet/InCoordinator.swift +++ b/AlphaWallet/InCoordinator.swift @@ -123,6 +123,11 @@ class InCoordinator: NSObject, Coordinator { //service.register(service: uniswap) + var quickSwap = QuickSwap() + quickSwap.theme = navigationController.traitCollection.uniswapTheme + + service.register(service: quickSwap) + return service }() diff --git a/AlphaWallet/Localization/en.lproj/Localizable.strings b/AlphaWallet/Localization/en.lproj/Localizable.strings index b891338ee..b7ab45ed6 100644 --- a/AlphaWallet/Localization/en.lproj/Localizable.strings +++ b/AlphaWallet/Localization/en.lproj/Localizable.strings @@ -523,6 +523,7 @@ "a.wallet.token.transaction.inProgress.subtitle" = "The transaction is sent to the Ethereum\nblockchain. It might take few minutes\nto be confirmed by miners."; "a.wallet.token.transaction.inProgress.confirm" = "OK, great!"; "a.wallet.token.erc20ExchangeOnUniswap.button.title" = "Exchange with Uniswap"; +"a.wallet.token.erc20ExchangeOnQuickSwap.button.title" = "Exchange with QuickSwap"; "a.wallet.token.erc20ExchangeOn1inch.button.title" = "Swap"; "a.wallet.token.erc20ExchangeHoneyswap.button.title" = "Swap with Honeyswap"; "a.wallet.token.xDaiBridge.button.title" = "Convert to DAI"; diff --git a/AlphaWallet/Localization/es.lproj/Localizable.strings b/AlphaWallet/Localization/es.lproj/Localizable.strings index 4f3b45a8d..0db6a3821 100644 --- a/AlphaWallet/Localization/es.lproj/Localizable.strings +++ b/AlphaWallet/Localization/es.lproj/Localizable.strings @@ -523,6 +523,7 @@ "a.wallet.token.transaction.inProgress.subtitle" = "The transaction is sent to the Ethereum\nblockchain. It might take few minutes\nto be confirmed by miners."; "a.wallet.token.transaction.inProgress.confirm" = "OK, great!"; "a.wallet.token.erc20ExchangeOnUniswap.button.title" = "Exchange with Uniswap"; +"a.wallet.token.erc20ExchangeOnQuickSwap.button.title" = "Exchange with QuickSwap"; "a.wallet.token.erc20ExchangeOn1inch.button.title" = "Swap"; "a.wallet.token.erc20ExchangeHoneyswap.button.title" = "Swap with Honeyswap"; "a.wallet.token.xDaiBridge.button.title" = "Convert to DAI"; diff --git a/AlphaWallet/Localization/ja.lproj/Localizable.strings b/AlphaWallet/Localization/ja.lproj/Localizable.strings index 8e13ca4db..87d1bf18d 100644 --- a/AlphaWallet/Localization/ja.lproj/Localizable.strings +++ b/AlphaWallet/Localization/ja.lproj/Localizable.strings @@ -523,6 +523,7 @@ "a.wallet.token.transaction.inProgress.subtitle" = "The transaction is sent to the Ethereum\nblockchain. It might take few minutes\nto be confirmed by miners."; "a.wallet.token.transaction.inProgress.confirm" = "OK, great!"; "a.wallet.token.erc20ExchangeOnUniswap.button.title" = "Exchange with Uniswap"; +"a.wallet.token.erc20ExchangeOnQuickSwap.button.title" = "Exchange with QuickSwap"; "a.wallet.token.erc20ExchangeOn1inch.button.title" = "Swap"; "a.wallet.token.erc20ExchangeHoneyswap.button.title" = "Swap with Honeyswap"; "a.wallet.token.xDaiBridge.button.title" = "Convert to DAI"; diff --git a/AlphaWallet/Localization/ko.lproj/Localizable.strings b/AlphaWallet/Localization/ko.lproj/Localizable.strings index e93bc31ad..d40c86b83 100644 --- a/AlphaWallet/Localization/ko.lproj/Localizable.strings +++ b/AlphaWallet/Localization/ko.lproj/Localizable.strings @@ -523,6 +523,7 @@ "a.wallet.token.transaction.inProgress.subtitle" = "The transaction is sent to the Ethereum\nblockchain. It might take few minutes\nto be confirmed by miners."; "a.wallet.token.transaction.inProgress.confirm" = "OK, great!"; "a.wallet.token.erc20ExchangeOnUniswap.button.title" = "Exchange with Uniswap"; +"a.wallet.token.erc20ExchangeOnQuickSwap.button.title" = "Exchange with QuickSwap"; "a.wallet.token.erc20ExchangeOn1inch.button.title" = "Swap"; "a.wallet.token.erc20ExchangeHoneyswap.button.title" = "Swap with Honeyswap"; "a.wallet.token.xDaiBridge.button.title" = "Convert to DAI"; diff --git a/AlphaWallet/Localization/zh-Hans.lproj/Localizable.strings b/AlphaWallet/Localization/zh-Hans.lproj/Localizable.strings index e21b68c69..0251f37ac 100644 --- a/AlphaWallet/Localization/zh-Hans.lproj/Localizable.strings +++ b/AlphaWallet/Localization/zh-Hans.lproj/Localizable.strings @@ -523,6 +523,7 @@ "a.wallet.token.transaction.inProgress.subtitle" = "The transaction is sent to the Ethereum\nblockchain. It might take few minutes\nto be confirmed by miners."; "a.wallet.token.transaction.inProgress.confirm" = "OK, great!"; "a.wallet.token.erc20ExchangeOnUniswap.button.title" = "Exchange with Uniswap"; +"a.wallet.token.erc20ExchangeOnQuickSwap.button.title" = "Exchange with QuickSwap"; "a.wallet.token.erc20ExchangeOn1inch.button.title" = "Swap"; "a.wallet.token.erc20ExchangeHoneyswap.button.title" = "Swap with Honeyswap"; "a.wallet.token.xDaiBridge.button.title" = "Convert to DAI";