blockchainethereumblockchain-walleterc20erc721walletxdaidappdecentralizederc1155erc875iosswifttokens
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
108 lines
3.5 KiB
108 lines
3.5 KiB
// Copyright SIX DAY LLC. All rights reserved.
|
|
|
|
import Foundation
|
|
import Geth
|
|
import APIKit
|
|
import JSONRPCKit
|
|
import Result
|
|
|
|
struct SentTransaction {
|
|
let id: String
|
|
}
|
|
|
|
class SendTransactionCoordinator {
|
|
|
|
let keystore = EtherKeystore()
|
|
let config = Config()
|
|
let session: WalletSession
|
|
|
|
init(
|
|
session: WalletSession
|
|
) {
|
|
self.session = session
|
|
}
|
|
|
|
func send(
|
|
address: Address,
|
|
value: Double,
|
|
data: Data = Data(),
|
|
configuration: TransactionConfiguration,
|
|
completion: @escaping (Result<SentTransaction, AnyError>) -> Void
|
|
) {
|
|
let amountDouble = BDouble(floatLiteral: value) * BDouble(Double(EthereumUnit.ether.rawValue) ?? 0)
|
|
let amount = GethBigInt.from(double: amountDouble)
|
|
|
|
let request = EtherServiceRequest(batch: BatchFactory().create(GetTransactionCountRequest(address: session.account.address.address)))
|
|
Session.send(request) { [weak self] result in
|
|
guard let `self` = self else { return }
|
|
switch result {
|
|
case .success(let count):
|
|
self.sign(address: address, nonce: count, amount: amount, data: data, configuration: configuration, completion: completion)
|
|
case .failure(let error):
|
|
completion(.failure(AnyError(error)))
|
|
}
|
|
}
|
|
}
|
|
|
|
func send(
|
|
contract: Address,
|
|
to: Address,
|
|
amount: Double,
|
|
decimals: Int,
|
|
configuration: TransactionConfiguration,
|
|
completion: @escaping (Result<SentTransaction, AnyError>) -> Void
|
|
) {
|
|
let amountToSend = (BDouble(floatLiteral: amount) * BDouble(pow(10, decimals).doubleValue)).description
|
|
session.web3.request(request: ContractERC20Transfer(amount: amountToSend, address: to.address)) { result in
|
|
switch result {
|
|
case .success(let res):
|
|
NSLog("result \(res)")
|
|
self.send(
|
|
address: contract,
|
|
value: 0,
|
|
data: Data(hex: res.drop0x),
|
|
configuration: configuration,
|
|
completion: completion
|
|
)
|
|
case .failure(let error):
|
|
completion(.failure(AnyError(error)))
|
|
}
|
|
}
|
|
}
|
|
|
|
func sign(
|
|
address: Address,
|
|
nonce: Int64 = 0,
|
|
amount: GethBigInt,
|
|
data: Data,
|
|
configuration: TransactionConfiguration,
|
|
completion: @escaping (Result<SentTransaction, AnyError>) -> Void
|
|
) {
|
|
let signTransaction = SignTransaction(
|
|
amount: amount,
|
|
account: session.account,
|
|
address: address,
|
|
nonce: nonce,
|
|
speed: configuration.speed,
|
|
data: data,
|
|
chainID: GethBigInt.from(int: config.chainID)
|
|
)
|
|
let signedTransaction = keystore.signTransaction(signTransaction)
|
|
|
|
switch signedTransaction {
|
|
case .success(let data):
|
|
let sendData = data.hexEncoded
|
|
let request = EtherServiceRequest(batch: BatchFactory().create(SendRawTransactionRequest(signedTransaction: sendData)))
|
|
Session.send(request) { result in
|
|
switch result {
|
|
case .success(let transactionID):
|
|
completion(.success(SentTransaction(id: transactionID)))
|
|
case .failure(let error):
|
|
completion(.failure(AnyError(error)))
|
|
}
|
|
}
|
|
case .failure(let error):
|
|
completion(.failure(AnyError(error)))
|
|
}
|
|
}
|
|
}
|
|
|