From 491b9875475899c9bc3952d179059d9f2e655e3f Mon Sep 17 00:00:00 2001 From: Hwee-Boon Yar Date: Mon, 19 Oct 2020 12:01:02 +0800 Subject: [PATCH] Fix: ERC721 transfer button not showing up after tapping on an ERC721 token instance --- .../TokenScriptClient/Models/XMLHandler.swift | 47 +++++++++++++++---- 1 file changed, 38 insertions(+), 9 deletions(-) diff --git a/AlphaWallet/TokenScriptClient/Models/XMLHandler.swift b/AlphaWallet/TokenScriptClient/Models/XMLHandler.swift index fc4295482..6c1fea0c5 100644 --- a/AlphaWallet/TokenScriptClient/Models/XMLHandler.swift +++ b/AlphaWallet/TokenScriptClient/Models/XMLHandler.swift @@ -113,7 +113,10 @@ private class PrivateXMLHandler { private lazy var selections = extractSelectionsForToken() private let isOfficial: Bool private let isCanonicalized: Bool - private let isBase: Bool + private var isBase: Bool { + baseTokenType != nil + } + private let baseTokenType: TokenType? lazy private var contractNamesAndAddresses: [String: [(AlphaWallet.Address, RPCServer)]] = extractContractNamesAndAddresses() private var tokenElement: XMLElement? { @@ -181,8 +184,12 @@ private class PrivateXMLHandler { } } if fromActionAsTopLevel.isEmpty { - tokenType - .flatMap { results.append(contentsOf: defaultActions(forTokenType: $0)) } + if let baseTokenType = baseTokenType, Features.isActivityEnabled { + results.append(contentsOf: defaultActions(forTokenType: baseTokenType)) + } else { + tokenType + .flatMap { results.append(contentsOf: defaultActions(forTokenType: $0)) } + } } else { //TODO "erc20Send" name is not good for cryptocurrency let defaultActionsForCryptoCurrency: [TokenInstanceAction] = [.init(type: .erc20Send), .init(type: .erc20Receive)] @@ -288,19 +295,19 @@ private class PrivateXMLHandler { let xmlString = assetDefinitionStore[contract] let isOfficial = assetDefinitionStore.isOfficial(contract: contract) let isCanonicalized = assetDefinitionStore.isCanonicalized(contract: contract) - self.init(contract: contract, xmlString: xmlString, isBase: false, isOfficial: isOfficial, isCanonicalized: isCanonicalized, assetDefinitionStore: assetDefinitionStore) + self.init(contract: contract, xmlString: xmlString, baseTokenType: nil, isOfficial: isOfficial, isCanonicalized: isCanonicalized, assetDefinitionStore: assetDefinitionStore) } - convenience init(contract: AlphaWallet.Address, baseXml: String, assetDefinitionStore: AssetDefinitionStore) { - self.init(contract: contract, xmlString: baseXml, isBase: true, isOfficial: true, isCanonicalized: true, assetDefinitionStore: assetDefinitionStore) + convenience init(contract: AlphaWallet.Address, baseXml: String, baseTokenType: TokenType, assetDefinitionStore: AssetDefinitionStore) { + self.init(contract: contract, xmlString: baseXml, baseTokenType: baseTokenType, isOfficial: true, isCanonicalized: true, assetDefinitionStore: assetDefinitionStore) } - private init(contract: AlphaWallet.Address, xmlString: String?, isBase: Bool, isOfficial: Bool, isCanonicalized: Bool, assetDefinitionStore: AssetDefinitionStore) { + private init(contract: AlphaWallet.Address, xmlString: String?, baseTokenType: TokenType?, isOfficial: Bool, isCanonicalized: Bool, assetDefinitionStore: AssetDefinitionStore) { let xmlString = xmlString ?? "" self.contractAddress = contract self.isOfficial = isOfficial self.isCanonicalized = isCanonicalized - self.isBase = isBase + self.baseTokenType = baseTokenType self.assetDefinitionStore = assetDefinitionStore //We still compute the TokenScript status even if xmlString is empty because it might be considered empty because there's a conflict let tokenScriptStatusPromise = PrivateXMLHandler.computeTokenScriptStatus(forContract: contract, xmlString: xmlString, isOfficial: isOfficial, isCanonicalized: isCanonicalized, assetDefinitionStore: assetDefinitionStore) @@ -317,6 +324,7 @@ private class PrivateXMLHandler { } else { xml = (try? Kanna.XML(xml: xmlString, encoding: .utf8)) ?? PrivateXMLHandler.emptyXML hasValidTokenScriptFile = true + let isBase = baseTokenType != nil if isBase { self.server = .any } else { @@ -525,6 +533,27 @@ private class PrivateXMLHandler { return actions.map { .init(type: $0) } } + private func defaultActions(forTokenType tokenType: TokenType) -> [TokenInstanceAction] { + let actions: [TokenInstanceAction.ActionType] + switch tokenType { + case .erc20, .nativeCryptocurrency: + actions = [.erc20Send, .erc20Receive] + case .erc721, .erc721ForTickets: + if contractAddress.isUEFATicketContract { + actions = [.nftRedeem, .nonFungibleTransfer] + } else { + actions = [.nonFungibleTransfer] + } + case .erc875: + if contractAddress.isFifaTicketContract { + actions = [.nftRedeem, .nftSell, .nonFungibleTransfer] + } else { + actions = [.nftSell, .nonFungibleTransfer] + } + } + return actions.map { .init(type: $0) } + } + private func createFunctionOriginFrom(ethereumFunctionElement: XMLElement) -> FunctionOrigin? { if let contract = ethereumFunctionElement["contract"].nilIfEmpty { guard let server = server else { return nil } @@ -791,7 +820,7 @@ public class XMLHandler { baseXMLHandler = handler } else { if let xml = TokenScript.baseTokenScriptFiles[tokenTypeForBaseXml] { - baseXMLHandler = PrivateXMLHandler(contract: contract, baseXml: xml, assetDefinitionStore: assetDefinitionStore) + baseXMLHandler = PrivateXMLHandler(contract: contract, baseXml: xml, baseTokenType: tokenTypeForBaseXml, assetDefinitionStore: assetDefinitionStore) XMLHandler.baseXmlHandlers[key] = baseXMLHandler } else { baseXMLHandler = nil