Merge pull request #3758 from oa-s/#3757

Refactor Enjin OpenSea providers #3757
pull/3782/head
Hwee-Boon Yar 3 years ago committed by GitHub
commit a52811e96e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 8
      AlphaWallet.xcodeproj/project.pbxproj
  2. 2
      AlphaWallet/AppCoordinator.swift
  3. 31
      AlphaWallet/Core/Enjin/EnjinProvider.swift
  4. 32
      AlphaWallet/Core/Enjin/EnjinUserManagementInterceptor.swift
  5. 7
      AlphaWallet/EtherClient/OpenSea.swift
  6. 6
      AlphaWallet/TokenScriptClient/Coordinators/AssetDefinitionStoreCoordinator.swift

@ -1010,7 +1010,7 @@
87FB0A8226D8D307000EC15F /* TokenProviderType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 87FB0A8126D8D307000EC15F /* TokenProviderType.swift */; };
87FBAE0124A1EE67005EF293 /* AddressOrEnsNameLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 87FBAE0024A1EE67005EF293 /* AddressOrEnsNameLabel.swift */; };
87FF2E422567F0A3002350EB /* BlockieGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 87FF2E412567F0A3002350EB /* BlockieGenerator.swift */; };
87FF649927355FDD00D59E20 /* EnjinAuthorization.swift in Sources */ = {isa = PBXBuildFile; fileRef = 87FF649827355FDD00D59E20 /* EnjinAuthorization.swift */; };
87FF649927355FDD00D59E20 /* EnjinUserManagementInterceptor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 87FF649827355FDD00D59E20 /* EnjinUserManagementInterceptor.swift */; };
AA26C61F20412A1E00318B9B /* TokensCardViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA26C61D20412A1D00318B9B /* TokensCardViewController.swift */; };
AA26C62320412A4100318B9B /* UIViewInspectableEnhancements.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA26C62120412A4100318B9B /* UIViewInspectableEnhancements.swift */; };
AA26C62420412A4100318B9B /* Double.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA26C62220412A4100318B9B /* Double.swift */; };
@ -2099,7 +2099,7 @@
87FB0A8126D8D307000EC15F /* TokenProviderType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TokenProviderType.swift; sourceTree = "<group>"; };
87FBAE0024A1EE67005EF293 /* AddressOrEnsNameLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddressOrEnsNameLabel.swift; sourceTree = "<group>"; };
87FF2E412567F0A3002350EB /* BlockieGenerator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlockieGenerator.swift; sourceTree = "<group>"; };
87FF649827355FDD00D59E20 /* EnjinAuthorization.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EnjinAuthorization.swift; sourceTree = "<group>"; };
87FF649827355FDD00D59E20 /* EnjinUserManagementInterceptor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EnjinUserManagementInterceptor.swift; sourceTree = "<group>"; };
AA26C61D20412A1D00318B9B /* TokensCardViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TokensCardViewController.swift; sourceTree = "<group>"; };
AA26C62120412A4100318B9B /* UIViewInspectableEnhancements.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIViewInspectableEnhancements.swift; sourceTree = "<group>"; };
AA26C62220412A4100318B9B /* Double.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Double.swift; sourceTree = "<group>"; };
@ -4991,7 +4991,7 @@
87D5BBDA2727DA7B0053E6D2 /* EnjinToken.graphql */,
87D5BBDC2727DCB40053E6D2 /* EnjinBalances.graphql */,
87D5BBD62727D69E0053E6D2 /* EnjinProvider.swift */,
87FF649827355FDD00D59E20 /* EnjinAuthorization.swift */,
87FF649827355FDD00D59E20 /* EnjinUserManagementInterceptor.swift */,
);
path = Enjin;
sourceTree = "<group>";
@ -5662,7 +5662,7 @@
29F114F21FA7966300114A29 /* PrivateKeyRule.swift in Sources */,
29E2E33A1F7A008C000CF94A /* UIView.swift in Sources */,
87509A6226F8D67E00D3EE85 /* CollectUsersEmailViewController.swift in Sources */,
87FF649927355FDD00D59E20 /* EnjinAuthorization.swift in Sources */,
87FF649927355FDD00D59E20 /* EnjinUserManagementInterceptor.swift in Sources */,
87A0C93225AEF1E400E73F60 /* EventInstanceValue.swift in Sources */,
299B5E491FD2C8900051361C /* ConfigureTransaction.swift in Sources */,
77872D25202505B70032D687 /* EnterPasswordViewController.swift in Sources */,

@ -331,7 +331,6 @@ extension AppCoordinator: InitialWalletCreationCoordinatorDelegate {
extension AppCoordinator: InCoordinatorDelegate {
func didRestart(in coordinator: InCoordinator, reason: RestartReason, wallet: Wallet) {
OpenSea.resetInstances()
disconnectWalletConnectSessionsSelectively(for: reason, walletConnectCoordinator: coordinator.walletConnectCoordinator)
keystore.recentlyUsedWallet = wallet
@ -530,7 +529,6 @@ extension AppCoordinator: AccountsCoordinatorDelegate {
pendingCoordinator.showTabBar(animated: true)
} else {
if let coordinator = pendingInCoordinator {
OpenSea.resetInstances()
disconnectWalletConnectSessionsSelectively(for: .walletChange, walletConnectCoordinator: coordinator.walletConnectCoordinator)
}

@ -13,26 +13,27 @@ struct EnjinError: Error {
var localizedDescription: String
}
class EnjinProvider {
private class WeakRef<T: AnyObject> {
weak var object: T?
init(object: T) {
self.object = object
}
class WeakRef<T: AnyObject> {
weak var object: T?
init(object: T) {
self.object = object
}
}
class EnjinProvider {
typealias PromiseResult = Promise<[AlphaWallet.Address: [GetEnjinTokenQuery.Data.EnjinToken]]>
private static let numberOfTokenIdsBeforeRateLimitingRequests = 25
private static let minimumSecondsBetweenRequests = TimeInterval(60)
private(set) lazy var graphqlClient: ApolloClient = {
let client = URLSessionClient()
let cache = InMemoryNormalizedCache()
let store = ApolloStore(cache: cache)
static let client = URLSessionClient()
static let cache = InMemoryNormalizedCache()
static let store = ApolloStore(cache: cache)
private static var graphqlClient: ApolloClient = {
let provider = NetworkInterceptorProvider(store: store, client: client)
let transport = RequestChainNetworkTransport(interceptorProvider: provider, endpointURL: Constants.enjinApiUrl)
return ApolloClient(networkTransport: transport, store: store)
}()
@ -109,7 +110,7 @@ class EnjinProvider {
}
}.then({ balances -> Promise<[AlphaWallet.Address: [GetEnjinTokenQuery.Data.EnjinToken]]> in
let ids = (balances[owner] ?? []).compactMap { $0.token?.id }
return EnjinProvider.functional.getTokens(graphqlClient: self.graphqlClient, ids: ids, owner: owner)
return EnjinProvider.functional.getTokens(graphqlClient: EnjinProvider.graphqlClient, ids: ids, owner: owner)
})
}
return fetch
@ -119,7 +120,7 @@ class EnjinProvider {
typealias MappedEnjinBalances = [AlphaWallet.Address: EnjinBalances]
private func fetchPage(forOwner owner: AlphaWallet.Address, offset: Int, completion: @escaping (Swift.Result<MappedEnjinBalances, EnjinError>) -> Void) {
EnjinProvider.functional.fetchPage(graphqlClient: graphqlClient, forOwner: owner, offset: offset) { [weak self] response in
EnjinProvider.functional.fetchPage(graphqlClient: EnjinProvider.graphqlClient, forOwner: owner, offset: offset) { [weak self] response in
switch response {
case .success(let result):
self?.cachePromise(withTokenIdCount: result.tokenIdCount, forOwner: result.owner)
@ -268,7 +269,7 @@ extension EnjinProvider.functional {
}
}
final class NetworkInterceptorProvider: InterceptorProvider {
final private class NetworkInterceptorProvider: InterceptorProvider {
// These properties will remain the same throughout the life of the `InterceptorProvider`, even though they
// will be handed to different interceptors.
private let store: ApolloStore
@ -283,7 +284,7 @@ final class NetworkInterceptorProvider: InterceptorProvider {
return [
MaxRetryInterceptor(),
CacheReadInterceptor(store: self.store),
UserManagementInterceptor(),
EnjinUserManagementInterceptor(),
NetworkFetchInterceptor(client: self.client),
ResponseCodeInterceptor(),
JSONResponseParsingInterceptor(cacheKeyForObject: self.store.cacheKeyForObject),

@ -25,23 +25,21 @@ extension Config {
}
}
class UserManager {
static let shared = UserManager()
private class EnjinUserManager {
static let shared = EnjinUserManager()
private init() {
}
private var config = Config()
private var config = Config()
private let graphqlClient: ApolloClient = {
let client = URLSessionClient()
let cache = InMemoryNormalizedCache()
let store = ApolloStore(cache: cache)
let provider = InterceptorProviderForAuthorization(client: client, store: store)
let provider = InterceptorProviderForAuthorization(client: EnjinProvider.client, store: EnjinProvider.store)
let transport = RequestChainNetworkTransport(interceptorProvider: provider, endpointURL: Constants.enjinApiUrl)
return ApolloClient(networkTransport: transport, store: store)
return ApolloClient(networkTransport: transport, store: EnjinProvider.store)
}()
enum UserManagerError: Error {
enum EnjinUserManagerError: Error {
case fetchAccessTokenFailure
}
@ -59,7 +57,7 @@ class UserManager {
if let accessToken = oauth.accessTokens?.compactMap({ $0 }).first {
return accessToken
} else {
throw UserManagerError.fetchAccessTokenFailure
throw EnjinUserManagerError.fetchAccessTokenFailure
}
}.get { accessToken in
self.config.accessToken = accessToken
@ -165,7 +163,7 @@ struct FallbackJSONResponseParsingInterceptor: ApolloInterceptor {
private func parseResult<Data>(from response: GraphQLResponse<Data>, cachePolicy: CachePolicy) throws -> GraphQLResult<Data> {
switch cachePolicy {
case .fetchIgnoringCacheCompletely:
// There is no cache, so we don't need to get any info on dependencies. Use fast parsing.
// There is no cache, so we don't need to get any info on dependencies. Use fast parsing.
return try response.parseResultFast()
default:
let (parsedResult, _) = try response.parseResult(cacheKeyForObject: self.cacheKeyForObject)
@ -175,7 +173,7 @@ struct FallbackJSONResponseParsingInterceptor: ApolloInterceptor {
}
class UserManagementInterceptor: ApolloInterceptor {
class EnjinUserManagementInterceptor: ApolloInterceptor {
enum UserError: Error {
case noUserLoggedIn
@ -193,7 +191,7 @@ class UserManagementInterceptor: ApolloInterceptor {
}
let performAuthorizeEnjinUser: () -> Void = {
let promise = UserManager.shared.enjinAuthorize()
let promise = EnjinUserManager.shared.enjinAuthorize()
promise.done { accessToken in
addTokenAndProceed(accessToken, to: request, chain: chain, response: response, completion: completion)
}.catch { error in
@ -211,9 +209,9 @@ class UserManagementInterceptor: ApolloInterceptor {
if let accessToken = promise.value {
addTokenAndProceed(accessToken, to: request, chain: chain, response: response, completion: completion)
} else if promise.isPending {
//NOTE: wait until access token resolved
//NOTE: wait until access token resolved
let block: () -> Void = {
guard let accessToken = UserManager.shared.accessToken else { return }
guard let accessToken = EnjinUserManager.shared.accessToken else { return }
addTokenAndProceed(accessToken, to: request, chain: chain, response: response, completion: completion)
}
Self.pending.append(block)
@ -245,7 +243,7 @@ class UserManagementInterceptor: ApolloInterceptor {
}
}
guard let token = UserManager.shared.accessToken else {
guard let token = EnjinUserManager.shared.accessToken else {
authorizeEnjinUser()
return
}

@ -8,13 +8,6 @@ import Result
import SwiftyJSON
class OpenSea {
private class WeakRef<T: AnyObject> {
weak var object: T?
init(object: T) {
self.object = object
}
}
typealias PromiseResult = Promise<[AlphaWallet.Address: [OpenSeaNonFungible]]>
//Assuming 1 token (token ID, rather than a token) is 4kb, 1500 HyperDragons is 6MB. So we rate limit requests

@ -30,12 +30,6 @@ enum OpenURLError: Error {
}
class AssetDefinitionStoreCoordinator: Coordinator {
private class WeakRef<T: AnyObject> {
weak var object: T?
init(object: T) {
self.object = object
}
}
private static var inboxDirectory: URL? {
let paths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .allDomainsMask, true).compactMap { URL(fileURLWithPath: $0) }

Loading…
Cancel
Save