Fix: TokenScript files should override behavior of ERC721 tokens fetched from OpenSea too

pull/1430/head
Hwee-Boon Yar 5 years ago
parent 0bc922aa1b
commit 51f95b2ccb
  1. 6
      AlphaWallet/Redeem/ViewControllers/RedeemTokenCardQuantitySelectionViewController.swift
  2. 6
      AlphaWallet/Redeem/ViewControllers/TokenCardRedemptionViewController.swift
  3. 6
      AlphaWallet/Sell/ViewControllers/EnterSellTokensCardPriceQuantityViewController.swift
  4. 6
      AlphaWallet/Sell/ViewControllers/SetSellTokensCardExpiryDateViewController.swift
  5. 6
      AlphaWallet/Tokens/Coordinators/SingleChainTokenCoordinator.swift
  6. 2
      AlphaWallet/Tokens/Helpers/TokenAdaptor.swift
  7. 21
      AlphaWallet/Tokens/Types/OpenSeaNonFungibleTokenHandling.swift
  8. 2
      AlphaWallet/Tokens/ViewControllers/TokenInstanceActionViewController.swift
  9. 8
      AlphaWallet/Tokens/ViewControllers/TokenInstanceViewController.swift
  10. 14
      AlphaWallet/Tokens/ViewControllers/TokensCardViewController.swift
  11. 6
      AlphaWallet/Transfer/ViewControllers/ChooseTokenCardTransferModeViewController.swift
  12. 6
      AlphaWallet/Transfer/ViewControllers/SetTransferTokensCardExpiryDateViewController.swift
  13. 6
      AlphaWallet/Transfer/ViewControllers/TransferTokensCardQuantitySelectionViewController.swift
  14. 6
      AlphaWallet/Transfer/ViewControllers/TransferTokensCardViaWalletAddressViewController.swift

@ -37,11 +37,11 @@ class RedeemTokenCardQuantitySelectionViewController: UIViewController, TokenVer
self.viewModel = viewModel self.viewModel = viewModel
self.assetDefinitionStore = assetDefinitionStore self.assetDefinitionStore = assetDefinitionStore
let tokenType = OpenSeaNonFungibleTokenHandling(token: token) let tokenType = OpenSeaBackedNonFungibleTokenHandling(token: token, assetDefinitionStore: assetDefinitionStore)
switch tokenType { switch tokenType {
case .supportedByOpenSea: case .backedByOpenSea:
tokenRowView = OpenSeaNonFungibleTokenCardRowView(tokenView: .viewIconified) tokenRowView = OpenSeaNonFungibleTokenCardRowView(tokenView: .viewIconified)
case .notSupportedByOpenSea: case .notBackedByOpenSea:
tokenRowView = TokenCardRowView(server: token.server, tokenView: .viewIconified, assetDefinitionStore: assetDefinitionStore) tokenRowView = TokenCardRowView(server: token.server, tokenView: .viewIconified, assetDefinitionStore: assetDefinitionStore)
} }

@ -35,11 +35,11 @@ class TokenCardRedemptionViewController: UIViewController, TokenVerifiableStatus
self.viewModel = viewModel self.viewModel = viewModel
self.assetDefinitionStore = assetDefinitionStore self.assetDefinitionStore = assetDefinitionStore
let tokenType = OpenSeaNonFungibleTokenHandling(token: token) let tokenType = OpenSeaBackedNonFungibleTokenHandling(token: token, assetDefinitionStore: assetDefinitionStore)
switch tokenType { switch tokenType {
case .supportedByOpenSea: case .backedByOpenSea:
tokenRowView = OpenSeaNonFungibleTokenCardRowView(tokenView: .viewIconified) tokenRowView = OpenSeaNonFungibleTokenCardRowView(tokenView: .viewIconified)
case .notSupportedByOpenSea: case .notBackedByOpenSea:
tokenRowView = TokenCardRowView(server: token.server, tokenView: .viewIconified, assetDefinitionStore: assetDefinitionStore) tokenRowView = TokenCardRowView(server: token.server, tokenView: .viewIconified, assetDefinitionStore: assetDefinitionStore)
} }

@ -66,11 +66,11 @@ class EnterSellTokensCardPriceQuantityViewController: UIViewController, TokenVer
self.viewModel = viewModel self.viewModel = viewModel
self.assetDefinitionStore = assetDefinitionStore self.assetDefinitionStore = assetDefinitionStore
let tokenType = OpenSeaNonFungibleTokenHandling(token: viewModel.token) let tokenType = OpenSeaBackedNonFungibleTokenHandling(token: viewModel.token, assetDefinitionStore: assetDefinitionStore)
switch tokenType { switch tokenType {
case .supportedByOpenSea: case .backedByOpenSea:
tokenRowView = OpenSeaNonFungibleTokenCardRowView(tokenView: .viewIconified) tokenRowView = OpenSeaNonFungibleTokenCardRowView(tokenView: .viewIconified)
case .notSupportedByOpenSea: case .notBackedByOpenSea:
tokenRowView = TokenCardRowView(server: viewModel.token.server, tokenView: .viewIconified, assetDefinitionStore: assetDefinitionStore) tokenRowView = TokenCardRowView(server: viewModel.token.server, tokenView: .viewIconified, assetDefinitionStore: assetDefinitionStore)
} }

@ -67,11 +67,11 @@ class SetSellTokensCardExpiryDateViewController: UIViewController, TokenVerifiab
self.viewModel = viewModel self.viewModel = viewModel
self.assetDefinitionStore = assetDefinitionStore self.assetDefinitionStore = assetDefinitionStore
let tokenType = OpenSeaNonFungibleTokenHandling(token: viewModel.token) let tokenType = OpenSeaBackedNonFungibleTokenHandling(token: viewModel.token, assetDefinitionStore: assetDefinitionStore)
switch tokenType { switch tokenType {
case .supportedByOpenSea: case .backedByOpenSea:
tokenRowView = OpenSeaNonFungibleTokenCardRowView(tokenView: .viewIconified) tokenRowView = OpenSeaNonFungibleTokenCardRowView(tokenView: .viewIconified)
case .notSupportedByOpenSea: case .notBackedByOpenSea:
tokenRowView = TokenCardRowView(server: viewModel.token.server, tokenView: .viewIconified, assetDefinitionStore: assetDefinitionStore) tokenRowView = TokenCardRowView(server: viewModel.token.server, tokenView: .viewIconified, assetDefinitionStore: assetDefinitionStore)
} }

@ -446,10 +446,10 @@ class SingleChainTokenCoordinator: Coordinator {
case .nativeCryptocurrency, .erc20, .erc875: case .nativeCryptocurrency, .erc20, .erc875:
break break
case .erc721: case .erc721:
switch OpenSeaNonFungibleTokenHandling(token: token) { switch OpenSeaBackedNonFungibleTokenHandling(token: token, assetDefinitionStore: assetDefinitionStore) {
case .supportedByOpenSea: case .backedByOpenSea:
break break
case .notSupportedByOpenSea: case .notBackedByOpenSea:
coordinator.isReadOnly = true coordinator.isReadOnly = true
} }
} }

@ -24,7 +24,7 @@ class TokenAdaptor {
case .nativeCryptocurrency, .erc20, .erc875: case .nativeCryptocurrency, .erc20, .erc875:
return getNotSupportedByOpenSeaTokenHolders(forWallet: account) return getNotSupportedByOpenSeaTokenHolders(forWallet: account)
case .erc721: case .erc721:
let tokenType = OpenSeaNonFungibleTokenHandling(token: token) let tokenType = OpenSeaSupportedNonFungibleTokenHandling(token: token)
switch tokenType { switch tokenType {
case .supportedByOpenSea: case .supportedByOpenSea:
return getSupportedByOpenSeaTokenHolders() return getSupportedByOpenSeaTokenHolders()

@ -2,9 +2,28 @@
import Foundation import Foundation
///Use this enum to "mark" where we handle non-fungible tokens backed by OpenSea differently instead of accessing the contract directly.
///If there is a TokenScript file available for the contract, it is assumed to be no longer "backed" by OpenSea
///If there are other special casing for tokens that doesn't fit this model, create another enum type (not case)
enum OpenSeaBackedNonFungibleTokenHandling {
case backedByOpenSea
case notBackedByOpenSea
init(token: TokenObject, assetDefinitionStore: AssetDefinitionStore) {
self = {
if !token.balance.isEmpty && token.balance[0].balance.hasPrefix("{") && !XMLHandler(contract: token.contractAddress, assetDefinitionStore: AssetDefinitionStore()).hasAssetDefinition {
return .backedByOpenSea
} else {
return .notBackedByOpenSea
}
}()
}
}
///Use this enum to "mark" where we handle non-fungible tokens supported by OpenSea differently instead of accessing the contract directly ///Use this enum to "mark" where we handle non-fungible tokens supported by OpenSea differently instead of accessing the contract directly
///Even if there is a TokenScript file available for the contract, it is assumed to still be supported by OpenSea
///If there are other special casing for tokens that doesn't fit this model, create another enum type (not case) ///If there are other special casing for tokens that doesn't fit this model, create another enum type (not case)
enum OpenSeaNonFungibleTokenHandling { enum OpenSeaSupportedNonFungibleTokenHandling {
case supportedByOpenSea case supportedByOpenSea
case notSupportedByOpenSea case notSupportedByOpenSea

@ -62,7 +62,7 @@ class TokenInstanceActionViewController: UIViewController, TokenVerifiableStatus
} }
var canPeekToken: Bool { var canPeekToken: Bool {
let tokenType = OpenSeaNonFungibleTokenHandling(token: tokenObject) let tokenType = OpenSeaSupportedNonFungibleTokenHandling(token: tokenObject)
switch tokenType { switch tokenType {
case .supportedByOpenSea: case .supportedByOpenSea:
return true return true

@ -44,7 +44,7 @@ class TokenInstanceViewController: UIViewController, TokenVerifiableStatusViewCo
} }
var canPeekToken: Bool { var canPeekToken: Bool {
let tokenType = OpenSeaNonFungibleTokenHandling(token: tokenObject) let tokenType = OpenSeaSupportedNonFungibleTokenHandling(token: tokenObject)
switch tokenType { switch tokenType {
case .supportedByOpenSea: case .supportedByOpenSea:
return true return true
@ -209,14 +209,14 @@ extension TokenInstanceViewController: UITableViewDelegate, UITableViewDataSourc
} }
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let tokenType = OpenSeaNonFungibleTokenHandling(token: tokenObject) let tokenType = OpenSeaBackedNonFungibleTokenHandling(token: tokenObject, assetDefinitionStore: assetDefinitionStore)
switch tokenType { switch tokenType {
case .supportedByOpenSea: case .backedByOpenSea:
let cell = tableView.dequeueReusableCell(withIdentifier: OpenSeaNonFungibleTokenCardTableViewCellWithoutCheckbox.identifier, for: indexPath) as! OpenSeaNonFungibleTokenCardTableViewCellWithoutCheckbox let cell = tableView.dequeueReusableCell(withIdentifier: OpenSeaNonFungibleTokenCardTableViewCellWithoutCheckbox.identifier, for: indexPath) as! OpenSeaNonFungibleTokenCardTableViewCellWithoutCheckbox
cell.delegate = self cell.delegate = self
cell.configure(viewModel: .init(tokenHolder: tokenHolder, cellWidth: tableView.frame.size.width, tokenView: .view)) cell.configure(viewModel: .init(tokenHolder: tokenHolder, cellWidth: tableView.frame.size.width, tokenView: .view))
return cell return cell
case .notSupportedByOpenSea: case .notBackedByOpenSea:
let cell = tableView.dequeueReusableCell(withIdentifier: TokenCardTableViewCellWithoutCheckbox.identifier, for: indexPath) as! TokenCardTableViewCellWithoutCheckbox let cell = tableView.dequeueReusableCell(withIdentifier: TokenCardTableViewCellWithoutCheckbox.identifier, for: indexPath) as! TokenCardTableViewCellWithoutCheckbox
cell.configure(viewModel: .init(tokenHolder: viewModel.tokenHolder, cellWidth: tableView.frame.size.width, tokenView: .view), assetDefinitionStore: assetDefinitionStore) cell.configure(viewModel: .init(tokenHolder: viewModel.tokenHolder, cellWidth: tableView.frame.size.width, tokenView: .view), assetDefinitionStore: assetDefinitionStore)
//TODO move into configure() //TODO move into configure()

@ -63,7 +63,7 @@ class TokensCardViewController: UIViewController, TokenVerifiableStatusViewContr
} }
var canPeekToken: Bool { var canPeekToken: Bool {
let tokenType = OpenSeaNonFungibleTokenHandling(token: tokenObject) let tokenType = OpenSeaSupportedNonFungibleTokenHandling(token: tokenObject)
switch tokenType { switch tokenType {
case .supportedByOpenSea: case .supportedByOpenSea:
return true return true
@ -236,12 +236,12 @@ class TokensCardViewController: UIViewController, TokenVerifiableStatusViewContr
//We only auto scroll to reveal for OpenSea-supported tokens which are usually taller and have a picture. Because //We only auto scroll to reveal for OpenSea-supported tokens which are usually taller and have a picture. Because
// (A) other tokens like ERC875 tickets are usually too short and all text, making it difficult for user to capture where it has scrolled to // (A) other tokens like ERC875 tickets are usually too short and all text, making it difficult for user to capture where it has scrolled to
// (B) OpenSea-supported tokens are tall, so after expanding, chances are user need to scroll quite a lot if we don't auto-scroll // (B) OpenSea-supported tokens are tall, so after expanding, chances are user need to scroll quite a lot if we don't auto-scroll
switch OpenSeaNonFungibleTokenHandling(token: viewModel.token) { switch OpenSeaBackedNonFungibleTokenHandling(token: viewModel.token, assetDefinitionStore: assetDefinitionStore) {
case .supportedByOpenSea: case .backedByOpenSea:
if let indexPath = indexPaths.first(where: { viewModel.item(for: $0).areDetailsVisible }) { if let indexPath = indexPaths.first(where: { viewModel.item(for: $0).areDetailsVisible }) {
tableview.scrollToRow(at: indexPath, at: .top, animated: false) tableview.scrollToRow(at: indexPath, at: .top, animated: false)
} }
case .notSupportedByOpenSea: case .notBackedByOpenSea:
break break
} }
} }
@ -300,9 +300,9 @@ extension TokensCardViewController: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let tokenHolder = viewModel.item(for: indexPath) let tokenHolder = viewModel.item(for: indexPath)
let tokenType = OpenSeaNonFungibleTokenHandling(token: tokenObject) let tokenType = OpenSeaBackedNonFungibleTokenHandling(token: tokenObject, assetDefinitionStore: assetDefinitionStore)
switch tokenType { switch tokenType {
case .supportedByOpenSea: case .backedByOpenSea:
let cell = tableView.dequeueReusableCell(withIdentifier: OpenSeaNonFungibleTokenCardTableViewCellWithCheckbox.identifier, for: indexPath) as! OpenSeaNonFungibleTokenCardTableViewCellWithCheckbox let cell = tableView.dequeueReusableCell(withIdentifier: OpenSeaNonFungibleTokenCardTableViewCellWithCheckbox.identifier, for: indexPath) as! OpenSeaNonFungibleTokenCardTableViewCellWithCheckbox
cell.delegate = self cell.delegate = self
cell.configure(viewModel: .init(tokenHolder: tokenHolder, cellWidth: tableView.frame.size.width, tokenView: .viewIconified)) cell.configure(viewModel: .init(tokenHolder: tokenHolder, cellWidth: tableView.frame.size.width, tokenView: .viewIconified))
@ -312,7 +312,7 @@ extension TokensCardViewController: UITableViewDelegate, UITableViewDataSource {
cell.addGestureRecognizer(UILongPressGestureRecognizer(target: self, action: #selector(longPressedTokenInstanceIconified))) cell.addGestureRecognizer(UILongPressGestureRecognizer(target: self, action: #selector(longPressedTokenInstanceIconified)))
} }
return cell return cell
case .notSupportedByOpenSea: case .notBackedByOpenSea:
let cell = tableView.dequeueReusableCell(withIdentifier: TokenCardTableViewCellWithCheckbox.identifier, for: indexPath) as! TokenCardTableViewCellWithCheckbox let cell = tableView.dequeueReusableCell(withIdentifier: TokenCardTableViewCellWithCheckbox.identifier, for: indexPath) as! TokenCardTableViewCellWithCheckbox
cell.configure(viewModel: .init(tokenHolder: tokenHolder, cellWidth: tableView.frame.size.width, tokenView: .viewIconified), assetDefinitionStore: assetDefinitionStore) cell.configure(viewModel: .init(tokenHolder: tokenHolder, cellWidth: tableView.frame.size.width, tokenView: .viewIconified), assetDefinitionStore: assetDefinitionStore)
cell.isCheckboxVisible = isMultipleSelectionMode cell.isCheckboxVisible = isMultipleSelectionMode

@ -38,11 +38,11 @@ class ChooseTokenCardTransferModeViewController: UIViewController, TokenVerifiab
self.viewModel = viewModel self.viewModel = viewModel
self.assetDefinitionStore = assetDefinitionStore self.assetDefinitionStore = assetDefinitionStore
let tokenType = OpenSeaNonFungibleTokenHandling(token: viewModel.token) let tokenType = OpenSeaBackedNonFungibleTokenHandling(token: viewModel.token, assetDefinitionStore: assetDefinitionStore)
switch tokenType { switch tokenType {
case .supportedByOpenSea: case .backedByOpenSea:
tokenRowView = OpenSeaNonFungibleTokenCardRowView(tokenView: .viewIconified) tokenRowView = OpenSeaNonFungibleTokenCardRowView(tokenView: .viewIconified)
case .notSupportedByOpenSea: case .notBackedByOpenSea:
tokenRowView = TokenCardRowView(server: viewModel.token.server, tokenView: .viewIconified, assetDefinitionStore: assetDefinitionStore) tokenRowView = TokenCardRowView(server: viewModel.token.server, tokenView: .viewIconified, assetDefinitionStore: assetDefinitionStore)
} }

@ -47,11 +47,11 @@ class SetTransferTokensCardExpiryDateViewController: UIViewController, TokenVeri
self.viewModel = viewModel self.viewModel = viewModel
self.assetDefinitionStore = assetDefinitionStore self.assetDefinitionStore = assetDefinitionStore
let tokenType = OpenSeaNonFungibleTokenHandling(token: viewModel.token) let tokenType = OpenSeaBackedNonFungibleTokenHandling(token: viewModel.token, assetDefinitionStore: assetDefinitionStore)
switch tokenType { switch tokenType {
case .supportedByOpenSea: case .backedByOpenSea:
tokenRowView = OpenSeaNonFungibleTokenCardRowView(tokenView: .viewIconified) tokenRowView = OpenSeaNonFungibleTokenCardRowView(tokenView: .viewIconified)
case .notSupportedByOpenSea: case .notBackedByOpenSea:
tokenRowView = TokenCardRowView(server: viewModel.token.server, tokenView: .viewIconified, assetDefinitionStore: assetDefinitionStore) tokenRowView = TokenCardRowView(server: viewModel.token.server, tokenView: .viewIconified, assetDefinitionStore: assetDefinitionStore)
} }

@ -38,11 +38,11 @@ class TransferTokensCardQuantitySelectionViewController: UIViewController, Token
self.viewModel = viewModel self.viewModel = viewModel
self.assetDefinitionStore = assetDefinitionStore self.assetDefinitionStore = assetDefinitionStore
let tokenType = OpenSeaNonFungibleTokenHandling(token: token) let tokenType = OpenSeaBackedNonFungibleTokenHandling(token: token, assetDefinitionStore: assetDefinitionStore)
switch tokenType { switch tokenType {
case .supportedByOpenSea: case .backedByOpenSea:
tokenRowView = OpenSeaNonFungibleTokenCardRowView(tokenView: .viewIconified) tokenRowView = OpenSeaNonFungibleTokenCardRowView(tokenView: .viewIconified)
case .notSupportedByOpenSea: case .notBackedByOpenSea:
tokenRowView = TokenCardRowView(server: token.server, tokenView: .viewIconified, assetDefinitionStore: assetDefinitionStore) tokenRowView = TokenCardRowView(server: token.server, tokenView: .viewIconified, assetDefinitionStore: assetDefinitionStore)
} }

@ -41,11 +41,11 @@ class TransferTokensCardViaWalletAddressViewController: UIViewController, TokenV
self.viewModel = viewModel self.viewModel = viewModel
self.assetDefinitionStore = assetDefinitionStore self.assetDefinitionStore = assetDefinitionStore
let tokenType = OpenSeaNonFungibleTokenHandling(token: token) let tokenType = OpenSeaBackedNonFungibleTokenHandling(token: token, assetDefinitionStore: assetDefinitionStore)
switch tokenType { switch tokenType {
case .supportedByOpenSea: case .backedByOpenSea:
tokenRowView = OpenSeaNonFungibleTokenCardRowView(tokenView: .viewIconified) tokenRowView = OpenSeaNonFungibleTokenCardRowView(tokenView: .viewIconified)
case .notSupportedByOpenSea: case .notBackedByOpenSea:
tokenRowView = TokenCardRowView(server: token.server, tokenView: .viewIconified, assetDefinitionStore: assetDefinitionStore) tokenRowView = TokenCardRowView(server: token.server, tokenView: .viewIconified, assetDefinitionStore: assetDefinitionStore)
} }

Loading…
Cancel
Save