func processTransactions(_ transactions: [YieldActionTransaction]) async throws {
let sorted = transactions.sorted { $0.stepIndex < $1.stepIndex }
for tx in sorted {
if tx.unsignedTransaction != nil && tx.status == YieldActionTransactionStatus.CREATED {
let success = await signAndSubmitAndConfirm(transaction: tx)
if !success { break }
}
}
}
func signAndSubmitAndConfirm(transaction: YieldActionTransaction) async -> Bool {
guard let unsignedTxJson = transaction.unsignedTransaction as? String else {
return false
}
// Parse the unsigned transaction JSON string
guard let jsonData = unsignedTxJson.data(using: .utf8),
let txParams = try? JSONSerialization.jsonObject(with: jsonData) as? [String: Any]
else {
return false
}
// Create ETHTransactionParam from the parsed JSON
let ethTransaction = ETHTransactionParam(
from: txParams["from"] as? String ?? "",
to: txParams["to"] as? String ?? "",
value: txParams["value"] as? String ?? "0x0",
data: txParams["data"] as? String ?? "0x"
// Portal handles gas estimation automatically
)
do {
// Sign and send the transaction
let sendResponse = try await portal.request(
transaction.network,
withMethod: .eth_sendTransaction,
andParams: [ethTransaction]
)
guard let txHash = sendResponse.result as? String else {
return false
}
// Track the transaction with the yield system
_ = try await portal.yield.yieldxyz.track(
transactionId: transaction.id,
txHash: txHash
)
// Wait for transaction confirmation
return await waitForReceipt(txHash: txHash, chainId: transaction.network)
} catch {
print("Error signing and submitting transaction: \(error)")
return false
}
}
func waitForReceipt(
txHash: String,
chainId: String,
maxAttempts: Int = 30,
delaySeconds: UInt64 = 2
) async -> Bool {
for _ in 0..<maxAttempts {
try? await Task.sleep(nanoseconds: delaySeconds * 1_000_000_000)
do {
let response = try await portal.request(
chainId,
withMethod: .eth_getTransactionReceipt,
andParams: [txHash]
)
if let innerResponse = response.result as? EthTransactionResponse,
let status = innerResponse.result?.status {
if status == "0x1" {
return true // Transaction succeeded
} else if status == "0x0" {
return false // Transaction reverted
}
}
} catch {
// Continue waiting if request fails
continue
}
}
return false // Timeout
}