From 35a73c340c7c5c4bf5df244d1f9b2cbf5f20707c Mon Sep 17 00:00:00 2001 From: darwincereska Date: Thu, 18 Dec 2025 09:34:36 -0500 Subject: [PATCH] feat: added wallet route --- .../kotlin/org/ccoin/routes/WalletRoutes.kt | 189 ++++++++++++++++++ 1 file changed, 189 insertions(+) diff --git a/server/src/main/kotlin/org/ccoin/routes/WalletRoutes.kt b/server/src/main/kotlin/org/ccoin/routes/WalletRoutes.kt index e69de29..734cb1d 100644 --- a/server/src/main/kotlin/org/ccoin/routes/WalletRoutes.kt +++ b/server/src/main/kotlin/org/ccoin/routes/WalletRoutes.kt @@ -0,0 +1,189 @@ +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.CreateWalletRequest +import org.ccoin.models.UpdateWalletRequest +import org.ccoin.services.ValidationService +import org.ccoin.services.WalletService + +fun Route.walletRoutes() { + route("/wallet") { + /** Create a new wallet */ + post("/create") { + try { + val request = call.receive() + + // Validate input + val validation = ValidationService.validateWalletCreation(request.label) + if (!validation.isValid) { + call.respond(HttpStatusCode.BadRequest, mapOf("error" to validation.getErrorMessage())) + return@post + } + + val wallet = WalletService.createWallet(request.label) + call.respond(HttpStatusCode.Created, wallet) + } catch (e: Exception) { + call.respond(HttpStatusCode.InternalServerError, mapOf("error" to (e.message ?: "Failed to create wallet"))) + } + } + + /** Get wallet by address */ + get("/{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 adress format")) + return@get + } + + val wallet = WalletService.getWallet(address) + if (wallet != null) { + call.respond(wallet) + } else { + call.respond(HttpStatusCode.NotFound, mapOf("error" to "Wallet not found")) + } + } catch (e: Exception) { + call.respond(HttpStatusCode.InternalServerError, mapOf("error" to (e.message ?: "Failed to get wallet"))) + } + } + + /** Get wallet balance */ + get("/{address}/balance") { + 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 balance = WalletService.getWalletBalance(address) + call.respond(mapOf("address" to address, "balance" to balance)) + + } catch (e: Exception) { + call.respond(HttpStatusCode.NotFound, mapOf("error" to (e.message ?: "Wallet not found"))) + } + } + + /** Update wallet label */ + put("/{address}/label") { + try { + val address = call.parameters["address"] ?: run { + call.respond(HttpStatusCode.BadRequest, mapOf("error" to "Address parameter required")) + return@put + } + + val request = call.receive() + + // Validate address format + if (!ValidationService.validateWalletAddress(address)) { + call.respond(HttpStatusCode.BadRequest, mapOf("error" to "Invalid address format")) + return@put + } + + // Validate label + if (!ValidationService.validateWalletLabel(request.label)) { + call.respond(HttpStatusCode.BadRequest, mapOf("error" to "Invalid label")) + return@put + } + + val updated = WalletService.updateLabel(address, request.label) + if (updated) { + call.respond(mapOf("message" to "Label updated successfully")) + } else { + call.respond(HttpStatusCode.NotFound, mapOf("error" to "Wallet not found")) + } + + } catch (e: Exception) { + call.respond(HttpStatusCode.InternalServerError, mapOf("error" to (e.message ?: "Failed to update label"))) + } + } + + /** Get all wallets with pagination */ + get("/list") { + try { + val page = call.request.queryParameters["page"]?.toIntOrNull() ?: 1 + val pageSize = call.request.queryParameters["pageSize"]?.toIntOrNull() ?: 50 + + // 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 wallets = WalletService.getAllWallets(pageSize, offset) + val totalCount = WalletService.getTotalWalletCount() + + call.respond(mapOf( + "wallets" to wallets, + "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 wallets"))) + } + } + + /** Get wallets with minimum balance */ + get("/rich") { + try { + val minBalance = call.request.queryParameters["minBalance"]?.toDoubleOrNull() ?: 1.0 + + if (!ValidationService.validateTransactionAmount(minBalance)) { + call.respond(HttpStatusCode.BadRequest, mapOf("error" to "Invalid minimum balance")) + return@get + } + + val wallets = WalletService.getWalletsWithBalance(minBalance) + call.respond(mapOf("wallets" to wallets, "minBalance" to minBalance)) + + } catch (e: Exception) { + call.respond(HttpStatusCode.InternalServerError, mapOf("error" to (e.message ?: "Failed to get rich wallets"))) + } + } + + /** Check if wallet exists */ + get("/{address}/exists") { + 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 exists = WalletService.walletExists(address) + call.respond(mapOf("address" to address, "exists" to exists)) + + } catch (e: Exception) { + call.respond(HttpStatusCode.InternalServerError, mapOf("error" to (e.message ?: "Failed to check wallet existence"))) + } + } + } +}