// // AccountServiceChangeKey.swift // Wallet // // Created by Alexandr Serpokrylow on 16.02.2022. // Copyright © 2022 AM. All rights reserved. // import Foundation import WalletKit import EosioSwift import eosswift struct ChangeKeyModel { let wallet: WalletKit.Wallet let keyType: WalletKeyType var key: WalletKey var privateKey: String var publicKey: String var isChecked: Bool = true var hasError: Bool = false static func create(by wallet: WalletKit.Wallet, with privateKey: String) -> [ChangeKeyModel] { guard let walletKey = try? WalletKey.create(private: privateKey) else { return [] } return [WalletKeyType.owner, WalletKeyType.active].map { ChangeKeyModel(wallet: wallet, keyType: $0, key: walletKey, privateKey: walletKey.privateKey ?? "", publicKey: walletKey.publicKey) } } } extension Account.Service { typealias TransitionId = String typealias Completion = (Result) -> Void final class ChangeKey: Common.Service.Provider { func change(for accounts: [ChangeKeyModel], using password: String, _ completion: @escaping Completion) { guard let wallet = accounts.first?.wallet, let privateKey = wallet.privateKey(password: password) else { completion(.success("None")) return } var actions = [(contract: EOSContract, action: Network.Model.Blockchain.Action, data: Codable)]() for account in accounts { if let data = self.createChangeKeyData(account: account) { actions.append((contract: .eosio, action: .updateauth, data: data)) } } Network.Service.Blockchain.execute(actions: actions, privateKeys: [privateKey]) { (result) in if case .success(let trxId) = result { Accounts().migrateChats(accounts: accounts, password: privateKey) Accounts().updateCredentialsIfNeeded(accounts: accounts, password: password) completion(.success(trxId)) } else { completion(result) } } } private func createChangeKeyData(account: ChangeKeyModel) -> Network.Model.Blockchain.UpdateAuth? { var keys: [Network.Model.Blockchain.KeyWeight] = [] guard let eosioPublicKey = (try? Data(eosioPublicKey: account.publicKey).toEosioK1PublicKey) else { return nil } let key = Network.Model.Blockchain.KeyWeight(key: eosioPublicKey, weight: 1) keys.append(key) let auth = Network.Model.Blockchain.Authority(threshold: 1, keys: keys, waits: [], accounts: []) let parent = account.keyType == WalletKeyType.active ? WalletKeyType.owner.rawValue : "" let permission = account.keyType return Network.Model.Blockchain.UpdateAuth(account: account.wallet.name, permission: permission.rawValue, parent: parent, auth: auth) } } }