205 lines
7.5 KiB
Swift
205 lines
7.5 KiB
Swift
//
|
|
// ResourcesServiceSetupPerformance.swift
|
|
// Wallet
|
|
//
|
|
// Created by Igor Danich on 19.08.2020.
|
|
// Copyright © 2020 List. All rights reserved.
|
|
//
|
|
|
|
import Foundation
|
|
|
|
extension Resources.Service.Setup {
|
|
class Performance: Common.Service.Provider {
|
|
|
|
let performance: Resources.Service.Performance
|
|
private let _staked: Resources.Service.Staked
|
|
|
|
var title: String {
|
|
let cpu = Resources.Model.Performance.Kind.cpu
|
|
let net = Resources.Model.Performance.Kind.net
|
|
return net.prefix.isEmpty ? "\(cpu.name)/\(net.name)" : "\(cpu.prefix)/\(net.prefix) (\(cpu.name)/\(net.name))"
|
|
}
|
|
|
|
enum Action: String, CommonMenuMappable {
|
|
case stake
|
|
case unstake
|
|
var title: String { "resources.setup.action.\(rawValue)".localized }
|
|
func toMenu() -> Common.Model.Menu { .menu(uuid: rawValue, title: title) }
|
|
}
|
|
let actions: [Action] = [.stake, .unstake]
|
|
private var _action: Action?
|
|
var action: Action? {
|
|
get { _action }
|
|
set { _action = newValue;clear() }
|
|
}
|
|
|
|
private var _isOtherEnabled = false
|
|
var isOtherEnabled: Bool {
|
|
get { _isOtherEnabled }
|
|
set {
|
|
_isOtherEnabled = newValue
|
|
_otherAccount = ""
|
|
transfer = false
|
|
update()
|
|
}
|
|
}
|
|
private var _otherAccount = ""
|
|
var otherAccount: String {
|
|
get { _otherAccount }
|
|
set { _otherAccount = newValue;update() }
|
|
}
|
|
var transfer = false
|
|
private(set) var submitText: String?
|
|
|
|
private var _netAmount = ""
|
|
var netAmount: String {
|
|
get { _netAmount }
|
|
set { _netAmount = newValue;update() }
|
|
}
|
|
private var _cpuAmount = ""
|
|
var cpuAmount: String {
|
|
get { _cpuAmount }
|
|
set { _cpuAmount = newValue;update() }
|
|
}
|
|
private(set) var isValid = false
|
|
|
|
var balance: Decimal {
|
|
Wallet.Service.Tokens.shared.balances.collection.first(where: {
|
|
$0.contract == ApplicationEnvironment.shared().current.contract(.eosioToken) && $0.symbol.uppercased() == "EOS"
|
|
})?.amount ?? 0
|
|
}
|
|
var balanceText: String {
|
|
Wallet.Service.Tokens.shared.balances.collection.first(where: {
|
|
$0.contract == ApplicationEnvironment.shared().current.contract(.eosioToken) && $0.symbol.uppercased() == "EOS"
|
|
})?.description ?? ""
|
|
}
|
|
|
|
init(account: String) {
|
|
_staked = .init(account: account)
|
|
performance = .init(account: account)
|
|
}
|
|
|
|
var didUpdate: (() -> Void)?
|
|
var didReload: (() -> Void)?
|
|
|
|
func clear(force: Bool = false) {
|
|
if force {
|
|
_action = nil
|
|
performance.clear()
|
|
}
|
|
_isOtherEnabled = false
|
|
_otherAccount = ""
|
|
transfer = false
|
|
_cpuAmount = ""
|
|
_netAmount = ""
|
|
isValid = false
|
|
submitText = ""
|
|
didReload?()
|
|
update()
|
|
}
|
|
|
|
func fetch() {
|
|
performance.fetch { _ in
|
|
self._staked.fetch { _ in
|
|
self.didReload?()
|
|
self.update()
|
|
}
|
|
}
|
|
}
|
|
|
|
var staked: [Resources.Model.Staked] { _staked.collection }
|
|
|
|
private func update() {
|
|
let value = netAmount.toDecimal() + cpuAmount.toDecimal()
|
|
let string = value.toString(max: 4, symbol: "EOS")
|
|
let isAvailable = action == .stake ? self.balance >= value : getSumUnstakeAmount() >= value
|
|
if let action = action {
|
|
isValid = isOtherEnabled ? (!otherAccount.isEmpty && value > 0 && isAvailable) : (value > 0 && isAvailable)
|
|
submitText = action == .stake ? L10n.Resources.Setup.Submit.stake(string) : L10n.Resources.Setup.Submit.unstake(string)
|
|
} else {
|
|
isValid = false
|
|
submitText = ""
|
|
}
|
|
didUpdate?()
|
|
}
|
|
|
|
func getSumUnstakeAmount() -> Decimal {
|
|
if isOtherEnabled {
|
|
return staked.map { $0.cpu_weight.toDecimal() }.reduce(0, +) + staked.map { $0.net_weight.toDecimal() }.reduce(0, +)
|
|
} else {
|
|
return performance[.cpu].stakedByMe.toDecimal() + performance[.net].stakedByMe.toDecimal()
|
|
}
|
|
}
|
|
|
|
func getAvailableUnstakeAmount(isCpu: Bool) -> Decimal {
|
|
if isOtherEnabled {
|
|
return isCpu ? staked.map { $0.cpu_weight.toDecimal() }.reduce(0, +) :
|
|
staked.map { $0.net_weight.toDecimal() }.reduce(0, +)
|
|
} else {
|
|
return isCpu ? performance[.cpu].stakedByMe.toDecimal() :
|
|
performance[.net].stakedByMe.toDecimal()
|
|
}
|
|
}
|
|
|
|
func refund(privateKey: String, _ completion: @escaping (NSError?) -> Void) {
|
|
Network.Service.Blockchain.execute(contract: .eosio, action: .refund, data: [
|
|
"owner" : performance.account
|
|
], privateKeys: [privateKey]) { (result) in
|
|
completion(.error(result))
|
|
}
|
|
}
|
|
|
|
// swiftlint:disable identifier_name
|
|
private struct StakeRequest: Codable {
|
|
let from: String
|
|
let receiver: String
|
|
let stake_net_quantity: String
|
|
let stake_cpu_quantity: String
|
|
let transfer: Bool
|
|
}
|
|
|
|
// swiftlint:disable identifier_name
|
|
private struct UnstakeRequest: Codable {
|
|
let from: String
|
|
let receiver: String
|
|
let unstake_net_quantity: String
|
|
let unstake_cpu_quantity: String
|
|
}
|
|
|
|
func submit(privateKey: String, _ completion: @escaping Completion.Network) {
|
|
guard let action = action, isValid else { return }
|
|
switch action {
|
|
case .stake:
|
|
Network.Service.Blockchain.execute(
|
|
contract: .eosio,
|
|
action: .delegatebw,
|
|
data: StakeRequest(
|
|
from: performance.account,
|
|
receiver: isOtherEnabled ? otherAccount : performance.account,
|
|
stake_net_quantity: netAmount.toDecimal().toString(precision: .eosioToken),
|
|
stake_cpu_quantity: cpuAmount.toDecimal().toString(precision: .eosioToken),
|
|
transfer: isOtherEnabled ? transfer : false
|
|
), privateKeys: [privateKey]
|
|
) { (result) in
|
|
completion(.error(result))
|
|
}
|
|
case .unstake:
|
|
Network.Service.Blockchain.execute(
|
|
contract: .eosio,
|
|
action: .undelegatebw,
|
|
data: UnstakeRequest(
|
|
from: performance.account,
|
|
receiver: isOtherEnabled ? otherAccount : performance.account,
|
|
unstake_net_quantity: netAmount.toDecimal().toString(precision: .eosioToken),
|
|
unstake_cpu_quantity: cpuAmount.toDecimal().toString(precision: .eosioToken)
|
|
), privateKeys: [privateKey]
|
|
) { (result) in
|
|
completion(.error(result))
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
}
|