fun processTransactions(transactions: List<YieldActionTransaction>?) {
    val sorted = transactions?.sortedBy { it.stepIndex } ?: emptyList()
    for (tx in sorted) {
        if (tx.unsignedTransaction != null && tx.status == YieldActionTransactionStatus.CREATED) {
            val ok = runBlocking { signAndSubmitAndConfirm(tx) }
            if (!ok) break
        }
    }
}
suspend fun signAndSubmitAndConfirm(transaction: YieldActionTransaction): Boolean {
    val unsignedTxJson = transaction.unsignedTransaction as? String ?: return false
    val gson = Gson()
    val type = object : TypeToken<Map<String, Any>>() {}.type
    val txParams = gson.fromJson<Map<String, Any>>(unsignedTxJson, type)
    val ethTransaction = EthTransactionParam(
        from = txParams["from"] as? String ?: "",
        to = txParams["to"] as? String ?: "",
        value = txParams["value"] as? String ?: "0x0",
        data = txParams["data"] as? String ?: "0x",
        gas = null, // Let Portal handle gas estimation`
        gasPrice = null,
        maxFeePerGas = null,
        maxPriorityFeePerGas = null
    )
    val send = portal.request(
        chainId = transaction.network,
        method = PortalRequestMethod.eth_sendTransaction,
        params = listOf(ethTransaction)
    )
    val txHash = send.result as? String ?: return false
    portal.yield.yieldxyz.track(transaction.id, txHash)
    return waitForReceipt(txHash, transaction.network)
}
suspend fun waitForReceipt(txHash: String, chainId: String, maxAttempts: Int = 30, delayMs: Long = 2000): Boolean {
    repeat(maxAttempts) {
        kotlinx.coroutines.delay(delayMs)
        val receiptResp = portal.request(
            chainId = chainId,
            method = PortalRequestMethod.eth_getTransactionReceipt,
            params = listOf(txHash)
        )
        val receipt = receiptResp.result as? Map<String, Any>
        val status = receipt?.get("status") as? String
        if (status == "0x1") return true // Was mined
        if (status == "0x0") return false // Was not mined yet
    }
    return false
}