diff --git a/api/api-core/src/main/kotlin/co/nilin/opex/api/core/spi/MarketUserDataProxy.kt b/api/api-core/src/main/kotlin/co/nilin/opex/api/core/spi/MarketUserDataProxy.kt index f51dae978..828a0c210 100644 --- a/api/api-core/src/main/kotlin/co/nilin/opex/api/core/spi/MarketUserDataProxy.kt +++ b/api/api-core/src/main/kotlin/co/nilin/opex/api/core/spi/MarketUserDataProxy.kt @@ -42,6 +42,15 @@ interface MarketUserDataProxy { offset: Int?, ): List + suspend fun getOrderHistoryCount( + uuid : String, + symbol: String?, + startTime: Long?, + endTime: Long?, + orderType: MatchingOrderType?, + direction: OrderDirection?, + ): Long + suspend fun getTradeHistory( uuid : String, symbol: String?, @@ -51,4 +60,12 @@ interface MarketUserDataProxy { limit: Int?, offset: Int?, ): List + + suspend fun getTradeHistoryCount( + uuid : String, + symbol: String?, + startTime: Long?, + endTime: Long?, + direction: OrderDirection?, + ): Long } \ No newline at end of file diff --git a/api/api-core/src/main/kotlin/co/nilin/opex/api/core/spi/WalletProxy.kt b/api/api-core/src/main/kotlin/co/nilin/opex/api/core/spi/WalletProxy.kt index e4ae309bd..bf6ac578f 100644 --- a/api/api-core/src/main/kotlin/co/nilin/opex/api/core/spi/WalletProxy.kt +++ b/api/api-core/src/main/kotlin/co/nilin/opex/api/core/spi/WalletProxy.kt @@ -21,6 +21,14 @@ interface WalletProxy { ascendingByTime: Boolean?, ): List + suspend fun getDepositTransactionsCount( + uuid: String, + token: String, + currency: String?, + startTime: Long?, + endTime: Long?, + ): Long + suspend fun getWithdrawTransactions( uuid: String, token: String, @@ -32,6 +40,14 @@ interface WalletProxy { ascendingByTime: Boolean?, ): List + suspend fun getWithdrawTransactionsCount( + uuid: String, + token: String, + currency: String?, + startTime: Long?, + endTime: Long?, + ): Long + suspend fun getTransactions( uuid: String, token: String, @@ -44,6 +60,15 @@ interface WalletProxy { ascendingByTime: Boolean?, ): List + suspend fun getTransactionsCount( + uuid: String, + token: String, + currency: String?, + category: UserTransactionCategory?, + startTime: Long?, + endTime: Long?, + ): Long + suspend fun getGateWays( includeOffChainGateways: Boolean, includeOnChainGateways: Boolean, @@ -97,4 +122,6 @@ interface WalletProxy { suspend fun submitVoucher(code: String, token: String): SubmitVoucherResponse suspend fun getQuoteCurrencies(): List + + suspend fun getSwapTransactionsCount(token: String, request: UserTransactionRequest):Long } \ No newline at end of file diff --git a/api/api-ports/api-opex-rest/src/main/kotlin/co/nilin/opex/api/ports/opex/controller/UserHistoryController.kt b/api/api-ports/api-opex-rest/src/main/kotlin/co/nilin/opex/api/ports/opex/controller/UserHistoryController.kt index 626960481..93121fe68 100644 --- a/api/api-ports/api-opex-rest/src/main/kotlin/co/nilin/opex/api/ports/opex/controller/UserHistoryController.kt +++ b/api/api-ports/api-opex-rest/src/main/kotlin/co/nilin/opex/api/ports/opex/controller/UserHistoryController.kt @@ -8,6 +8,8 @@ import co.nilin.opex.api.ports.opex.util.tokenValue import org.springframework.security.core.annotation.CurrentSecurityContext import org.springframework.security.core.context.SecurityContext import org.springframework.web.bind.annotation.GetMapping +import org.springframework.web.bind.annotation.PostMapping +import org.springframework.web.bind.annotation.RequestBody import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RequestParam import org.springframework.web.bind.annotation.RestController @@ -42,6 +44,25 @@ class UserHistoryController( ) } + @GetMapping("/history/order/count") + suspend fun getOrderHistoryCount( + @RequestParam symbol: String?, + @RequestParam startTime: Long?, + @RequestParam endTime: Long?, + @RequestParam orderType: MatchingOrderType?, + @RequestParam direction: OrderDirection?, + @CurrentSecurityContext securityContext: SecurityContext, + ): Long { + return marketUserDataProxy.getOrderHistoryCount( + securityContext.authentication.name, + symbol, + startTime, + endTime, + orderType, + direction, + ) + } + @GetMapping("/history/trade") suspend fun getTradeHistory( @RequestParam symbol: String?, @@ -57,6 +78,19 @@ class UserHistoryController( ) } + @GetMapping("/history/trade/count") + suspend fun getTradeHistoryCount( + @RequestParam symbol: String?, + @RequestParam startTime: Long?, + @RequestParam endTime: Long?, + @RequestParam direction: OrderDirection?, + @CurrentSecurityContext securityContext: SecurityContext, + ): Long { + return marketUserDataProxy.getTradeHistoryCount( + securityContext.authentication.name, symbol, startTime, endTime, direction + ) + } + @GetMapping("/history/withdraw") suspend fun getWithdrawHistory( @RequestParam currency: String?, @@ -79,6 +113,22 @@ class UserHistoryController( ) } + @GetMapping("/history/withdraw/count") + suspend fun getWithdrawHistoryCount( + @RequestParam currency: String?, + @RequestParam startTime: Long?, + @RequestParam endTime: Long?, + @CurrentSecurityContext securityContext: SecurityContext, + ): Long { + return walletProxy.getWithdrawTransactionsCount( + securityContext.jwtAuthentication().name, + securityContext.jwtAuthentication().tokenValue(), + currency, + startTime, + endTime, + ) + } + @GetMapping("/history/deposit") suspend fun getDepositHistory( @RequestParam currency: String?, @@ -101,6 +151,22 @@ class UserHistoryController( ) } + @GetMapping("/history/deposit/count") + suspend fun getDepositHistoryCount( + @RequestParam currency: String?, + @RequestParam startTime: Long?, + @RequestParam endTime: Long?, + @CurrentSecurityContext securityContext: SecurityContext, + ): Long { + return walletProxy.getDepositTransactionsCount( + securityContext.jwtAuthentication().name, + securityContext.jwtAuthentication().tokenValue(), + currency, + startTime, + endTime, + ) + } + @GetMapping("/history/transaction") suspend fun getTransactionHistory( @RequestParam currency: String?, @@ -125,6 +191,24 @@ class UserHistoryController( ) } + @GetMapping("/history/transaction/count") + suspend fun getTransactionHistoryCount( + @RequestParam currency: String?, + @RequestParam category: UserTransactionCategory?, + @RequestParam startTime: Long?, + @RequestParam endTime: Long?, + @CurrentSecurityContext securityContext: SecurityContext, + ): Long { + return walletProxy.getTransactionsCount( + securityContext.jwtAuthentication().name, + securityContext.jwtAuthentication().tokenValue(), + currency, + category, + startTime, + endTime, + ) + } + @GetMapping("/summary/trade") suspend fun getTradeTransactionSummary( @RequestParam startTime: Long?, @@ -172,4 +256,11 @@ class UserHistoryController( limit, ) } + @PostMapping("/history/swap/count") + suspend fun getSwapHistoryCount( + @CurrentSecurityContext securityContext: SecurityContext, + @RequestBody request: UserTransactionRequest + ): Long { + return walletProxy.getSwapTransactionsCount(securityContext.jwtAuthentication().tokenValue(), request) + } } \ No newline at end of file diff --git a/api/api-ports/api-proxy-rest/src/main/kotlin/co/nilin/opex/api/ports/proxy/data/TransactionRequest.kt b/api/api-ports/api-proxy-rest/src/main/kotlin/co/nilin/opex/api/ports/proxy/data/TransactionRequest.kt index 1b7ea5fc8..b1d3debb5 100644 --- a/api/api-ports/api-proxy-rest/src/main/kotlin/co/nilin/opex/api/ports/proxy/data/TransactionRequest.kt +++ b/api/api-ports/api-proxy-rest/src/main/kotlin/co/nilin/opex/api/ports/proxy/data/TransactionRequest.kt @@ -4,7 +4,7 @@ data class TransactionRequest( val currency: String?, val startTime: Long? = null, val endTime: Long? = null, - val limit: Int, - val offset: Int, + val limit: Int?, + val offset: Int?, val ascendingByTime: Boolean? = false ) \ No newline at end of file diff --git a/api/api-ports/api-proxy-rest/src/main/kotlin/co/nilin/opex/api/ports/proxy/impl/MarketUserDataProxyImpl.kt b/api/api-ports/api-proxy-rest/src/main/kotlin/co/nilin/opex/api/ports/proxy/impl/MarketUserDataProxyImpl.kt index 37e622ba6..c3b06e2ec 100644 --- a/api/api-ports/api-proxy-rest/src/main/kotlin/co/nilin/opex/api/ports/proxy/impl/MarketUserDataProxyImpl.kt +++ b/api/api-ports/api-proxy-rest/src/main/kotlin/co/nilin/opex/api/ports/proxy/impl/MarketUserDataProxyImpl.kt @@ -139,6 +139,32 @@ class MarketUserDataProxyImpl(private val webClient: WebClient) : MarketUserData } } + override suspend fun getOrderHistoryCount( + uuid: String, + symbol: String?, + startTime: Long?, + endTime: Long?, + orderType: MatchingOrderType?, + direction: OrderDirection?, + ): Long { + return withContext(ProxyDispatchers.market) { + webClient.get() + .uri("$baseUrl/v1/user/order/history/count/$uuid") { + it.queryParam("symbol", symbol) + it.queryParam("startTime", startTime) + it.queryParam("endTime", endTime) + it.queryParam("orderType", orderType) + it.queryParam("direction", direction) + it.build() + }.accept(MediaType.APPLICATION_JSON) + .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) + .retrieve() + .onStatus({ t -> t.isError }, { it.createException() }) + .bodyToMono() + .awaitFirstOrElse { 0L } + } + } + override suspend fun getTradeHistory( uuid: String, symbol: String?, @@ -167,4 +193,28 @@ class MarketUserDataProxyImpl(private val webClient: WebClient) : MarketUserData .awaitFirstOrElse { emptyList() } } } + + override suspend fun getTradeHistoryCount( + uuid: String, + symbol: String?, + startTime: Long?, + endTime: Long?, + direction: OrderDirection?, + ): Long { + return withContext(ProxyDispatchers.market) { + webClient.get() + .uri("$baseUrl/v1/user/trade/history/count/$uuid") { + it.queryParam("symbol", symbol) + it.queryParam("startTime", startTime) + it.queryParam("endTime", endTime) + it.queryParam("direction", direction) + it.build() + }.accept(MediaType.APPLICATION_JSON) + .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) + .retrieve() + .onStatus({ t -> t.isError }, { it.createException() }) + .bodyToMono() + .awaitFirstOrElse { 0L } + } + } } \ No newline at end of file diff --git a/api/api-ports/api-proxy-rest/src/main/kotlin/co/nilin/opex/api/ports/proxy/impl/WalletProxyImpl.kt b/api/api-ports/api-proxy-rest/src/main/kotlin/co/nilin/opex/api/ports/proxy/impl/WalletProxyImpl.kt index c5c2cb76d..cc7fb4555 100644 --- a/api/api-ports/api-proxy-rest/src/main/kotlin/co/nilin/opex/api/ports/proxy/impl/WalletProxyImpl.kt +++ b/api/api-ports/api-proxy-rest/src/main/kotlin/co/nilin/opex/api/ports/proxy/impl/WalletProxyImpl.kt @@ -96,6 +96,27 @@ class WalletProxyImpl(private val webClient: WebClient) : WalletProxy { } } + override suspend fun getDepositTransactionsCount( + uuid: String, + token: String, + currency: String?, + startTime: Long?, + endTime: Long?, + ): Long { + logger.info("fetching deposit transaction count for $uuid") + return withContext(ProxyDispatchers.wallet) { + webClient.post() + .uri("$baseUrl/v1/deposit/history/count") + .accept(MediaType.APPLICATION_JSON) + .header(HttpHeaders.AUTHORIZATION, "Bearer $token") + .body(Mono.just(TransactionRequest(currency, startTime, endTime, null, null))) + .retrieve() + .onStatus({ t -> t.isError }, { it.createException() }) + .bodyToMono() + .awaitFirstOrElse { 0L } + } + } + override suspend fun getWithdrawTransactions( uuid: String, token: String, @@ -121,6 +142,27 @@ class WalletProxyImpl(private val webClient: WebClient) : WalletProxy { } } + override suspend fun getWithdrawTransactionsCount( + uuid: String, + token: String, + currency: String?, + startTime: Long?, + endTime: Long?, + ): Long { + logger.info("fetching withdraw transaction count for $uuid") + return withContext(ProxyDispatchers.wallet) { + webClient.post() + .uri("$baseUrl/withdraw/history/count") + .accept(MediaType.APPLICATION_JSON) + .header(HttpHeaders.AUTHORIZATION, "Bearer $token") + .body(Mono.just(TransactionRequest(currency, startTime, endTime, null, null))) + .retrieve() + .onStatus({ t -> t.isError }, { it.createException() }) + .bodyToMono() + .awaitFirstOrElse { 0L } + } + } + override suspend fun getTransactions( uuid: String, token: String, @@ -156,6 +198,25 @@ class WalletProxyImpl(private val webClient: WebClient) : WalletProxy { .awaitFirstOrElse { emptyList() } } + override suspend fun getTransactionsCount( + uuid: String, + token: String, + currency: String?, + category: UserTransactionCategory?, + startTime: Long?, + endTime: Long?, + ): Long { + return webClient.post() + .uri("$baseUrl/v2/transaction/count") + .accept(MediaType.APPLICATION_JSON) + .header(HttpHeaders.AUTHORIZATION, "Bearer $token") + .body(Mono.just(UserTransactionRequest(currency, category, startTime, endTime))) + .retrieve() + .onStatus({ t -> t.isError }, { it.createException() }) + .bodyToMono() + .awaitFirstOrElse { 0L } + } + override suspend fun getGateWays( includeOffChainGateways: Boolean, includeOnChainGateways: Boolean, @@ -347,5 +408,20 @@ class WalletProxyImpl(private val webClient: WebClient) : WalletProxy { .awaitFirstOrElse { emptyList() } } } + + override suspend fun getSwapTransactionsCount( + token: String, + request: UserTransactionRequest + ): Long { + return webClient.post() + .uri("$baseUrl/v1/swap/history/count") + .accept(MediaType.APPLICATION_JSON) + .header(HttpHeaders.AUTHORIZATION, "Bearer $token") + .body(Mono.just(request)) + .retrieve() + .onStatus({ t -> t.isError }, { it.createException() }) + .bodyToMono() + .awaitFirstOrElse { 0L } + } } diff --git a/market/market-app/src/main/kotlin/co/nilin/opex/market/app/controller/UserDataController.kt b/market/market-app/src/main/kotlin/co/nilin/opex/market/app/controller/UserDataController.kt index 6d1382138..ccdd5f812 100644 --- a/market/market-app/src/main/kotlin/co/nilin/opex/market/app/controller/UserDataController.kt +++ b/market/market-app/src/main/kotlin/co/nilin/opex/market/app/controller/UserDataController.kt @@ -80,6 +80,27 @@ class UserDataController(private val userQueryHandler: UserQueryHandler) { ) } + @GetMapping("/order/history/count/{uuid}") + suspend fun getOrderHistoryCount( + @RequestParam symbol: String?, + @RequestParam startTime: Long?, + @RequestParam endTime: Long?, + @RequestParam orderType: MatchingOrderType?, + @RequestParam direction: OrderDirection?, + @RequestParam limit: Int?, + @RequestParam offset: Int?, + @PathVariable uuid: String, + ): Long { + return userQueryHandler.getOrderHistoryCount( + uuid, + symbol, + startTime?.let { startTime.asLocalDateTime() }, + endTime?.let { endTime.asLocalDateTime() }, + orderType, + direction, + ) + } + @GetMapping("/trade/history/{uuid}") suspend fun getTradeHistory( @PathVariable uuid: String, @@ -101,4 +122,21 @@ class UserDataController(private val userQueryHandler: UserQueryHandler) { ) } + @GetMapping("/trade/history/count/{uuid}") + suspend fun getTradeHistoryCount( + @PathVariable uuid: String, + @RequestParam symbol: String?, + @RequestParam startTime: Long?, + @RequestParam endTime: Long?, + @RequestParam direction: OrderDirection?, + ): Long { + return userQueryHandler.getTradeHistoryCount( + uuid, + symbol, + startTime?.let { startTime.asLocalDateTime() }, + endTime?.let { endTime.asLocalDateTime() }, + direction, + ) + } + } \ No newline at end of file diff --git a/market/market-core/src/main/kotlin/co/nilin/opex/market/core/spi/UserQueryHandler.kt b/market/market-core/src/main/kotlin/co/nilin/opex/market/core/spi/UserQueryHandler.kt index 4a68e90dd..0086ec66e 100644 --- a/market/market-core/src/main/kotlin/co/nilin/opex/market/core/spi/UserQueryHandler.kt +++ b/market/market-core/src/main/kotlin/co/nilin/opex/market/core/spi/UserQueryHandler.kt @@ -30,6 +30,15 @@ interface UserQueryHandler { offset: Int?, ): List + suspend fun getOrderHistoryCount( + uuid: String, + symbol: String?, + startTime: LocalDateTime?, + endTime: LocalDateTime?, + orderType: MatchingOrderType?, + direction: OrderDirection?, + ): Long + suspend fun getTradeHistory( uuid: String, symbol: String?, @@ -40,4 +49,11 @@ interface UserQueryHandler { offset: Int?, ): List + suspend fun getTradeHistoryCount( + uuid: String, + symbol: String?, + startTime: LocalDateTime?, + endTime: LocalDateTime?, + direction: OrderDirection?, + ): Long } \ No newline at end of file diff --git a/market/market-ports/market-persister-postgres/src/main/kotlin/co/nilin/opex/market/ports/postgres/dao/OrderRepository.kt b/market/market-ports/market-persister-postgres/src/main/kotlin/co/nilin/opex/market/ports/postgres/dao/OrderRepository.kt index 1c930b72e..a9e6700c8 100644 --- a/market/market-ports/market-persister-postgres/src/main/kotlin/co/nilin/opex/market/ports/postgres/dao/OrderRepository.kt +++ b/market/market-ports/market-persister-postgres/src/main/kotlin/co/nilin/opex/market/ports/postgres/dao/OrderRepository.kt @@ -174,4 +174,26 @@ order by create_date desc limit: Int?, offset: Int?, ): Flow + + @Query( + """ +select count(*) +from orders o + WHERE uuid = :uuid + and (:symbol is null or o.symbol = :symbol) + and (:startTime is null or o.create_date >= :startTime) + and (:endTime is null or o.create_date <= :endTime) + and (:orderType is null or o.order_type = :orderType) + and (:direction is null or o.side = :direction) + """ + ) + fun countByCriteria( + uuid: String, + symbol: String?, + startTime: LocalDateTime?, + endTime: LocalDateTime?, + orderType: MatchingOrderType?, + direction: OrderDirection?, + ): Mono + } \ No newline at end of file diff --git a/market/market-ports/market-persister-postgres/src/main/kotlin/co/nilin/opex/market/ports/postgres/dao/TradeRepository.kt b/market/market-ports/market-persister-postgres/src/main/kotlin/co/nilin/opex/market/ports/postgres/dao/TradeRepository.kt index e42035be6..428d2bb22 100644 --- a/market/market-ports/market-persister-postgres/src/main/kotlin/co/nilin/opex/market/ports/postgres/dao/TradeRepository.kt +++ b/market/market-ports/market-persister-postgres/src/main/kotlin/co/nilin/opex/market/ports/postgres/dao/TradeRepository.kt @@ -534,7 +534,6 @@ interface TradeRepository : ReactiveCrudRepository { ): Flow - @Query( """ select t.symbol, @@ -556,7 +555,7 @@ select t.symbol, true as is_best_match, case when o.side = 'bid' and t.maker_uuid = :uuid then true else false end as is_maker_buyer from trades t - inner join orders o on o.ouid in (t.maker_ouid, t.taker_ouid) + inner join orders o on o.ouid = t.maker_ouid or o.ouid = t.taker_ouid where :uuid in (t.maker_uuid, t.taker_uuid) and (:symbol is null or t.symbol = :symbol) and (:startTime is null or t.trade_date >= :startTime) @@ -575,5 +574,25 @@ where :uuid in (t.maker_uuid, t.taker_uuid) direction: OrderDirection?, limit: Int?, offset: Int?, - ) : Flow + ): Flow + + @Query( + """ +select count(*) +from trades t + inner join orders o on o.ouid = t.maker_ouid or o.ouid = t.taker_ouid +where :uuid in (t.maker_uuid, t.taker_uuid) + and (:symbol is null or t.symbol = :symbol) + and (:startTime is null or t.trade_date >= :startTime) + and (:endTime is null or t.trade_date <= :endTime) + and (:direction is null or o.side = :direction) + """ + ) + suspend fun countByCriteria( + uuid: String, + symbol: String?, + startTime: LocalDateTime?, + endTime: LocalDateTime?, + direction: OrderDirection?, + ): Mono } \ No newline at end of file diff --git a/market/market-ports/market-persister-postgres/src/main/kotlin/co/nilin/opex/market/ports/postgres/impl/UserQueryHandlerImpl.kt b/market/market-ports/market-persister-postgres/src/main/kotlin/co/nilin/opex/market/ports/postgres/impl/UserQueryHandlerImpl.kt index 336cdd035..17e0f8433 100644 --- a/market/market-ports/market-persister-postgres/src/main/kotlin/co/nilin/opex/market/ports/postgres/impl/UserQueryHandlerImpl.kt +++ b/market/market-ports/market-persister-postgres/src/main/kotlin/co/nilin/opex/market/ports/postgres/impl/UserQueryHandlerImpl.kt @@ -12,6 +12,7 @@ import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.toList import kotlinx.coroutines.reactive.awaitFirst +import kotlinx.coroutines.reactive.awaitFirstOrElse import kotlinx.coroutines.reactive.awaitFirstOrNull import kotlinx.coroutines.reactor.awaitSingleOrNull import org.springframework.stereotype.Component @@ -179,6 +180,24 @@ class UserQueryHandlerImpl( ).toList() } + override suspend fun getOrderHistoryCount( + uuid: String, + symbol: String?, + startTime: LocalDateTime?, + endTime: LocalDateTime?, + orderType: MatchingOrderType?, + direction: OrderDirection? + ): Long { + return orderRepository.countByCriteria( + uuid, + symbol, + startTime, + endTime, + orderType, + direction, + ).awaitFirstOrElse { 0L } + } + override suspend fun getTradeHistory( uuid: String, symbol: String?, @@ -198,4 +217,20 @@ class UserQueryHandlerImpl( offset ).toList() } + + override suspend fun getTradeHistoryCount( + uuid: String, + symbol: String?, + startTime: LocalDateTime?, + endTime: LocalDateTime?, + direction: OrderDirection? + ): Long { + return tradeRepository.countByCriteria( + uuid, + symbol, + startTime, + endTime, + direction, + ).awaitFirst() + } } \ No newline at end of file diff --git a/wallet/wallet-app/src/main/kotlin/co/nilin/opex/wallet/app/controller/AdvancedTransferController.kt b/wallet/wallet-app/src/main/kotlin/co/nilin/opex/wallet/app/controller/AdvancedTransferController.kt index b8dd3a93f..e3ef85e7b 100644 --- a/wallet/wallet-app/src/main/kotlin/co/nilin/opex/wallet/app/controller/AdvancedTransferController.kt +++ b/wallet/wallet-app/src/main/kotlin/co/nilin/opex/wallet/app/controller/AdvancedTransferController.kt @@ -1,7 +1,10 @@ package co.nilin.opex.wallet.app.controller import co.nilin.opex.common.OpexError -import co.nilin.opex.wallet.app.dto.* +import co.nilin.opex.wallet.app.dto.ReservedTransferResponse +import co.nilin.opex.wallet.app.dto.TransferPreEvaluateResponse +import co.nilin.opex.wallet.app.dto.TransferReserveRequest +import co.nilin.opex.wallet.app.dto.UserTransactionRequest import co.nilin.opex.wallet.app.service.TransferService import co.nilin.opex.wallet.core.inout.SwapResponse import co.nilin.opex.wallet.core.inout.TransferResult @@ -49,19 +52,19 @@ class AdvancedTransferController { @GetMapping("/v3/amount/{symbol}/{amount}_{destSymbol}") @ApiResponse( - message = "OK", - code = 200, - examples = Example( - ExampleProperty( - value = "{ \"destAmount\": \"111\"}", - mediaType = "application/json" - ) + message = "OK", + code = 200, + examples = Example( + ExampleProperty( + value = "{ \"destAmount\": \"111\"}", + mediaType = "application/json" ) + ) ) suspend fun calculateSourceAmount( - @PathVariable symbol: String, - @PathVariable amount: BigDecimal, - @PathVariable destSymbol: String, + @PathVariable symbol: String, + @PathVariable amount: BigDecimal, + @PathVariable destSymbol: String, ): TransferPreEvaluateResponse { return TransferPreEvaluateResponse(transferService.calculateSourceAmount(symbol, amount, destSymbol)) } @@ -165,4 +168,32 @@ class AdvancedTransferController { } } + @PostMapping("/v1/swap/history/count") + suspend fun getSwapHistoryCount( + @CurrentSecurityContext securityContext: SecurityContext, + @RequestBody request: UserTransactionRequest + + ): Long { + return with(request) { + reservedTransferManager.countByCriteria( + securityContext.authentication.name, + sourceSymbol, + destSymbol, + startTime?.let { + LocalDateTime.ofInstant( + Instant.ofEpochMilli(it), + ZoneId.systemDefault() + ) + }, + endTime?.let { + LocalDateTime.ofInstant( + Instant.ofEpochMilli(it), + ZoneId.systemDefault() + ) + }, + status + ) + } + } + } \ No newline at end of file diff --git a/wallet/wallet-app/src/main/kotlin/co/nilin/opex/wallet/app/controller/DepositController.kt b/wallet/wallet-app/src/main/kotlin/co/nilin/opex/wallet/app/controller/DepositController.kt index 468da7bc7..0536ac9b8 100644 --- a/wallet/wallet-app/src/main/kotlin/co/nilin/opex/wallet/app/controller/DepositController.kt +++ b/wallet/wallet-app/src/main/kotlin/co/nilin/opex/wallet/app/controller/DepositController.kt @@ -46,6 +46,23 @@ class DepositController( ) } + @PostMapping("/v1/deposit/history/count") + suspend fun getDepositTransactionsCountForUser( + @RequestBody request: DepositHistoryRequest, + @CurrentSecurityContext securityContext: SecurityContext, + ): Long { + return depositService.getDepositHistoryCount( + securityContext.authentication.name, + request.currency, + request.startTime?.let { + LocalDateTime.ofInstant(Instant.ofEpochMilli(request.startTime), ZoneId.systemDefault()) + }, + request.endTime?.let { + LocalDateTime.ofInstant(Instant.ofEpochMilli(request.endTime), ZoneId.systemDefault()) + }, + ) + } + @PostMapping("/deposit/{amount}_{chain}_{symbol}/{receiverUuid}_{receiverWalletType}") @ApiResponse( message = "OK", diff --git a/wallet/wallet-app/src/main/kotlin/co/nilin/opex/wallet/app/controller/TransactionController.kt b/wallet/wallet-app/src/main/kotlin/co/nilin/opex/wallet/app/controller/TransactionController.kt index 84a686b92..6f8eb18eb 100644 --- a/wallet/wallet-app/src/main/kotlin/co/nilin/opex/wallet/app/controller/TransactionController.kt +++ b/wallet/wallet-app/src/main/kotlin/co/nilin/opex/wallet/app/controller/TransactionController.kt @@ -39,6 +39,22 @@ class TransactionController( } } + @PostMapping("/count") + suspend fun getUserTransactionsCount( + principal: Principal, + @RequestBody request: UserTransactionRequest, + ): Long { + return with(request) { + manager.getTransactionHistoryCount( + principal.name, + currency, + category, + startTime?.let { LocalDateTime.ofInstant(Instant.ofEpochMilli(it), ZoneId.systemDefault()) }, + endTime?.let { LocalDateTime.ofInstant(Instant.ofEpochMilli(it), ZoneId.systemDefault()) }, + ) + } + } + @GetMapping("/trade/summary/{uuid}") suspend fun getUserTradeTransactionSummary( @RequestParam startTime: Long?, diff --git a/wallet/wallet-app/src/main/kotlin/co/nilin/opex/wallet/app/controller/WithdrawController.kt b/wallet/wallet-app/src/main/kotlin/co/nilin/opex/wallet/app/controller/WithdrawController.kt index 9d0159043..a9bcd0704 100644 --- a/wallet/wallet-app/src/main/kotlin/co/nilin/opex/wallet/app/controller/WithdrawController.kt +++ b/wallet/wallet-app/src/main/kotlin/co/nilin/opex/wallet/app/controller/WithdrawController.kt @@ -107,6 +107,24 @@ class WithdrawController(private val withdrawService: WithdrawService) { } } + @PostMapping("/history/count") + suspend fun getWithdrawTransactionsCountForUser( + @CurrentSecurityContext securityContext: SecurityContext, + @RequestBody request: WithdrawHistoryRequest, + ): Long { + return withdrawService.findWithdrawHistoryCount( + securityContext.authentication.name, + request.currency, + request.startTime?.let { + LocalDateTime.ofInstant(Instant.ofEpochMilli(request.startTime), ZoneId.systemDefault()) + } + ?: null, + request.endTime?.let { + LocalDateTime.ofInstant(Instant.ofEpochMilli(request.endTime), ZoneId.systemDefault()) + } ?: null, + ) + } + @GetMapping("/summary/{uuid}") suspend fun getUserWithdrawSummary( @RequestParam startTime: Long?, diff --git a/wallet/wallet-app/src/main/kotlin/co/nilin/opex/wallet/app/service/DepositService.kt b/wallet/wallet-app/src/main/kotlin/co/nilin/opex/wallet/app/service/DepositService.kt index 9a59e8252..b0595d5e7 100644 --- a/wallet/wallet-app/src/main/kotlin/co/nilin/opex/wallet/app/service/DepositService.kt +++ b/wallet/wallet-app/src/main/kotlin/co/nilin/opex/wallet/app/service/DepositService.kt @@ -3,7 +3,6 @@ package co.nilin.opex.wallet.app.service import co.nilin.opex.common.OpexError import co.nilin.opex.utility.error.data.OpexException import co.nilin.opex.wallet.app.dto.ManualTransferRequest -import co.nilin.opex.wallet.app.utils.asLocalDateTime import co.nilin.opex.wallet.core.inout.* import co.nilin.opex.wallet.core.model.DepositStatus import co.nilin.opex.wallet.core.model.DepositType @@ -228,6 +227,15 @@ class DepositService( } } + suspend fun getDepositHistoryCount( + uuid: String, + symbol: String?, + startTime: LocalDateTime?, + endTime: LocalDateTime?, + ): Long { + return depositPersister.getDepositHistoryCount(uuid, symbol, startTime, endTime) + } + suspend fun searchDeposit( ownerUuid: String?, diff --git a/wallet/wallet-core/src/main/kotlin/co/nilin/opex/wallet/core/service/WithdrawService.kt b/wallet/wallet-core/src/main/kotlin/co/nilin/opex/wallet/core/service/WithdrawService.kt index b57bec5b4..a4bf55f10 100644 --- a/wallet/wallet-core/src/main/kotlin/co/nilin/opex/wallet/core/service/WithdrawService.kt +++ b/wallet/wallet-core/src/main/kotlin/co/nilin/opex/wallet/core/service/WithdrawService.kt @@ -373,6 +373,15 @@ class WithdrawService( return withdrawPersister.findWithdrawHistory(uuid, currency, startTime, endTime, limit, offset, ascendingByTime) } + suspend fun findWithdrawHistoryCount( + uuid: String, + currency: String?, + startTime: LocalDateTime?, + endTime: LocalDateTime?, + ): Long { + return withdrawPersister.findWithdrawHistoryCount(uuid, currency, startTime, endTime) + } + suspend fun getWithdrawSummary( uuid: String, startTime: LocalDateTime?, diff --git a/wallet/wallet-core/src/main/kotlin/co/nilin/opex/wallet/core/spi/DepositPersister.kt b/wallet/wallet-core/src/main/kotlin/co/nilin/opex/wallet/core/spi/DepositPersister.kt index 04462d223..3d321a6a6 100644 --- a/wallet/wallet-core/src/main/kotlin/co/nilin/opex/wallet/core/spi/DepositPersister.kt +++ b/wallet/wallet-core/src/main/kotlin/co/nilin/opex/wallet/core/spi/DepositPersister.kt @@ -19,6 +19,13 @@ interface DepositPersister { ascendingByTime: Boolean? ): List + suspend fun getDepositHistoryCount ( + uuid: String, + currency: String?, + startTime: LocalDateTime?, + endTime: LocalDateTime?, + ): Long + suspend fun findByCriteria( ownerUuid: String?, symbol: String?, diff --git a/wallet/wallet-core/src/main/kotlin/co/nilin/opex/wallet/core/spi/ReservedTransferManager.kt b/wallet/wallet-core/src/main/kotlin/co/nilin/opex/wallet/core/spi/ReservedTransferManager.kt index 112d94c4b..f552bab19 100644 --- a/wallet/wallet-core/src/main/kotlin/co/nilin/opex/wallet/core/spi/ReservedTransferManager.kt +++ b/wallet/wallet-core/src/main/kotlin/co/nilin/opex/wallet/core/spi/ReservedTransferManager.kt @@ -25,5 +25,14 @@ interface ReservedTransferManager { status: ReservedStatus? ): List? + suspend fun countByCriteria( + owner: String?, + sourceSymbol: String?, + destSymbol: String?, + startTime: LocalDateTime?, + endTime: LocalDateTime?, + status: ReservedStatus? + ): Long + } \ No newline at end of file diff --git a/wallet/wallet-core/src/main/kotlin/co/nilin/opex/wallet/core/spi/UserTransactionManager.kt b/wallet/wallet-core/src/main/kotlin/co/nilin/opex/wallet/core/spi/UserTransactionManager.kt index 6ccabf320..35ea5fde2 100644 --- a/wallet/wallet-core/src/main/kotlin/co/nilin/opex/wallet/core/spi/UserTransactionManager.kt +++ b/wallet/wallet-core/src/main/kotlin/co/nilin/opex/wallet/core/spi/UserTransactionManager.kt @@ -21,6 +21,14 @@ interface UserTransactionManager { offset: Int, ): List + suspend fun getTransactionHistoryCount( + userId: String?, + currency: String?, + category: UserTransactionCategory?, + startTime: LocalDateTime?, + endTime: LocalDateTime?, + ): Long + suspend fun getTradeTransactionSummary( uuid: String, startTime: LocalDateTime?, diff --git a/wallet/wallet-core/src/main/kotlin/co/nilin/opex/wallet/core/spi/WithdrawPersister.kt b/wallet/wallet-core/src/main/kotlin/co/nilin/opex/wallet/core/spi/WithdrawPersister.kt index 50f7fc957..e0ffdfc29 100644 --- a/wallet/wallet-core/src/main/kotlin/co/nilin/opex/wallet/core/spi/WithdrawPersister.kt +++ b/wallet/wallet-core/src/main/kotlin/co/nilin/opex/wallet/core/spi/WithdrawPersister.kt @@ -53,6 +53,13 @@ interface WithdrawPersister { ascendingByTime: Boolean?, ): List + suspend fun findWithdrawHistoryCount( + uuid: String, + currency: String?, + startTime: LocalDateTime?, + endTime: LocalDateTime?, + ): Long + suspend fun getWithdrawSummary( uuid: String, startTime: LocalDateTime?, diff --git a/wallet/wallet-ports/wallet-persister-postgres/src/main/kotlin/co/nilin/opex/wallet/ports/postgres/dao/DepositRepository.kt b/wallet/wallet-ports/wallet-persister-postgres/src/main/kotlin/co/nilin/opex/wallet/ports/postgres/dao/DepositRepository.kt index e81101036..cc877ba13 100644 --- a/wallet/wallet-ports/wallet-persister-postgres/src/main/kotlin/co/nilin/opex/wallet/ports/postgres/dao/DepositRepository.kt +++ b/wallet/wallet-ports/wallet-persister-postgres/src/main/kotlin/co/nilin/opex/wallet/ports/postgres/dao/DepositRepository.kt @@ -7,6 +7,7 @@ import kotlinx.coroutines.flow.Flow import org.springframework.data.r2dbc.repository.Query import org.springframework.data.repository.reactive.ReactiveCrudRepository import org.springframework.stereotype.Repository +import reactor.core.publisher.Mono import java.time.LocalDateTime @Repository @@ -113,4 +114,23 @@ interface DepositRepository : ReactiveCrudRepository { endTime: LocalDateTime?, limit: Int?, ): Flow + + + @Query( + """ + select count(*) from deposits + where uuid = :uuid + and (:currency is null or currency = :currency) + and (:startTime is null or create_date > :startTime ) + and (:endTime is null or create_date <= :endTime) + and status in (:status) + """ + ) + fun countByCriteria( + uuid: String, + currency: String?, + startTime: LocalDateTime?, + endTime: LocalDateTime?, + status: List? = listOf(DepositStatus.DONE, DepositStatus.INVALID), + ): Mono } \ No newline at end of file diff --git a/wallet/wallet-ports/wallet-persister-postgres/src/main/kotlin/co/nilin/opex/wallet/ports/postgres/dao/ReservedTransferRepository.kt b/wallet/wallet-ports/wallet-persister-postgres/src/main/kotlin/co/nilin/opex/wallet/ports/postgres/dao/ReservedTransferRepository.kt index 6996e38ca..8a9ebbeb1 100644 --- a/wallet/wallet-ports/wallet-persister-postgres/src/main/kotlin/co/nilin/opex/wallet/ports/postgres/dao/ReservedTransferRepository.kt +++ b/wallet/wallet-ports/wallet-persister-postgres/src/main/kotlin/co/nilin/opex/wallet/ports/postgres/dao/ReservedTransferRepository.kt @@ -39,4 +39,24 @@ interface ReservedTransferRepository : ReactiveCrudRepository? + + @Query( + """ + select count(*) from reserved_transfer + where ( :owner is null or sender_uuid=:owner) + and (:sourceSymbol is null or source_symbol =:sourceSymbol) + and (:destSymbol is null or dest_symbol =:destSymbol) + and (:startTime is null or reserve_date > :startTime ) + and (:endTime is null or reserve_date <= :endTime) + and (:status is null or status=:status) + """ + ) + fun countByCriteria( + owner: String?, + sourceSymbol: String?, + destSymbol: String?, + startTime: LocalDateTime?, + endTime: LocalDateTime?, + status: ReservedStatus? + ): Mono } \ No newline at end of file diff --git a/wallet/wallet-ports/wallet-persister-postgres/src/main/kotlin/co/nilin/opex/wallet/ports/postgres/dao/UserTransactionRepository.kt b/wallet/wallet-ports/wallet-persister-postgres/src/main/kotlin/co/nilin/opex/wallet/ports/postgres/dao/UserTransactionRepository.kt index 4d8c5c612..3ec2ea6a9 100644 --- a/wallet/wallet-ports/wallet-persister-postgres/src/main/kotlin/co/nilin/opex/wallet/ports/postgres/dao/UserTransactionRepository.kt +++ b/wallet/wallet-ports/wallet-persister-postgres/src/main/kotlin/co/nilin/opex/wallet/ports/postgres/dao/UserTransactionRepository.kt @@ -9,6 +9,7 @@ import org.springframework.data.r2dbc.repository.Query import org.springframework.data.repository.reactive.ReactiveCrudRepository import org.springframework.stereotype.Repository import reactor.core.publisher.Flux +import reactor.core.publisher.Mono import java.time.LocalDateTime @Repository @@ -85,4 +86,25 @@ interface UserTransactionRepository : ReactiveCrudRepository + + + @Query( + """ + select count(*) + from user_transaction ut + join wallet_owner o on o.id = ut.owner_id + where (:userId is null or o.uuid = :userId) + and (:currency is null or currency = :currency) + and (:category is null or category = :category) + and (:startTime is null or date > :startTime) + and (:endTime is null or date <= :endTime) + """ + ) + fun countByCriteria( + userId: String?, + currency: String?, + category: UserTransactionCategory?, + startTime: LocalDateTime?, + endTime: LocalDateTime? + ): Mono } \ No newline at end of file diff --git a/wallet/wallet-ports/wallet-persister-postgres/src/main/kotlin/co/nilin/opex/wallet/ports/postgres/dao/WithdrawRepository.kt b/wallet/wallet-ports/wallet-persister-postgres/src/main/kotlin/co/nilin/opex/wallet/ports/postgres/dao/WithdrawRepository.kt index a11938dc9..fb32533f6 100644 --- a/wallet/wallet-ports/wallet-persister-postgres/src/main/kotlin/co/nilin/opex/wallet/ports/postgres/dao/WithdrawRepository.kt +++ b/wallet/wallet-ports/wallet-persister-postgres/src/main/kotlin/co/nilin/opex/wallet/ports/postgres/dao/WithdrawRepository.kt @@ -193,6 +193,22 @@ interface WithdrawRepository : ReactiveCrudRepository { offset: Int? = 10000 ): Flow + @Query( + """ + select count(*) from withdraws + where uuid = :uuid + and (:currency is null or currency = :currency) + and (:startTime is null or create_date > :startTime ) + and (:endTime is null or create_date <= :endTime) + """ + ) + fun findWithdrawHistoryCount( + uuid: String, + currency: String?, + startTime: LocalDateTime?, + endTime: LocalDateTime?, + ): Mono + // @Query( // """ // select * from withdraws diff --git a/wallet/wallet-ports/wallet-persister-postgres/src/main/kotlin/co/nilin/opex/wallet/ports/postgres/impl/DepositPersisterImpl.kt b/wallet/wallet-ports/wallet-persister-postgres/src/main/kotlin/co/nilin/opex/wallet/ports/postgres/impl/DepositPersisterImpl.kt index d41416db5..d253efc42 100644 --- a/wallet/wallet-ports/wallet-persister-postgres/src/main/kotlin/co/nilin/opex/wallet/ports/postgres/impl/DepositPersisterImpl.kt +++ b/wallet/wallet-ports/wallet-persister-postgres/src/main/kotlin/co/nilin/opex/wallet/ports/postgres/impl/DepositPersisterImpl.kt @@ -10,6 +10,7 @@ import co.nilin.opex.wallet.ports.postgres.util.toModel import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.toList import kotlinx.coroutines.reactive.awaitFirst +import kotlinx.coroutines.reactive.awaitFirstOrElse import org.springframework.stereotype.Service import java.time.LocalDateTime @@ -35,6 +36,15 @@ class DepositPersisterImpl(private val depositRepository: DepositRepository) : D return deposits.map { it.toDto() }.toList() } + override suspend fun getDepositHistoryCount( + uuid: String, + currency: String?, + startTime: LocalDateTime?, + endTime: LocalDateTime? + ): Long { + return depositRepository.countByCriteria(uuid, currency, startTime, endTime).awaitFirstOrElse { 0L } + } + override suspend fun findByCriteria( ownerUuid: String?, symbol: String?, diff --git a/wallet/wallet-ports/wallet-persister-postgres/src/main/kotlin/co/nilin/opex/wallet/ports/postgres/impl/ReservedTransferImpl.kt b/wallet/wallet-ports/wallet-persister-postgres/src/main/kotlin/co/nilin/opex/wallet/ports/postgres/impl/ReservedTransferImpl.kt index 16a168b61..ec93426a4 100644 --- a/wallet/wallet-ports/wallet-persister-postgres/src/main/kotlin/co/nilin/opex/wallet/ports/postgres/impl/ReservedTransferImpl.kt +++ b/wallet/wallet-ports/wallet-persister-postgres/src/main/kotlin/co/nilin/opex/wallet/ports/postgres/impl/ReservedTransferImpl.kt @@ -7,6 +7,7 @@ import co.nilin.opex.wallet.core.spi.ReservedTransferManager import co.nilin.opex.wallet.ports.postgres.dao.ReservedTransferRepository import co.nilin.opex.wallet.ports.postgres.model.ReservedTransferModel import kotlinx.coroutines.flow.toList +import kotlinx.coroutines.reactive.awaitFirstOrElse import kotlinx.coroutines.reactor.awaitSingleOrNull import org.springframework.beans.factory.annotation.Value import org.springframework.stereotype.Component @@ -65,6 +66,24 @@ class ReservedTransferImpl(private val reservedTransferRepository: ReservedTrans )?.toList()?.map { it.asResponse() } } + override suspend fun countByCriteria( + owner: String?, + sourceSymbol: String?, + destSymbol: String?, + startTime: LocalDateTime?, + endTime: LocalDateTime?, + status: ReservedStatus? + ): Long { + return reservedTransferRepository.countByCriteria( + owner, + sourceSymbol, + destSymbol, + startTime, + endTime, + status + ).awaitFirstOrElse { 0L } + } + fun ReservedTransferModel.asResponse(): SwapResponse { return SwapResponse( reserveNumber, diff --git a/wallet/wallet-ports/wallet-persister-postgres/src/main/kotlin/co/nilin/opex/wallet/ports/postgres/impl/UserTransactionManagerImpl.kt b/wallet/wallet-ports/wallet-persister-postgres/src/main/kotlin/co/nilin/opex/wallet/ports/postgres/impl/UserTransactionManagerImpl.kt index f70d66271..619695690 100644 --- a/wallet/wallet-ports/wallet-persister-postgres/src/main/kotlin/co/nilin/opex/wallet/ports/postgres/impl/UserTransactionManagerImpl.kt +++ b/wallet/wallet-ports/wallet-persister-postgres/src/main/kotlin/co/nilin/opex/wallet/ports/postgres/impl/UserTransactionManagerImpl.kt @@ -9,6 +9,7 @@ import co.nilin.opex.wallet.ports.postgres.dao.UserTransactionRepository import co.nilin.opex.wallet.ports.postgres.model.UserTransactionModel import kotlinx.coroutines.flow.toList import kotlinx.coroutines.reactive.awaitFirstOrElse +import kotlinx.coroutines.reactor.awaitFirst import kotlinx.coroutines.reactor.awaitSingleOrNull import org.springframework.stereotype.Component import java.time.LocalDateTime @@ -49,6 +50,16 @@ class UserTransactionManagerImpl(private val repository: UserTransactionReposito return transactions.collectList().awaitFirstOrElse { emptyList() } } + override suspend fun getTransactionHistoryCount( + userId: String?, + currency: String?, + category: UserTransactionCategory?, + startTime: LocalDateTime?, + endTime: LocalDateTime? + ): Long { + return repository.countByCriteria(userId, currency, category, startTime, endTime).awaitFirstOrElse { 0L } + } + override suspend fun getTradeTransactionSummary( uuid: String, startTime: LocalDateTime?, diff --git a/wallet/wallet-ports/wallet-persister-postgres/src/main/kotlin/co/nilin/opex/wallet/ports/postgres/impl/WithdrawPersisterImpl.kt b/wallet/wallet-ports/wallet-persister-postgres/src/main/kotlin/co/nilin/opex/wallet/ports/postgres/impl/WithdrawPersisterImpl.kt index bf05f78fe..d2f8a7c3d 100644 --- a/wallet/wallet-ports/wallet-persister-postgres/src/main/kotlin/co/nilin/opex/wallet/ports/postgres/impl/WithdrawPersisterImpl.kt +++ b/wallet/wallet-ports/wallet-persister-postgres/src/main/kotlin/co/nilin/opex/wallet/ports/postgres/impl/WithdrawPersisterImpl.kt @@ -171,6 +171,22 @@ class WithdrawPersisterImpl(private val withdrawRepository: WithdrawRepository) return withdraws.map { it.asWithdrawResponse() }.toList() } + override suspend fun findWithdrawHistoryCount( + uuid: String, + currency: String?, + startTime: LocalDateTime?, + endTime: LocalDateTime?, + ): Long { + + return withdrawRepository.findWithdrawHistoryCount( + uuid, + currency, + startTime, + endTime, + ).awaitFirstOrElse { 0L } + + } + private suspend fun WithdrawModel.asWithdrawResponse(): WithdrawResponse { return WithdrawResponse(