feat: added transaction routes
This commit is contained in:
@@ -0,0 +1,210 @@
|
||||
package org.ccoin.routes
|
||||
|
||||
import io.ktor.http.*
|
||||
import io.ktor.server.application.*
|
||||
import io.ktor.server.request.*
|
||||
import io.ktor.server.response.*
|
||||
import io.ktor.server.routing.*
|
||||
import org.ccoin.models.SendTransactionRequest
|
||||
import org.ccoin.services.TransactionService
|
||||
import org.ccoin.services.ValidationService
|
||||
|
||||
fun Route.transactionRoutes() {
|
||||
route("/transaction") {
|
||||
/** Send a transaction */
|
||||
post("/send") {
|
||||
try {
|
||||
val request = call.receive<SendTransactionRequest>()
|
||||
|
||||
// Validate transaction data
|
||||
val validation = ValidationService.validateTransaction(
|
||||
request.fromAddress,
|
||||
request.toAddress,
|
||||
request.amount,
|
||||
request.fee,
|
||||
request.memo
|
||||
)
|
||||
|
||||
if (!validation.isValid) {
|
||||
call.respond(HttpStatusCode.BadRequest, mapOf("error" to validation.getErrorMessage()))
|
||||
return@post
|
||||
}
|
||||
|
||||
val transaction = TransactionService.sendTransaction(
|
||||
request.fromAddress,
|
||||
request.toAddress,
|
||||
request.amount,
|
||||
request.fee,
|
||||
request.memo
|
||||
)
|
||||
|
||||
call.respond(HttpStatusCode.Created, transaction)
|
||||
|
||||
} catch (e: Exception) {
|
||||
call.respond(HttpStatusCode.BadRequest, mapOf("error" to (e.message ?: "Transaction failed")))
|
||||
}
|
||||
}
|
||||
|
||||
/** Get transaction by hash */
|
||||
get("/{hash}") {
|
||||
try {
|
||||
val hash = call.parameters["hash"] ?: run {
|
||||
call.respond(HttpStatusCode.BadRequest, mapOf("error" to "Transaction hash parameter required"))
|
||||
return@get
|
||||
}
|
||||
|
||||
// Validate hash format
|
||||
if (!ValidationService.validateTransactionHash(hash)) {
|
||||
call.respond(HttpStatusCode.BadRequest, mapOf("error" to "Invalid transaction hash format"))
|
||||
return@get
|
||||
}
|
||||
|
||||
val transaction = TransactionService.getTransaction(hash)
|
||||
if (transaction != null) {
|
||||
call.respond(transaction)
|
||||
} else {
|
||||
call.respond(HttpStatusCode.NotFound, mapOf("error" to "Transaction not found"))
|
||||
}
|
||||
|
||||
} catch (e: Exception) {
|
||||
call.respond(HttpStatusCode.InternalServerError, mapOf("error" to (e.message ?: "Failed to get transaction")))
|
||||
}
|
||||
}
|
||||
|
||||
/** Get transaction history for an address */
|
||||
get("/history/{address}") {
|
||||
try {
|
||||
val address = call.parameters["address"] ?: run {
|
||||
call.respond(HttpStatusCode.BadRequest, mapOf("error" to "Address parameter required"))
|
||||
return@get
|
||||
}
|
||||
|
||||
val page = call.request.queryParameters["page"]?.toIntOrNull() ?: 1
|
||||
val pageSize = call.request.queryParameters["pageSize"]?.toIntOrNull() ?: 50
|
||||
|
||||
// Validate address format
|
||||
if (!ValidationService.validateWalletAddress(address)) {
|
||||
call.respond(HttpStatusCode.BadRequest, mapOf("error" to "Invalid address format"))
|
||||
return@get
|
||||
}
|
||||
|
||||
// Validate pagination
|
||||
val validation = ValidationService.validatePagination(page, pageSize)
|
||||
if (!validation.isValid) {
|
||||
call.respond(HttpStatusCode.BadRequest, mapOf("error" to validation.getErrorMessage()))
|
||||
return@get
|
||||
}
|
||||
|
||||
val offset = (page - 1) * pageSize
|
||||
val transactions = TransactionService.getTransactionHistory(address, pageSize, offset)
|
||||
val totalCount = TransactionService.getTransactionCountForAddress(address)
|
||||
|
||||
call.respond(mapOf(
|
||||
"transactions" to transactions,
|
||||
"address" to address,
|
||||
"pagination" to mapOf(
|
||||
"currentPage" to page,
|
||||
"pageSize" to pageSize,
|
||||
"totalItems" to totalCount,
|
||||
"totalPages" to ((totalCount + pageSize - 1) / pageSize),
|
||||
"hasNext" to (offset + pageSize < totalCount),
|
||||
"hasPrevious" to (page > 1)
|
||||
)
|
||||
))
|
||||
|
||||
} catch (e: Exception) {
|
||||
call.respond(HttpStatusCode.InternalServerError, mapOf("error" to (e.message ?: "Failed to get transaction history")))
|
||||
}
|
||||
}
|
||||
|
||||
/** Get pending transactions */
|
||||
get("/pending") {
|
||||
try {
|
||||
val transactions = TransactionService.getPendingTransactions()
|
||||
call.respond(mapOf(
|
||||
"transactions" to transactions,
|
||||
"count" to transactions.size
|
||||
))
|
||||
|
||||
} catch (e: Exception) {
|
||||
call.respond(HttpStatusCode.InternalServerError, mapOf("error" to (e.message ?: "Failed to get pending transactions")))
|
||||
}
|
||||
}
|
||||
|
||||
/** Get transaction count for address */
|
||||
get("/count/{address}") {
|
||||
try {
|
||||
val address = call.parameters["address"] ?: run {
|
||||
call.respond(HttpStatusCode.BadRequest, mapOf("error" to "Address parameter required"))
|
||||
return@get
|
||||
}
|
||||
|
||||
// Validate address format
|
||||
if (!ValidationService.validateWalletAddress(address)) {
|
||||
call.respond(HttpStatusCode.BadRequest, mapOf("error" to "Invalid address format"))
|
||||
return@get
|
||||
}
|
||||
|
||||
val count = TransactionService.getTransactionCountForAddress(address)
|
||||
call.respond(mapOf(
|
||||
"address" to address,
|
||||
"transactionCount" to count
|
||||
))
|
||||
|
||||
} catch (e: Exception) {
|
||||
call.respond(HttpStatusCode.InternalServerError, mapOf("error" to (e.message ?: "Failed to get transaction count")))
|
||||
}
|
||||
}
|
||||
|
||||
/** Get all transactions with pagination */
|
||||
get("/list") {
|
||||
try {
|
||||
val page = call.request.queryParameters["page"]?.toIntOrNull() ?: 1
|
||||
val pageSize = call.request.queryParameters["pageSize"]?.toIntOrNull() ?: 50
|
||||
val status = call.request.queryParameters["status"] // Optional filter
|
||||
|
||||
// Validate pagination
|
||||
val validation = ValidationService.validatePagination(page, pageSize)
|
||||
if (!validation.isValid) {
|
||||
call.respond(HttpStatusCode.BadRequest, mapOf("error" to validation.getErrorMessage()))
|
||||
return@get
|
||||
}
|
||||
|
||||
// For now, just get pending transactions as an example
|
||||
// You could extend this to support status filtering
|
||||
val transactions = if (status == "pending") {
|
||||
TransactionService.getPendingTransactions()
|
||||
} else {
|
||||
// This would need a new service method for all transactions
|
||||
TransactionService.getPendingTransactions() // Placeholder
|
||||
}
|
||||
|
||||
call.respond(mapOf(
|
||||
"transactions" to transactions,
|
||||
"count" to transactions.size,
|
||||
"status" to status
|
||||
))
|
||||
|
||||
} catch (e: Exception) {
|
||||
call.respond(HttpStatusCode.InternalServerError, mapOf("error" to (e.message ?: "Failed to get transactions")))
|
||||
}
|
||||
}
|
||||
|
||||
/** Get network transaction statistics */
|
||||
get("/stats") {
|
||||
try {
|
||||
val totalCount = TransactionService.getTotalTransactionCount()
|
||||
val pendingCount = TransactionService.getPendingTransactions().size
|
||||
|
||||
call.respond(mapOf(
|
||||
"totalTransactions" to totalCount,
|
||||
"pendingTransactions" to pendingCount,
|
||||
"confirmedTransactions" to (totalCount - pendingCount)
|
||||
))
|
||||
|
||||
} catch (e: Exception) {
|
||||
call.respond(HttpStatusCode.InternalServerError, mapOf("error" to (e.message ?: "Failed to get transaction statistics")))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user