// // NetworkServiceAPIBalance.swift // Wallet // // Created by Igor on 04.11.2020. // Copyright © 2020 List. All rights reserved. // import Foundation import Alamofire extension Network.Service.Balance { typealias Model = Network.Model.Token } extension Network.Service { class Balance: Common.Service.Provider { var pools: [Swap.Model.Pool] = [] } } extension Network.Service.Balance { func fetch(account: String, completion: @escaping ([Model], Error?) -> Void) { if pools.isEmpty { Network.table.fetch( code: ApplicationEnvironment.shared().current.contract(.swap), table: "pools", scope: ApplicationEnvironment.shared().current.contract(.swap), limit: 1000, type: Swap.Model.Pool.self ) { (result) in self.pools = result self.fetchWithCities(account: account, pools: result, completion: completion) } } else { fetchWithCities(account: account, pools: pools, completion: completion) } } private func fetchWithCities(account: String, pools: [Swap.Model.Pool], completion: @escaping ([Model], Error?) -> Void) { Network.cities.fetch(lang: Language.current) { (cities) in func sort(collection: [Model]) -> [Model] { collection.map { var token = $0 if token.isListContract, let city = cities.first(where: { $0.token.name == token.symbol }) { token.city = city.name token.country = city.country.name } else if token.isCashContract, let city = cities.first(where: { $0.token.name.dropFirst(2) == token.symbol.dropFirst(2) }) { token.city = city.name token.country = city.country.name } else if token.isSwapContract { token.pool = pools.first(where: { $0.code == token.symbol }) } return token } .sorted(by: { $0.amount == $1.amount ? $0.symbol < $1.symbol : $0.amount > $1.amount }) } if ApplicationEnvironment.shared().current.useScatter { self.fetchScatter(account: account) { completion(sort(collection: $0), $1) } } else { self.fetchHyperion(account: account) { completion(sort(collection: $0), $1) } } } } } extension Network.Service.Balance { private struct HyperionResponse: Decodable { let account: String let tokens: [Network.Model.Token] } private func fetchHyperion(account: String, completion: @escaping ([Model], Error?) -> Void) { let environment = ApplicationEnvironment.shared().current AF.request( "\(environment.hyperion.orCreate(""))/v2/state/get_tokens", method: .get, parameters: ["account": account, "limit": 5000], headers: HTTPHeaders(environment.headers) ).responseDecodable(of: HyperionResponse.self) { (response) in completion(response.value?.tokens ?? [], response.error) } } } extension Network.Service.Balance { private struct ScatterResponse: Decodable { let balances: [Network.Model.Token] } private func fetchScatter(account: String, completion: @escaping ([Model], Error?) -> Void) { AF.request( "https://api.light.xeos.me/api/balances/eos/\(account)", method: .get ).responseDecodable(of: ScatterResponse.self) { (response) in completion(response.value?.balances ?? [], response.error) } } }