257 lines
9.2 KiB
Swift
257 lines
9.2 KiB
Swift
//
|
|
// NetworkModelToken.swift
|
|
// Wallet
|
|
//
|
|
// Created by Igor on 04.11.2020.
|
|
// Copyright © 2020 List. All rights reserved.
|
|
//
|
|
|
|
import UIKit
|
|
|
|
extension Network.Model {
|
|
|
|
struct TokenSmall: Codable {
|
|
let quantity: String
|
|
let contract: String
|
|
|
|
var asToken: Token? {
|
|
if !contract.isEmpty, !quantity.symbol.isEmpty {
|
|
return Token(
|
|
symbol: quantity.symbol,
|
|
precision: quantity.precision,
|
|
amount: quantity.amount.toDecimal(),
|
|
contract: contract,
|
|
certCoef: 0,
|
|
certName: "",
|
|
city: nil,
|
|
country: nil
|
|
)
|
|
} else {
|
|
return nil
|
|
}
|
|
}
|
|
}
|
|
|
|
struct TokenSmallParsed: Codable {
|
|
let amount: Decimal
|
|
let amountDouble: Double
|
|
let id: String
|
|
let symbol: String
|
|
let contract: String
|
|
let precision: Int
|
|
|
|
var asToken: Token? {
|
|
if !contract.isEmpty, !symbol.isEmpty {
|
|
return Token(
|
|
symbol: symbol,
|
|
precision: precision,
|
|
amount: amount,
|
|
contract: contract,
|
|
certCoef: 0,
|
|
certName: "",
|
|
city: nil,
|
|
country: nil
|
|
)
|
|
} else {
|
|
return nil
|
|
}
|
|
}
|
|
}
|
|
|
|
struct Token: Codable {
|
|
|
|
let symbol: String
|
|
let precision: Int
|
|
var amount: Decimal
|
|
let contract: String
|
|
var country: String?
|
|
var city: String?
|
|
var pool: Swap.Model.Pool?
|
|
|
|
// Cash tokens fields
|
|
var certCoef: Decimal
|
|
var certName: String
|
|
|
|
init(
|
|
symbol: String,
|
|
precision: Int,
|
|
amount: Decimal,
|
|
contract: String,
|
|
certCoef: Decimal = 100,
|
|
certName: String? = nil,
|
|
city: String? = nil,
|
|
country: String? = nil
|
|
) {
|
|
self.symbol = symbol
|
|
self.precision = precision
|
|
self.amount = amount
|
|
self.contract = contract
|
|
self.certCoef = certCoef
|
|
self.certName = certName ?? String(symbol.uppercased().dropFirst(2))
|
|
self.city = city
|
|
self.country = country
|
|
}
|
|
|
|
enum CodingKeys: String, CodingKey {
|
|
case symbol
|
|
case precision
|
|
case amount
|
|
case contract
|
|
case currency
|
|
case decimals
|
|
}
|
|
|
|
init(from decoder: Decoder) throws {
|
|
let values = try decoder.container(keyedBy: CodingKeys.self)
|
|
if let value = try? values.decodeIfPresent(String.self, forKey: .symbol) {
|
|
symbol = value
|
|
precision = try values.decodeIfPresent(Int.self, forKey: .precision) ?? 0
|
|
let amountString = (try values.decodeIfPresent(Double.self, forKey: .amount) ?? 0.0).toString(precision: precision)
|
|
amount = Decimal(string: amountString) ?? 0.0
|
|
} else {
|
|
symbol = try values.decodeIfPresent(String.self, forKey: .currency) ?? ""
|
|
precision = Int((try? values.decodeIfPresent(String.self, forKey: .decimals)) ?? "0") ?? 0
|
|
amount = (try? values.decodeIfPresent(String.self, forKey: .amount))?.toDecimal() ?? 0.0
|
|
}
|
|
contract = try values.decodeIfPresent(String.self, forKey: .contract) ?? ""
|
|
certCoef = 100
|
|
certName = String(symbol.uppercased().dropFirst(2))
|
|
}
|
|
|
|
func encode(to encoder: Encoder) throws {}
|
|
}
|
|
}
|
|
|
|
extension Network.Model.Token {
|
|
var swappableContracts: Bool {
|
|
(!isSwapContract || isMLNK) && checkSafeName() && !isCertificate
|
|
}
|
|
var isCashContract: Bool { contract == ApplicationEnvironment.shared().current.contract(.cash) }
|
|
var isListContract: Bool { contract == ApplicationEnvironment.shared().current.contract(.list) }
|
|
var isSwapContract: Bool { contract == ApplicationEnvironment.shared().current.contract(.swap) }
|
|
var isUSDTContract: Bool { contract == ApplicationEnvironment.shared().current.contract(.usdt) }
|
|
var isOurContract: Bool { isCashContract || isListContract || isSwapContract }
|
|
|
|
var isUSDTName: Bool { symbol.uppercased() == "USDT" }
|
|
var isUSDT: Bool { isUSDTContract && isUSDTName }
|
|
|
|
var isMLNKName: Bool { symbol.uppercased() == "MLNK" }
|
|
var isMLNK: Bool { isSwapContract && isMLNKName }
|
|
|
|
var isListName: Bool { symbol.uppercased().hasPrefix("LI") && symbol.count == 7 }
|
|
var isList: Bool { isListContract && isListName }
|
|
|
|
var isCashName: Bool { symbol.uppercased().hasSuffix("CASH") && symbol.count == 7 }
|
|
var isCash: Bool { isCashContract && isCashName }
|
|
|
|
var isKLNKName: Bool { symbol.uppercased() == "KLNK" }
|
|
var isKLNK: Bool { isCashContract && isKLNKName }
|
|
|
|
var isCertificateName: Bool { symbol.uppercased().hasPrefix("G") && !symbol.uppercased().hasSuffix("CASH") && symbol.count == 7 }
|
|
var isCertificate: Bool { isCashContract && isCertificateName }
|
|
}
|
|
|
|
extension Network.Model.Token: CustomStringConvertible {
|
|
var description: String { amount.toString(max: precision, symbol: symbol) }
|
|
}
|
|
|
|
extension Network.Model.Token {
|
|
|
|
func checkSafeName() -> Bool {
|
|
|
|
let ourNames = ["USDCASH","EURCASH",
|
|
"UAHCASH","RUBCASH",
|
|
"GBPCASH","INRCASH",
|
|
"RMBCASH","JPYCASH",
|
|
"MLNK",
|
|
"LIRUMOW","LIRUCEK",
|
|
"LIRULED","LIUAIEV"]
|
|
|
|
if !self.isOurContract {
|
|
return !ourNames.contains(self.symbol)
|
|
}
|
|
|
|
return true
|
|
}
|
|
}
|
|
|
|
extension Network.Model.Token {
|
|
var name: String? {
|
|
var name: String?
|
|
|
|
if let city = city, let country = country, isListContract {
|
|
name = "LiST \(country), \(city)"
|
|
} else if isKLNK {
|
|
return "Kalinka"
|
|
} else if isCashContract {
|
|
switch symbol.uppercased() {
|
|
case "USDCASH": name = L10n.Wallet.Token.Usdcash.description
|
|
case "EURCASH": name = L10n.Wallet.Token.Eurcash.description
|
|
case "UAHCASH": name = L10n.Wallet.Token.Uahcash.description
|
|
case "RUBCASH": name = L10n.Wallet.Token.Rubcash.description
|
|
case "GBPCASH": name = L10n.Wallet.Token.Gbpcash.description
|
|
case "INRCASH": name = L10n.Wallet.Token.Inrcash.description
|
|
case "RMBCASH": name = L10n.Wallet.Token.Rmbcash.description
|
|
case "JPYCASH": name = L10n.Wallet.Token.Jpycash.description
|
|
default:
|
|
switch symbol.uppercased().dropFirst().first {
|
|
case "U": name = L10n.Wallet.Token.Cert.description(L10n.Wallet.Token.usdcash, city ?? "")
|
|
case "E": name = L10n.Wallet.Token.Cert.description(L10n.Wallet.Token.eurcash, city ?? "")
|
|
case "H": name = L10n.Wallet.Token.Cert.description(L10n.Wallet.Token.uahcash, city ?? "")
|
|
case "R": name = L10n.Wallet.Token.Cert.description(L10n.Wallet.Token.rubcash, city ?? "")
|
|
case "G": name = L10n.Wallet.Token.Cert.description(L10n.Wallet.Token.gbpcash, city ?? "")
|
|
case "I": name = L10n.Wallet.Token.Cert.description(L10n.Wallet.Token.inrcash, city ?? "")
|
|
case "J": name = L10n.Wallet.Token.Cert.description(L10n.Wallet.Token.rmbcash, city ?? "")
|
|
case "Y": name = L10n.Wallet.Token.Cert.description(L10n.Wallet.Token.jpycash, city ?? "")
|
|
default: name = nil
|
|
}
|
|
}
|
|
} else if isMLNK {
|
|
return "Malinka"
|
|
} else if let pool = pool {
|
|
name = "\(pool.token1?.symbol ?? "") - \(pool.token2?.symbol ?? "")"
|
|
} else {
|
|
name = contract
|
|
}
|
|
|
|
return name?.uppercased().replacingOccurrences(of: "LIST", with: "LiST")
|
|
}
|
|
}
|
|
|
|
extension Network.Model.Token: CommonMenuMappable {
|
|
func toMenu() -> Common.Model.Menu {
|
|
.menu(
|
|
uuid: symbol + contract,
|
|
image: .from(token: Network.Model.TokenSmall(quantity: "0 \(symbol)", contract: contract).asToken),
|
|
imageURLs: [.from(symbol: symbol, contract: contract), .from(symbol: symbol)],
|
|
title: symbol,
|
|
text: name,
|
|
details: amount.toString(max: precision)
|
|
)
|
|
}
|
|
}
|
|
|
|
extension Network.Model.Token {
|
|
static let eosioToken = Network.Model.Token(symbol: "EOS", precision: 4, amount: 0, contract: ApplicationEnvironment.shared().current.contract(.eosioToken))
|
|
}
|
|
|
|
extension Network.Model.Token: Equatable {
|
|
static func == (lhs: Network.Model.Token, rhs: Network.Model.Token) -> Bool { lhs.symbol == rhs.symbol && lhs.contract == rhs.contract }
|
|
}
|
|
|
|
extension Network.Model.Token: Hashable {
|
|
func hash(into hasher: inout Hasher) {
|
|
hasher.combine(symbol)
|
|
hasher.combine(contract)
|
|
}
|
|
}
|
|
|
|
extension Array where Element == Network.Model.Token {
|
|
func first(_ element: Element) -> Element? {
|
|
if let index = firstIndex(of: element) {
|
|
return self[index]
|
|
}
|
|
return nil
|
|
}
|
|
}
|