From d3368db9a0196815f0d27f1fa0329bc2263121f1 Mon Sep 17 00:00:00 2001 From: Amir Rajabi <34955519+AmirRajabii@users.noreply.github.com> Date: Mon, 6 Jan 2025 11:36:34 +0330 Subject: [PATCH 01/51] Fix chart problem (#495) Fix query for get candle data --- .../co/nilin/opex/market/ports/postgres/dao/TradeRepository.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 e7e65c16f..1277cf431 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 @@ -221,7 +221,7 @@ interface TradeRepository : ReactiveCrudRepository { @Query( """ - WITH intervals AS (SELECT * FROM interval_generator((:startTime), (:endTime), :interval ::INTERVAL)), + WITH intervals AS (SELECT * FROM interval_generator((TO_TIMESTAMP(:startTime)) ::TIMESTAMP WITHOUT TIME ZONE, (:endTime), :interval ::INTERVAL)), first_trade AS ( SELECT DISTINCT ON (f.start_time) f.start_time, f.end_time, t.matched_price AS open_price FROM intervals f LEFT JOIN trades t ON t.create_date >= f.start_time AND t.create_date < f.end_time AND t.symbol = :symbol From 05fc3d6014654cd03b44507633897c2f36d7f6e0 Mon Sep 17 00:00:00 2001 From: Amir Rajabi <34955519+AmirRajabii@users.noreply.github.com> Date: Mon, 13 Jan 2025 17:51:59 +0330 Subject: [PATCH 02/51] =?UTF-8?q?New=20transfer=20=E2=80=8Ccategory(for=20?= =?UTF-8?q?referral)=20(#487)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wallet/core/model/TransferCategory.kt | 5 +- .../core/model/UserTransactionCategory.kt | 4 + .../core/service/TransferManagerImpl.kt | 125 +++++++++++++++++- 3 files changed, 128 insertions(+), 6 deletions(-) diff --git a/wallet/wallet-core/src/main/kotlin/co/nilin/opex/wallet/core/model/TransferCategory.kt b/wallet/wallet-core/src/main/kotlin/co/nilin/opex/wallet/core/model/TransferCategory.kt index b9b25eac0..92facb06b 100644 --- a/wallet/wallet-core/src/main/kotlin/co/nilin/opex/wallet/core/model/TransferCategory.kt +++ b/wallet/wallet-core/src/main/kotlin/co/nilin/opex/wallet/core/model/TransferCategory.kt @@ -16,6 +16,9 @@ enum class TransferCategory { ORDER_FINALIZED, TRADE, FEE, - + REFERRAL_COMMISSION, + REFERRAL_KYC_REWARD, + REFERENT_COMMISSION, + KYC_ACCEPTED_REWARD, NORMAL //TODO TEST? } \ No newline at end of file diff --git a/wallet/wallet-core/src/main/kotlin/co/nilin/opex/wallet/core/model/UserTransactionCategory.kt b/wallet/wallet-core/src/main/kotlin/co/nilin/opex/wallet/core/model/UserTransactionCategory.kt index 37ebc40af..018b899d3 100644 --- a/wallet/wallet-core/src/main/kotlin/co/nilin/opex/wallet/core/model/UserTransactionCategory.kt +++ b/wallet/wallet-core/src/main/kotlin/co/nilin/opex/wallet/core/model/UserTransactionCategory.kt @@ -7,5 +7,9 @@ enum class UserTransactionCategory { DEPOSIT_TO, // for admin using DEPOSIT_MANUALLY WITHDRAW, FEE, + REFERRAL_COMMISSION, + REFERRAL_KYC_REWARD, + REFERENT_COMMISSION, + KYC_ACCEPTED_REWARD, SYSTEM } \ No newline at end of file diff --git a/wallet/wallet-core/src/main/kotlin/co/nilin/opex/wallet/core/service/TransferManagerImpl.kt b/wallet/wallet-core/src/main/kotlin/co/nilin/opex/wallet/core/service/TransferManagerImpl.kt index f4fd05ee4..139bbcae8 100644 --- a/wallet/wallet-core/src/main/kotlin/co/nilin/opex/wallet/core/service/TransferManagerImpl.kt +++ b/wallet/wallet-core/src/main/kotlin/co/nilin/opex/wallet/core/service/TransferManagerImpl.kt @@ -1,16 +1,11 @@ package co.nilin.opex.wallet.core.service import co.nilin.opex.common.OpexError -import co.nilin.opex.wallet.core.exc.CurrencyNotMatchedException -import co.nilin.opex.wallet.core.exc.DepositLimitExceededException -import co.nilin.opex.wallet.core.exc.NotEnoughBalanceException -import co.nilin.opex.wallet.core.exc.WithdrawLimitExceededException import co.nilin.opex.wallet.core.inout.TransferCommand import co.nilin.opex.wallet.core.inout.TransferResult import co.nilin.opex.wallet.core.inout.TransferResultDetailed import co.nilin.opex.wallet.core.model.* import co.nilin.opex.wallet.core.spi.* -import org.slf4j.LoggerFactory import org.springframework.stereotype.Component import org.springframework.transaction.annotation.Transactional import java.time.LocalDateTime @@ -191,6 +186,126 @@ class TransferManagerImpl( userTransactionManager.save(tx) } + TransferCategory.KYC_ACCEPTED_REWARD -> { + val loserOwner = command.sourceWallet.owner.id!! + val loserMainWallet = command.sourceWallet + val loserBalance = loserMainWallet.balance.amount + + val gainerOwner = command.destWallet.owner.id!! + val gainerMainWallet = command.destWallet + val gainerBalance = gainerMainWallet.balance.amount + + val loserTx = UserTransaction( + loserOwner, + txId, + currency, + loserBalance - amount, + -amount, + UserTransactionCategory.KYC_ACCEPTED_REWARD + ) + userTransactionManager.save(loserTx) + + val gainerTx = UserTransaction( + gainerOwner, + txId, + currency, + gainerBalance + amount, + amount, + UserTransactionCategory.KYC_ACCEPTED_REWARD, + ) + userTransactionManager.save(gainerTx) + } + + TransferCategory.REFERRAL_COMMISSION -> { + val loserOwner = command.sourceWallet.owner.id!! + val loserMainWallet = command.sourceWallet + val loserBalance = loserMainWallet.balance.amount + + val gainerOwner = command.destWallet.owner.id!! + val gainerMainWallet = command.destWallet + val gainerBalance = gainerMainWallet.balance.amount + + val loserTx = UserTransaction( + loserOwner, + txId, + currency, + loserBalance - amount, + -amount, + UserTransactionCategory.REFERRAL_COMMISSION + ) + userTransactionManager.save(loserTx) + + val gainerTx = UserTransaction( + gainerOwner, + txId, + currency, + gainerBalance + amount, + amount, + UserTransactionCategory.REFERRAL_COMMISSION, + ) + userTransactionManager.save(gainerTx) + } + + TransferCategory.REFERENT_COMMISSION -> { + val loserOwner = command.sourceWallet.owner.id!! + val loserMainWallet = command.sourceWallet + val loserBalance = loserMainWallet.balance.amount + + val gainerOwner = command.destWallet.owner.id!! + val gainerMainWallet = command.destWallet + val gainerBalance = gainerMainWallet.balance.amount + + val loserTx = UserTransaction( + loserOwner, + txId, + currency, + loserBalance - amount, + -amount, + UserTransactionCategory.REFERENT_COMMISSION + ) + userTransactionManager.save(loserTx) + + val gainerTx = UserTransaction( + gainerOwner, + txId, + currency, + gainerBalance + amount, + amount, + UserTransactionCategory.REFERENT_COMMISSION, + ) + userTransactionManager.save(gainerTx) + } + + TransferCategory.REFERRAL_KYC_REWARD -> { + val loserOwner = command.sourceWallet.owner.id!! + val loserMainWallet = command.sourceWallet + val loserBalance = loserMainWallet.balance.amount + + val gainerOwner = command.destWallet.owner.id!! + val gainerMainWallet = command.destWallet + val gainerBalance = gainerMainWallet.balance.amount + + val loserTx = UserTransaction( + loserOwner, + txId, + currency, + loserBalance - amount, + -amount, + UserTransactionCategory.REFERRAL_KYC_REWARD + ) + userTransactionManager.save(loserTx) + + val gainerTx = UserTransaction( + gainerOwner, + txId, + currency, + gainerBalance + amount, + amount, + UserTransactionCategory.REFERRAL_KYC_REWARD, + ) + userTransactionManager.save(gainerTx) + } + else -> { // No tx needed for other types } From 08274a3c4a8af4523e8fd15fe75e8a774edffc36 Mon Sep 17 00:00:00 2001 From: Amir Rajabi <34955519+AmirRajabii@users.noreply.github.com> Date: Wed, 15 Jan 2025 13:01:42 +0330 Subject: [PATCH 03/51] SVG Chart of Price Trend (#498) --- market/market-app/pom.xml | 10 +++ .../market/app/controller/ChartController.kt | 32 ++++++++++ .../market/app/data/SparkLineDataResponse.kt | 7 +++ .../opex/market/app/utils/ChartBuilder.kt | 62 +++++++++++++++++++ .../nilin/opex/market/core/inout/PriceTime.kt | 9 +++ .../market/core/spi/MarketQueryHandler.kt | 15 +++-- .../ports/postgres/dao/TradeRepository.kt | 37 +++++++++-- .../postgres/impl/MarketQueryHandlerImpl.kt | 57 ++++++++++++++++- .../ports/postgres/model/PriceTimeData.kt | 9 +++ 9 files changed, 225 insertions(+), 13 deletions(-) create mode 100644 market/market-app/src/main/kotlin/co/nilin/opex/market/app/data/SparkLineDataResponse.kt create mode 100644 market/market-app/src/main/kotlin/co/nilin/opex/market/app/utils/ChartBuilder.kt create mode 100644 market/market-core/src/main/kotlin/co/nilin/opex/market/core/inout/PriceTime.kt create mode 100644 market/market-ports/market-persister-postgres/src/main/kotlin/co/nilin/opex/market/ports/postgres/model/PriceTimeData.kt diff --git a/market/market-app/pom.xml b/market/market-app/pom.xml index 37d7e0e47..200e0a55d 100644 --- a/market/market-app/pom.xml +++ b/market/market-app/pom.xml @@ -93,6 +93,16 @@ micrometer-registry-prometheus runtime + + org.jfree + jfreechart + 1.5.3 + + + org.jfree + jfreesvg + 3.4.3 + diff --git a/market/market-app/src/main/kotlin/co/nilin/opex/market/app/controller/ChartController.kt b/market/market-app/src/main/kotlin/co/nilin/opex/market/app/controller/ChartController.kt index 88cd3f2dc..2d616feb7 100644 --- a/market/market-app/src/main/kotlin/co/nilin/opex/market/app/controller/ChartController.kt +++ b/market/market-app/src/main/kotlin/co/nilin/opex/market/app/controller/ChartController.kt @@ -1,13 +1,29 @@ package co.nilin.opex.market.app.controller +import co.nilin.opex.market.app.data.SparkLineDataResponse import co.nilin.opex.market.core.inout.CandleData +import co.nilin.opex.market.core.inout.PriceTime import co.nilin.opex.market.core.spi.MarketQueryHandler +import createLineChart import org.springframework.web.bind.annotation.* +import java.math.BigDecimal + @RestController @RequestMapping("/v1/chart") class ChartController(private val marketQueryHandler: MarketQueryHandler) { + enum class Period { + DAILY, + WEEKLY, + MONTHLY + } + + data class SparkLineRequest( + val symbols: List, + val period: Period + ) + @GetMapping("/{symbol}/candle") suspend fun getCandleDataForSymbol( @PathVariable symbol: String, @@ -19,4 +35,20 @@ class ChartController(private val marketQueryHandler: MarketQueryHandler) { return marketQueryHandler.getCandleInfo(symbol, interval, since, until, limit) } + @GetMapping("/spark-line") + suspend fun getSparkLineForSymbols( + @RequestBody request: SparkLineRequest + ): List { + return request.symbols.mapNotNull { symbol -> + val priceData: List = when (request.period) { + Period.WEEKLY -> marketQueryHandler.getWeeklyPriceData(symbol) + Period.MONTHLY -> marketQueryHandler.getMonthlyPriceData(symbol) + Period.DAILY -> marketQueryHandler.getDailyPriceData(symbol) + } + if (priceData.all { it.closePrice == BigDecimal.ZERO }) return@mapNotNull null + val isTrendUp = priceData.last().closePrice >= priceData.first().closePrice + val svgData = createLineChart(priceData.map { it.closePrice }, priceData.map { it.closeTime }) + SparkLineDataResponse(symbol, isTrendUp, svgData) + } + } } \ No newline at end of file diff --git a/market/market-app/src/main/kotlin/co/nilin/opex/market/app/data/SparkLineDataResponse.kt b/market/market-app/src/main/kotlin/co/nilin/opex/market/app/data/SparkLineDataResponse.kt new file mode 100644 index 000000000..3a54ad1b5 --- /dev/null +++ b/market/market-app/src/main/kotlin/co/nilin/opex/market/app/data/SparkLineDataResponse.kt @@ -0,0 +1,7 @@ +package co.nilin.opex.market.app.data + +data class SparkLineDataResponse( + val symbol: String, + val isTrendUp: Boolean, + val svgData: String +) diff --git a/market/market-app/src/main/kotlin/co/nilin/opex/market/app/utils/ChartBuilder.kt b/market/market-app/src/main/kotlin/co/nilin/opex/market/app/utils/ChartBuilder.kt new file mode 100644 index 000000000..b23f23834 --- /dev/null +++ b/market/market-app/src/main/kotlin/co/nilin/opex/market/app/utils/ChartBuilder.kt @@ -0,0 +1,62 @@ +import org.jfree.chart.ChartFactory +import org.jfree.chart.JFreeChart +import org.jfree.chart.plot.PlotOrientation +import org.jfree.chart.plot.XYPlot +import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer +import org.jfree.data.xy.XYSeries +import org.jfree.data.xy.XYSeriesCollection +import org.jfree.graphics2d.svg.SVGGraphics2D +import java.awt.Rectangle +import java.math.BigDecimal +import java.time.LocalDateTime +import java.util.Base64 + +fun createLineChart(prices: List, times: List): String { + val series = XYSeries("Price").apply { + prices.zip(times).forEach { (price, time) -> + add(time.atZone(java.time.ZoneId.systemDefault()).toInstant().toEpochMilli(), price.toDouble()) + } + } + val dataset = XYSeriesCollection().apply { + addSeries(series) + } + val chart = ChartFactory.createXYLineChart( + null, // Chart title + null, // X-axis label + null, // Y-axis label + dataset, // Data + PlotOrientation.VERTICAL, + false, + false, + false + ) + val plot: XYPlot = chart.xyPlot + val renderer = XYLineAndShapeRenderer(true, false) + // Set chart color + renderer.setSeriesPaint(0, java.awt.Color.WHITE) + // Set axis ranges to keep the chart logical + plot.rangeAxis.range = org.jfree.data.Range( + prices.minOrNull()?.toDouble()?.times(0.99) ?: 0.0, + prices.maxOrNull()?.toDouble() ?: 0.0 + ) + // Remove gridlines, axis, and background + plot.renderer = renderer + plot.isDomainGridlinesVisible = false + plot.isRangeGridlinesVisible = false + plot.backgroundPaint = null + plot.domainAxis.isVisible = false + plot.rangeAxis.isVisible = false + plot.isOutlineVisible = false + chart.backgroundPaint = null + + return chartToSvgString(chart, 100, 35) +} + +fun chartToSvgString(chart: JFreeChart, width: Int, height: Int): String { + val svg = SVGGraphics2D(width, height) + chart.draw(svg, Rectangle(width, height)) + val svgString = svg.svgElement + svg.dispose() + val base64SvgString = Base64.getEncoder().encodeToString(svgString.toByteArray(Charsets.UTF_8)) + return base64SvgString +} diff --git a/market/market-core/src/main/kotlin/co/nilin/opex/market/core/inout/PriceTime.kt b/market/market-core/src/main/kotlin/co/nilin/opex/market/core/inout/PriceTime.kt new file mode 100644 index 000000000..8df9109fc --- /dev/null +++ b/market/market-core/src/main/kotlin/co/nilin/opex/market/core/inout/PriceTime.kt @@ -0,0 +1,9 @@ +package co.nilin.opex.market.core.inout + +import java.math.BigDecimal +import java.time.LocalDateTime + +data class PriceTime( + val closeTime: LocalDateTime, + val closePrice: BigDecimal, +) diff --git a/market/market-core/src/main/kotlin/co/nilin/opex/market/core/spi/MarketQueryHandler.kt b/market/market-core/src/main/kotlin/co/nilin/opex/market/core/spi/MarketQueryHandler.kt index 37e644c6c..77a9bcfab 100644 --- a/market/market-core/src/main/kotlin/co/nilin/opex/market/core/spi/MarketQueryHandler.kt +++ b/market/market-core/src/main/kotlin/co/nilin/opex/market/core/spi/MarketQueryHandler.kt @@ -2,7 +2,6 @@ package co.nilin.opex.market.core.spi import co.nilin.opex.common.utils.Interval import co.nilin.opex.market.core.inout.* -import java.time.LocalDateTime interface MarketQueryHandler { @@ -23,11 +22,11 @@ interface MarketQueryHandler { suspend fun getBestPriceForSymbols(symbols: List): List suspend fun getCandleInfo( - symbol: String, - interval: String, - startTime: Long?, - endTime: Long?, - limit: Int + symbol: String, + interval: String, + startTime: Long?, + endTime: Long?, + limit: Int ): List suspend fun numberOfActiveUsers(interval: Interval): Long @@ -44,5 +43,9 @@ interface MarketQueryHandler { suspend fun mostTrades(interval: Interval): TradeVolumeStat? + suspend fun getWeeklyPriceData(symbol: String): List + suspend fun getMonthlyPriceData(symbol: String): List + + suspend fun getDailyPriceData(symbol: String): List } \ 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 1277cf431..801df16cd 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 @@ -4,12 +4,8 @@ import co.nilin.opex.market.core.inout.BestPrice import co.nilin.opex.market.core.inout.PriceStat import co.nilin.opex.market.core.inout.TradeVolumeStat import co.nilin.opex.market.core.inout.Transaction -import co.nilin.opex.market.ports.postgres.model.CandleInfoData -import co.nilin.opex.market.ports.postgres.model.LastPrice -import co.nilin.opex.market.ports.postgres.model.TradeModel -import co.nilin.opex.market.ports.postgres.model.TradeTickerData +import co.nilin.opex.market.ports.postgres.model.* import kotlinx.coroutines.flow.Flow -import org.springframework.data.domain.Pageable import org.springframework.data.r2dbc.repository.Query import org.springframework.data.repository.query.Param import org.springframework.data.repository.reactive.ReactiveCrudRepository @@ -463,5 +459,34 @@ interface TradeRepository : ReactiveCrudRepository { fun findTxOfTradesDesc(user: String, startDate: LocalDateTime?, endDate: LocalDateTime?, offset: Int?, limit: Int?): Flux - + @Query( + """ + WITH intervals AS (SELECT * FROM interval_generator((:startTime), (:endTime), :interval ::INTERVAL)), + last_trade AS ( + SELECT DISTINCT ON (f.start_time) f.start_time, f.end_time, t.matched_price AS close_price FROM intervals f + LEFT JOIN trades t ON t.create_date >= f.start_time AND t.create_date < f.end_time AND t.symbol = :symbol + ORDER BY f.start_time, t.create_date DESC + ) + SELECT + i.end_time AS close_time, + lt.close_price AS close_price + FROM intervals i + LEFT JOIN trades t + ON t.create_date >= i.start_time AND t.create_date < i.end_time AND t.symbol = :symbol + LEFT JOIN last_trade lt + ON i.start_time = lt.start_time + GROUP BY i.start_time, i.end_time, lt.close_price + ORDER BY i.start_time; + """ + ) + suspend fun getPriceTimeData( + @Param("symbol") + symbol: String, + @Param("interval") + interval: String, + @Param("startTime") + startTime: LocalDateTime, + @Param("endTime") + endTime: LocalDateTime, + ): Flux } \ 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/MarketQueryHandlerImpl.kt b/market/market-ports/market-persister-postgres/src/main/kotlin/co/nilin/opex/market/ports/postgres/impl/MarketQueryHandlerImpl.kt index 477a4d770..42ef36888 100644 --- a/market/market-ports/market-persister-postgres/src/main/kotlin/co/nilin/opex/market/ports/postgres/impl/MarketQueryHandlerImpl.kt +++ b/market/market-ports/market-persister-postgres/src/main/kotlin/co/nilin/opex/market/ports/postgres/impl/MarketQueryHandlerImpl.kt @@ -19,7 +19,6 @@ import kotlinx.coroutines.reactive.awaitFirstOrElse import kotlinx.coroutines.reactive.awaitFirstOrNull import kotlinx.coroutines.reactor.awaitSingleOrNull import org.springframework.stereotype.Component -import java.lang.StringBuilder import java.math.BigDecimal import java.time.Instant import java.time.LocalDateTime @@ -238,6 +237,62 @@ class MarketQueryHandlerImpl( tradeRepository.findByMostTrades(interval.getLocalDateTime()).awaitSingleOrNull() } } + override suspend fun getWeeklyPriceData(symbol: String): List { + return getPriceDataWithCache( + symbol = symbol, + cacheKeyPrefix = "weeklyPriceData", + interval = "4h", + fromDate = LocalDateTime.now().minusDays(7) + ) + } + + override suspend fun getMonthlyPriceData(symbol: String): List { + return getPriceDataWithCache( + symbol = symbol, + cacheKeyPrefix = "monthlyPriceData", + interval = "24h", + fromDate = LocalDateTime.now().minusDays(30) + ) + } + + override suspend fun getDailyPriceData(symbol: String): List { + return getPriceDataWithCache( + symbol = symbol, + cacheKeyPrefix = "dailyPriceData", + interval = "1h", + fromDate = LocalDateTime.now().minusDays(1) + ) + } + private suspend fun getPriceDataWithCache( + symbol: String, + cacheKeyPrefix: String, + interval: String, + fromDate: LocalDateTime + ): List { + val cacheKey = "${cacheKeyPrefix}:${symbol.lowercase()}" + val cachedData = redisCacheHelper.getList(cacheKey) + if (!cachedData.isNullOrEmpty()) { + return cachedData.toList() + } + + return tradeRepository.getPriceTimeData(symbol, interval, fromDate, LocalDateTime.now()) + .collectList() + .awaitFirstOrElse { emptyList() } + .let { priceTimes -> + var lastNonNullPrice: BigDecimal? = null + val firstNonNullPrice = priceTimes.firstOrNull { it.closePrice != null }?.closePrice ?: BigDecimal.ZERO + priceTimes.map { item -> + val price = item.closePrice ?: lastNonNullPrice ?: firstNonNullPrice + lastNonNullPrice = price + PriceTime( + item.closeTime, + price + ) + } + .onEach { redisCacheHelper.putListItem(cacheKey, it) } + .also { redisCacheHelper.setExpiration(cacheKey, 1.hours()) } + } + } private fun TradeTickerData.asPriceChangeResponse(openTime: Long, closeTime: Long) = PriceChange( symbol, diff --git a/market/market-ports/market-persister-postgres/src/main/kotlin/co/nilin/opex/market/ports/postgres/model/PriceTimeData.kt b/market/market-ports/market-persister-postgres/src/main/kotlin/co/nilin/opex/market/ports/postgres/model/PriceTimeData.kt new file mode 100644 index 000000000..875e3d76e --- /dev/null +++ b/market/market-ports/market-persister-postgres/src/main/kotlin/co/nilin/opex/market/ports/postgres/model/PriceTimeData.kt @@ -0,0 +1,9 @@ +package co.nilin.opex.market.ports.postgres.model + +import java.math.BigDecimal +import java.time.LocalDateTime + +data class PriceTimeData( + val closeTime: LocalDateTime, + val closePrice: BigDecimal?, +) \ No newline at end of file From 5dffd9ec477c4622e5317ed14de0c3b01dbdf6c0 Mon Sep 17 00:00:00 2001 From: Peyman Date: Sat, 25 Jan 2025 13:27:59 +0330 Subject: [PATCH 04/51] Merge OTC changes to dev (#501) * refactor currency services m1 ( apply deposit/withdraw methods for different types of currency) * refactor currency services m2 (create/ update currency service base on requirements) * refactor currency services m3 * - * Encapsulating various operations related to currency as much as possible * Add cryptoCurrency services (CryptoCurrencies have imps in addition of other currency informations) * start refactoring cryptoCurrency data models * start refactoring assign address algth * develop/change tests to cover new data models * . * sync * change strategy in fetching currencies * Try to modify the fk relations of the tables based on the new currency model. * try to pass diferent tests * change otc services base on new currency model * change primary field in currency model :((((((((( * change primary field in currency model :((((((((( * start developing crypto currency * - * - * complete crypto currency services (remove currency table from bc-gateway) * connect currency <-> cryptocurrency) * Complete connections: currency <-> cryptocurrency and Develop managing document services for external data of assets * Update security config * Comment 2 tests * set default value for some filds of impl * create system wallet for new currencies * Create wallet for system when creating new currency * Create wallet for system when creating new currency * - * change in assign address logic * change in test of assigning address * change life time in assigning address * change life time in assigning address * change life time in assigning address * change life time in assigning address * change in revoking address's scedule time * Have some temproray logic to hande gap between dev and otc branch * have some log to debug wallet sync process * have log to debug * have log to debug * Fetch all impls in single request and postprocess response base on each symbol * - * - * wallet's stat * fix conflict * remove omni-wallet-url temporary * add applicator to withdraw review * change in withdraws schema * add withdrawMin to currency Obj * add withdrawMin to currency Obj * Fix bug in updating currency * Fix bug in updating currency * - * - * Handle error in fetching balance of assets * Handle error in fetching balance of assets * Set log to debug * Set log to debug * Set log to debug * Set log to debug * change docker gateway ip address * change omni-wallet baseurl * change omni-wallet baseurl * Develop manual withdraw * Develop manual withdraw * Save sourceWalletId in manual withdraw * Fix bug in fetching withdraws * Fix bug in fetching withdraws * Add ascendingByTime field in Geting withdraw * Check amount validation in reserve a swap * Change securityConfig in getting chains * Change in fetching chins service * Develop custom message translation in error handling * Change security config in manual deposit * Change security config in manual deposit * Add extra-host to wallet service configuration * Add extra-host to otc services configuration * Disable security config for actuator endpoints * Calculate buy and sell price for each currency (#465) * Refactor history services (#473) * Remove pulling dev branch in otc workflow (#462) * Remove pulling dev branch in otc workflow * Remove pulling dev branch in otc workflow * Upgrade error-hanlder.version * Replace user_transctions with transactions for external use (#463) * Remove details from fiActions in wallet and accountant * Use enum for withdraw status * Use enum for more hardcoded variables * Use enum for transfer category * Modify database * Add try catch in wallet BackupService * FinancialActionJobKafka TBC * Adding rest services * Add admin tx for DEPOSIT_MANUALLY * Remove balance_before * Change fi_actions transfer ref to use uuid * Fix test failure * Fix type mismatch error * Make one test function suspended * Fix quote asset not included in estimated value * Edit schema Transaction refactor completed * Replace docker-compose with docker compose in workflows * Start to handle different type of gateways for currencies * Implement requred services for all type of gateways * Complete create new gateway service * Complete gateway services * Fix bug of currency creation * Fix bug of currency creation * Fix bug of currency creation * Refactor withdraw services (#464) * Start refactoring withdraw * Remove applied_fee Refactor withdraw service * Delete deprecated services * Add fee service * Fix amount mismatch * Fix user transaction service * Change getUserTransactions http method * - * Fix dependency bug * Fix schema.sql for old DB version * Set scale for Division Calculations * Set withdraw/deposit allowed field in a currency object using detail of it's gateways * Set withdraw/deposit allowed field in a currency object using detail of it's gateways * Clean up deposit withdraw services (#466) * Simplified deposit services * Clean up withdraw services * Fix quote asset not considered in total assets * Add docker compose instead of docker-compose in actions scripts * try to merge * add availableGatewayType to currency object * docker-compose -> docker compose (#471) * docker-compose -> docker compose * rm prefrences config from otc profile * Rm isCryptoCurrency field from currency class * Rm isCryptoCurrency field from currency class * Try to debug wrong value in availableGatewayType * Try to debug wrong value in availableGatewayType * Try to debug wrong value in availableGatewayType * Solve bug in having wrong value for availableGatewayType * Try to solve diffrent merge conflicts * Try to solve diffrent merge conflicts * Try to solve diffrent merge conflicts * Try to solve diffrent merge conflicts * Try to solve diffrent merge conflicts * Replace main with MAIN in wallet proxy * Try to solve diffrent merge conflicts * Try to solve diffrent merge conflicts * Try to solve diffrent merge conflicts * Try to solve diffrent merge conflicts * Set default value for advanced transfer * Transfer ref is not nullable field * Set default value for wallet type in advanced transfer * Set default value for wallet type in advanced transfer * Add swap category to user transactions history * Support get transactions history by admin * Fix change in balance calculation for swap category * sync * Add last update date and applicator to withdraw model * Add last update date and applicator to withdraw model * Handle off-chain withdraw request * Handle off-chain withdraw request * Handle off-chain withdraw request * Handle off-chain withdraw request * Handle off-chain withdraw request * Set default message in error handling process * refactor deposit's endpoints * Fetch seaps history for user and admin * Develop services to get history for transfer-based actions for trusted users and admins * Fix ithdrw search query * Fix withdrow search query * Fix withdrow search query * Fix withdrow search query * Fix withdrow search query * Fix deposit search param * Change swap history services * Fix query of swap history * Fix query of swap history * Fix query of swap history * Fix query of swap history * Fix query of swap history * Fix query of swap history * Fix query of swap history * Change in swap hitory detail * - * - * - * - * Alter table -> - * - * Fix a calculation issue in swap history * Consider attachment field for withdraw/deposit actions --------- Co-authored-by: Peyman Co-authored-by: Peyman * Manage of out of bounds deposits (#475) * management invalid deposits * Fix typo in naming a requestParam * Fix typo in naming a requestParam * Change rules in deposit validation * Change logic of handling invalid deposits * Change logic of handling invalid deposits * Change logic of handling invalid deposits * Change logic of handling invalid deposits * Change logic of handling invalid deposits * Change logic of handling invalid withdraws * Change in transfer response to return tx.id * Manage admin's bank data to assign off-chain gateways (#474) * Search by status in deposit history * Search by status in deposit history * sync * Fix merge conflicts * Reformating code * Change in naming payment currency * Record IPG deposits * Withdraw from otc to opex (#480) * New TransferMethod Added. * Update InitializeService * Rename BankData to Terminal. * change in schema.sql and method names * Update schema.sql * Refactor bankData to terminal concept * Rename dest_networks in withdraw requests * Change the schema to prevent creation of expired tables * Change the schema to prevent creation of expired tables * Change the schema to prevent creation of expired tables * Change the order of recording deposits and actual deposits * Change default value for status in deposit service * - * - * - * Add webhook controller * Update security config in opex * Add new workflow for test env * Change name of test workflow * Merge with otc branch * Set profile for extract token class * reset profile on auth class and change auth data in exchange profile * reset profile on auth class and change auth data in exchange profile * Set expire time for assigned addresses * Set expire time for assigned addresses * Comment initialized cammand in wallet module * reset security filter for can_withdraw service * reset security filter for can_withdraw service * Remove currencyInfo service from ipg module * reset security filter for /v2/transfer service * Finish scanner webhook service * Fix merger conflict * Fix import --------- Co-authored-by: fatemeh imanipour Co-authored-by: Fatemeh imani <46007372+fatemeh-i@users.noreply.github.com> Co-authored-by: Amir Rajabi <34955519+AmirRajabii@users.noreply.github.com> --- .github/ISSUE_TEMPLATE/bug_report.md | 17 +- .github/workflows/dev-otc.yml | 10 +- .github/workflows/dev.yml | 2 +- .github/workflows/main-otc.yml | 10 +- .github/workflows/main.yml | 2 +- .github/workflows/pr.yml | 2 +- .github/workflows/test.yml | 7 +- accountant/accountant-app/pom.xml | 2 +- .../opex/accountant/app/AccountantApp.kt | 1 - .../opex/accountant/app/config/AppConfig.kt | 11 +- .../accountant/app/data/PairFeeResponse.kt | 2 +- .../app/listener/KycLevelUpdatedListener.kt | 10 +- .../src/test/resources/application.yml | 2 +- accountant/accountant-core/pom.xml | 2 +- .../service/FinancialActionJobManagerImpl.kt | 4 +- .../accountant/core/spi/UserLevelLoader.kt | 2 +- .../accountant-eventlistener-kafka/pom.xml | 2 +- .../kafka/listener/inout/OrderRequestEvent.kt | 2 +- .../accountant-persister-postgres/pom.xml | 2 +- .../postgres/dao/FinancialActionRepository.kt | 6 +- .../impl/FinancialActionPersisterImpl.kt | 1 - .../postgres/impl/TempEventPersisterImpl.kt | 1 - .../postgres/impl/UserLevelLoaderImpl.kt | 29 +- .../postgres/model/FinancialActionModel.kt | 1 - .../postgres/model/UserLevelMapperModel.kt | 6 +- .../src/main/resources/schema.sql | 325 ++++++++++---- .../accountant-submitter-kafka/pom.xml | 2 +- .../accountant-wallet-proxy/pom.xml | 2 +- .../walletproxy/config/WebClientConfig.kt | 1 - accountant/pom.xml | 2 +- .../kotlin/co/nilin/opex/api/app/ApiApp.kt | 2 - .../api/app/controller/APIKeyController.kt | 9 +- .../nilin/opex/api/app/data/APIKeyResponse.kt | 1 - .../opex/api/app/service/APIKeyServiceImpl.kt | 1 - .../api/core/spi/BlockchainGatewayProxy.kt | 3 +- .../opex/api/core/spi/MarketDataProxy.kt | 1 - .../co/nilin/opex/api/core/spi/WalletProxy.kt | 32 +- .../ports/binance/config/WebClientConfig.kt | 1 - .../binance/controller/MarketController.kt | 44 +- .../binance/controller/WalletController.kt | 7 +- .../ports/binance/data/NewOrderResponse.kt | 1 - .../api/ports/binance/data/WithDrawRequest.kt | 23 +- .../api/ports/opex/config/WebClientConfig.kt | 1 - .../opex/controller/AccountController.kt | 7 +- .../api/ports/postgres/model/APIKeyModel.kt | 2 +- .../src/main/resources/schema.sql | 67 ++- .../api/ports/postgres/impl/sample/Samples.kt | 3 - .../ports/proxy/data/TransactionRequest.kt | 12 +- .../proxy/impl/BlockchainGatewayProxyImpl.kt | 28 +- bc-gateway/bc-gateway-app/pom.xml | 6 +- .../opex/bcgateway/app/config/AppConfig.kt | 35 +- .../opex/bcgateway/app/config/ErrorConfig.kt | 30 ++ .../bcgateway/app/config/InitializeService.kt | 29 +- .../bcgateway/app/config/SecurityConfig.kt | 68 +-- .../bcgateway/app/config/WebClientConfig.kt | 6 +- .../app/controller/AddressController.kt | 8 +- .../app/controller/AdminController.kt | 105 ++--- .../controller/CryptoCurrencyController.kt | 79 ++++ .../app/controller/CurrencyController.kt | 86 ---- .../app/controller/OmniBCWalletController.kt | 23 + .../app/controller/ScannerController.kt | 71 +++ .../bcgateway/app/dto/AddCurrencyRequest.kt | 24 +- .../opex/bcgateway/app/dto/TokenResponse.kt | 3 +- .../app/listener/AdminEventListenerImpl.kt | 11 +- .../app/service/AddressAllocatorJob.kt | 9 +- .../bcgateway/app/service/AdminService.kt | 68 ++- .../app/service/OmniBalanceService.kt | 58 +++ .../opex/bcgateway/app/utils/Extensions.kt | 10 +- .../src/main/resources/application-otc.yml | 5 +- .../src/main/resources/application.yml | 7 +- .../src/main/resources/scanner-public.pem | 9 + bc-gateway/bc-gateway-core/pom.xml | 2 +- .../core/api/AssignAddressService.kt | 5 +- .../bcgateway/core/api/WalletSyncService.kt | 4 + .../bcgateway/core/model/AssignedAddress.kt | 2 +- .../bcgateway/core/model/AssignedAddressV2.kt | 32 ++ .../core/model/CryptoCurrencyCommand.kt | 37 ++ .../opex/bcgateway/core/model/Currency.kt | 6 +- .../core/model/CurrencyImplementation.kt | 10 +- .../opex/bcgateway/core/model/CurrencyInfo.kt | 2 +- .../opex/bcgateway/core/model/Deposit.kt | 19 +- .../bcgateway/core/model/FetchGateways.kt | 8 + .../opex/bcgateway/core/model/OmniBalance.kt | 6 + .../opex/bcgateway/core/model/Transfer.kt | 1 - .../bcgateway/core/model/otc/LoginRequest.kt | 2 +- .../bcgateway/core/model/otc/LoginResponse.kt | 10 +- .../core/service/AssignAddressServiceImpl.kt | 68 +-- .../service/AssignAddressServiceImplV2.kt | 69 +++ .../core/service/WalletSyncServiceImpl.kt | 54 ++- .../core/spi/AssignedAddressHandler.kt | 1 - .../opex/bcgateway/core/spi/AuthProxy.kt | 5 +- .../opex/bcgateway/core/spi/ChainLoader.kt | 4 +- .../core/spi/CryptoCurrencyHandlerV2.kt | 29 ++ .../bcgateway/core/spi/CurrencyHandler.kt | 74 ---- .../opex/bcgateway/core/spi/DepositHandler.kt | 4 +- .../bcgateway/core/spi/OmniWalletManager.kt | 11 + .../opex/bcgateway/core/spi/WalletProxy.kt | 9 +- .../AssignAddressServiceImplUnitTest.kt | 65 ++- .../bc-gateway-auth-proxy/pom.xml | 4 +- .../ports/authproxy/impl/AuthProxyImpl.kt | 19 +- .../bc-gateway-eventlistener-kafka/pom.xml | 2 +- .../bc-gateway-omniwallet-proxy/pom.xml | 48 ++ .../omniwallet/impl/OmniWalletManagerImpl.kt | 31 ++ .../omniwallet/model/AddressBalanceWithUsd.kt | 8 + .../omniwallet/proxy/OmniWalletProxy.kt | 69 +++ .../bc-gateway-persister-postgres/pom.xml | 7 +- .../postgres/dao/AssignedAddressRepository.kt | 15 +- .../dao/CurrencyImplementationRepository.kt | 40 +- .../ports/postgres/dao/CurrencyRepository.kt | 28 +- .../ports/postgres/impl/AddressManagerImpl.kt | 11 +- .../impl/AssignedAddressHandlerImpl.kt | 97 ++-- .../ports/postgres/impl/ChainHandler.kt | 2 +- .../postgres/impl/CurrencyHandlerImpl.kt | 246 ----------- .../postgres/impl/CurrencyHandlerImplV2.kt | 121 +++++ .../ports/postgres/impl/DepositHandlerImpl.kt | 21 +- .../postgres/model/AssignedAddressModel.kt | 20 +- .../model/CurrencyImplementationModel.kt | 22 - .../model/CurrencyOnChainGatewayModel.kt | 33 ++ .../ports/postgres/model/DepositModel.kt | 1 - .../model/NewCurrencyImplementationModel.kt | 28 ++ .../ports/postgres/util/convertor.kt | 50 +++ .../src/main/resources/schema.sql | 80 ++-- .../bc-gateway-wallet-proxy/pom.xml | 4 +- .../walletproxy/impl/ExtractBackgroundAuth.kt | 4 - .../ports/walletproxy/impl/WalletProxyImpl.kt | 47 +- bc-gateway/pom.xml | 8 +- common/pom.xml | 4 +- .../kotlin/co/nilin/opex/common/OpexError.kt | 9 + .../common/utils/CustomErrorTranslator.kt | 22 + .../src/main/resources/messages_en.properties | 76 ++++ .../src/main/resources/messages_fa.properties | 78 ++++ docker-compose-otc.yml | 28 +- docker-images/kafka/kafka-jmx-exporter.yml | 6 +- docker-images/vault/workflow-vault.sh | 1 + eventlog/eventlog-app/pom.xml | 2 +- .../app/listeners/DeadLetterListener.kt | 41 +- .../src/main/resources/application.yml | 4 +- eventlog/eventlog-core/pom.xml | 2 +- .../eventlog-eventlistener-kafka/pom.xml | 2 +- .../listener/consumer/DLTKafkaListener.kt | 10 +- .../kafka/listener/inout/OrderRequestEvent.kt | 2 +- .../eventlog-persister-postgres/pom.xml | 2 +- .../src/main/resources/schema.sql | 234 +++++++--- eventlog/pom.xml | 2 +- .../opex/market/app/MarketAppApplication.kt | 2 +- .../market/app/config/InitializeService.kt | 3 - .../opex/market/app/config/WebClientConfig.kt | 2 - .../app/controller/MarketStatsController.kt | 5 - .../app/controller/UserDataController.kt | 6 +- .../market/app/service/ReportingService.kt | 2 - .../app/utils/PrometheusHealthExtension.kt | 1 - .../opex/market/core/inout/Transaction.kt | 18 +- .../market/core/inout/TransactionRequest.kt | 16 +- .../market/core/inout/TransactionResponse.kt | 21 +- .../opex/market/core/spi/UserQueryHandler.kt | 1 - .../ports/postgres/dao/TradeRepository.kt | 109 +++-- .../postgres/impl/UserQueryHandlerImpl.kt | 118 ++--- .../ports/postgres/model/CandleInfoData.kt | 1 - .../market/ports/postgres/model/LastPrice.kt | 2 +- .../market/ports/postgres/model/TradeModel.kt | 1 - .../market/ports/postgres/util/Convertor.kt | 23 +- .../src/main/resources/schema.sql | 240 +++++++--- .../postgres/impl/MarketQueryHandlerTest.kt | 5 +- .../postgres/impl/UserQueryHandlerTest.kt | 2 - .../ports/postgres/impl/sample/Samples.kt | 1 - matching-engine/matching-engine-app/pom.xml | 2 +- .../src/main/resources/application.yml | 2 +- matching-engine/matching-engine-core/pom.xml | 2 +- .../engine/core/inout/OrderRequestEvent.kt | 2 +- .../pom.xml | 2 +- .../kafka/listener/config/OrderKafkaConfig.kt | 1 - .../matching-engine-snapshots-redis/pom.xml | 2 +- .../matching-engine-submitter-kafka/pom.xml | 2 +- .../submitter/config/EventsKafkaConfig.kt | 1 - matching-engine/pom.xml | 2 +- matching-gateway/matching-gateway-app/pom.xml | 2 +- .../gateway/app/config/WebClientConfig.kt | 1 - .../src/main/resources/application.yml | 2 +- .../gateway/app/service/OrderServiceTest.kt | 6 +- .../matching-gateway-submitter-kafka/pom.xml | 2 +- .../submitter/config/OrderKafkaConfig.kt | 1 - .../submitter/inout/OrderRequestEvent.kt | 2 +- matching-gateway/pom.xml | 2 +- pom.xml | 4 +- preferences-demo.yml | 2 +- preferences.yml | 319 ++++++++++++++ user-management/keycloak-gateway/pom.xml | 2 +- .../opex/auth/gateway/KeycloakGatewayApp.kt | 1 - .../gateway/config/EmbeddedKeycloakConfig.kt | 9 +- .../opex/auth/gateway/config/KafkaConfig.kt | 20 +- .../gateway/data/ChangePasswordRequest.kt | 8 +- .../auth/gateway/data/WhiteListAdaptor.kt | 2 +- .../ExtendedEventListenerProvider.kt | 2 +- .../extension/HashicorpVaultProvider.java | 18 +- .../HashicorpVaultProviderFactory.java | 106 +++-- .../extension/UserManagementResource.kt | 1 - .../auth/gateway/extension/VaultService.java | 20 +- .../listener/KycLevelUpdatedListener.kt | 6 +- .../auth/gateway/model/UserCreatedEvent.kt | 1 + .../opex/auth/gateway/model/WhiteListModel.kt | 4 +- .../META-INF/whitelisttt-changelog.xml | 4 +- .../src/main/resources/application.yml | 6 +- .../email-templates/execute-action.html | 77 ++-- .../email-templates/password-reset.html | 80 ++-- .../resources/email-templates/test-smtp.html | 74 ++-- .../email-templates/verify-email.html | 80 ++-- .../src/main/resources/opex-realm.json | 1 - user-management/pom.xml | 2 +- user-management/user-management-core/pom.xml | 2 +- .../auth/core/data/KycLevelUpdatedEvent.kt | 2 +- .../core/spi/KycLevelUpdatedEventListener.kt | 2 +- .../user-management-kafka-listener/pom.xml | 2 +- .../ports/kafka/config/KafkaListenerConfig.kt | 25 +- .../consumer/KycLevelUpdatedKafkaListener.kt | 7 +- wallet/pom.xml | 2 +- wallet/wallet-app/pom.xml | 2 +- .../co/nilin/opex/wallet/app/WalletApp.kt | 2 + .../nilin/opex/wallet/app/config/AppConfig.kt | 8 +- .../opex/wallet/app/config/ErrorConfig.kt | 30 ++ .../wallet/app/config/InitializeService.kt | 49 ++- .../opex/wallet/app/config/SecurityConfig.kt | 34 +- .../opex/wallet/app/config/WebClientConfig.kt | 1 - .../AdvancedTransferAdminController.kt | 64 +++ .../controller/AdvancedTransferController.kt | 61 ++- .../app/controller/BalanceController.kt | 14 +- .../app/controller/CurrencyController.kt | 143 ++++++ .../app/controller/CurrencyRatesController.kt | 46 +- .../app/controller/DepositAdminController.kt | 116 +++++ .../app/controller/DepositController.kt | 65 ++- .../app/controller/InquiryController.kt | 11 +- .../controller/LegacyTransactionController.kt | 2 +- .../controller/PaymentGatewayController.kt | 54 ++- .../app/controller/StorageController.kt | 40 ++ .../controller/TransactionAdminController.kt | 38 ++ .../app/controller/TransactionController.kt | 10 +- .../app/controller/TransferController.kt | 40 +- .../app/controller/WalletStatController.kt | 2 +- .../app/controller/WithdrawAdminController.kt | 82 +++- .../app/controller/WithdrawController.kt | 191 ++++---- .../opex/wallet/app/dto/AddCurrencyRequest.kt | 22 +- .../app/dto/AdminSearchWithdrawRequest.kt | 15 + .../nilin/opex/wallet/app/dto/CurrencyDto.kt | 59 +++ .../opex/wallet/app/dto/CurrencyGatewayDto.kt | 4 + .../opex/wallet/app/dto/DepositResponse.kt | 3 +- .../opex/wallet/app/dto/DocumentResponse.kt | 3 + .../wallet/app/dto/ManualTransferRequest.kt | 8 +- .../opex/wallet/app/dto/PaymentCurrency.kt | 2 +- .../wallet/app/dto/RequestWithdrawBody.kt | 5 +- .../app/dto/ReservedTransferResponse.kt | 20 +- .../app/dto/SetCurrencyExchangeRateRequest.kt | 3 +- .../wallet/app/dto/TransferReserveRequest.kt | 3 - .../wallet/app/dto/UserTransactionRequest.kt | 7 +- .../app/listener/AdminEventListenerImpl.kt | 20 +- .../opex/wallet/app/service/BackupService.kt | 4 +- .../wallet/app/service/BankDataService.kt | 7 + .../wallet/app/service/CurrencyServiceV2.kt | 152 +++++++ .../opex/wallet/app/service/DepositService.kt | 246 +++++++++++ .../wallet/app/service/DocumentService.kt | 51 +++ .../app/service/ManualWithdrawService.kt | 95 ++++ .../wallet/app/service/TraceDepositService.kt | 19 + .../wallet/app/service/TransferService.kt | 243 ++-------- .../app/service/UserRegistrationService.kt | 13 +- .../wallet/app/service/otc/CurrencyService.kt | 126 ------ .../wallet/app/service/otc/GraphService.kt | 415 ++++-------------- .../app/service/otc/OTCCurrencyService.kt | 152 ------- .../nilin/opex/wallet/app/utils/Convertor.kt | 30 ++ .../nilin/opex/wallet/app/utils/Extensions.kt | 6 +- .../src/main/resources/application-otc.yml | 36 +- .../src/main/resources/application.yml | 23 +- .../nilin/opex/wallet/app/KafkaEnabledTest.kt | 1 + .../wallet/app/TestProfileSecurityConfig.kt | 4 +- .../AdvancedTransferControllerIT.kt | 109 +++-- .../controller/CurrencyRatesControllerIT.kt | 33 +- .../app/controller/TransferControllerIT.kt | 97 ++-- .../app/service/TransactionManagerImplIT.kt | 18 +- .../app/service/TransferManagerImplIT.kt | 56 ++- .../wallet/app/service/otc/CurrencyGraphIT.kt | 17 +- .../src/test/resources/application.yml | 2 +- wallet/wallet-core/pom.xml | 2 +- .../exc/ConcurrentBalanceChangException.kt | 2 +- .../opex/wallet/core/inout/CurrencyCommand.kt | 39 ++ .../opex/wallet/core/inout/CurrencyPrice.kt | 5 + .../nilin/opex/wallet/core/inout/Deposit.kt | 4 +- .../opex/wallet/core/inout/DepositResponse.kt | 21 + .../opex/wallet/core/inout/DepositType.kt | 5 + .../opex/wallet/core/inout/GatewayCommand.kt | 117 +++++ .../opex/wallet/core/inout/GatewayData.kt | 10 + .../opex/wallet/core/inout/SwapResponse.kt | 18 + .../opex/wallet/core/inout/TerminalCommand.kt | 11 + .../opex/wallet/core/inout/TransferMethod.kt | 5 + .../opex/wallet/core/inout/TransferResult.kt | 4 +- .../core/inout/WithdrawAcceptCommand.kt | 4 +- .../opex/wallet/core/inout/WithdrawCommand.kt | 11 +- .../core/inout/WithdrawRejectCommand.kt | 2 + .../wallet/core/inout/WithdrawResponse.kt | 7 +- .../opex/wallet/core/inout/WithdrawType.kt | 5 + .../co/nilin/opex/wallet/core/model/Amount.kt | 3 +- .../nilin/opex/wallet/core/model/Currency.kt | 77 ---- .../opex/wallet/core/model/DepositStatus.kt | 2 +- .../opex/wallet/core/model/DepositType.kt | 2 +- .../opex/wallet/core/model/FetchCurrency.kt | 3 + .../opex/wallet/core/model/FetchGateways.kt | 8 + .../wallet/core/model/TransferCategory.kt | 2 +- .../opex/wallet/core/model/UserTransaction.kt | 2 +- .../core/model/UserTransactionCategory.kt | 2 + .../co/nilin/opex/wallet/core/model/Wallet.kt | 4 +- .../nilin/opex/wallet/core/model/Withdraw.kt | 5 +- .../opex/wallet/core/model/WithdrawType.kt | 6 + .../otc/CurrencyImplementationResponse.kt | 22 +- .../wallet/core/model/otc/ForbiddenPair.kt | 8 +- .../wallet/core/model/otc/LoginRequest.kt | 2 +- .../wallet/core/model/otc/LoginResponse.kt | 10 +- .../nilin/opex/wallet/core/model/otc/Rate.kt | 4 +- .../wallet/core/model/otc/ReservedTransfer.kt | 5 +- .../opex/wallet/core/model/otc/Symbols.kt | 2 +- .../opex/wallet/core/service/AuthService.kt | 28 ++ .../wallet/core/service/GatewayService.kt | 122 +++++ .../core/service/TransferManagerImpl.kt | 55 ++- .../wallet/core/service/WithdrawService.kt | 149 +++++-- .../wallet/core/service/otc/RateService.kt | 16 +- .../nilin/opex/wallet/core/spi/AuthProxy.kt | 8 +- .../opex/wallet/core/spi/BcGatewayProxy.kt | 19 - .../wallet/core/spi/CurrencyRateService.kt | 4 +- .../opex/wallet/core/spi/CurrencyService.kt | 18 - .../wallet/core/spi/CurrencyServiceManager.kt | 19 + .../opex/wallet/core/spi/DepositPersister.kt | 22 +- .../opex/wallet/core/spi/GatewayPersister.kt | 38 ++ .../wallet/core/spi/GatewayTerminalManager.kt | 12 + .../core/spi/ReservedTransferManager.kt | 22 +- .../opex/wallet/core/spi/TerminalManager.kt | 12 + .../wallet/core/spi/UserTransactionManager.kt | 4 +- .../opex/wallet/core/spi/WalletDataManager.kt | 2 +- .../opex/wallet/core/spi/WalletManager.kt | 16 +- .../wallet/core/spi/WalletOwnerManager.kt | 1 + .../opex/wallet/core/spi/WithdrawPersister.kt | 17 +- .../wallet/core/service/sample/Samples.kt | 5 +- wallet/wallet-ports/wallet-auth-proxy/pom.xml | 4 +- .../ports/proxy/auth/impl/AuthProxyImpl.kt | 23 +- .../wallet-bcgateway-proxy/pom.xml | 4 +- .../bcgateway/impl/BcGatewayProxyImpl.kt | 120 +++-- .../bcgateway/impl/ExtractBackgroundAuth.kt | 36 -- .../wallet-eventlistener-kafka/pom.xml | 2 +- .../listener/config/KafkaProducerConfig.kt | 1 - .../listener/config/WalletKafkaConfig.kt | 36 +- .../consumer/FinancialActionKafkaListener.kt | 1 - .../wallet-persister-postgres/pom.xml | 7 +- .../ports/postgres/dao/CurrencyRepository.kt | 49 --- .../postgres/dao/CurrencyRepositoryV2.kt | 46 ++ .../ports/postgres/dao/DepositRepository.kt | 69 ++- .../postgres/dao/GatewayTerminalRepository.kt | 18 + .../postgres/dao/ManualGatewayRepository.kt | 23 + .../postgres/dao/OffChainGatewayRepository.kt | 27 ++ .../ports/postgres/dao/RatesRepository.kt | 8 +- .../dao/ReservedTransferRepository.kt | 32 +- .../ports/postgres/dao/TerminalRepository.kt | 14 + .../postgres/dao/TransactionRepository.kt | 3 +- .../postgres/dao/UserTransactionRepository.kt | 8 +- .../postgres/dao/WalletOwnerRepository.kt | 1 - .../ports/postgres/dao/WalletRepository.kt | 1 - .../ports/postgres/dao/WithdrawRepository.kt | 64 ++- .../wallet/ports/postgres/dto/CurrencyDto.kt | 32 +- .../wallet/ports/postgres/dto/WalletDto.kt | 4 +- .../postgres/impl/CurrencyServiceImpl.kt | 148 ------- .../postgres/impl/CurrencyServiceImplV2.kt | 109 +++++ .../postgres/impl/DepositPersisterImpl.kt | 68 ++- .../postgres/impl/GatewayTerminalImpl.kt | 64 +++ .../postgres/impl/ManualGatewayManagerImpl.kt | 77 ++++ .../impl/OffChainGatewayManagerImpl.kt | 76 ++++ .../ports/postgres/impl/RateServiceImpl.kt | 88 ++-- .../postgres/impl/ReservedTransferImpl.kt | 74 +++- .../postgres/impl/TerminalManagerImpl.kt | 53 +++ .../postgres/impl/TransactionManagerImpl.kt | 16 +- .../impl/UserTransactionManagerImpl.kt | 4 +- .../postgres/impl/WalletDataManagerImpl.kt | 22 +- ...tManagerImpl.kt => WalletManagerImplV2.kt} | 174 ++++---- .../postgres/impl/WalletOwnerManagerImpl.kt | 6 +- .../postgres/impl/WithdrawPersisterImpl.kt | 88 ++-- .../ports/postgres/model/CurrencyModel.kt | 21 +- .../ports/postgres/model/DepositModel.kt | 3 +- .../postgres/model/GatewayTerminalModel.kt | 13 + .../postgres/model/ManualGatewayModel.kt | 23 + .../postgres/model/OffChainGatewayModel.kt | 23 + .../postgres/model/ReservedTransferModel.kt | 4 +- .../ports/postgres/model/TerminalModel.kt | 19 + .../postgres/model/UserTransactionModel.kt | 2 +- .../ports/postgres/model/WalletConfigModel.kt | 1 - .../ports/postgres/model/WalletLimitsModel.kt | 1 - .../ports/postgres/model/WithdrawModel.kt | 6 +- .../wallet/ports/postgres/util/Convertor.kt | 138 +++++- .../src/main/resources/schema.sql | 262 ++++++++--- .../postgres/impl/CurrencyServiceTest.kt | 41 +- .../ports/postgres/impl/WalletManagerTest.kt | 46 +- .../ports/postgres/impl/sample/Samples.kt | 7 +- 393 files changed, 7709 insertions(+), 3964 deletions(-) create mode 100644 bc-gateway/bc-gateway-app/src/main/kotlin/co/nilin/opex/bcgateway/app/config/ErrorConfig.kt create mode 100644 bc-gateway/bc-gateway-app/src/main/kotlin/co/nilin/opex/bcgateway/app/controller/CryptoCurrencyController.kt delete mode 100644 bc-gateway/bc-gateway-app/src/main/kotlin/co/nilin/opex/bcgateway/app/controller/CurrencyController.kt create mode 100644 bc-gateway/bc-gateway-app/src/main/kotlin/co/nilin/opex/bcgateway/app/controller/OmniBCWalletController.kt create mode 100644 bc-gateway/bc-gateway-app/src/main/kotlin/co/nilin/opex/bcgateway/app/controller/ScannerController.kt create mode 100644 bc-gateway/bc-gateway-app/src/main/kotlin/co/nilin/opex/bcgateway/app/service/OmniBalanceService.kt create mode 100644 bc-gateway/bc-gateway-app/src/main/resources/scanner-public.pem create mode 100644 bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/model/AssignedAddressV2.kt create mode 100644 bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/model/CryptoCurrencyCommand.kt create mode 100644 bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/model/FetchGateways.kt create mode 100644 bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/model/OmniBalance.kt create mode 100644 bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/service/AssignAddressServiceImplV2.kt create mode 100644 bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/spi/CryptoCurrencyHandlerV2.kt create mode 100644 bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/spi/OmniWalletManager.kt create mode 100644 bc-gateway/bc-gateway-ports/bc-gateway-omniwallet-proxy/pom.xml create mode 100644 bc-gateway/bc-gateway-ports/bc-gateway-omniwallet-proxy/src/main/kotlin/co/nilin/opex/bcgateway/omniwallet/impl/OmniWalletManagerImpl.kt create mode 100644 bc-gateway/bc-gateway-ports/bc-gateway-omniwallet-proxy/src/main/kotlin/co/nilin/opex/bcgateway/omniwallet/model/AddressBalanceWithUsd.kt create mode 100644 bc-gateway/bc-gateway-ports/bc-gateway-omniwallet-proxy/src/main/kotlin/co/nilin/opex/bcgateway/omniwallet/proxy/OmniWalletProxy.kt create mode 100644 bc-gateway/bc-gateway-ports/bc-gateway-persister-postgres/src/main/kotlin/co/nilin/opex/bcgateway/ports/postgres/impl/CurrencyHandlerImplV2.kt delete mode 100644 bc-gateway/bc-gateway-ports/bc-gateway-persister-postgres/src/main/kotlin/co/nilin/opex/bcgateway/ports/postgres/model/CurrencyImplementationModel.kt create mode 100644 bc-gateway/bc-gateway-ports/bc-gateway-persister-postgres/src/main/kotlin/co/nilin/opex/bcgateway/ports/postgres/model/CurrencyOnChainGatewayModel.kt create mode 100644 bc-gateway/bc-gateway-ports/bc-gateway-persister-postgres/src/main/kotlin/co/nilin/opex/bcgateway/ports/postgres/model/NewCurrencyImplementationModel.kt create mode 100644 bc-gateway/bc-gateway-ports/bc-gateway-persister-postgres/src/main/kotlin/co/nilin/opex/bcgateway/ports/postgres/util/convertor.kt create mode 100644 common/src/main/kotlin/co/nilin/opex/common/utils/CustomErrorTranslator.kt create mode 100644 common/src/main/resources/messages_en.properties create mode 100644 common/src/main/resources/messages_fa.properties create mode 100644 preferences.yml create mode 100644 wallet/wallet-app/src/main/kotlin/co/nilin/opex/wallet/app/config/ErrorConfig.kt create mode 100644 wallet/wallet-app/src/main/kotlin/co/nilin/opex/wallet/app/controller/AdvancedTransferAdminController.kt create mode 100644 wallet/wallet-app/src/main/kotlin/co/nilin/opex/wallet/app/controller/CurrencyController.kt create mode 100644 wallet/wallet-app/src/main/kotlin/co/nilin/opex/wallet/app/controller/DepositAdminController.kt create mode 100644 wallet/wallet-app/src/main/kotlin/co/nilin/opex/wallet/app/controller/StorageController.kt create mode 100644 wallet/wallet-app/src/main/kotlin/co/nilin/opex/wallet/app/controller/TransactionAdminController.kt create mode 100644 wallet/wallet-app/src/main/kotlin/co/nilin/opex/wallet/app/dto/CurrencyDto.kt create mode 100644 wallet/wallet-app/src/main/kotlin/co/nilin/opex/wallet/app/dto/CurrencyGatewayDto.kt create mode 100644 wallet/wallet-app/src/main/kotlin/co/nilin/opex/wallet/app/dto/DocumentResponse.kt create mode 100644 wallet/wallet-app/src/main/kotlin/co/nilin/opex/wallet/app/service/BankDataService.kt create mode 100644 wallet/wallet-app/src/main/kotlin/co/nilin/opex/wallet/app/service/CurrencyServiceV2.kt create mode 100644 wallet/wallet-app/src/main/kotlin/co/nilin/opex/wallet/app/service/DepositService.kt create mode 100644 wallet/wallet-app/src/main/kotlin/co/nilin/opex/wallet/app/service/DocumentService.kt create mode 100644 wallet/wallet-app/src/main/kotlin/co/nilin/opex/wallet/app/service/ManualWithdrawService.kt create mode 100644 wallet/wallet-app/src/main/kotlin/co/nilin/opex/wallet/app/service/TraceDepositService.kt delete mode 100644 wallet/wallet-app/src/main/kotlin/co/nilin/opex/wallet/app/service/otc/CurrencyService.kt delete mode 100644 wallet/wallet-app/src/main/kotlin/co/nilin/opex/wallet/app/service/otc/OTCCurrencyService.kt create mode 100644 wallet/wallet-app/src/main/kotlin/co/nilin/opex/wallet/app/utils/Convertor.kt create mode 100644 wallet/wallet-core/src/main/kotlin/co/nilin/opex/wallet/core/inout/CurrencyCommand.kt create mode 100644 wallet/wallet-core/src/main/kotlin/co/nilin/opex/wallet/core/inout/CurrencyPrice.kt create mode 100644 wallet/wallet-core/src/main/kotlin/co/nilin/opex/wallet/core/inout/DepositResponse.kt create mode 100644 wallet/wallet-core/src/main/kotlin/co/nilin/opex/wallet/core/inout/DepositType.kt create mode 100644 wallet/wallet-core/src/main/kotlin/co/nilin/opex/wallet/core/inout/GatewayCommand.kt create mode 100644 wallet/wallet-core/src/main/kotlin/co/nilin/opex/wallet/core/inout/GatewayData.kt create mode 100644 wallet/wallet-core/src/main/kotlin/co/nilin/opex/wallet/core/inout/SwapResponse.kt create mode 100644 wallet/wallet-core/src/main/kotlin/co/nilin/opex/wallet/core/inout/TerminalCommand.kt create mode 100644 wallet/wallet-core/src/main/kotlin/co/nilin/opex/wallet/core/inout/TransferMethod.kt create mode 100644 wallet/wallet-core/src/main/kotlin/co/nilin/opex/wallet/core/inout/WithdrawType.kt delete mode 100644 wallet/wallet-core/src/main/kotlin/co/nilin/opex/wallet/core/model/Currency.kt create mode 100644 wallet/wallet-core/src/main/kotlin/co/nilin/opex/wallet/core/model/FetchCurrency.kt create mode 100644 wallet/wallet-core/src/main/kotlin/co/nilin/opex/wallet/core/model/FetchGateways.kt create mode 100644 wallet/wallet-core/src/main/kotlin/co/nilin/opex/wallet/core/model/WithdrawType.kt create mode 100644 wallet/wallet-core/src/main/kotlin/co/nilin/opex/wallet/core/service/AuthService.kt create mode 100644 wallet/wallet-core/src/main/kotlin/co/nilin/opex/wallet/core/service/GatewayService.kt delete mode 100644 wallet/wallet-core/src/main/kotlin/co/nilin/opex/wallet/core/spi/CurrencyService.kt create mode 100644 wallet/wallet-core/src/main/kotlin/co/nilin/opex/wallet/core/spi/CurrencyServiceManager.kt create mode 100644 wallet/wallet-core/src/main/kotlin/co/nilin/opex/wallet/core/spi/GatewayPersister.kt create mode 100644 wallet/wallet-core/src/main/kotlin/co/nilin/opex/wallet/core/spi/GatewayTerminalManager.kt create mode 100644 wallet/wallet-core/src/main/kotlin/co/nilin/opex/wallet/core/spi/TerminalManager.kt delete mode 100644 wallet/wallet-ports/wallet-bcgateway-proxy/src/main/kotlin/co/nilin/opex/wallet/ports/proxy/bcgateway/impl/ExtractBackgroundAuth.kt create mode 100644 wallet/wallet-ports/wallet-persister-postgres/src/main/kotlin/co/nilin/opex/wallet/ports/postgres/dao/CurrencyRepositoryV2.kt create mode 100644 wallet/wallet-ports/wallet-persister-postgres/src/main/kotlin/co/nilin/opex/wallet/ports/postgres/dao/GatewayTerminalRepository.kt create mode 100644 wallet/wallet-ports/wallet-persister-postgres/src/main/kotlin/co/nilin/opex/wallet/ports/postgres/dao/ManualGatewayRepository.kt create mode 100644 wallet/wallet-ports/wallet-persister-postgres/src/main/kotlin/co/nilin/opex/wallet/ports/postgres/dao/OffChainGatewayRepository.kt create mode 100644 wallet/wallet-ports/wallet-persister-postgres/src/main/kotlin/co/nilin/opex/wallet/ports/postgres/dao/TerminalRepository.kt create mode 100644 wallet/wallet-ports/wallet-persister-postgres/src/main/kotlin/co/nilin/opex/wallet/ports/postgres/impl/CurrencyServiceImplV2.kt create mode 100644 wallet/wallet-ports/wallet-persister-postgres/src/main/kotlin/co/nilin/opex/wallet/ports/postgres/impl/GatewayTerminalImpl.kt create mode 100644 wallet/wallet-ports/wallet-persister-postgres/src/main/kotlin/co/nilin/opex/wallet/ports/postgres/impl/ManualGatewayManagerImpl.kt create mode 100644 wallet/wallet-ports/wallet-persister-postgres/src/main/kotlin/co/nilin/opex/wallet/ports/postgres/impl/OffChainGatewayManagerImpl.kt create mode 100644 wallet/wallet-ports/wallet-persister-postgres/src/main/kotlin/co/nilin/opex/wallet/ports/postgres/impl/TerminalManagerImpl.kt rename wallet/wallet-ports/wallet-persister-postgres/src/main/kotlin/co/nilin/opex/wallet/ports/postgres/impl/{WalletManagerImpl.kt => WalletManagerImplV2.kt} (62%) create mode 100644 wallet/wallet-ports/wallet-persister-postgres/src/main/kotlin/co/nilin/opex/wallet/ports/postgres/model/GatewayTerminalModel.kt create mode 100644 wallet/wallet-ports/wallet-persister-postgres/src/main/kotlin/co/nilin/opex/wallet/ports/postgres/model/ManualGatewayModel.kt create mode 100644 wallet/wallet-ports/wallet-persister-postgres/src/main/kotlin/co/nilin/opex/wallet/ports/postgres/model/OffChainGatewayModel.kt create mode 100644 wallet/wallet-ports/wallet-persister-postgres/src/main/kotlin/co/nilin/opex/wallet/ports/postgres/model/TerminalModel.kt diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index dd84ea782..320592668 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -12,6 +12,7 @@ A clear and concise description of what the bug is. **To Reproduce** Steps to reproduce the behavior: + 1. Go to '...' 2. Click on '....' 3. Scroll down to '....' @@ -24,15 +25,17 @@ A clear and concise description of what you expected to happen. If applicable, add screenshots to help explain your problem. **Desktop (please complete the following information):** - - OS: [e.g. iOS] - - Browser [e.g. chrome, safari] - - Version [e.g. 22] + +- OS: [e.g. iOS] +- Browser [e.g. chrome, safari] +- Version [e.g. 22] **Smartphone (please complete the following information):** - - Device: [e.g. iPhone6] - - OS: [e.g. iOS8.1] - - Browser [e.g. stock browser, safari] - - Version [e.g. 22] + +- Device: [e.g. iPhone6] +- OS: [e.g. iOS8.1] +- Browser [e.g. stock browser, safari] +- Version [e.g. 22] **Additional context** Add any other context about the problem here. diff --git a/.github/workflows/dev-otc.yml b/.github/workflows/dev-otc.yml index 54dc68967..7bae08279 100644 --- a/.github/workflows/dev-otc.yml +++ b/.github/workflows/dev-otc.yml @@ -1,8 +1,8 @@ -name: Build, Test, and Deploy otc (DEV env) services for specific partner +name: Build, Test, and Deploy otc (DEV env) services for specific partner on: -# push: -# branches: -# - dev + # push: + # branches: + # - dev workflow_dispatch: inputs: @@ -107,7 +107,7 @@ jobs: echo "password=$server_pass" >> $GITHUB_OUTPUT - name: Build - run: | + run: | mvn -pl common -am -B -T 1C clean install -Potc mvn -pl wallet,bc-gateway -amd -B -T 1C clean install -Potc diff --git a/.github/workflows/dev.yml b/.github/workflows/dev.yml index d96d0ff81..f39cac69b 100644 --- a/.github/workflows/dev.yml +++ b/.github/workflows/dev.yml @@ -21,7 +21,7 @@ jobs: distribution: 'adopt' java-package: jdk java-version: ${{ matrix.java }} -# cache: maven + # cache: maven - name: Build run: mvn -B -T 1C clean install - name: Run Tests diff --git a/.github/workflows/main-otc.yml b/.github/workflows/main-otc.yml index 81bffbb29..0a2610ce9 100644 --- a/.github/workflows/main-otc.yml +++ b/.github/workflows/main-otc.yml @@ -1,8 +1,8 @@ -name: Build, Test, and Deploy otc (PRD env) services for specific partner +name: Build, Test, and Deploy otc (PRD env) services for specific partner on: -# push: -# branches: -# - main + # push: + # branches: + # - main workflow_dispatch: inputs: @@ -107,7 +107,7 @@ jobs: echo "password=$server_pass" >> $GITHUB_OUTPUT - name: Build - run: | + run: | mvn -pl common -am -B -T 1C clean install -Potc mvn -pl wallet,bc-gateway -amd -B -T 1C clean install -Potc diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 987c441cd..866a4e178 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -21,7 +21,7 @@ jobs: distribution: 'adopt' java-package: jdk java-version: ${{ matrix.java }} -# cache: maven + # cache: maven - name: Build run: mvn -B -T 1C clean install - name: Run Tests diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index 435b5b931..dd9932aff 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -20,7 +20,7 @@ jobs: distribution: 'adopt' java-package: jdk java-version: ${{ matrix.java }} -# cache: maven + # cache: maven - name: Build run: mvn -B -T 1C clean install -Potc - name: Run Tests diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index eb644660a..2557c80a7 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -5,7 +5,12 @@ on: # branches: # - dev workflow_dispatch: - +# inputs: +# partner_name: +# type: string +# description: 'The name of the partner (provided during workflow execution)' +# required: true +# default: default jobs: build: runs-on: ubuntu-20.04 diff --git a/accountant/accountant-app/pom.xml b/accountant/accountant-app/pom.xml index f722891eb..7504526f6 100644 --- a/accountant/accountant-app/pom.xml +++ b/accountant/accountant-app/pom.xml @@ -1,5 +1,5 @@ - 4.0.0 diff --git a/accountant/accountant-app/src/main/kotlin/co/nilin/opex/accountant/app/AccountantApp.kt b/accountant/accountant-app/src/main/kotlin/co/nilin/opex/accountant/app/AccountantApp.kt index 02bc1d88d..ad5272a2c 100644 --- a/accountant/accountant-app/src/main/kotlin/co/nilin/opex/accountant/app/AccountantApp.kt +++ b/accountant/accountant-app/src/main/kotlin/co/nilin/opex/accountant/app/AccountantApp.kt @@ -1,7 +1,6 @@ package co.nilin.opex.accountant.app import org.springframework.boot.autoconfigure.SpringBootApplication -import org.springframework.boot.context.properties.ConfigurationPropertiesScan import org.springframework.boot.runApplication import org.springframework.context.annotation.ComponentScan diff --git a/accountant/accountant-app/src/main/kotlin/co/nilin/opex/accountant/app/config/AppConfig.kt b/accountant/accountant-app/src/main/kotlin/co/nilin/opex/accountant/app/config/AppConfig.kt index f63ed9800..8b4e26e95 100644 --- a/accountant/accountant-app/src/main/kotlin/co/nilin/opex/accountant/app/config/AppConfig.kt +++ b/accountant/accountant-app/src/main/kotlin/co/nilin/opex/accountant/app/config/AppConfig.kt @@ -1,10 +1,6 @@ package co.nilin.opex.accountant.app.config import co.nilin.opex.accountant.app.listener.* -import co.nilin.opex.accountant.app.listener.AccountantEventListener -import co.nilin.opex.accountant.app.listener.AccountantTempEventListener -import co.nilin.opex.accountant.app.listener.AccountantTradeListener -import co.nilin.opex.accountant.app.listener.OrderListener import co.nilin.opex.accountant.core.api.FeeCalculator import co.nilin.opex.accountant.core.api.FinancialActionJobManager import co.nilin.opex.accountant.core.api.OrderManager @@ -14,10 +10,6 @@ import co.nilin.opex.accountant.core.service.OrderManagerImpl import co.nilin.opex.accountant.core.service.TradeManagerImpl import co.nilin.opex.accountant.core.spi.* import co.nilin.opex.accountant.ports.kafka.listener.consumer.* -import co.nilin.opex.accountant.ports.kafka.listener.consumer.EventKafkaListener -import co.nilin.opex.accountant.ports.kafka.listener.consumer.OrderKafkaListener -import co.nilin.opex.accountant.ports.kafka.listener.consumer.TempEventKafkaListener -import co.nilin.opex.accountant.ports.kafka.listener.consumer.TradeKafkaListener import co.nilin.opex.accountant.ports.kafka.listener.spi.FAResponseListener import org.springframework.beans.factory.annotation.Autowired import org.springframework.context.annotation.Bean @@ -147,7 +139,8 @@ class AppConfig { @Autowired fun configureTempEventListener( tempEventKafkaListener: TempEventKafkaListener, - accountantTempEventListener: AccountantTempEventListener) { + accountantTempEventListener: AccountantTempEventListener + ) { tempEventKafkaListener.addListener(accountantTempEventListener) } diff --git a/accountant/accountant-app/src/main/kotlin/co/nilin/opex/accountant/app/data/PairFeeResponse.kt b/accountant/accountant-app/src/main/kotlin/co/nilin/opex/accountant/app/data/PairFeeResponse.kt index cbfb4c63f..6ac8d804b 100644 --- a/accountant/accountant-app/src/main/kotlin/co/nilin/opex/accountant/app/data/PairFeeResponse.kt +++ b/accountant/accountant-app/src/main/kotlin/co/nilin/opex/accountant/app/data/PairFeeResponse.kt @@ -3,7 +3,7 @@ package co.nilin.opex.accountant.app.data import java.math.BigDecimal data class PairFeeResponse( - val pair:String, + val pair: String, val direction: String, val userLevel: String, val makerFee: BigDecimal, diff --git a/accountant/accountant-app/src/main/kotlin/co/nilin/opex/accountant/app/listener/KycLevelUpdatedListener.kt b/accountant/accountant-app/src/main/kotlin/co/nilin/opex/accountant/app/listener/KycLevelUpdatedListener.kt index b7ff38ba7..98ae6147b 100644 --- a/accountant/accountant-app/src/main/kotlin/co/nilin/opex/accountant/app/listener/KycLevelUpdatedListener.kt +++ b/accountant/accountant-app/src/main/kotlin/co/nilin/opex/accountant/app/listener/KycLevelUpdatedListener.kt @@ -3,11 +3,11 @@ package co.nilin.opex.accountant.app.listener import co.nilin.opex.accountant.core.inout.KycLevelUpdatedEvent import co.nilin.opex.accountant.ports.kafka.listener.spi.KycLevelUpdatedEventListener import co.nilin.opex.accountant.ports.postgres.impl.UserLevelLoaderImpl -import org.slf4j.LoggerFactory -import org.springframework.stereotype.Component import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch +import org.slf4j.LoggerFactory +import org.springframework.stereotype.Component @Component class KycLevelUpdatedListener(val userLevelLoaderImpl: UserLevelLoaderImpl) : KycLevelUpdatedEventListener { @@ -18,8 +18,10 @@ class KycLevelUpdatedListener(val userLevelLoaderImpl: UserLevelLoaderImpl) : Ky return "KycLevelUpdatedListener" } - override fun onEvent(event: KycLevelUpdatedEvent, - partition: Int, offset: Long, timestamp: Long, eventId: String) { + override fun onEvent( + event: KycLevelUpdatedEvent, + partition: Int, offset: Long, timestamp: Long, eventId: String + ) { logger.info("==========================================================================") logger.info("Incoming UserLevelUpdated event: $event") logger.info("==========================================================================") diff --git a/accountant/accountant-app/src/test/resources/application.yml b/accountant/accountant-app/src/test/resources/application.yml index 005d0e363..6fa2654d1 100644 --- a/accountant/accountant-app/src/test/resources/application.yml +++ b/accountant/accountant-app/src/test/resources/application.yml @@ -38,7 +38,7 @@ management: web: base-path: /actuator exposure: - include: ["health", "metrics"] + include: [ "health", "metrics" ] endpoint: health: show-details: always diff --git a/accountant/accountant-core/pom.xml b/accountant/accountant-core/pom.xml index fe9705d0c..4ef1fd63d 100644 --- a/accountant/accountant-core/pom.xml +++ b/accountant/accountant-core/pom.xml @@ -1,5 +1,5 @@ - 4.0.0 diff --git a/accountant/accountant-core/src/main/kotlin/co/nilin/opex/accountant/core/service/FinancialActionJobManagerImpl.kt b/accountant/accountant-core/src/main/kotlin/co/nilin/opex/accountant/core/service/FinancialActionJobManagerImpl.kt index f6c25d076..0dce40930 100644 --- a/accountant/accountant-core/src/main/kotlin/co/nilin/opex/accountant/core/service/FinancialActionJobManagerImpl.kt +++ b/accountant/accountant-core/src/main/kotlin/co/nilin/opex/accountant/core/service/FinancialActionJobManagerImpl.kt @@ -3,7 +3,9 @@ package co.nilin.opex.accountant.core.service import co.nilin.opex.accountant.core.api.FinancialActionJobManager import co.nilin.opex.accountant.core.model.FinancialAction import co.nilin.opex.accountant.core.model.FinancialActionStatus -import co.nilin.opex.accountant.core.spi.* +import co.nilin.opex.accountant.core.spi.FinancialActionLoader +import co.nilin.opex.accountant.core.spi.FinancialActionPersister +import co.nilin.opex.accountant.core.spi.WalletProxy import co.nilin.opex.utility.error.data.OpexException import org.slf4j.LoggerFactory import org.springframework.web.reactive.function.client.WebClientResponseException diff --git a/accountant/accountant-core/src/main/kotlin/co/nilin/opex/accountant/core/spi/UserLevelLoader.kt b/accountant/accountant-core/src/main/kotlin/co/nilin/opex/accountant/core/spi/UserLevelLoader.kt index b1e2c3173..1946ee4fd 100644 --- a/accountant/accountant-core/src/main/kotlin/co/nilin/opex/accountant/core/spi/UserLevelLoader.kt +++ b/accountant/accountant-core/src/main/kotlin/co/nilin/opex/accountant/core/spi/UserLevelLoader.kt @@ -6,6 +6,6 @@ interface UserLevelLoader { suspend fun load(uuid: String): String - suspend fun update(uuid: String,userLevel:KycLevel) + suspend fun update(uuid: String, userLevel: KycLevel) } \ No newline at end of file diff --git a/accountant/accountant-ports/accountant-eventlistener-kafka/pom.xml b/accountant/accountant-ports/accountant-eventlistener-kafka/pom.xml index a27cadb8f..52c433ffe 100644 --- a/accountant/accountant-ports/accountant-eventlistener-kafka/pom.xml +++ b/accountant/accountant-ports/accountant-eventlistener-kafka/pom.xml @@ -1,5 +1,5 @@ - 4.0.0 diff --git a/accountant/accountant-ports/accountant-eventlistener-kafka/src/main/kotlin/co/nilin/opex/accountant/ports/kafka/listener/inout/OrderRequestEvent.kt b/accountant/accountant-ports/accountant-eventlistener-kafka/src/main/kotlin/co/nilin/opex/accountant/ports/kafka/listener/inout/OrderRequestEvent.kt index 04876ee6f..f4d99e7b6 100644 --- a/accountant/accountant-ports/accountant-eventlistener-kafka/src/main/kotlin/co/nilin/opex/accountant/ports/kafka/listener/inout/OrderRequestEvent.kt +++ b/accountant/accountant-ports/accountant-eventlistener-kafka/src/main/kotlin/co/nilin/opex/accountant/ports/kafka/listener/inout/OrderRequestEvent.kt @@ -2,4 +2,4 @@ package co.nilin.opex.accountant.ports.kafka.listener.inout import co.nilin.opex.matching.engine.core.model.Pair -abstract class OrderRequestEvent(val ouid:String, val uuid: String, val pair: Pair) \ No newline at end of file +abstract class OrderRequestEvent(val ouid: String, val uuid: String, val pair: Pair) \ No newline at end of file diff --git a/accountant/accountant-ports/accountant-persister-postgres/pom.xml b/accountant/accountant-ports/accountant-persister-postgres/pom.xml index 15d35337e..b90ec1cf5 100644 --- a/accountant/accountant-ports/accountant-persister-postgres/pom.xml +++ b/accountant/accountant-ports/accountant-persister-postgres/pom.xml @@ -1,5 +1,5 @@ - 4.0.0 diff --git a/accountant/accountant-ports/accountant-persister-postgres/src/main/kotlin/co/nilin/opex/accountant/ports/postgres/dao/FinancialActionRepository.kt b/accountant/accountant-ports/accountant-persister-postgres/src/main/kotlin/co/nilin/opex/accountant/ports/postgres/dao/FinancialActionRepository.kt index fa04c317d..3139f647d 100644 --- a/accountant/accountant-ports/accountant-persister-postgres/src/main/kotlin/co/nilin/opex/accountant/ports/postgres/dao/FinancialActionRepository.kt +++ b/accountant/accountant-ports/accountant-persister-postgres/src/main/kotlin/co/nilin/opex/accountant/ports/postgres/dao/FinancialActionRepository.kt @@ -41,10 +41,12 @@ interface FinancialActionRepository : ReactiveCrudRepository, status: FinancialActionStatus): Mono - @Query(""" + @Query( + """ select * from fi_actions fi where status = 'CREATED' and (parent_id is null or 'ERROR' != (select pfi.status from fi_actions pfi where pfi.id = fi.parent_id)) - """) + """ + ) fun findReadyToProcess(of: Pageable): Flow } \ No newline at end of file diff --git a/accountant/accountant-ports/accountant-persister-postgres/src/main/kotlin/co/nilin/opex/accountant/ports/postgres/impl/FinancialActionPersisterImpl.kt b/accountant/accountant-ports/accountant-persister-postgres/src/main/kotlin/co/nilin/opex/accountant/ports/postgres/impl/FinancialActionPersisterImpl.kt index b347977cc..86d9dcd89 100644 --- a/accountant/accountant-ports/accountant-persister-postgres/src/main/kotlin/co/nilin/opex/accountant/ports/postgres/impl/FinancialActionPersisterImpl.kt +++ b/accountant/accountant-ports/accountant-persister-postgres/src/main/kotlin/co/nilin/opex/accountant/ports/postgres/impl/FinancialActionPersisterImpl.kt @@ -3,7 +3,6 @@ package co.nilin.opex.accountant.ports.postgres.impl import co.nilin.opex.accountant.core.model.FinancialAction import co.nilin.opex.accountant.core.model.FinancialActionStatus import co.nilin.opex.accountant.core.spi.FinancialActionPersister -import co.nilin.opex.accountant.core.spi.JsonMapper import co.nilin.opex.accountant.ports.postgres.dao.FinancialActionErrorRepository import co.nilin.opex.accountant.ports.postgres.dao.FinancialActionRepository import co.nilin.opex.accountant.ports.postgres.dao.FinancialActionRetryRepository diff --git a/accountant/accountant-ports/accountant-persister-postgres/src/main/kotlin/co/nilin/opex/accountant/ports/postgres/impl/TempEventPersisterImpl.kt b/accountant/accountant-ports/accountant-persister-postgres/src/main/kotlin/co/nilin/opex/accountant/ports/postgres/impl/TempEventPersisterImpl.kt index 8bfa95402..2aed7a703 100644 --- a/accountant/accountant-ports/accountant-persister-postgres/src/main/kotlin/co/nilin/opex/accountant/ports/postgres/impl/TempEventPersisterImpl.kt +++ b/accountant/accountant-ports/accountant-persister-postgres/src/main/kotlin/co/nilin/opex/accountant/ports/postgres/impl/TempEventPersisterImpl.kt @@ -6,7 +6,6 @@ import co.nilin.opex.accountant.ports.postgres.dao.TempEventRepository import co.nilin.opex.accountant.ports.postgres.model.TempEventModel import co.nilin.opex.matching.engine.core.eventh.events.CoreEvent import com.fasterxml.jackson.databind.ObjectMapper -import com.fasterxml.jackson.module.kotlin.readValue import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.toList import kotlinx.coroutines.reactive.awaitFirstOrNull diff --git a/accountant/accountant-ports/accountant-persister-postgres/src/main/kotlin/co/nilin/opex/accountant/ports/postgres/impl/UserLevelLoaderImpl.kt b/accountant/accountant-ports/accountant-persister-postgres/src/main/kotlin/co/nilin/opex/accountant/ports/postgres/impl/UserLevelLoaderImpl.kt index ac2817040..4ecd0b13f 100644 --- a/accountant/accountant-ports/accountant-persister-postgres/src/main/kotlin/co/nilin/opex/accountant/ports/postgres/impl/UserLevelLoaderImpl.kt +++ b/accountant/accountant-ports/accountant-persister-postgres/src/main/kotlin/co/nilin/opex/accountant/ports/postgres/impl/UserLevelLoaderImpl.kt @@ -9,8 +9,10 @@ import kotlinx.coroutines.reactor.awaitSingleOrNull import org.springframework.stereotype.Component @Component -class UserLevelLoaderImpl(private val userLevelMapperRepository: UserLevelMapperRepository, - private val userLevelRepository: UserLevelRepository) : UserLevelLoader { +class UserLevelLoaderImpl( + private val userLevelMapperRepository: UserLevelMapperRepository, + private val userLevelRepository: UserLevelRepository +) : UserLevelLoader { override suspend fun load(uuid: String): String { val mapper = userLevelMapperRepository.findByUuid(uuid).awaitSingleOrNull() @@ -21,14 +23,23 @@ class UserLevelLoaderImpl(private val userLevelMapperRepository: UserLevelMapper userLevelRepository.findByLevel(userLevel.name).awaitSingleOrNull()?.let { userLevelMapperRepository.findByUuid(uuid).awaitSingleOrNull() - ?.let { userLevelMapperRepository.save(UserLevelMapperModel(it.id, it.uuid, userLevel.name)).awaitSingleOrNull() } - ?: run { userLevelMapperRepository.save(UserLevelMapperModel(null, uuid, userLevel.name)).awaitSingleOrNull() } - }?: - run { - userLevelRepository.insert(userLevel.name) .awaitSingleOrNull() + ?.let { + userLevelMapperRepository.save(UserLevelMapperModel(it.id, it.uuid, userLevel.name)) + .awaitSingleOrNull() + } + ?: run { + userLevelMapperRepository.save(UserLevelMapperModel(null, uuid, userLevel.name)).awaitSingleOrNull() + } + } ?: run { + userLevelRepository.insert(userLevel.name).awaitSingleOrNull() userLevelMapperRepository.findByUuid(uuid).awaitSingleOrNull() - ?.let { userLevelMapperRepository.save(UserLevelMapperModel(it.id, it.uuid, userLevel.name)).awaitSingleOrNull() } - ?: run { userLevelMapperRepository.save(UserLevelMapperModel(null, uuid, userLevel.name)).awaitSingleOrNull() } + ?.let { + userLevelMapperRepository.save(UserLevelMapperModel(it.id, it.uuid, userLevel.name)) + .awaitSingleOrNull() + } + ?: run { + userLevelMapperRepository.save(UserLevelMapperModel(null, uuid, userLevel.name)).awaitSingleOrNull() + } } } diff --git a/accountant/accountant-ports/accountant-persister-postgres/src/main/kotlin/co/nilin/opex/accountant/ports/postgres/model/FinancialActionModel.kt b/accountant/accountant-ports/accountant-persister-postgres/src/main/kotlin/co/nilin/opex/accountant/ports/postgres/model/FinancialActionModel.kt index 59d10c675..a8b79712a 100644 --- a/accountant/accountant-ports/accountant-persister-postgres/src/main/kotlin/co/nilin/opex/accountant/ports/postgres/model/FinancialActionModel.kt +++ b/accountant/accountant-ports/accountant-persister-postgres/src/main/kotlin/co/nilin/opex/accountant/ports/postgres/model/FinancialActionModel.kt @@ -4,7 +4,6 @@ import co.nilin.opex.accountant.core.model.FinancialActionCategory import co.nilin.opex.accountant.core.model.FinancialActionStatus import co.nilin.opex.accountant.core.model.WalletType import org.springframework.data.annotation.Id -import org.springframework.data.relational.core.mapping.Column import org.springframework.data.relational.core.mapping.Table import java.math.BigDecimal import java.time.LocalDateTime diff --git a/accountant/accountant-ports/accountant-persister-postgres/src/main/kotlin/co/nilin/opex/accountant/ports/postgres/model/UserLevelMapperModel.kt b/accountant/accountant-ports/accountant-persister-postgres/src/main/kotlin/co/nilin/opex/accountant/ports/postgres/model/UserLevelMapperModel.kt index f2f2f08f3..af4c5512e 100644 --- a/accountant/accountant-ports/accountant-persister-postgres/src/main/kotlin/co/nilin/opex/accountant/ports/postgres/model/UserLevelMapperModel.kt +++ b/accountant/accountant-ports/accountant-persister-postgres/src/main/kotlin/co/nilin/opex/accountant/ports/postgres/model/UserLevelMapperModel.kt @@ -5,7 +5,7 @@ import org.springframework.data.relational.core.mapping.Table @Table("user_level_mapper") data class UserLevelMapperModel( - @Id val id: Long?, - val uuid: String, - val userLevel: String + @Id val id: Long?, + val uuid: String, + val userLevel: String ) \ No newline at end of file diff --git a/accountant/accountant-ports/accountant-persister-postgres/src/main/resources/schema.sql b/accountant/accountant-ports/accountant-persister-postgres/src/main/resources/schema.sql index beeddfa88..c541c8e59 100644 --- a/accountant/accountant-ports/accountant-persister-postgres/src/main/resources/schema.sql +++ b/accountant/accountant-ports/accountant-persister-postgres/src/main/resources/schema.sql @@ -1,119 +1,276 @@ CREATE TABLE IF NOT EXISTS orders ( - id SERIAL PRIMARY KEY, - ouid VARCHAR(72) NOT NULL UNIQUE, - uuid VARCHAR(72) NOT NULL, - pair VARCHAR(72) NOT NULL, - matching_engine_id INTEGER, - maker_fee DECIMAL NOT NULL, - taker_fee DECIMAL NOT NULL, - left_side_fraction DECIMAL NOT NULL, - right_side_fraction DECIMAL NOT NULL, - user_level VARCHAR(20) NOT NULL, - direction VARCHAR(20) NOT NULL, - match_constraint VARCHAR(30) NOT NULL, - order_type VARCHAR(30) NOT NULL, - price DECIMAL NOT NULL, - quantity DECIMAL NOT NULL, - filled_quantity DECIMAL NOT NULL, - orig_price DECIMAL NOT NULL, - orig_quantity DECIMAL NOT NULL, - filled_orig_quantity DECIMAL NOT NULL, - first_transfer_amount DECIMAL NOT NULL, - remained_transfer_amount DECIMAL NOT NULL, - status INTEGER NOT NULL, - agent VARCHAR(20), - ip VARCHAR(11), - create_date TIMESTAMP NOT NULL -); + id + SERIAL + PRIMARY + KEY, + ouid + VARCHAR +( + 72 +) NOT NULL UNIQUE, + uuid VARCHAR +( + 72 +) NOT NULL, + pair VARCHAR +( + 72 +) NOT NULL, + matching_engine_id INTEGER, + maker_fee DECIMAL NOT NULL, + taker_fee DECIMAL NOT NULL, + left_side_fraction DECIMAL NOT NULL, + right_side_fraction DECIMAL NOT NULL, + user_level VARCHAR +( + 20 +) NOT NULL, + direction VARCHAR +( + 20 +) NOT NULL, + match_constraint VARCHAR +( + 30 +) NOT NULL, + order_type VARCHAR +( + 30 +) NOT NULL, + price DECIMAL NOT NULL, + quantity DECIMAL NOT NULL, + filled_quantity DECIMAL NOT NULL, + orig_price DECIMAL NOT NULL, + orig_quantity DECIMAL NOT NULL, + filled_orig_quantity DECIMAL NOT NULL, + first_transfer_amount DECIMAL NOT NULL, + remained_transfer_amount DECIMAL NOT NULL, + status INTEGER NOT NULL, + agent VARCHAR +( + 20 +), + ip VARCHAR +( + 11 +), + create_date TIMESTAMP NOT NULL + ); CREATE TABLE IF NOT EXISTS fi_actions ( - id SERIAL PRIMARY KEY, - uuid VARCHAR(72) NOT NULL UNIQUE, - parent_id INTEGER, - event_type VARCHAR(72) NOT NULL, - pointer VARCHAR(72) NOT NULL, - symbol VARCHAR(36) NOT NULL, - amount DECIMAL NOT NULL, - sender VARCHAR(36) NOT NULL, - sender_wallet_type VARCHAR(36) NOT NULL, - receiver VARCHAR(36) NOT NULL, - receiver_wallet_type VARCHAR(36) NOT NULL, - agent VARCHAR(20), - ip VARCHAR(11), - create_date TIMESTAMP NOT NULL, - status VARCHAR(20) -); + id + SERIAL + PRIMARY + KEY, + uuid + VARCHAR +( + 72 +) NOT NULL UNIQUE, + parent_id INTEGER, + event_type VARCHAR +( + 72 +) NOT NULL, + pointer VARCHAR +( + 72 +) NOT NULL, + symbol VARCHAR +( + 36 +) NOT NULL, + amount DECIMAL NOT NULL, + sender VARCHAR +( + 36 +) NOT NULL, + sender_wallet_type VARCHAR +( + 36 +) NOT NULL, + receiver VARCHAR +( + 36 +) NOT NULL, + receiver_wallet_type VARCHAR +( + 36 +) NOT NULL, + agent VARCHAR +( + 20 +), + ip VARCHAR +( + 11 +), + create_date TIMESTAMP NOT NULL, + status VARCHAR +( + 20 +) + ); CREATE INDEX IF NOT EXISTS idx_fi_actions_symbol ON fi_actions(symbol); CREATE INDEX IF NOT EXISTS idx_fi_event_type ON fi_actions(event_type); CREATE INDEX IF NOT EXISTS idx_fi_actions_status ON fi_actions(status); CREATE INDEX IF NOT EXISTS idx_fi_actions_pointer ON fi_actions(pointer); ALTER TABLE fi_actions - ADD COLUMN IF NOT EXISTS category_name VARCHAR(36); + ADD COLUMN IF NOT EXISTS category_name VARCHAR (36); CREATE TABLE IF NOT EXISTS fi_action_retry ( - id SERIAL PRIMARY KEY, - fa_id INTEGER NOT NULL UNIQUE REFERENCES fi_actions (id), - retries INTEGER NOT NULL DEFAULT 0, + id + SERIAL + PRIMARY + KEY, + fa_id + INTEGER + NOT + NULL + UNIQUE + REFERENCES + fi_actions +( + id +), + retries INTEGER NOT NULL DEFAULT 0, next_run_time TIMESTAMP NOT NULL, - is_resolved BOOLEAN NOT NULL DEFAULT false, - has_given_up BOOLEAN NOT NULL DEFAULT false -); + is_resolved BOOLEAN NOT NULL DEFAULT false, + has_given_up BOOLEAN NOT NULL DEFAULT false + ); CREATE TABLE IF NOT EXISTS fi_action_error ( - id SERIAL PRIMARY KEY, - fa_id INTEGER NOT NULL REFERENCES fi_actions (id), - error TEXT NOT NULL, - message TEXT NOT NULL, - body TEXT, - retry_id INTEGER REFERENCES fi_action_retry (id), - date TIMESTAMP NOT NULL DEFAULT CURRENT_DATE -); + id + SERIAL + PRIMARY + KEY, + fa_id + INTEGER + NOT + NULL + REFERENCES + fi_actions +( + id +), + error TEXT NOT NULL, + message TEXT NOT NULL, + body TEXT, + retry_id INTEGER REFERENCES fi_action_retry +( + id +), + date TIMESTAMP NOT NULL DEFAULT CURRENT_DATE + ); CREATE TABLE IF NOT EXISTS pair_config ( - pair VARCHAR(72) PRIMARY KEY, - left_side_wallet_symbol VARCHAR(36) NOT NULL, - right_side_wallet_symbol VARCHAR(36) NOT NULL, - left_side_fraction DECIMAL NOT NULL, - right_side_fraction DECIMAL NOT NULL, - UNIQUE (left_side_wallet_symbol, right_side_wallet_symbol) -); + pair VARCHAR +( + 72 +) PRIMARY KEY, + left_side_wallet_symbol VARCHAR +( + 36 +) NOT NULL, + right_side_wallet_symbol VARCHAR +( + 36 +) NOT NULL, + left_side_fraction DECIMAL NOT NULL, + right_side_fraction DECIMAL NOT NULL, + UNIQUE +( + left_side_wallet_symbol, + right_side_wallet_symbol +) + ); CREATE TABLE IF NOT EXISTS user_level ( - level VARCHAR(36) PRIMARY KEY -); + level VARCHAR +( + 36 +) PRIMARY KEY + ); CREATE TABLE IF NOT EXISTS pair_fee_config ( - id SERIAL PRIMARY KEY, - pair_config_id VARCHAR(72) NOT NULL REFERENCES pair_config (pair), - direction VARCHAR(36) NOT NULL, - user_level VARCHAR(36) NOT NULL REFERENCES user_level (level), - maker_fee DECIMAL NOT NULL, - taker_fee DECIMAL NOT NULL, - UNIQUE (direction, user_level, pair_config_id) -); + id + SERIAL + PRIMARY + KEY, + pair_config_id + VARCHAR +( + 72 +) NOT NULL REFERENCES pair_config +( + pair +), + direction VARCHAR +( + 36 +) NOT NULL, + user_level VARCHAR +( + 36 +) NOT NULL REFERENCES user_level +( + level +), + maker_fee DECIMAL NOT NULL, + taker_fee DECIMAL NOT NULL, + UNIQUE +( + direction, + user_level, + pair_config_id +) + ); CREATE TABLE IF NOT EXISTS user_level_mapper ( - id SERIAL PRIMARY KEY, - uuid VARCHAR(36) NOT NULL UNIQUE, - user_level VARCHAR(36) NOT NULL REFERENCES user_level (level) -); + id + SERIAL + PRIMARY + KEY, + uuid + VARCHAR +( + 36 +) NOT NULL UNIQUE, + user_level VARCHAR +( + 36 +) NOT NULL REFERENCES user_level +( + level +) + ); CREATE TABLE IF NOT EXISTS temp_events ( - id SERIAL PRIMARY KEY, - ouid VARCHAR(72) NOT NULL, - event_type VARCHAR(72) NOT NULL, - event_body TEXT NOT NULL, - event_date TIMESTAMP NOT NULL -); + id + SERIAL + PRIMARY + KEY, + ouid + VARCHAR +( + 72 +) NOT NULL, + event_type VARCHAR +( + 72 +) NOT NULL, + event_body TEXT NOT NULL, + event_date TIMESTAMP NOT NULL + ); COMMIT; diff --git a/accountant/accountant-ports/accountant-submitter-kafka/pom.xml b/accountant/accountant-ports/accountant-submitter-kafka/pom.xml index 2759d98c3..353a37eba 100644 --- a/accountant/accountant-ports/accountant-submitter-kafka/pom.xml +++ b/accountant/accountant-ports/accountant-submitter-kafka/pom.xml @@ -1,5 +1,5 @@ - 4.0.0 diff --git a/accountant/accountant-ports/accountant-wallet-proxy/pom.xml b/accountant/accountant-ports/accountant-wallet-proxy/pom.xml index 3819743c8..17fecd3ba 100644 --- a/accountant/accountant-ports/accountant-wallet-proxy/pom.xml +++ b/accountant/accountant-ports/accountant-wallet-proxy/pom.xml @@ -1,5 +1,5 @@ - 4.0.0 diff --git a/accountant/accountant-ports/accountant-wallet-proxy/src/main/kotlin/co/nilin/opex/accountant/ports/walletproxy/config/WebClientConfig.kt b/accountant/accountant-ports/accountant-wallet-proxy/src/main/kotlin/co/nilin/opex/accountant/ports/walletproxy/config/WebClientConfig.kt index b559aa504..2ba1c3c02 100644 --- a/accountant/accountant-ports/accountant-wallet-proxy/src/main/kotlin/co/nilin/opex/accountant/ports/walletproxy/config/WebClientConfig.kt +++ b/accountant/accountant-ports/accountant-wallet-proxy/src/main/kotlin/co/nilin/opex/accountant/ports/walletproxy/config/WebClientConfig.kt @@ -5,7 +5,6 @@ import org.springframework.cloud.client.loadbalancer.reactive.ReactiveLoadBalanc import org.springframework.cloud.client.loadbalancer.reactive.ReactorLoadBalancerExchangeFilterFunction import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration -import org.springframework.http.client.reactive.ReactorClientHttpConnector import org.springframework.web.reactive.function.client.WebClient import org.zalando.logbook.Logbook import org.zalando.logbook.netty.LogbookClientHandler diff --git a/accountant/pom.xml b/accountant/pom.xml index 15916c8d3..86eefc950 100644 --- a/accountant/pom.xml +++ b/accountant/pom.xml @@ -1,5 +1,5 @@ - 4.0.0 diff --git a/api/api-app/src/main/kotlin/co/nilin/opex/api/app/ApiApp.kt b/api/api-app/src/main/kotlin/co/nilin/opex/api/app/ApiApp.kt index 35df759a8..e1c0b542a 100644 --- a/api/api-app/src/main/kotlin/co/nilin/opex/api/app/ApiApp.kt +++ b/api/api-app/src/main/kotlin/co/nilin/opex/api/app/ApiApp.kt @@ -2,10 +2,8 @@ package co.nilin.opex.api.app import org.springframework.boot.autoconfigure.SpringBootApplication import org.springframework.boot.runApplication -import org.springframework.cache.annotation.EnableCaching import org.springframework.context.annotation.ComponentScan import org.springframework.scheduling.annotation.EnableScheduling -import springfox.documentation.swagger2.annotations.EnableSwagger2 @SpringBootApplication @ComponentScan("co.nilin.opex") diff --git a/api/api-app/src/main/kotlin/co/nilin/opex/api/app/controller/APIKeyController.kt b/api/api-app/src/main/kotlin/co/nilin/opex/api/app/controller/APIKeyController.kt index ab8bcd624..7a616d2d0 100644 --- a/api/api-app/src/main/kotlin/co/nilin/opex/api/app/controller/APIKeyController.kt +++ b/api/api-app/src/main/kotlin/co/nilin/opex/api/app/controller/APIKeyController.kt @@ -7,14 +7,7 @@ import co.nilin.opex.api.ports.binance.util.jwtAuthentication import co.nilin.opex.api.ports.binance.util.tokenValue import org.springframework.security.core.annotation.CurrentSecurityContext import org.springframework.security.core.context.SecurityContext -import org.springframework.web.bind.annotation.DeleteMapping -import org.springframework.web.bind.annotation.GetMapping -import org.springframework.web.bind.annotation.PathVariable -import org.springframework.web.bind.annotation.PostMapping -import org.springframework.web.bind.annotation.PutMapping -import org.springframework.web.bind.annotation.RequestBody -import org.springframework.web.bind.annotation.RequestMapping -import org.springframework.web.bind.annotation.RestController +import org.springframework.web.bind.annotation.* import java.security.Principal @RestController diff --git a/api/api-app/src/main/kotlin/co/nilin/opex/api/app/data/APIKeyResponse.kt b/api/api-app/src/main/kotlin/co/nilin/opex/api/app/data/APIKeyResponse.kt index dfe733f83..b2832019f 100644 --- a/api/api-app/src/main/kotlin/co/nilin/opex/api/app/data/APIKeyResponse.kt +++ b/api/api-app/src/main/kotlin/co/nilin/opex/api/app/data/APIKeyResponse.kt @@ -1,7 +1,6 @@ package co.nilin.opex.api.app.data import java.time.LocalDateTime -import java.util.* data class APIKeyResponse( val label: String, diff --git a/api/api-app/src/main/kotlin/co/nilin/opex/api/app/service/APIKeyServiceImpl.kt b/api/api-app/src/main/kotlin/co/nilin/opex/api/app/service/APIKeyServiceImpl.kt index 034808af0..a95ae30f5 100644 --- a/api/api-app/src/main/kotlin/co/nilin/opex/api/app/service/APIKeyServiceImpl.kt +++ b/api/api-app/src/main/kotlin/co/nilin/opex/api/app/service/APIKeyServiceImpl.kt @@ -25,7 +25,6 @@ import java.util.concurrent.TimeUnit import javax.crypto.Cipher import javax.crypto.spec.IvParameterSpec import javax.crypto.spec.SecretKeySpec -import kotlin.math.log @Service class APIKeyServiceImpl( diff --git a/api/api-core/src/main/kotlin/co/nilin/opex/api/core/spi/BlockchainGatewayProxy.kt b/api/api-core/src/main/kotlin/co/nilin/opex/api/core/spi/BlockchainGatewayProxy.kt index cd99d1064..abc249a26 100644 --- a/api/api-core/src/main/kotlin/co/nilin/opex/api/core/spi/BlockchainGatewayProxy.kt +++ b/api/api-core/src/main/kotlin/co/nilin/opex/api/core/spi/BlockchainGatewayProxy.kt @@ -10,6 +10,7 @@ interface BlockchainGatewayProxy { suspend fun getDepositDetails(refs: List): List - suspend fun getCurrencyImplementations(currency: String? = null): List +// suspend fun getCurrencyImplementations(currency: String? = null): List + } \ No newline at end of file diff --git a/api/api-core/src/main/kotlin/co/nilin/opex/api/core/spi/MarketDataProxy.kt b/api/api-core/src/main/kotlin/co/nilin/opex/api/core/spi/MarketDataProxy.kt index 00b3d2abf..f58daca30 100644 --- a/api/api-core/src/main/kotlin/co/nilin/opex/api/core/spi/MarketDataProxy.kt +++ b/api/api-core/src/main/kotlin/co/nilin/opex/api/core/spi/MarketDataProxy.kt @@ -2,7 +2,6 @@ package co.nilin.opex.api.core.spi import co.nilin.opex.api.core.inout.* import co.nilin.opex.common.utils.Interval -import java.time.LocalDateTime interface MarketDataProxy { 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 85a628217..8c8620f1c 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 @@ -14,25 +14,25 @@ interface WalletProxy { suspend fun getOwnerLimits(uuid: String?, token: String?): OwnerLimitsResponse suspend fun getDepositTransactions( - uuid: String, - token: String?, - coin: String?, - startTime: Long?, - endTime: Long?, - limit: Int, - offset: Int, - ascendingByTime: Boolean? + uuid: String, + token: String?, + coin: String?, + startTime: Long?, + endTime: Long?, + limit: Int, + offset: Int, + ascendingByTime: Boolean? ): List suspend fun getWithdrawTransactions( - uuid: String, - token: String?, - coin: String?, - startTime: Long?, - endTime: Long?, - limit: Int, - offset: Int, - ascendingByTime: Boolean? + uuid: String, + token: String?, + coin: String?, + startTime: Long?, + endTime: Long?, + limit: Int, + offset: Int, + ascendingByTime: Boolean? ): List diff --git a/api/api-ports/api-binance-rest/src/main/kotlin/co/nilin/opex/api/ports/binance/config/WebClientConfig.kt b/api/api-ports/api-binance-rest/src/main/kotlin/co/nilin/opex/api/ports/binance/config/WebClientConfig.kt index 57f5243a9..7033f8027 100644 --- a/api/api-ports/api-binance-rest/src/main/kotlin/co/nilin/opex/api/ports/binance/config/WebClientConfig.kt +++ b/api/api-ports/api-binance-rest/src/main/kotlin/co/nilin/opex/api/ports/binance/config/WebClientConfig.kt @@ -5,7 +5,6 @@ import org.springframework.cloud.client.loadbalancer.reactive.ReactiveLoadBalanc import org.springframework.cloud.client.loadbalancer.reactive.ReactorLoadBalancerExchangeFilterFunction import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration -import org.springframework.http.client.reactive.ReactorClientHttpConnector import org.springframework.web.reactive.function.client.WebClient import org.zalando.logbook.Logbook import org.zalando.logbook.netty.LogbookClientHandler diff --git a/api/api-ports/api-binance-rest/src/main/kotlin/co/nilin/opex/api/ports/binance/controller/MarketController.kt b/api/api-ports/api-binance-rest/src/main/kotlin/co/nilin/opex/api/ports/binance/controller/MarketController.kt index d4dc0b3d5..761bd14f0 100644 --- a/api/api-ports/api-binance-rest/src/main/kotlin/co/nilin/opex/api/ports/binance/controller/MarketController.kt +++ b/api/api-ports/api-binance-rest/src/main/kotlin/co/nilin/opex/api/ports/binance/controller/MarketController.kt @@ -176,28 +176,28 @@ class MarketController( } // Custom service - @GetMapping("/v3/currencyInfo") - suspend fun getNetworks(@RequestParam(required = false) currency: String?): List { - return blockchainGatewayProxy.getCurrencyImplementations(currency) - .groupBy { it.currency } - .toList() - .map { pair -> - CurrencyNetworkResponse( - pair.first.symbol, - pair.first.name, - pair.second.map { - CurrencyNetwork( - it.chain.name, - it.implCurrency.symbol, - it.withdrawMin, - it.withdrawFee, - it.token, - it.tokenAddress - ) - } - ) - } - } +// @GetMapping("/v3/currencyInfo") +// suspend fun getNetworks(@RequestParam(required = false) currency: String?): List { +// return blockchainGatewayProxy.getCurrencyImplementations(currency) +// .groupBy { it.currency } +// .toList() +// .map { pair -> +// CurrencyNetworkResponse( +// pair.first.symbol, +// pair.first.name, +// pair.second.map { +// CurrencyNetwork( +// it.chain.name, +// it.implCurrency.symbol, +// it.withdrawMin, +// it.withdrawFee, +// it.token, +// it.tokenAddress +// ) +// } +// ) +// } +// } // Custom service @GetMapping("/v3/currencyInfo/quotes") diff --git a/api/api-ports/api-binance-rest/src/main/kotlin/co/nilin/opex/api/ports/binance/controller/WalletController.kt b/api/api-ports/api-binance-rest/src/main/kotlin/co/nilin/opex/api/ports/binance/controller/WalletController.kt index 0b21b8399..1e73fe7a4 100644 --- a/api/api-ports/api-binance-rest/src/main/kotlin/co/nilin/opex/api/ports/binance/controller/WalletController.kt +++ b/api/api-ports/api-binance-rest/src/main/kotlin/co/nilin/opex/api/ports/binance/controller/WalletController.kt @@ -7,14 +7,9 @@ import co.nilin.opex.api.ports.binance.data.* import co.nilin.opex.api.ports.binance.util.jwtAuthentication import co.nilin.opex.api.ports.binance.util.tokenValue import co.nilin.opex.common.OpexError -import co.nilin.opex.common.utils.Interval 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.RequestParam -import org.springframework.web.bind.annotation.RestController +import org.springframework.web.bind.annotation.* import java.math.BigDecimal import java.time.Instant import java.time.LocalDateTime diff --git a/api/api-ports/api-binance-rest/src/main/kotlin/co/nilin/opex/api/ports/binance/data/NewOrderResponse.kt b/api/api-ports/api-binance-rest/src/main/kotlin/co/nilin/opex/api/ports/binance/data/NewOrderResponse.kt index 69bbe87a2..cc50e652f 100644 --- a/api/api-ports/api-binance-rest/src/main/kotlin/co/nilin/opex/api/ports/binance/data/NewOrderResponse.kt +++ b/api/api-ports/api-binance-rest/src/main/kotlin/co/nilin/opex/api/ports/binance/data/NewOrderResponse.kt @@ -4,7 +4,6 @@ import co.nilin.opex.api.core.inout.OrderSide import co.nilin.opex.api.core.inout.OrderStatus import co.nilin.opex.api.core.inout.OrderType import co.nilin.opex.api.core.inout.TimeInForce -import co.nilin.opex.api.ports.binance.controller.AccountController import com.fasterxml.jackson.annotation.JsonInclude import java.math.BigDecimal import java.util.* diff --git a/api/api-ports/api-binance-rest/src/main/kotlin/co/nilin/opex/api/ports/binance/data/WithDrawRequest.kt b/api/api-ports/api-binance-rest/src/main/kotlin/co/nilin/opex/api/ports/binance/data/WithDrawRequest.kt index 4b32b5080..00cccfaa3 100644 --- a/api/api-ports/api-binance-rest/src/main/kotlin/co/nilin/opex/api/ports/binance/data/WithDrawRequest.kt +++ b/api/api-ports/api-binance-rest/src/main/kotlin/co/nilin/opex/api/ports/binance/data/WithDrawRequest.kt @@ -1,18 +1,17 @@ package co.nilin.opex.api.ports.binance.data import com.fasterxml.jackson.annotation.JsonProperty -import org.springframework.web.bind.annotation.RequestParam data class WithDrawRequest( - var coin: String?, - var withdrawOrderId: String?, - @JsonProperty("status") - var withdrawStatus: Int?, - var offset: Int?, - var limit: Int?, - var startTime: Long?, - var endTime: Long?, - var ascendingByTime: Boolean? = false, - var recvWindow: Long?, //The value cannot be greater than 60000 - var timestamp: Long, + var coin: String?, + var withdrawOrderId: String?, + @JsonProperty("status") + var withdrawStatus: Int?, + var offset: Int?, + var limit: Int?, + var startTime: Long?, + var endTime: Long?, + var ascendingByTime: Boolean? = false, + var recvWindow: Long?, //The value cannot be greater than 60000 + var timestamp: Long, ) diff --git a/api/api-ports/api-opex-rest/src/main/kotlin/co/nilin/opex/api/ports/opex/config/WebClientConfig.kt b/api/api-ports/api-opex-rest/src/main/kotlin/co/nilin/opex/api/ports/opex/config/WebClientConfig.kt index 7da7c0aad..96edf5772 100644 --- a/api/api-ports/api-opex-rest/src/main/kotlin/co/nilin/opex/api/ports/opex/config/WebClientConfig.kt +++ b/api/api-ports/api-opex-rest/src/main/kotlin/co/nilin/opex/api/ports/opex/config/WebClientConfig.kt @@ -5,7 +5,6 @@ import org.springframework.cloud.client.loadbalancer.reactive.ReactiveLoadBalanc import org.springframework.cloud.client.loadbalancer.reactive.ReactorLoadBalancerExchangeFilterFunction import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration -import org.springframework.http.client.reactive.ReactorClientHttpConnector import org.springframework.web.reactive.function.client.WebClient import org.zalando.logbook.Logbook import org.zalando.logbook.netty.LogbookClientHandler diff --git a/api/api-ports/api-opex-rest/src/main/kotlin/co/nilin/opex/api/ports/opex/controller/AccountController.kt b/api/api-ports/api-opex-rest/src/main/kotlin/co/nilin/opex/api/ports/opex/controller/AccountController.kt index 2fef5ab05..852fe64bc 100644 --- a/api/api-ports/api-opex-rest/src/main/kotlin/co/nilin/opex/api/ports/opex/controller/AccountController.kt +++ b/api/api-ports/api-opex-rest/src/main/kotlin/co/nilin/opex/api/ports/opex/controller/AccountController.kt @@ -1,11 +1,6 @@ package co.nilin.opex.api.ports.opex.controller -import co.nilin.opex.api.core.inout.* -import co.nilin.opex.api.core.spi.MarketUserDataProxy -import co.nilin.opex.api.core.spi.MatchingGatewayProxy -import co.nilin.opex.api.core.spi.SymbolMapper -import co.nilin.opex.api.core.spi.WalletProxy -import org.springframework.web.bind.annotation.* +import org.springframework.web.bind.annotation.RestController @RestController diff --git a/api/api-ports/api-persister-postgres/src/main/kotlin/co/nilin/opex/api/ports/postgres/model/APIKeyModel.kt b/api/api-ports/api-persister-postgres/src/main/kotlin/co/nilin/opex/api/ports/postgres/model/APIKeyModel.kt index 77f4bf4c5..f33c9cd65 100644 --- a/api/api-ports/api-persister-postgres/src/main/kotlin/co/nilin/opex/api/ports/postgres/model/APIKeyModel.kt +++ b/api/api-ports/api-persister-postgres/src/main/kotlin/co/nilin/opex/api/ports/postgres/model/APIKeyModel.kt @@ -4,7 +4,7 @@ import org.springframework.data.annotation.Id import org.springframework.data.relational.core.mapping.Column import org.springframework.data.relational.core.mapping.Table import java.time.LocalDateTime -import java.util.UUID +import java.util.* @Table("api_key") data class APIKeyModel( diff --git a/api/api-ports/api-persister-postgres/src/main/resources/schema.sql b/api/api-ports/api-persister-postgres/src/main/resources/schema.sql index 1d4db9878..5f4a12367 100644 --- a/api/api-ports/api-persister-postgres/src/main/resources/schema.sql +++ b/api/api-ports/api-persister-postgres/src/main/resources/schema.sql @@ -1,23 +1,54 @@ CREATE TABLE IF NOT EXISTS symbol_maps ( - id SERIAL PRIMARY KEY, - symbol VARCHAR(72) NOT NULL, - alias_key VARCHAR(72) NOT NULL, - alias VARCHAR(72) NOT NULL, - UNIQUE (symbol, alias_key, alias) -); + id + SERIAL + PRIMARY + KEY, + symbol + VARCHAR +( + 72 +) NOT NULL, + alias_key VARCHAR +( + 72 +) NOT NULL, + alias VARCHAR +( + 72 +) NOT NULL, + UNIQUE +( + symbol, + alias_key, + alias +) + ); CREATE TABLE IF NOT EXISTS api_key ( - id SERIAL PRIMARY KEY, - user_id VARCHAR(36) NOT NULL, - label VARCHAR(200) NOT NULL, - access_token TEXT NOT NULL, - refresh_token TEXT NOT NULL, - expiration_time TIMESTAMP, - allowed_ips TEXT, - token_expiration_time TIMESTAMP NOT NULL, - key VARCHAR(36) NOT NULL UNIQUE, - is_enabled BOOLEAN NOT NULL DEFAULT true, - is_expired BOOLEAN NOT NULL DEFAULT false -); + id + SERIAL + PRIMARY + KEY, + user_id + VARCHAR +( + 36 +) NOT NULL, + label VARCHAR +( + 200 +) NOT NULL, + access_token TEXT NOT NULL, + refresh_token TEXT NOT NULL, + expiration_time TIMESTAMP, + allowed_ips TEXT, + token_expiration_time TIMESTAMP NOT NULL, + key VARCHAR +( + 36 +) NOT NULL UNIQUE, + is_enabled BOOLEAN NOT NULL DEFAULT true, + is_expired BOOLEAN NOT NULL DEFAULT false + ); diff --git a/api/api-ports/api-persister-postgres/src/test/kotlin/co/nilin/opex/api/ports/postgres/impl/sample/Samples.kt b/api/api-ports/api-persister-postgres/src/test/kotlin/co/nilin/opex/api/ports/postgres/impl/sample/Samples.kt index b6fc9e909..82e2905ba 100644 --- a/api/api-ports/api-persister-postgres/src/test/kotlin/co/nilin/opex/api/ports/postgres/impl/sample/Samples.kt +++ b/api/api-ports/api-persister-postgres/src/test/kotlin/co/nilin/opex/api/ports/postgres/impl/sample/Samples.kt @@ -1,9 +1,6 @@ package co.nilin.opex.api.ports.postgres.impl.sample import co.nilin.opex.api.ports.postgres.model.SymbolMapModel -import java.security.Principal -import java.time.LocalDateTime -import java.time.ZoneOffset object VALID { 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 33a6640f4..1d0636ba3 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 @@ -1,10 +1,10 @@ package co.nilin.opex.api.ports.proxy.data data class TransactionRequest( - val coin: String?, - val startTime: Long?=null, - val endTime: Long?=null, - val limit: Int, - val offset: Int, - val ascendingByTime: Boolean? = false + val coin: String?, + val startTime: Long? = null, + val endTime: Long? = null, + 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/BlockchainGatewayProxyImpl.kt b/api/api-ports/api-proxy-rest/src/main/kotlin/co/nilin/opex/api/ports/proxy/impl/BlockchainGatewayProxyImpl.kt index bc3fa6814..a7d53ac6f 100644 --- a/api/api-ports/api-proxy-rest/src/main/kotlin/co/nilin/opex/api/ports/proxy/impl/BlockchainGatewayProxyImpl.kt +++ b/api/api-ports/api-proxy-rest/src/main/kotlin/co/nilin/opex/api/ports/proxy/impl/BlockchainGatewayProxyImpl.kt @@ -59,19 +59,17 @@ class BlockchainGatewayProxyImpl(private val client: WebClient) : BlockchainGate } } - override suspend fun getCurrencyImplementations(currency: String?): List { - logger.info("calling bc-gateway chain details") - return withContext(ProxyDispatchers.general) { - client.get() - .uri("$baseUrl/currency/chains") { - it.queryParam("currency", currency) - it.build() - }.accept(MediaType.APPLICATION_JSON) - .retrieve() - .onStatus({ t -> t.isError }, { it.createException() }) - .bodyToFlux() - .collectList() - .awaitFirstOrElse { emptyList() } - } - } +// override suspend fun getCurrencyImplementations(currency: String?): List { +// logger.info("calling bc-gateway chain details") +// return client.get() +// .uri("$baseUrl/currency/chains") { +// it.queryParam("currency", currency) +// it.build() +// }.accept(MediaType.APPLICATION_JSON) +// .retrieve() +// .onStatus({ t -> t.isError }, { it.createException() }) +// .bodyToFlux() +// .collectList() +// .awaitFirstOrElse { emptyList() } +// } } \ No newline at end of file diff --git a/bc-gateway/bc-gateway-app/pom.xml b/bc-gateway/bc-gateway-app/pom.xml index 86f6888d3..58dc07a68 100644 --- a/bc-gateway/bc-gateway-app/pom.xml +++ b/bc-gateway/bc-gateway-app/pom.xml @@ -1,5 +1,5 @@ - 4.0.0 @@ -112,6 +112,10 @@ co.nilin.opex.bcgateway.ports.walletproxy bc-gateway-wallet-proxy + + co.nilin.opex.bcgateway.ports.omniwallet + bc-gateway-omniwallet-proxy + co.nilin.opex.bcgateway.ports.authproxy bc-gateway-auth-proxy diff --git a/bc-gateway/bc-gateway-app/src/main/kotlin/co/nilin/opex/bcgateway/app/config/AppConfig.kt b/bc-gateway/bc-gateway-app/src/main/kotlin/co/nilin/opex/bcgateway/app/config/AppConfig.kt index 67e51c50a..8dfd8a261 100644 --- a/bc-gateway/bc-gateway-app/src/main/kotlin/co/nilin/opex/bcgateway/app/config/AppConfig.kt +++ b/bc-gateway/bc-gateway-app/src/main/kotlin/co/nilin/opex/bcgateway/app/config/AppConfig.kt @@ -6,24 +6,33 @@ import co.nilin.opex.bcgateway.core.api.InfoService import co.nilin.opex.bcgateway.core.service.AssignAddressServiceImpl import co.nilin.opex.bcgateway.core.service.InfoServiceImpl import co.nilin.opex.bcgateway.core.spi.AssignedAddressHandler -import co.nilin.opex.bcgateway.core.spi.CurrencyHandler +import co.nilin.opex.bcgateway.core.spi.ChainLoader import co.nilin.opex.bcgateway.core.spi.ReservedAddressHandler import co.nilin.opex.bcgateway.ports.kafka.listener.consumer.AdminEventKafkaListener import co.nilin.opex.bcgateway.ports.kafka.listener.spi.AdminEventListener +import co.nilin.opex.bcgateway.ports.postgres.impl.CurrencyHandlerImplV2 import org.springframework.beans.factory.annotation.Autowired import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration +import org.springframework.core.io.ResourceLoader +import java.security.KeyFactory +import java.security.PublicKey +import java.security.spec.PKCS8EncodedKeySpec +import java.security.spec.X509EncodedKeySpec +import java.util.* + @Configuration -class AppConfig { +class AppConfig(private val resourceLoader: ResourceLoader) { @Bean fun assignAddressService( - currencyHandler: CurrencyHandler, + currencyHandler: CurrencyHandlerImplV2, assignedAddressHandler: AssignedAddressHandler, - reservedAddressHandler: ReservedAddressHandler + reservedAddressHandler: ReservedAddressHandler, + chainLoader: ChainLoader ): AssignAddressService { - return AssignAddressServiceImpl(currencyHandler, assignedAddressHandler, reservedAddressHandler) + return AssignAddressServiceImpl(currencyHandler, assignedAddressHandler, reservedAddressHandler, chainLoader) } @Bean @@ -38,4 +47,20 @@ class AppConfig { ) { adminKafkaEventListener.addEventListener(adminEventListener) } + + @Bean("webhookPublicKey") + fun webhookPublicKey(): PublicKey { + val publicKeyString = resourceLoader.getResource("classpath:scanner-public.pem").inputStream + .readAllBytes() + .toString(Charsets.UTF_8) + .replace("-----BEGIN PUBLIC KEY-----", "") + .replace("-----END PUBLIC KEY-----", "") + .replace("\n", "") + + val keyBytes = Base64.getDecoder().decode(publicKeyString) + val keySpec = X509EncodedKeySpec(keyBytes) + val keyFactory = KeyFactory.getInstance("RSA") + return keyFactory.generatePublic(keySpec) + } + } diff --git a/bc-gateway/bc-gateway-app/src/main/kotlin/co/nilin/opex/bcgateway/app/config/ErrorConfig.kt b/bc-gateway/bc-gateway-app/src/main/kotlin/co/nilin/opex/bcgateway/app/config/ErrorConfig.kt new file mode 100644 index 000000000..b05337f4a --- /dev/null +++ b/bc-gateway/bc-gateway-app/src/main/kotlin/co/nilin/opex/bcgateway/app/config/ErrorConfig.kt @@ -0,0 +1,30 @@ +package co.nilin.opex.bcgateway.app.config + +import co.nilin.opex.common.utils.CustomErrorTranslator +import co.nilin.opex.utility.error.spi.ErrorTranslator +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean +import org.springframework.context.MessageSource +import org.springframework.context.annotation.Bean +import org.springframework.context.annotation.Configuration +import org.springframework.context.annotation.Profile +import org.springframework.context.support.ReloadableResourceBundleMessageSource + +@Configuration +@Profile("otc") +class ErrorConfig { + + @Bean + fun messageSource(): MessageSource { + val messageSource = ReloadableResourceBundleMessageSource() + messageSource.setBasename("classpath:messages") + messageSource.setCacheSeconds(10) //reload messages every 10 seconds + messageSource.setDefaultEncoding("UTF-8") + return messageSource + } + + @Bean + @ConditionalOnMissingBean + fun translator(): ErrorTranslator { + return CustomErrorTranslator(messageSource = messageSource()) + } +} \ No newline at end of file diff --git a/bc-gateway/bc-gateway-app/src/main/kotlin/co/nilin/opex/bcgateway/app/config/InitializeService.kt b/bc-gateway/bc-gateway-app/src/main/kotlin/co/nilin/opex/bcgateway/app/config/InitializeService.kt index 58879f017..3e4f3f803 100644 --- a/bc-gateway/bc-gateway-app/src/main/kotlin/co/nilin/opex/bcgateway/app/config/InitializeService.kt +++ b/bc-gateway/bc-gateway-app/src/main/kotlin/co/nilin/opex/bcgateway/app/config/InitializeService.kt @@ -3,7 +3,7 @@ package co.nilin.opex.bcgateway.app.config import co.nilin.opex.bcgateway.ports.postgres.dao.* import co.nilin.opex.bcgateway.ports.postgres.model.AddressTypeModel import co.nilin.opex.bcgateway.ports.postgres.model.ChainAddressTypeModel -import co.nilin.opex.bcgateway.ports.postgres.model.CurrencyImplementationModel +import co.nilin.opex.bcgateway.ports.postgres.model.CurrencyOnChainGatewayModel import co.nilin.opex.utility.preferences.AddressType import co.nilin.opex.utility.preferences.Chain import co.nilin.opex.utility.preferences.Currency @@ -14,16 +14,20 @@ import kotlinx.coroutines.reactor.awaitSingleOrNull import kotlinx.coroutines.runBlocking import org.springframework.beans.factory.annotation.Autowired import org.springframework.context.annotation.DependsOn +import org.springframework.context.annotation.Profile import org.springframework.stereotype.Component +import java.math.BigDecimal +import java.util.* import javax.annotation.PostConstruct @Component @DependsOn("postgresConfig") +@Profile("!otc") class InitializeService( private val addressTypeRepository: AddressTypeRepository, private val chainRepository: ChainRepository, private val chainAddressTypeRepository: ChainAddressTypeRepository, - private val currencyRepository: CurrencyRepository, +// private val currencyRepository: CurrencyRepository, private val currencyImplementationRepository: CurrencyImplementationRepository, ) { @Autowired @@ -54,14 +58,15 @@ class InitializeService( } private suspend fun addCurrencies(data: List) = coroutineScope { - coroutineScope { - data.forEach { - currencyRepository.insert(it.name, it.symbol).awaitSingleOrNull() - } - } +// coroutineScope { +// data.forEach { +// currencyRepository.insert(it.name, it.symbol).awaitSingleOrNull() +// } +// } val items = data.flatMap { it.implementations.map { impl -> it to impl } }.map { (currency, impl) -> - CurrencyImplementationModel( + CurrencyOnChainGatewayModel( null, + UUID.randomUUID().toString(), currency.symbol, impl.symbol.takeUnless { it.isEmpty() } ?: currency.symbol, impl.chain, @@ -69,9 +74,15 @@ class InitializeService( impl.tokenAddress, impl.tokenName, impl.withdrawEnabled, + true!!, impl.withdrawFee, impl.withdrawMin, - impl.decimal + BigDecimal.ZERO, + BigDecimal.ZERO, + BigDecimal.ZERO, + impl.decimal, + true + ) } runCatching { currencyImplementationRepository.saveAll(items).collectList().awaitSingleOrNull() } diff --git a/bc-gateway/bc-gateway-app/src/main/kotlin/co/nilin/opex/bcgateway/app/config/SecurityConfig.kt b/bc-gateway/bc-gateway-app/src/main/kotlin/co/nilin/opex/bcgateway/app/config/SecurityConfig.kt index ca05ba715..d40663b6a 100644 --- a/bc-gateway/bc-gateway-app/src/main/kotlin/co/nilin/opex/bcgateway/app/config/SecurityConfig.kt +++ b/bc-gateway/bc-gateway-app/src/main/kotlin/co/nilin/opex/bcgateway/app/config/SecurityConfig.kt @@ -1,9 +1,7 @@ package co.nilin.opex.bcgateway.app.config -import co.nilin.opex.bcgateway.app.utils.hasRole import co.nilin.opex.bcgateway.app.utils.hasRole import co.nilin.opex.bcgateway.app.utils.hasRoleAndLevel -import org.springframework.beans.factory.annotation.Qualifier import org.springframework.beans.factory.annotation.Value import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Profile @@ -25,21 +23,24 @@ class SecurityConfig(private val webClient: WebClient) { @Profile("!otc") fun springSecurityFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain? { http.csrf().disable() - .authorizeExchange() - .pathMatchers("/actuator/**").permitAll() - .pathMatchers("/swagger-ui/**").permitAll() - .pathMatchers("/swagger-resources/**").permitAll() - .pathMatchers("/wallet-sync/**").permitAll() - .pathMatchers("/currency/**").permitAll() - .pathMatchers("/filter/**").hasAuthority("SCOPE_trust") - .pathMatchers("/admin/**").hasRole("SCOPE_trust", "admin_system") - .pathMatchers("/v1/address/**").permitAll() - .pathMatchers("/deposit/**").permitAll() - .pathMatchers("/addresses/**").hasRole("SCOPE_trust", "admin_system") - .anyExchange().authenticated() - .and() - .oauth2ResourceServer() - .jwt() + .authorizeExchange() + .pathMatchers("/actuator/**").permitAll() + .pathMatchers("/swagger-ui/**").permitAll() + .pathMatchers("/swagger-resources/**").permitAll() + .pathMatchers("/wallet-sync/**").permitAll() + .pathMatchers("/currency/**").permitAll() + .pathMatchers("/filter/**").hasAuthority("SCOPE_trust") + .pathMatchers("/admin/**").hasRole("SCOPE_trust", "admin_system") + .pathMatchers("/v1/address/**").permitAll() + .pathMatchers("/deposit/**").permitAll() + .pathMatchers("/addresses/**").hasRole("SCOPE_trust", "admin_system") + .pathMatchers("/scanner/**").permitAll() + .pathMatchers("/crypto-currency/**").permitAll() + .pathMatchers("/currency/**").permitAll() + .anyExchange().authenticated() + .and() + .oauth2ResourceServer() + .jwt() return http.build() } @@ -48,19 +49,22 @@ class SecurityConfig(private val webClient: WebClient) { @Profile("otc") fun otcSpringSecurityFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain? { http.csrf().disable() - .authorizeExchange() - .pathMatchers("/actuator/**").permitAll() - .pathMatchers("/swagger-ui/**").permitAll() - .pathMatchers(HttpMethod.PUT,"/v1/address").hasRoleAndLevel("Admin") - .pathMatchers("/swagger-resources/**").permitAll() - .pathMatchers("/admin/**").hasRoleAndLevel("Admin") - .pathMatchers("/wallet-sync/**").hasRoleAndLevel("System") - .pathMatchers("/currency/chains").hasRoleAndLevel("user") - .pathMatchers("/currency/**").hasRoleAndLevel("System") - .anyExchange().authenticated() - .and() - .oauth2ResourceServer() - .jwt() + .authorizeExchange() + .pathMatchers("/actuator/**").permitAll() + .pathMatchers("/swagger-ui/**").permitAll() + .pathMatchers(HttpMethod.PUT, "/v1/address").hasRoleAndLevel("Admin") + .pathMatchers("/swagger-resources/**").permitAll() + .pathMatchers("/admin/**").hasRoleAndLevel("Admin") + .pathMatchers("/wallet-sync/**").hasRoleAndLevel("System") + .pathMatchers("/crypto-currency/chain").hasRoleAndLevel("user") + .pathMatchers("/crypto-currency/**").hasRoleAndLevel("System") + .pathMatchers("/omni-balance/bc/**").hasRoleAndLevel("Admin") + .pathMatchers("/actuator/**").permitAll() + .pathMatchers("/scanner/**").permitAll() + .anyExchange().authenticated() + .and() + .oauth2ResourceServer() + .jwt() return http.build() } @@ -68,8 +72,8 @@ class SecurityConfig(private val webClient: WebClient) { @Throws(Exception::class) fun reactiveJwtDecoder(): ReactiveJwtDecoder? { return NimbusReactiveJwtDecoder.withJwkSetUri(jwkUrl) - .webClient(webClient) - .build() + .webClient(webClient) + .build() } diff --git a/bc-gateway/bc-gateway-app/src/main/kotlin/co/nilin/opex/bcgateway/app/config/WebClientConfig.kt b/bc-gateway/bc-gateway-app/src/main/kotlin/co/nilin/opex/bcgateway/app/config/WebClientConfig.kt index 8e4775d8b..4330d39fa 100644 --- a/bc-gateway/bc-gateway-app/src/main/kotlin/co/nilin/opex/bcgateway/app/config/WebClientConfig.kt +++ b/bc-gateway/bc-gateway-app/src/main/kotlin/co/nilin/opex/bcgateway/app/config/WebClientConfig.kt @@ -6,7 +6,6 @@ import org.springframework.cloud.client.loadbalancer.reactive.ReactorLoadBalance import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration import org.springframework.context.annotation.Profile -import org.springframework.http.client.reactive.ReactorClientHttpConnector import org.springframework.web.reactive.function.client.ExchangeStrategies import org.springframework.web.reactive.function.client.WebClient import org.zalando.logbook.Logbook @@ -18,7 +17,10 @@ class WebClientConfig { @Bean @Profile("!otc") - fun loadBalancedWebClient(loadBalancerFactory: ReactiveLoadBalancer.Factory, logbook: Logbook): WebClient { + fun loadBalancedWebClient( + loadBalancerFactory: ReactiveLoadBalancer.Factory, + logbook: Logbook + ): WebClient { val client = HttpClient.create().doOnConnected { it.addHandlerLast(LogbookClientHandler(logbook)) } return WebClient.builder() //.clientConnector(ReactorClientHttpConnector(client)) diff --git a/bc-gateway/bc-gateway-app/src/main/kotlin/co/nilin/opex/bcgateway/app/controller/AddressController.kt b/bc-gateway/bc-gateway-app/src/main/kotlin/co/nilin/opex/bcgateway/app/controller/AddressController.kt index e5510a1dc..4757b2737 100644 --- a/bc-gateway/bc-gateway-app/src/main/kotlin/co/nilin/opex/bcgateway/app/controller/AddressController.kt +++ b/bc-gateway/bc-gateway-app/src/main/kotlin/co/nilin/opex/bcgateway/app/controller/AddressController.kt @@ -2,12 +2,10 @@ package co.nilin.opex.bcgateway.app.controller import co.nilin.opex.bcgateway.core.api.AssignAddressService import co.nilin.opex.bcgateway.core.model.AssignedAddress -import co.nilin.opex.bcgateway.core.model.Currency import co.nilin.opex.bcgateway.core.model.ReservedAddress import co.nilin.opex.bcgateway.core.spi.AddressTypeHandler import co.nilin.opex.bcgateway.core.spi.ReservedAddressHandler import co.nilin.opex.common.OpexError -import co.nilin.opex.utility.error.data.OpexException import kotlinx.coroutines.reactive.awaitSingle import kotlinx.coroutines.reactor.awaitSingleOrNull import org.springframework.http.codec.multipart.FilePart @@ -17,10 +15,6 @@ import org.springframework.web.bind.annotation.* import reactor.core.publisher.Mono import java.io.File import java.nio.charset.StandardCharsets -import java.time.ZoneId -import java.util.Collections -import java.util.stream.Collector -import java.util.stream.Collectors @RestController @RequestMapping("/v1/address") @@ -41,7 +35,7 @@ class AddressController( throw OpexError.Forbidden.exception() val assignedAddress = assignAddressService.assignAddress( assignAddressRequest.uuid, - Currency(assignAddressRequest.currency, assignAddressRequest.currency), + assignAddressRequest.currency, assignAddressRequest.chain ) diff --git a/bc-gateway/bc-gateway-app/src/main/kotlin/co/nilin/opex/bcgateway/app/controller/AdminController.kt b/bc-gateway/bc-gateway-app/src/main/kotlin/co/nilin/opex/bcgateway/app/controller/AdminController.kt index cf4b720d0..6fee22976 100644 --- a/bc-gateway/bc-gateway-app/src/main/kotlin/co/nilin/opex/bcgateway/app/controller/AdminController.kt +++ b/bc-gateway/bc-gateway-app/src/main/kotlin/co/nilin/opex/bcgateway/app/controller/AdminController.kt @@ -5,17 +5,16 @@ import co.nilin.opex.bcgateway.app.service.AdminService import co.nilin.opex.bcgateway.core.model.AddressType import co.nilin.opex.bcgateway.core.spi.AddressTypeHandler import co.nilin.opex.bcgateway.core.spi.ChainLoader -import co.nilin.opex.bcgateway.core.spi.CurrencyHandler +import co.nilin.opex.bcgateway.ports.postgres.impl.CurrencyHandlerImplV2 import co.nilin.opex.common.OpexError import org.springframework.web.bind.annotation.* -import java.math.BigDecimal @RestController @RequestMapping("/admin") class AdminController( private val service: AdminService, private val chainLoader: ChainLoader, - private val currencyHandler: CurrencyHandler, + private val currencyHandler: CurrencyHandlerImplV2, private val addressTypeHandler: AddressTypeHandler ) { @@ -43,55 +42,61 @@ class AdminController( service.addAddressType(body.name, body.addressRegex, body.memoRegex) } - @GetMapping("/token") - suspend fun getCurrencyImplementation(): List { - return currencyHandler.fetchAllImplementations() - .map { - TokenResponse( - it.currency.symbol, - it.chain.name, - it.token, - it.tokenAddress, - it.tokenName, - it.withdrawEnabled, - it.withdrawFee, - it.withdrawMin, - it.decimal - ) - } - } - @PostMapping("/token") - suspend fun addCurrencyImplementation(@RequestBody body: TokenRequest): TokenResponse { - val ex = OpexError.InvalidRequestBody.exception() - with(body) { - if (currencySymbol.isNullOrEmpty() || chain.isNullOrEmpty()) throw ex - if (isToken && (tokenName.isNullOrEmpty() || tokenAddress.isNullOrEmpty())) throw ex - if (withdrawFee < BigDecimal.ZERO || minimumWithdraw < BigDecimal.ZERO || decimal < 0) throw ex - } + // shifted to crypto currency class! - return with(service.addToken(body)) { - TokenResponse( - currency.symbol, - chain.name, - token, - tokenAddress, - tokenName, - withdrawEnabled, - withdrawFee, - withdrawMin, - decimal - ) - } - } +// //todo filter tokens????? +// @GetMapping("/token") +// suspend fun getCurrencyImplementation(): List? { +// return currencyHandler.fetchCurrencyImpls()?.imps +// ?.map { +// TokenResponse( +// it.currencySymbol, +// it.chain, +// it.isToken!!, +// it.tokenAddress, +// it.tokenName, +// it.withdrawAllowed!!, +// it.withdrawFee!!, +// it.withdrawMin!!, +// it.decimal, +// it.isActive!! +// ) +// } +// } - @PutMapping("/token/{symbol}_{chain}/withdraw") - suspend fun changeWithdrawStatus( - @PathVariable symbol: String, - @PathVariable chain: String, - @RequestParam("enabled") status: Boolean - ) { - service.changeTokenWithdrawStatus(symbol, chain, status) - } +// @PostMapping("/token") +// suspend fun addCurrencyImplementation(@RequestBody body: TokenRequest): TokenResponse { +// val ex = OpexError.InvalidRequestBody.exception() +// with(body) { +// if (currencySymbol.isNullOrEmpty() || chain.isNullOrEmpty()) throw ex +// if (isToken && (tokenName.isNullOrEmpty() || tokenAddress.isNullOrEmpty())) throw ex +// if (withdrawFee < BigDecimal.ZERO || minimumWithdraw < BigDecimal.ZERO || decimal < 0) throw ex +// } +// +// return with(service.addToken(body)) { +// TokenResponse( +// currency, +// chain, +// token, +// tokenAddress, +// tokenName, +// withdrawEnabled, +// withdrawFee, +// withdrawMin, +// decimal, +// isActive +// ) +// } +// } + +// @PutMapping("/token/{symbol}_{chain}/withdraw") +// suspend fun changeWithdrawStatus( +// @PathVariable symbol: String, +// @PathVariable chain: String, +// @RequestParam("enabled") status: Boolean +// ) { +// service.changeTokenWithdrawStatus(symbol, chain, status) +// } } diff --git a/bc-gateway/bc-gateway-app/src/main/kotlin/co/nilin/opex/bcgateway/app/controller/CryptoCurrencyController.kt b/bc-gateway/bc-gateway-app/src/main/kotlin/co/nilin/opex/bcgateway/app/controller/CryptoCurrencyController.kt new file mode 100644 index 000000000..de882f7a3 --- /dev/null +++ b/bc-gateway/bc-gateway-app/src/main/kotlin/co/nilin/opex/bcgateway/app/controller/CryptoCurrencyController.kt @@ -0,0 +1,79 @@ +package co.nilin.opex.bcgateway.app.controller + +import co.nilin.opex.bcgateway.app.dto.ChainResponse +import co.nilin.opex.bcgateway.core.model.* +import co.nilin.opex.bcgateway.core.spi.ChainLoader +import co.nilin.opex.bcgateway.core.spi.CryptoCurrencyHandlerV2 +import org.springframework.web.bind.annotation.* + +@RestController +@RequestMapping("/crypto-currency") +class CryptoCurrencyController( + val cryptoCurrencyHandler: CryptoCurrencyHandlerV2, + private val chainLoader: ChainLoader +) { + + @PostMapping("/{currencySymbol}/gateway") + suspend fun addNewCurrencyGateway( + @PathVariable("currencySymbol") currencySymbol: String, + @RequestBody request: CryptoCurrencyCommand + ): CryptoCurrencyCommand? { + return cryptoCurrencyHandler.createOnChainGateway(request.apply { + this.currencySymbol = currencySymbol + }) + } + + + @PutMapping("/{currency}/gateway/{gatewayUuid}") + suspend fun updateCurrencyGateway( + @PathVariable("currency") currencySymbol: String, + @PathVariable("gatewayUuid") gatewayUuid: String, + @RequestBody request: CryptoCurrencyCommand + ): CryptoCurrencyCommand? { + return cryptoCurrencyHandler.updateOnChainGateway(request.apply { + this.currencySymbol = currencySymbol + this.gatewayUuid = gatewayUuid + }) + } + + + @DeleteMapping("/{currency}/gateway/{gatewayUuid}") + suspend fun deleteCurrencyGateway( + @PathVariable("currency") currencySymbol: String, + @PathVariable("gatewayUuid") gatewayUuid: String, + ): Void? { + return cryptoCurrencyHandler.deleteOnChainGateway( + gatewayUuid, currencySymbol + ) + } + + @GetMapping("/gateways") + suspend fun fetchGateways(@RequestParam("currency") currencySymbol: String? = null): List? { + return cryptoCurrencyHandler.fetchCurrencyOnChainGateways(FetchGateways(currencySymbol = currencySymbol)) + } + + @GetMapping("/{currency}/gateways") + suspend fun fetchCurrencyGateways(@PathVariable("currency") currencySymbol: String): List?? { + return cryptoCurrencyHandler.fetchCurrencyOnChainGateways(FetchGateways(currencySymbol = currencySymbol)) + } + + @GetMapping("/{currency}/gateway/{gatewayUuid}") + suspend fun fetchSpecificGateway( + @PathVariable("gatewayUuid") gatewayUuid: String, + @PathVariable("currency") currencySymbol: String + ): CryptoCurrencyCommand? { + return cryptoCurrencyHandler.fetchOnChainGateway(gatewayUuid, currencySymbol) + } + + @GetMapping("/chain") + suspend fun getChains(): List { + return chainLoader.fetchAllChains().map { c -> ChainResponse(c.name, c.addressTypes.map { it.type }) } + } + + + @GetMapping("/{currency}/network/{network}/withdrawData") + suspend fun getFeeForCurrency(@PathVariable currency: String, @PathVariable network: String): WithdrawData { + return cryptoCurrencyHandler.getWithdrawData(currency, network) + } + +} diff --git a/bc-gateway/bc-gateway-app/src/main/kotlin/co/nilin/opex/bcgateway/app/controller/CurrencyController.kt b/bc-gateway/bc-gateway-app/src/main/kotlin/co/nilin/opex/bcgateway/app/controller/CurrencyController.kt deleted file mode 100644 index 213f273a4..000000000 --- a/bc-gateway/bc-gateway-app/src/main/kotlin/co/nilin/opex/bcgateway/app/controller/CurrencyController.kt +++ /dev/null @@ -1,86 +0,0 @@ -package co.nilin.opex.bcgateway.app.controller - -import co.nilin.opex.bcgateway.app.dto.AddCurrencyRequest -import co.nilin.opex.bcgateway.core.model.CurrencyImplementation -import co.nilin.opex.bcgateway.core.model.CurrencyInfo -import co.nilin.opex.bcgateway.core.model.WithdrawData -import co.nilin.opex.bcgateway.core.spi.CurrencyHandler -import org.springframework.web.bind.annotation.GetMapping -import org.springframework.web.bind.annotation.PathVariable -import org.springframework.web.bind.annotation.PostMapping -import org.springframework.web.bind.annotation.PutMapping -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 -import java.math.BigDecimal - -@RestController -@RequestMapping("/currency") -class CurrencyController(val currencyHandler: CurrencyHandler) { - - @GetMapping("/{currency}") - suspend fun fetchCurrencyInfo(@PathVariable("currency") currency: String): CurrencyInfo { - return currencyHandler.fetchCurrencyInfo(currency) - } - - @PostMapping("/{currency}") - suspend fun addCurrencyInfo( - @PathVariable("currency") currencySymbol: String, - @RequestBody addCurrencyRequest: AddCurrencyRequest - ): CurrencyImplementation? { - addCurrencyRequest.currencySymbol = currencySymbol - with(addCurrencyRequest) { - return currencyHandler.addCurrencyImplementationV2( - this.currencySymbol, - implementationSymbol, - currencyName, - chain, - tokenName, - tokenAddress, - isToken!!, - withdrawFee, - minimumWithdraw, - isWithdrawEnabled!!, - decimal - ) - } - } - - @PutMapping("/{currency}") - suspend fun updateCurrencyInfo( - @PathVariable("currency") currencySymbol: String, - @RequestBody addCurrencyRequest: AddCurrencyRequest - ): CurrencyImplementation? { - addCurrencyRequest.currencySymbol = currencySymbol - with(addCurrencyRequest) { - return currencyHandler.updateCurrencyImplementation( - this.currencySymbol, - implementationSymbol, - currencyName, - newChain, - tokenName, - tokenAddress, - isToken!!, - withdrawFee, - minimumWithdraw, - isWithdrawEnabled!!, - decimal, - chain - ) - } - } - - @GetMapping("/chains") - suspend fun getNetworks(@RequestParam(required = false) currency: String?): List { - return if (currency != null) - currencyHandler.findImplementationsByCurrency(currency) - else - currencyHandler.fetchAllImplementations() - } - - @GetMapping("/{currency}/network/{network}/withdrawData") - suspend fun getFeeForCurrency(@PathVariable currency: String, @PathVariable network: String): WithdrawData { - return currencyHandler.getWithdrawData(currency, network) - } -} diff --git a/bc-gateway/bc-gateway-app/src/main/kotlin/co/nilin/opex/bcgateway/app/controller/OmniBCWalletController.kt b/bc-gateway/bc-gateway-app/src/main/kotlin/co/nilin/opex/bcgateway/app/controller/OmniBCWalletController.kt new file mode 100644 index 000000000..17bba3a55 --- /dev/null +++ b/bc-gateway/bc-gateway-app/src/main/kotlin/co/nilin/opex/bcgateway/app/controller/OmniBCWalletController.kt @@ -0,0 +1,23 @@ +package co.nilin.opex.bcgateway.app.controller + +import co.nilin.opex.bcgateway.app.service.OmniBalanceService +import org.springframework.web.bind.annotation.GetMapping +import org.springframework.web.bind.annotation.PathVariable +import org.springframework.web.bind.annotation.RequestMapping +import org.springframework.web.bind.annotation.RestController + +@RestController +@RequestMapping("/omni-balance/bc") +class OmniBCWalletController(private val omniBalanceService: OmniBalanceService) { + + @GetMapping("") + suspend fun getOmniBalance(): List? { + return omniBalanceService.fetchSystemBalance() + } + + @GetMapping("/{currency}") + suspend fun getOmniBalanceOfCurrency(@PathVariable currency: String): OmniBalanceService.OmniBalanceForCurrency { + return omniBalanceService.fetchSystemBalance(currency) + } + +} \ No newline at end of file diff --git a/bc-gateway/bc-gateway-app/src/main/kotlin/co/nilin/opex/bcgateway/app/controller/ScannerController.kt b/bc-gateway/bc-gateway-app/src/main/kotlin/co/nilin/opex/bcgateway/app/controller/ScannerController.kt new file mode 100644 index 000000000..fd89f0b83 --- /dev/null +++ b/bc-gateway/bc-gateway-app/src/main/kotlin/co/nilin/opex/bcgateway/app/controller/ScannerController.kt @@ -0,0 +1,71 @@ +package co.nilin.opex.bcgateway.app.controller + +import co.nilin.opex.bcgateway.core.api.WalletSyncService +import co.nilin.opex.bcgateway.core.model.Transfer +import co.nilin.opex.bcgateway.core.model.Wallet +import co.nilin.opex.common.OpexError +import co.nilin.opex.utility.error.data.OpexException +import com.fasterxml.jackson.databind.ObjectMapper +import org.slf4j.LoggerFactory +import org.springframework.core.io.ResourceLoader +import org.springframework.web.bind.annotation.PostMapping +import org.springframework.web.bind.annotation.RequestBody +import org.springframework.web.bind.annotation.RequestHeader +import org.springframework.web.bind.annotation.RequestMapping +import org.springframework.web.bind.annotation.RestController +import java.math.BigDecimal +import java.security.PublicKey +import java.security.Signature +import java.util.* + +data class WebhookBody( + val txId: String, + val address: String, + val chain: String, + val amount: BigDecimal, + val memo: String?, + val isToken: Boolean, + val tokenAddress: String?, + val id: String?, + val date: Long +) + +@RestController +@RequestMapping("/scanner") +class ScannerController( + private val publicKey: PublicKey, + private val mapper: ObjectMapper, + private val service: WalletSyncService +) { + + private val logger = LoggerFactory.getLogger(ScannerController::class.java) + + @PostMapping("/webhook") + suspend fun webhook(@RequestHeader("X-Signature") sign: String, @RequestBody body: WebhookBody) { + verifySignature(sign, body) + logger.info("Webhook received for address ${body.address}, amount ${body.amount}") + service.sendTransfer(with(body) { Transfer(txId, Wallet(address, memo), isToken, amount, chain, tokenAddress) }) + } + + private fun verifySignature(sign: String, request: WebhookBody) { + try { + logger.info("Verifying signature for address ${request.address}") + val reqStr = mapper.writeValueAsString(request) + val decodedSign = Base64.getDecoder().decode(sign) + val verifier = Signature.getInstance("SHA256withRSA").apply { + initVerify(publicKey) + update(reqStr.toByteArray()) + } + + if (!verifier.verify(decodedSign)) { + logger.warn("Signature is not valid!") + throw OpexError.Forbidden.exception() + } + } catch (e: OpexException) { + throw e + } catch (e: Exception) { + logger.error("Unable to verify signature", e) + throw OpexError.InternalServerError.exception() + } + } +} \ No newline at end of file diff --git a/bc-gateway/bc-gateway-app/src/main/kotlin/co/nilin/opex/bcgateway/app/dto/AddCurrencyRequest.kt b/bc-gateway/bc-gateway-app/src/main/kotlin/co/nilin/opex/bcgateway/app/dto/AddCurrencyRequest.kt index 26682e900..23293ef52 100644 --- a/bc-gateway/bc-gateway-app/src/main/kotlin/co/nilin/opex/bcgateway/app/dto/AddCurrencyRequest.kt +++ b/bc-gateway/bc-gateway-app/src/main/kotlin/co/nilin/opex/bcgateway/app/dto/AddCurrencyRequest.kt @@ -3,16 +3,16 @@ package co.nilin.opex.bcgateway.app.dto import java.math.BigDecimal data class AddCurrencyRequest( - var currencySymbol: String, - var implementationSymbol: String, - var currencyName:String, - var newChain: String?=null, - var tokenName: String?, - var tokenAddress: String?, - var isToken: Boolean? = false, - var withdrawFee: BigDecimal, - var minimumWithdraw: BigDecimal, - var isWithdrawEnabled: Boolean? = true, - var decimal: Int, - var chain: String + var currencySymbol: String, + var implementationSymbol: String, + var currencyName: String, + var newChain: String? = null, + var tokenName: String?, + var tokenAddress: String?, + var isToken: Boolean? = false, + var withdrawFee: BigDecimal, + var minimumWithdraw: BigDecimal, + var isWithdrawEnabled: Boolean? = true, + var decimal: Int, + var chain: String ) \ No newline at end of file diff --git a/bc-gateway/bc-gateway-app/src/main/kotlin/co/nilin/opex/bcgateway/app/dto/TokenResponse.kt b/bc-gateway/bc-gateway-app/src/main/kotlin/co/nilin/opex/bcgateway/app/dto/TokenResponse.kt index d6cbbc9f5..d5bee76b6 100644 --- a/bc-gateway/bc-gateway-app/src/main/kotlin/co/nilin/opex/bcgateway/app/dto/TokenResponse.kt +++ b/bc-gateway/bc-gateway-app/src/main/kotlin/co/nilin/opex/bcgateway/app/dto/TokenResponse.kt @@ -11,5 +11,6 @@ data class TokenResponse( val isWithdrawEnabled: Boolean, val withdrawFee: BigDecimal, val withdrawMin: BigDecimal, - val decimal: Int + val decimal: Int, + val isActive: Boolean ) \ No newline at end of file diff --git a/bc-gateway/bc-gateway-app/src/main/kotlin/co/nilin/opex/bcgateway/app/listener/AdminEventListenerImpl.kt b/bc-gateway/bc-gateway-app/src/main/kotlin/co/nilin/opex/bcgateway/app/listener/AdminEventListenerImpl.kt index 1bcf766c7..7787bbe31 100644 --- a/bc-gateway/bc-gateway-app/src/main/kotlin/co/nilin/opex/bcgateway/app/listener/AdminEventListenerImpl.kt +++ b/bc-gateway/bc-gateway-app/src/main/kotlin/co/nilin/opex/bcgateway/app/listener/AdminEventListenerImpl.kt @@ -1,10 +1,7 @@ package co.nilin.opex.bcgateway.app.listener import co.nilin.opex.bcgateway.app.service.AdminService -import co.nilin.opex.bcgateway.ports.kafka.listener.model.AddCurrencyEvent import co.nilin.opex.bcgateway.ports.kafka.listener.model.AdminEvent -import co.nilin.opex.bcgateway.ports.kafka.listener.model.DeleteCurrencyEvent -import co.nilin.opex.bcgateway.ports.kafka.listener.model.EditCurrencyEvent import co.nilin.opex.bcgateway.ports.kafka.listener.spi.AdminEventListener import kotlinx.coroutines.runBlocking import org.slf4j.LoggerFactory @@ -18,12 +15,14 @@ class AdminEventListenerImpl(private val adminService: AdminService) : AdminEven override fun id() = "AdminEventListener" override fun onEvent(event: AdminEvent, partition: Int, offset: Long, timestamp: Long): Unit = runBlocking { + //todo check with peyman logger.info("Incoming admin event $event") when (event) { - is AddCurrencyEvent -> adminService.addCurrency(event.name, event.symbol) - is EditCurrencyEvent -> adminService.editCurrency(event.name, event.symbol) - is DeleteCurrencyEvent -> adminService.deleteCurrency(event.name) +// is AddCurrencyEvent -> adminService.addCurrency(event.name, event.symbol) +// is EditCurrencyEvent -> adminService.editCurrency(event.name, event.symbol) +// is DeleteCurrencyEvent -> adminService.deleteCurrency(event.name) else -> {} } } + } \ No newline at end of file diff --git a/bc-gateway/bc-gateway-app/src/main/kotlin/co/nilin/opex/bcgateway/app/service/AddressAllocatorJob.kt b/bc-gateway/bc-gateway-app/src/main/kotlin/co/nilin/opex/bcgateway/app/service/AddressAllocatorJob.kt index 4fda7a2c5..94ca46580 100644 --- a/bc-gateway/bc-gateway-app/src/main/kotlin/co/nilin/opex/bcgateway/app/service/AddressAllocatorJob.kt +++ b/bc-gateway/bc-gateway-app/src/main/kotlin/co/nilin/opex/bcgateway/app/service/AddressAllocatorJob.kt @@ -7,18 +7,17 @@ import org.slf4j.Logger import org.springframework.beans.factory.annotation.Value import org.springframework.context.annotation.Configuration import org.springframework.scheduling.annotation.Scheduled -import java.util.concurrent.TimeUnit @Configuration class AddressAllocatorJob(private val addressManager: AddressManager) { private val logger: Logger by LoggerDelegate() - @Value("\${app.address.life-time.value}") - private var lifeTime: Long? = null + @Value("\${app.address.life-time}") + private var addressLifeTime: Long? = null - @Scheduled(fixedDelayString = "\${app.address.life-time.value:0}000") + @Scheduled(fixedDelayString = "60000") fun revokeExpiredAddress() { - if (lifeTime != null) { + if (addressLifeTime != null) { logger.info("going to lookup assigned address .....") runBlocking { addressManager.revokeExpiredAddress() } } diff --git a/bc-gateway/bc-gateway-app/src/main/kotlin/co/nilin/opex/bcgateway/app/service/AdminService.kt b/bc-gateway/bc-gateway-app/src/main/kotlin/co/nilin/opex/bcgateway/app/service/AdminService.kt index aa3b9de76..db4dd8a8d 100644 --- a/bc-gateway/bc-gateway-app/src/main/kotlin/co/nilin/opex/bcgateway/app/service/AdminService.kt +++ b/bc-gateway/bc-gateway-app/src/main/kotlin/co/nilin/opex/bcgateway/app/service/AdminService.kt @@ -1,32 +1,30 @@ package co.nilin.opex.bcgateway.app.service import co.nilin.opex.bcgateway.app.dto.AddChainRequest -import co.nilin.opex.bcgateway.app.dto.TokenRequest -import co.nilin.opex.bcgateway.core.model.CurrencyImplementation import co.nilin.opex.bcgateway.core.spi.AddressTypeHandler import co.nilin.opex.bcgateway.core.spi.ChainLoader -import co.nilin.opex.bcgateway.core.spi.CurrencyHandler +import co.nilin.opex.bcgateway.core.spi.CryptoCurrencyHandlerV2 import org.springframework.stereotype.Service import org.springframework.transaction.annotation.Transactional @Service class AdminService( private val chainLoader: ChainLoader, - private val currencyHandler: CurrencyHandler, + private val currencyHandler: CryptoCurrencyHandlerV2, private val addressTypeHandler: AddressTypeHandler ) { - suspend fun addCurrency(name: String, symbol: String) { - currencyHandler.addCurrency(name, symbol) - } - - suspend fun editCurrency(name: String, symbol: String) { - currencyHandler.editCurrency(name, symbol) - } - - suspend fun deleteCurrency(name: String) { - currencyHandler.deleteCurrency(name) - } +// suspend fun addCurrency(name: String, symbol: String) { +// currencyHandler.addCurrency(name, symbol) +// } +// +// suspend fun editCurrency(name: String, symbol: String) { +// currencyHandler.editCurrency(name, symbol) +// } +// +// suspend fun deleteCurrency(name: String) { +// currencyHandler.deleteCurrency(name) +// } @Transactional suspend fun addChain(body: AddChainRequest) { @@ -37,25 +35,25 @@ class AdminService( addressTypeHandler.addAddressType(name, addressRegex, memoRegex) } - suspend fun addToken(body: TokenRequest): CurrencyImplementation { - return with(body) { - currencyHandler.addCurrencyImplementation( - currencySymbol!!, - implementationSymbol ?: currencySymbol, - chain!!, - tokenName, - tokenAddress, - isToken, - withdrawFee, - minimumWithdraw, - isWithdrawEnabled, - decimal - ) - } - } - - suspend fun changeTokenWithdrawStatus(symbol: String, chain: String, status: Boolean) { - currencyHandler.changeWithdrawStatus(symbol, chain, status) - } +// suspend fun addToken(body: TokenRequest): CryptoCurrencyCommand { +// return with(body) { +// currencyHandler.addCurrencyImplementation( +// currencySymbol!!, +// implementationSymbol ?: currencySymbol, +// chain!!, +// tokenName, +// tokenAddress, +// isToken, +// withdrawFee, +// minimumWithdraw, +// isWithdrawEnabled, +// decimal +// ) +// } +// } + +// suspend fun changeTokenWithdrawStatus(symbol: String, chain: String, status: Boolean) { +// currencyHandler.changeWithdrawStatus(symbol, chain, status) +// } } diff --git a/bc-gateway/bc-gateway-app/src/main/kotlin/co/nilin/opex/bcgateway/app/service/OmniBalanceService.kt b/bc-gateway/bc-gateway-app/src/main/kotlin/co/nilin/opex/bcgateway/app/service/OmniBalanceService.kt new file mode 100644 index 000000000..93318c40a --- /dev/null +++ b/bc-gateway/bc-gateway-app/src/main/kotlin/co/nilin/opex/bcgateway/app/service/OmniBalanceService.kt @@ -0,0 +1,58 @@ +package co.nilin.opex.bcgateway.app.service + +import co.nilin.opex.bcgateway.core.model.FetchGateways +import co.nilin.opex.bcgateway.core.spi.CryptoCurrencyHandlerV2 +import co.nilin.opex.bcgateway.core.spi.OmniWalletManager +import co.nilin.opex.common.OpexError +import org.slf4j.LoggerFactory +import org.springframework.stereotype.Service +import java.math.BigDecimal + +@Service +class OmniBalanceService( + private val cryptoCurrencyHandlerV2: CryptoCurrencyHandlerV2, + private val omniWalletManager: OmniWalletManager +) { + + data class OmniBalanceForCurrency(val currency: String, val balance: BigDecimal? = BigDecimal.ZERO) + data class OmniBalance(val data: ArrayList? = ArrayList()) + + private val logger = LoggerFactory.getLogger(OmniBalanceService::class.java) + + suspend fun fetchSystemBalance(currency: String): OmniBalanceForCurrency { + val currencyImpls = + cryptoCurrencyHandlerV2.fetchCurrencyOnChainGateways(FetchGateways(currencySymbol = currency)) + ?: throw OpexError.CurrencyNotFound.exception() + val totalBalance: BigDecimal = currencyImpls?.map { + when (it.isToken) { + true -> it.tokenAddress?.let { ta -> omniWalletManager.getTokenBalance(it).balance } + ?: BigDecimal.ZERO + + false -> omniWalletManager.getAssetBalance(it).balance ?: BigDecimal.ZERO + else -> BigDecimal.ZERO + } + }.reduce { a, b -> a + b } + return OmniBalanceForCurrency(currency = currency, balance = totalBalance) + } + + suspend fun fetchSystemBalance(): List? { + val currencyImpls = cryptoCurrencyHandlerV2.fetchCurrencyOnChainGateways(FetchGateways()) + ?: throw OpexError.CurrencyNotFound.exception() + val implsGroupedByCurrency = currencyImpls?.groupBy { it.currencySymbol } + val result = ArrayList() + for (currency in implsGroupedByCurrency.keys) { + val balance = implsGroupedByCurrency[currency]?.map { + when (it.isToken) { + true -> it.tokenAddress?.let { ta -> omniWalletManager.getTokenBalance(it).balance } + ?: BigDecimal.ZERO + + false -> omniWalletManager.getAssetBalance(it).balance ?: BigDecimal.ZERO + else -> BigDecimal.ZERO + } + }?.reduce { a, b -> a + b } + result.add(OmniBalanceForCurrency(currency, balance)) + } + return result.toList() + } + +} \ No newline at end of file diff --git a/bc-gateway/bc-gateway-app/src/main/kotlin/co/nilin/opex/bcgateway/app/utils/Extensions.kt b/bc-gateway/bc-gateway-app/src/main/kotlin/co/nilin/opex/bcgateway/app/utils/Extensions.kt index f7306eea4..121c5fc88 100644 --- a/bc-gateway/bc-gateway-app/src/main/kotlin/co/nilin/opex/bcgateway/app/utils/Extensions.kt +++ b/bc-gateway/bc-gateway-app/src/main/kotlin/co/nilin/opex/bcgateway/app/utils/Extensions.kt @@ -6,8 +6,8 @@ import org.springframework.security.config.web.server.ServerHttpSecurity import org.springframework.security.oauth2.jwt.Jwt fun ServerHttpSecurity.AuthorizeExchangeSpec.Access.hasRole( - authority: String, - role: String + authority: String, + role: String ): ServerHttpSecurity.AuthorizeExchangeSpec = access { mono, _ -> mono.map { auth -> val hasAuthority = auth.authorities.any { it.authority == authority } @@ -17,12 +17,12 @@ fun ServerHttpSecurity.AuthorizeExchangeSpec.Access.hasRole( } fun ServerHttpSecurity.AuthorizeExchangeSpec.Access.hasRoleAndLevel( - role: String, - level: String?=null + role: String, + level: String? = null ): ServerHttpSecurity.AuthorizeExchangeSpec = access { mono, _ -> mono.map { auth -> val hasLevel = level?.let { ((auth.principal as Jwt).claims["level"] as String?)?.equals(level) == true } - ?: true + ?: true val hasRole = ((auth.principal as Jwt).claims["roles"] as JSONArray?)?.contains(role) == true AuthorizationDecision(hasLevel && hasRole) } diff --git a/bc-gateway/bc-gateway-app/src/main/resources/application-otc.yml b/bc-gateway/bc-gateway-app/src/main/resources/application-otc.yml index 2661b7831..3d5598e06 100644 --- a/bc-gateway/bc-gateway-app/src/main/resources/application-otc.yml +++ b/bc-gateway/bc-gateway-app/src/main/resources/application-otc.yml @@ -66,6 +66,8 @@ logging: swagger: authUrl: ${SWAGGER_AUTH_URL:https://api.opex.dev/auth}/realms/opex/protocol/openid-connect/token app: + omni-wallet: + url: http://app:8080 #todo ->env auth: url: ${auth_url} cert-url: ${auth_jwk_endpoint} @@ -74,5 +76,4 @@ app: wallet: url: http://wallet:8080 address: - life-time: - value: ${ADDRESS_EXP_TIME} # second + life-time: ${ADDRESS_EXP_TIME} # second diff --git a/bc-gateway/bc-gateway-app/src/main/resources/application.yml b/bc-gateway/bc-gateway-app/src/main/resources/application.yml index 09aafe8ff..780272d81 100644 --- a/bc-gateway/bc-gateway-app/src/main/resources/application.yml +++ b/bc-gateway/bc-gateway-app/src/main/resources/application.yml @@ -48,7 +48,7 @@ management: web: base-path: /actuator exposure: - include: ["health", "prometheus", "metrics"] + include: [ "health", "prometheus", "metrics" ] endpoint: health: show-details: when_authorized @@ -99,6 +99,8 @@ logging: co.nilin: INFO org.zalando.logbook: TRACE app: + omni-wallet: + url: localhost:8080 #todo -> env auth: url: lb://opex-auth cert-url: lb://opex-auth/auth/realms/opex/protocol/openid-connect/certs @@ -107,8 +109,7 @@ app: wallet: url: lb://opex-wallet address: - life-time: - value: ${ADDRESS_EXP_TIME} # second + life-time: 167234670 swagger: authUrl: ${SWAGGER_AUTH_URL:https://api.opex.dev/auth}/realms/opex/protocol/openid-connect/token} diff --git a/bc-gateway/bc-gateway-app/src/main/resources/scanner-public.pem b/bc-gateway/bc-gateway-app/src/main/resources/scanner-public.pem new file mode 100644 index 000000000..8180c26d9 --- /dev/null +++ b/bc-gateway/bc-gateway-app/src/main/resources/scanner-public.pem @@ -0,0 +1,9 @@ +-----BEGIN PUBLIC KEY----- +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqn6tRj45adbvNt6TzxYg +zo4WaREorv91NM5vhQ+wXeY787EmPsQ/mZqyX6yyo5+RnBy9M4mU7ADrS3jQmi+4 +jMCncGrylgYTGAtsY9O6x0sVM/aG7Na3jlXqL/0ZeLyMv0uo0IWhzcapSSTnozOz +oGAyp/VLmQ5Jtk9wgxQlz67sqFMHXRzF4p3/I15eZu7td1oEViHaY1rArXYOsPMD +M4/avAr50kYtP995hApGEdxw1mlBrXyB1Wy7cHuuRDJ7BY3jY8gLE/JJddmKH1/i +vFvKM+K5If2d50qhkI6SQ0aTZ0lEnQsVcdt4o2HT1hxsA8TIz6N1+xVoFjJ27Ry6 +yQIDAQAB +-----END PUBLIC KEY----- diff --git a/bc-gateway/bc-gateway-core/pom.xml b/bc-gateway/bc-gateway-core/pom.xml index 0dce4d6ce..cbd3c236a 100644 --- a/bc-gateway/bc-gateway-core/pom.xml +++ b/bc-gateway/bc-gateway-core/pom.xml @@ -1,5 +1,5 @@ - 4.0.0 diff --git a/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/api/AssignAddressService.kt b/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/api/AssignAddressService.kt index 069db26cc..a154cfc0b 100644 --- a/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/api/AssignAddressService.kt +++ b/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/api/AssignAddressService.kt @@ -1,8 +1,9 @@ package co.nilin.opex.bcgateway.core.api import co.nilin.opex.bcgateway.core.model.AssignedAddress -import co.nilin.opex.bcgateway.core.model.Currency + +//import co.nilin.opex.bcgateway.core.model.Currency interface AssignAddressService { - suspend fun assignAddress(user: String, currency: Currency, chain: String): List + suspend fun assignAddress(user: String, currency: String, chain: String): List } \ No newline at end of file diff --git a/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/api/WalletSyncService.kt b/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/api/WalletSyncService.kt index 68a2032c9..584801888 100644 --- a/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/api/WalletSyncService.kt +++ b/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/api/WalletSyncService.kt @@ -3,5 +3,9 @@ package co.nilin.opex.bcgateway.core.api import co.nilin.opex.bcgateway.core.model.Transfer interface WalletSyncService { + + suspend fun sendTransfer(transfer: Transfer) + + @Deprecated("Use above function instead") suspend fun syncTransfers(transfers: List) } diff --git a/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/model/AssignedAddress.kt b/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/model/AssignedAddress.kt index 47bdd13e6..9dfe6e5db 100644 --- a/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/model/AssignedAddress.kt +++ b/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/model/AssignedAddress.kt @@ -12,7 +12,7 @@ data class AssignedAddress( var assignedDate: LocalDateTime? = null, var revokedDate: LocalDateTime? = null, var status: AddressStatus? = AddressStatus.Reserved, - var id: Long?=null + var id: Long? = null ) { override fun equals(other: Any?): Boolean { if (this === other) return true diff --git a/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/model/AssignedAddressV2.kt b/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/model/AssignedAddressV2.kt new file mode 100644 index 000000000..918423b3c --- /dev/null +++ b/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/model/AssignedAddressV2.kt @@ -0,0 +1,32 @@ +package co.nilin.opex.bcgateway.core.model + +import java.time.LocalDateTime + +data class AssignedAddressV2( + val typeId: Long, + val address: String, + val memo: String?, + var expTime: LocalDateTime? = null, + var assignedDate: LocalDateTime? = null, + var revokedDate: LocalDateTime? = null, + var status: AddressStatus? = AddressStatus.Reserved, + var id: Long? = null +) { + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false + + other as AssignedAddressV2 + + if (address != other.address) return false + if (memo != other.memo) return false + + return true + } + + override fun hashCode(): Int { + var result = address.hashCode() + result = 31 * result + (memo?.hashCode() ?: 0) + return result + } +} diff --git a/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/model/CryptoCurrencyCommand.kt b/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/model/CryptoCurrencyCommand.kt new file mode 100644 index 000000000..dde6a200b --- /dev/null +++ b/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/model/CryptoCurrencyCommand.kt @@ -0,0 +1,37 @@ +package co.nilin.opex.bcgateway.core.model + +import java.math.BigDecimal + +data class CryptoCurrencyCommand( + var currencySymbol: String, + var gatewayUuid: String?, + var implementationSymbol: String? = currencySymbol, + var isActive: Boolean? = true, + var isToken: Boolean? = false, + var tokenName: String? = null, + var tokenAddress: String? = null, + var withdrawFee: BigDecimal?, + var withdrawAllowed: Boolean? = true, + var depositAllowed: Boolean? = true, + val withdrawMin: BigDecimal? = BigDecimal.ZERO, + var withdrawMax: BigDecimal? = BigDecimal.ZERO, + var depositMin: BigDecimal? = BigDecimal.ZERO, + var depositMax: BigDecimal? = BigDecimal.ZERO, + var decimal: Int, + var chain: String, + var type: String = "OnChain" + +// var chainDetail: Chain? = null + + +) { + fun updateTo(newData: CryptoCurrencyCommand): CryptoCurrencyCommand { + return newData.apply { + this.currencySymbol = currencySymbol + this.gatewayUuid = gatewayUuid + } + } + +} + + diff --git a/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/model/Currency.kt b/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/model/Currency.kt index a66ef7a84..580f36d28 100644 --- a/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/model/Currency.kt +++ b/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/model/Currency.kt @@ -1,3 +1,3 @@ -package co.nilin.opex.bcgateway.core.model - -data class Currency(val symbol: String, val name: String) +//package co.nilin.opex.bcgateway.core.model +// +//data class Currency(val symbol: String, val name: String) diff --git a/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/model/CurrencyImplementation.kt b/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/model/CurrencyImplementation.kt index 7eb58a866..9e2f544c8 100644 --- a/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/model/CurrencyImplementation.kt +++ b/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/model/CurrencyImplementation.kt @@ -3,14 +3,16 @@ package co.nilin.opex.bcgateway.core.model import java.math.BigDecimal data class CurrencyImplementation( - val currency: Currency, - val implCurrency: Currency, - val chain: Chain, + val currency: String, + val implCurrency: String, + val chain: String, val token: Boolean, val tokenAddress: String?, val tokenName: String?, val withdrawEnabled: Boolean, val withdrawFee: BigDecimal, val withdrawMin: BigDecimal, - val decimal: Int + val decimal: Int, +// val chainDetail:Chain?=null, + ) diff --git a/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/model/CurrencyInfo.kt b/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/model/CurrencyInfo.kt index fdb9ad665..2a350b440 100644 --- a/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/model/CurrencyInfo.kt +++ b/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/model/CurrencyInfo.kt @@ -1,3 +1,3 @@ package co.nilin.opex.bcgateway.core.model -data class CurrencyInfo(val currency: Currency, val implementations: List) +data class CurrencyInfo(val currency: String, val implementations: List) diff --git a/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/model/Deposit.kt b/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/model/Deposit.kt index 01b728da9..ac44765b4 100644 --- a/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/model/Deposit.kt +++ b/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/model/Deposit.kt @@ -1,16 +1,15 @@ package co.nilin.opex.bcgateway.core.model import java.math.BigDecimal -import java.time.LocalDateTime data class Deposit( - val id: Long?, - val hash: String, - val depositor: String, - val depositorMemo: String?, - val amount: BigDecimal, - val chain: String, - val token: Boolean, - val tokenAddress: String?, + val id: Long?, + val hash: String, + val depositor: String, + val depositorMemo: String?, + val amount: BigDecimal, + val chain: String, + val token: Boolean, + val tokenAddress: String?, -) \ No newline at end of file + ) \ No newline at end of file diff --git a/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/model/FetchGateways.kt b/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/model/FetchGateways.kt new file mode 100644 index 000000000..3af7b2ad0 --- /dev/null +++ b/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/model/FetchGateways.kt @@ -0,0 +1,8 @@ +package co.nilin.opex.bcgateway.core.model + +data class FetchGateways( + val currencySymbol: String? = null, + var gatewayUuid: String? = null, + var chain: String? = null, + var currencyImplementationName: String? = null +) \ No newline at end of file diff --git a/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/model/OmniBalance.kt b/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/model/OmniBalance.kt new file mode 100644 index 000000000..76d6bb134 --- /dev/null +++ b/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/model/OmniBalance.kt @@ -0,0 +1,6 @@ +package co.nilin.opex.bcgateway.core.model + +import java.math.BigDecimal + +data class OmniBalance(val currency: String, val network: String, val balance: BigDecimal? = BigDecimal.ZERO) + diff --git a/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/model/Transfer.kt b/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/model/Transfer.kt index e01b440c5..e33ffbd99 100644 --- a/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/model/Transfer.kt +++ b/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/model/Transfer.kt @@ -5,7 +5,6 @@ import java.math.BigInteger data class Transfer( val txHash: String, - val blockNumber: BigInteger, val receiver: Wallet, val isTokenTransfer: Boolean, val amount: BigDecimal, diff --git a/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/model/otc/LoginRequest.kt b/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/model/otc/LoginRequest.kt index 7d9dc1c70..eac149b2c 100644 --- a/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/model/otc/LoginRequest.kt +++ b/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/model/otc/LoginRequest.kt @@ -1,3 +1,3 @@ package co.nilin.opex.bcgateway.core.model.otc -data class LoginRequest(var clientId:String, var clientSecret:String) +data class LoginRequest(var clientId: String, var clientSecret: String) diff --git a/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/model/otc/LoginResponse.kt b/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/model/otc/LoginResponse.kt index 8a03bffdc..d8c03116c 100644 --- a/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/model/otc/LoginResponse.kt +++ b/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/model/otc/LoginResponse.kt @@ -4,7 +4,9 @@ import com.fasterxml.jackson.annotation.JsonProperty data class LoginResponse(var data: Token) -data class Token(@JsonProperty("access_token") - val accessToken: String, - @JsonProperty("expires_in") - val expireIn: Long) +data class Token( + @JsonProperty("access_token") + val accessToken: String, + @JsonProperty("expires_in") + val expireIn: Long +) diff --git a/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/service/AssignAddressServiceImpl.kt b/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/service/AssignAddressServiceImpl.kt index 37516d23b..da6bc54b2 100644 --- a/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/service/AssignAddressServiceImpl.kt +++ b/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/service/AssignAddressServiceImpl.kt @@ -3,44 +3,48 @@ package co.nilin.opex.bcgateway.core.service import co.nilin.opex.bcgateway.core.api.AssignAddressService import co.nilin.opex.bcgateway.core.model.* import co.nilin.opex.bcgateway.core.spi.AssignedAddressHandler -import co.nilin.opex.bcgateway.core.spi.CurrencyHandler +import co.nilin.opex.bcgateway.core.spi.ChainLoader +import co.nilin.opex.bcgateway.core.spi.CryptoCurrencyHandlerV2 import co.nilin.opex.bcgateway.core.spi.ReservedAddressHandler import co.nilin.opex.bcgateway.core.utils.LoggerDelegate import co.nilin.opex.common.OpexError -import co.nilin.opex.utility.error.data.OpexException import org.slf4j.Logger import org.springframework.beans.factory.annotation.Value import org.springframework.transaction.annotation.Transactional import java.time.LocalDateTime -import java.time.ZoneId open class AssignAddressServiceImpl( - private val currencyHandler: CurrencyHandler, - private val assignedAddressHandler: AssignedAddressHandler, - private val reservedAddressHandler: ReservedAddressHandler + private val currencyHandler: CryptoCurrencyHandlerV2, + private val assignedAddressHandler: AssignedAddressHandler, + private val reservedAddressHandler: ReservedAddressHandler, + private val chainLoader: ChainLoader + ) : AssignAddressService { - @Value("\${app.address.life-time.value}") - private var lifeTime: Long? = null + @Value("\${app.address.life-time}") + private var addressLifeTime: Long? = null private val logger: Logger by LoggerDelegate() @Transactional - override suspend fun assignAddress(user: String, currency: Currency, chain: String): List { - logger.info(ZoneId.systemDefault().toString()) - val currencyInfo = currencyHandler.fetchCurrencyInfo(currency.symbol) - val chains = currencyInfo.implementations - .map { imp -> imp.chain } - .filter { it.name.equals(chain, true) } + override suspend fun assignAddress(user: String, currency: String, chain: String): List { + logger.info("address life time: " + addressLifeTime.toString()) + addressLifeTime = 7200 + val currencyInfo = currencyHandler.fetchCurrencyOnChainGateways(FetchGateways(currencySymbol = currency)) + ?: throw OpexError.CurrencyNotFound.exception() + val chains = currencyInfo + ?.map { imp -> chainLoader.fetchChainInfo(imp.chain) } + ?.filter { it?.name.equals(chain, true) } val addressTypes = chains - .flatMap { chain -> chain.addressTypes } - .distinct() + ?.flatMap { chain -> chain?.addressTypes!! } + ?.distinct() val chainAddressTypeMap = HashMap>() - chains.forEach { chain -> - chain.addressTypes.forEach { addressType -> + chains?.forEach { chain -> + chain?.addressTypes?.forEach { addressType -> chainAddressTypeMap.putIfAbsent(addressType, mutableListOf()) - chainAddressTypeMap.getValue(addressType).add(chain) + chainAddressTypeMap.getValue(addressType).add(chain!!) } } - val userAssignedAddresses = (assignedAddressHandler.fetchAssignedAddresses(user, addressTypes)).toMutableList() + val userAssignedAddresses = + (assignedAddressHandler.fetchAssignedAddresses(user, addressTypes!!)).toMutableList() val result = mutableSetOf() addressTypes.forEach { addressType -> val assigned = userAssignedAddresses.firstOrNull { assignAddress -> assignAddress.type == addressType } @@ -55,17 +59,17 @@ open class AssignAddressServiceImpl( val reservedAddress = reservedAddressHandler.peekReservedAddress(addressType) if (reservedAddress != null) { val newAssigned = AssignedAddress( - user, - reservedAddress.address, - reservedAddress.memo, - addressType, - chainAddressTypeMap[addressType]!!, - lifeTime?.let { LocalDateTime.now().plusSeconds(lifeTime!!) } - ?: null, - LocalDateTime.now(), - null, - AddressStatus.Assigned, - null + user, + reservedAddress.address, + reservedAddress.memo, + addressType, + chainAddressTypeMap[addressType]!!, + addressLifeTime?.let { LocalDateTime.now().plusSeconds(addressLifeTime!!) } + ?: null, + LocalDateTime.now(), + null, + AddressStatus.Assigned, + null ) reservedAddressHandler.remove(reservedAddress) result.add(newAssigned) @@ -78,7 +82,7 @@ open class AssignAddressServiceImpl( } result.forEach { address -> assignedAddressHandler.persist(address) - address.apply { id=null } + address.apply { id = null } } return result.toMutableList() } diff --git a/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/service/AssignAddressServiceImplV2.kt b/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/service/AssignAddressServiceImplV2.kt new file mode 100644 index 000000000..755a84199 --- /dev/null +++ b/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/service/AssignAddressServiceImplV2.kt @@ -0,0 +1,69 @@ +//package co.nilin.opex.bcgateway.core.service +// +//import co.nilin.opex.bcgateway.core.api.AssignAddressService +//import co.nilin.opex.bcgateway.core.model.* +//import co.nilin.opex.bcgateway.core.spi.* +//import co.nilin.opex.bcgateway.core.utils.LoggerDelegate +//import co.nilin.opex.common.OpexError +//import org.slf4j.Logger +//import org.springframework.beans.factory.annotation.Value +//import org.springframework.transaction.annotation.Transactional +//import java.time.LocalDateTime +//import java.time.ZoneId +// +//open class AssignAddressServiceImplV2( +// private val currencyHandler: CryptoCurrencyHandlerV2, +// private val assignedAddressHandler: AssignedAddressHandler, +// private val reservedAddressHandler: ReservedAddressHandler, +// private val chainLoader: ChainLoader +//) : AssignAddressService { +// @Value("\${app.address.life-time}") +// private var lifeTime: Long? = null +// private val logger: Logger by LoggerDelegate() +// +// override suspend fun assignAddress(user: String, currencyImplUuid: String): List { +// logger.info(ZoneId.systemDefault().toString()) +// val result = mutableSetOf() +// currencyHandler.fetchCurrencyImpls(FetchImpls(currencyImplUuid)) +// ?.imps?.firstOrNull()?.let { it -> +// //for requested chain check all available address types and for each of them do : +// chainLoader.fetchChainInfo(it.chain!!).addressTypes.map { it -> it.id }.distinct() +// .forEach { addressType -> +// //check: Is there any assigned address(user, specific address type on requested chain) +// assignedAddressHandler.fetchAssignedAddresses(user, addressType)?.let { +// result.add(it) +// } ?: run { +// // there is no assigned address(user,specific address type on requested chain) +// //then assign new address (ip applicable) +// assignNewAddress(user, addressType)?.let { ra -> +// result.add(ra) +// } +// } +// +// +// } +// if (result.size == 0) +// throw OpexError.ReservedAddressNotAvailable.exception() +// return result.toMutableList() +// } ?: throw OpexError.BadRequest.exception() +// +// } +// +// @Transactional +// open suspend fun assignNewAddress(user: String, addressTypeId: Long): AssignedAddressV2? { +// reservedAddressHandler.peekReservedAddress(addressTypeId)?.let {// +// reservedAddressHandler.remove(it) +// return assignedAddressHandler.persist(user, +// AssignedAddressV2(addressTypeId, it.address, it.memo, +// lifeTime?.let { LocalDateTime.now().plusSeconds(lifeTime!!) } ?: null, +// LocalDateTime.now(), +// null, +// AddressStatus.Assigned, +// null)) +// } +// +// ?: run { return null } +// +// } +// +//} diff --git a/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/service/WalletSyncServiceImpl.kt b/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/service/WalletSyncServiceImpl.kt index 997811691..8f0938eea 100644 --- a/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/service/WalletSyncServiceImpl.kt +++ b/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/service/WalletSyncServiceImpl.kt @@ -1,15 +1,15 @@ package co.nilin.opex.bcgateway.core.service import co.nilin.opex.bcgateway.core.api.WalletSyncService -import co.nilin.opex.bcgateway.core.model.CurrencyImplementation +import co.nilin.opex.bcgateway.core.model.CryptoCurrencyCommand import co.nilin.opex.bcgateway.core.model.Deposit import co.nilin.opex.bcgateway.core.model.Transfer import co.nilin.opex.bcgateway.core.spi.AssignedAddressHandler -import co.nilin.opex.bcgateway.core.spi.CurrencyHandler +import co.nilin.opex.bcgateway.core.spi.CryptoCurrencyHandlerV2 import co.nilin.opex.bcgateway.core.spi.DepositHandler import co.nilin.opex.bcgateway.core.spi.WalletProxy import co.nilin.opex.bcgateway.core.utils.LoggerDelegate -import kotlinx.coroutines.async +import co.nilin.opex.common.OpexError import kotlinx.coroutines.coroutineScope import org.slf4j.Logger import org.springframework.stereotype.Service @@ -20,23 +20,55 @@ import java.math.BigDecimal class WalletSyncServiceImpl( private val walletProxy: WalletProxy, private val assignedAddressHandler: AssignedAddressHandler, - private val currencyHandler: CurrencyHandler, + private val currencyHandler: CryptoCurrencyHandlerV2, private val depositHandler: DepositHandler ) : WalletSyncService { private val logger: Logger by LoggerDelegate() + @Transactional + override suspend fun sendTransfer(transfer: Transfer) { + val uuid = assignedAddressHandler.findUuid(transfer.receiver.address, transfer.receiver.memo) ?: return + val currencyGateway = + currencyHandler.fetchGatewayWithoutSymbol(transfer.chain, transfer.isTokenTransfer, transfer.tokenAddress) + ?: throw OpexError.CurrencyNotFound.exception() + + depositHandler.save( + with(transfer) { + Deposit( + null, + txHash, + receiver.address, + receiver.memo, + amount, + chain, + isTokenTransfer, + tokenAddress + ) + } + ) + + sendDeposit(uuid, currencyGateway, transfer) + } + @Transactional override suspend fun syncTransfers(transfers: List) = coroutineScope { - val groupedByChain = currencyHandler.fetchAllImplementations().groupBy { it.chain.name } + val groupedByChain = currencyHandler.fetchCurrencyOnChainGateways()?.groupBy { it.chain } + ?: throw OpexError.CurrencyNotFound.exception() val deposits = transfers.mapNotNull { coroutineScope { + val currencyImpl = groupedByChain[it.chain]?.find { c -> c.tokenAddress == it.tokenAddress } - ?: throw IllegalStateException("Currency implementation not found") - assignedAddressHandler.findUuid(it.receiver.address, it.receiver.memo)?.let { it to currencyImpl } + ?: run { + logger.info("Currency implementation not found") + return@coroutineScope null + } + assignedAddressHandler.findUuid(it.receiver.address, it.receiver.memo)?.let { + it to currencyImpl + } }?.let { (uuid, currencyImpl) -> sendDeposit(uuid, currencyImpl, it) - logger.info("Deposit synced for $uuid on ${currencyImpl.currency.symbol} - to ${it.receiver.address}") + logger.info("Deposit synced for $uuid on ${currencyImpl.currencySymbol} - to ${it.receiver.address}") it } }.map { @@ -54,10 +86,10 @@ class WalletSyncServiceImpl( depositHandler.saveAll(deposits) } - private suspend fun sendDeposit(uuid: String, currencyImpl: CurrencyImplementation, transfer: Transfer) { + private suspend fun sendDeposit(uuid: String, currencyImpl: CryptoCurrencyCommand, transfer: Transfer) { val amount = transfer.amount.divide(BigDecimal.TEN.pow(currencyImpl.decimal)) - val symbol = currencyImpl.currency.symbol + val symbol = currencyImpl.currencySymbol logger.info("Sending deposit to $uuid - $amount $symbol") - walletProxy.transfer(uuid, symbol, amount, transfer.txHash,transfer.chain) + walletProxy.transfer(uuid, symbol, amount, transfer.txHash, transfer.chain, currencyImpl.gatewayUuid) } } diff --git a/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/spi/AssignedAddressHandler.kt b/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/spi/AssignedAddressHandler.kt index e6a4d12fe..9af419764 100644 --- a/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/spi/AssignedAddressHandler.kt +++ b/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/spi/AssignedAddressHandler.kt @@ -2,7 +2,6 @@ package co.nilin.opex.bcgateway.core.spi import co.nilin.opex.bcgateway.core.model.AddressType import co.nilin.opex.bcgateway.core.model.AssignedAddress -import java.time.LocalDateTime interface AssignedAddressHandler { suspend fun fetchAssignedAddresses(user: String, addressTypes: List): List diff --git a/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/spi/AuthProxy.kt b/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/spi/AuthProxy.kt index 8cbf15f68..ac9f21f6f 100644 --- a/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/spi/AuthProxy.kt +++ b/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/spi/AuthProxy.kt @@ -1,8 +1,9 @@ package co.nilin.opex.bcgateway.core.spi -import co.nilin.opex.bcgateway.core.model.otc.* +import co.nilin.opex.bcgateway.core.model.otc.LoginRequest +import co.nilin.opex.bcgateway.core.model.otc.LoginResponse interface AuthProxy { - suspend fun getToken(loginRequest: LoginRequest):LoginResponse + suspend fun getToken(loginRequest: LoginRequest): LoginResponse } \ No newline at end of file diff --git a/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/spi/ChainLoader.kt b/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/spi/ChainLoader.kt index ac274c2e0..6c3f6bd4c 100644 --- a/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/spi/ChainLoader.kt +++ b/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/spi/ChainLoader.kt @@ -4,9 +4,9 @@ import co.nilin.opex.bcgateway.core.model.Chain interface ChainLoader { - suspend fun addChain(name: String, addressType:String):Chain + suspend fun addChain(name: String, addressType: String): Chain - suspend fun fetchAllChains():List + suspend fun fetchAllChains(): List suspend fun fetchChainInfo(chain: String): Chain } diff --git a/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/spi/CryptoCurrencyHandlerV2.kt b/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/spi/CryptoCurrencyHandlerV2.kt new file mode 100644 index 000000000..11b4eb755 --- /dev/null +++ b/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/spi/CryptoCurrencyHandlerV2.kt @@ -0,0 +1,29 @@ +package co.nilin.opex.bcgateway.core.spi + +import co.nilin.opex.bcgateway.core.model.CryptoCurrencyCommand +import co.nilin.opex.bcgateway.core.model.FetchGateways +import co.nilin.opex.bcgateway.core.model.WithdrawData + +interface CryptoCurrencyHandlerV2 { + + suspend fun createOnChainGateway(request: CryptoCurrencyCommand): CryptoCurrencyCommand? + + suspend fun updateOnChainGateway(request: CryptoCurrencyCommand): CryptoCurrencyCommand? + + suspend fun deleteOnChainGateway(gatewayUuid: String, currency: String): Void? + + suspend fun fetchCurrencyOnChainGateways(data: FetchGateways? = null): List? + + suspend fun fetchOnChainGateway(gatewayUuid: String, currency: String): CryptoCurrencyCommand? + + suspend fun changeWithdrawStatus(symbol: String, chain: String, status: Boolean) + + suspend fun getWithdrawData(symbol: String, network: String): WithdrawData + + suspend fun fetchGatewayWithoutSymbol( + chain: String, + isToken: Boolean, + tokenAddress: String? + ): CryptoCurrencyCommand? + +} diff --git a/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/spi/CurrencyHandler.kt b/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/spi/CurrencyHandler.kt index 768141df4..e69de29bb 100644 --- a/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/spi/CurrencyHandler.kt +++ b/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/spi/CurrencyHandler.kt @@ -1,74 +0,0 @@ -package co.nilin.opex.bcgateway.core.spi - -import co.nilin.opex.bcgateway.core.model.CurrencyImplementation -import co.nilin.opex.bcgateway.core.model.CurrencyInfo -import co.nilin.opex.bcgateway.core.model.WithdrawData -import java.math.BigDecimal - -interface CurrencyHandler { - - suspend fun addCurrency(name: String, symbol: String) - - suspend fun addCurrencyImplementationV2( - currencySymbol: String, - implementationSymbol: String, - currencyName: String, - chain: String, - tokenName: String?, - tokenAddress: String?, - isToken: Boolean, - withdrawFee: BigDecimal, - minimumWithdraw: BigDecimal, - isWithdrawEnabled: Boolean, - decimal: Int - ): CurrencyImplementation? - - - suspend fun updateCurrencyImplementation( - currencySymbol: String, - implementationSymbol: String, - currencyName: String, - newChain: String? = null, - tokenName: String?, - tokenAddress: String?, - isToken: Boolean, - withdrawFee: BigDecimal, - minimumWithdraw: BigDecimal, - isWithdrawEnabled: Boolean, - decimal: Int, - chain: String - ): CurrencyImplementation? - - - suspend fun editCurrency(name: String, symbol: String) - - suspend fun deleteCurrency(name: String) - - suspend fun addCurrencyImplementation( - currencySymbol: String, - implementationSymbol: String, - chain: String, - tokenName: String?, - tokenAddress: String?, - isToken: Boolean, - withdrawFee: BigDecimal, - minimumWithdraw: BigDecimal, - isWithdrawEnabled: Boolean, - decimal: Int - ): CurrencyImplementation - - suspend fun fetchAllImplementations(): List - - suspend fun fetchCurrencyInfo(symbol: String): CurrencyInfo - - suspend fun findByChainAndTokenAddress(chain: String, address: String?): CurrencyImplementation? - - suspend fun findImplementationsWithTokenOnChain(chain: String): List - - suspend fun findImplementationsByCurrency(currency: String): List - - suspend fun changeWithdrawStatus(symbol: String, chain: String, status: Boolean) - - suspend fun getWithdrawData(symbol: String, network: String): WithdrawData - -} diff --git a/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/spi/DepositHandler.kt b/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/spi/DepositHandler.kt index a8373e322..8451688db 100644 --- a/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/spi/DepositHandler.kt +++ b/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/spi/DepositHandler.kt @@ -3,8 +3,10 @@ package co.nilin.opex.bcgateway.core.spi import co.nilin.opex.bcgateway.core.model.Deposit interface DepositHandler { + suspend fun findDepositsByHash(hash: List): List - suspend fun saveAll(deposits: List) + suspend fun saveAll(deposits: List) + suspend fun save(deposit: Deposit) } \ No newline at end of file diff --git a/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/spi/OmniWalletManager.kt b/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/spi/OmniWalletManager.kt new file mode 100644 index 000000000..85901e004 --- /dev/null +++ b/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/spi/OmniWalletManager.kt @@ -0,0 +1,11 @@ +package co.nilin.opex.bcgateway.core.spi + +import co.nilin.opex.bcgateway.core.model.CryptoCurrencyCommand +import co.nilin.opex.bcgateway.core.model.OmniBalance + +interface OmniWalletManager { + + suspend fun getTokenBalance(currencyImpl: CryptoCurrencyCommand): OmniBalance + suspend fun getAssetBalance(cryptoCurrencyCommand: CryptoCurrencyCommand): OmniBalance + +} \ No newline at end of file diff --git a/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/spi/WalletProxy.kt b/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/spi/WalletProxy.kt index 1c932e776..be1ee0c49 100644 --- a/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/spi/WalletProxy.kt +++ b/bc-gateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/spi/WalletProxy.kt @@ -3,5 +3,12 @@ package co.nilin.opex.bcgateway.core.spi import java.math.BigDecimal interface WalletProxy { - suspend fun transfer(uuid: String, symbol: String, amount: BigDecimal, hash: String, chain: String) + suspend fun transfer( + uuid: String, + symbol: String, + amount: BigDecimal, + hash: String, + chain: String, + gatewayUuid: String? + ) } diff --git a/bc-gateway/bc-gateway-core/src/test/kotlin/co/nilin/opex/bcgateway/core/service/AssignAddressServiceImplUnitTest.kt b/bc-gateway/bc-gateway-core/src/test/kotlin/co/nilin/opex/bcgateway/core/service/AssignAddressServiceImplUnitTest.kt index 8aa515ff6..c74996234 100644 --- a/bc-gateway/bc-gateway-core/src/test/kotlin/co/nilin/opex/bcgateway/core/service/AssignAddressServiceImplUnitTest.kt +++ b/bc-gateway/bc-gateway-core/src/test/kotlin/co/nilin/opex/bcgateway/core/service/AssignAddressServiceImplUnitTest.kt @@ -1,29 +1,33 @@ package co.nilin.opex.bcgateway.core.service +//import co.nilin.opex.bcgateway.core.spi.CurrencyHandler import co.nilin.opex.bcgateway.core.model.* -import co.nilin.opex.bcgateway.core.model.Currency import co.nilin.opex.bcgateway.core.spi.AssignedAddressHandler -import co.nilin.opex.bcgateway.core.spi.CurrencyHandler +import co.nilin.opex.bcgateway.core.spi.ChainLoader +import co.nilin.opex.bcgateway.core.spi.CryptoCurrencyHandlerV2 import co.nilin.opex.bcgateway.core.spi.ReservedAddressHandler import io.mockk.coEvery import io.mockk.mockk import kotlinx.coroutines.runBlocking -import org.junit.jupiter.api.Test import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test import java.math.BigDecimal import java.util.* class AssignAddressServiceImplUnitTest { - private val currencyHandler = mockk() + private val currencyHandler = mockk() private val assignedAddressHandler = mockk() private val reservedAddressHandler = mockk() + private val chainLoader = mockk() + private val assignAddressServiceImpl = - AssignAddressServiceImpl(currencyHandler, assignedAddressHandler, reservedAddressHandler) + AssignAddressServiceImpl(currencyHandler, assignedAddressHandler, reservedAddressHandler, chainLoader) - private val currency = Currency("ETH", "Ethereum") + // private val currency = Currency("ETH", "Ethereum") private val chain = "ETH_MAINNET" + private val currency = "ETH" private val ethAddressType = AddressType(1, "ETH", "+*", ".*") private val ethMemoAddressType = AddressType(2, "ETH", "+*", "+*") private val ethChain = Chain("ETH_MAINNET", arrayListOf(ethAddressType)) @@ -31,37 +35,56 @@ class AssignAddressServiceImplUnitTest { init { - val eth = CurrencyImplementation( + val eth = CryptoCurrencyCommand( currency, + UUID.randomUUID().toString(), currency, - ethChain, + true, false, null, null, + BigDecimal.ZERO, true, - BigDecimal.ONE, - BigDecimal.TEN, - 18 + true, + BigDecimal.ZERO, + BigDecimal.ZERO, + BigDecimal.ZERO, + BigDecimal.ZERO, + 18, + ethChain.name, +// ethChain ) - val wrappedEth = CurrencyImplementation( + + val wrappedEth = CryptoCurrencyCommand( currency, + UUID.randomUUID().toString(), currency, - bscChain, + true, false, - "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", "WETH", + "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", + BigDecimal.ZERO, true, - BigDecimal.ONE, - BigDecimal.ONE, - 18 - ) + true, + BigDecimal.ZERO, + BigDecimal.ZERO, + BigDecimal.ZERO, + BigDecimal.ZERO, + 18, + bscChain.name, +// bscChain - coEvery { currencyHandler.fetchCurrencyInfo(currency.symbol) } returns CurrencyInfo( - currency, - listOf(eth, wrappedEth) ) + coEvery { currencyHandler.fetchCurrencyOnChainGateways(FetchGateways(currencySymbol = currency)) } returns + listOf(eth, wrappedEth) + + coEvery { chainLoader.fetchChainInfo(chain = ethChain.name) } returns ethChain + + coEvery { chainLoader.fetchChainInfo(chain = bscChain.name) } returns bscChain + + coEvery { assignedAddressHandler.persist(any()) } returns Unit coEvery { reservedAddressHandler.remove(any()) } returns Unit } diff --git a/bc-gateway/bc-gateway-ports/bc-gateway-auth-proxy/pom.xml b/bc-gateway/bc-gateway-ports/bc-gateway-auth-proxy/pom.xml index 359b1ce63..73b162182 100644 --- a/bc-gateway/bc-gateway-ports/bc-gateway-auth-proxy/pom.xml +++ b/bc-gateway/bc-gateway-ports/bc-gateway-auth-proxy/pom.xml @@ -1,6 +1,6 @@ - 4.0.0 diff --git a/bc-gateway/bc-gateway-ports/bc-gateway-auth-proxy/src/main/kotlin/co/nilin/opex/bcgateway/ports/authproxy/impl/AuthProxyImpl.kt b/bc-gateway/bc-gateway-ports/bc-gateway-auth-proxy/src/main/kotlin/co/nilin/opex/bcgateway/ports/authproxy/impl/AuthProxyImpl.kt index 553b1cd3c..5937ccb2f 100644 --- a/bc-gateway/bc-gateway-ports/bc-gateway-auth-proxy/src/main/kotlin/co/nilin/opex/bcgateway/ports/authproxy/impl/AuthProxyImpl.kt +++ b/bc-gateway/bc-gateway-ports/bc-gateway-auth-proxy/src/main/kotlin/co/nilin/opex/bcgateway/ports/authproxy/impl/AuthProxyImpl.kt @@ -5,6 +5,7 @@ import co.nilin.opex.bcgateway.core.model.otc.LoginResponse import co.nilin.opex.bcgateway.core.spi.AuthProxy import kotlinx.coroutines.reactive.awaitFirst import org.springframework.beans.factory.annotation.Value +import org.springframework.context.annotation.Profile import org.springframework.core.ParameterizedTypeReference import org.springframework.http.HttpHeaders import org.springframework.http.MediaType @@ -24,14 +25,16 @@ class AuthProxyImpl(private val webClient: WebClient) : AuthProxy { override suspend fun getToken(loginRequest: LoginRequest): LoginResponse { return webClient.post() - .uri(URI.create("${baseUrl}/api/v1/login")) - .header(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE) - .body(BodyInserters.fromFormData("mobile", loginRequest.clientId) - .with("password", loginRequest.clientSecret)) - .retrieve() - .onStatus({ t -> t.isError }, { it.createException() }) - .bodyToMono(typeRef()) - .awaitFirst() + .uri(URI.create("${baseUrl}/api/v1/login")) + .header(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE) + .body( + BodyInserters.fromFormData("mobile", loginRequest.clientId) + .with("password", loginRequest.clientSecret) + ) + .retrieve() + .onStatus({ t -> t.isError }, { it.createException() }) + .bodyToMono(typeRef()) + .awaitFirst() } } diff --git a/bc-gateway/bc-gateway-ports/bc-gateway-eventlistener-kafka/pom.xml b/bc-gateway/bc-gateway-ports/bc-gateway-eventlistener-kafka/pom.xml index b9b9baa18..c60167193 100644 --- a/bc-gateway/bc-gateway-ports/bc-gateway-eventlistener-kafka/pom.xml +++ b/bc-gateway/bc-gateway-ports/bc-gateway-eventlistener-kafka/pom.xml @@ -1,5 +1,5 @@ - 4.0.0 diff --git a/bc-gateway/bc-gateway-ports/bc-gateway-omniwallet-proxy/pom.xml b/bc-gateway/bc-gateway-ports/bc-gateway-omniwallet-proxy/pom.xml new file mode 100644 index 000000000..6ac89442c --- /dev/null +++ b/bc-gateway/bc-gateway-ports/bc-gateway-omniwallet-proxy/pom.xml @@ -0,0 +1,48 @@ + + + 4.0.0 + + + co.nilin.opex.bcgateway + bc-gateway + 1.0.1-beta.7 + ../../pom.xml + + + co.nilin.opex.bcgateway.ports.omniwallet + bc-gateway-omniwallet-proxy + bc-gateway-omniwallet-proxy + + + + org.jetbrains.kotlin + kotlin-reflect + + + org.springframework.boot + spring-boot-starter + + + io.projectreactor.kotlin + reactor-kotlin-extensions + + + org.jetbrains.kotlinx + kotlinx-coroutines-reactor + + + org.jetbrains.kotlinx + kotlinx-coroutines-core + + + co.nilin.opex.bcgateway.core + bc-gateway-core + + + org.springframework + spring-webflux + + + diff --git a/bc-gateway/bc-gateway-ports/bc-gateway-omniwallet-proxy/src/main/kotlin/co/nilin/opex/bcgateway/omniwallet/impl/OmniWalletManagerImpl.kt b/bc-gateway/bc-gateway-ports/bc-gateway-omniwallet-proxy/src/main/kotlin/co/nilin/opex/bcgateway/omniwallet/impl/OmniWalletManagerImpl.kt new file mode 100644 index 000000000..f134aef2d --- /dev/null +++ b/bc-gateway/bc-gateway-ports/bc-gateway-omniwallet-proxy/src/main/kotlin/co/nilin/opex/bcgateway/omniwallet/impl/OmniWalletManagerImpl.kt @@ -0,0 +1,31 @@ +package co.nilin.opex.bcgateway.omniwallet.impl + +import co.nilin.opex.bcgateway.core.model.CryptoCurrencyCommand +import co.nilin.opex.bcgateway.core.model.OmniBalance +import co.nilin.opex.bcgateway.core.spi.OmniWalletManager +import co.nilin.opex.bcgateway.omniwallet.model.AddressBalanceWithUsd +import co.nilin.opex.bcgateway.omniwallet.proxy.OmniWalletProxy +import org.slf4j.LoggerFactory +import org.springframework.stereotype.Component +import java.math.BigDecimal + +@Component +class OmniWalletManagerImpl(private val omniWalletProxy: OmniWalletProxy) : OmniWalletManager { + private val logger = LoggerFactory.getLogger(omniWalletProxy::class.java) + + override suspend fun getTokenBalance(cryptoCurrencyCommand: CryptoCurrencyCommand): OmniBalance { + return OmniBalance(currency = cryptoCurrencyCommand.currencySymbol, + network = cryptoCurrencyCommand.chain, + balance = omniWalletProxy.getTokenBalance(cryptoCurrencyCommand.tokenAddress!!, cryptoCurrencyCommand.chain) + ?.stream()?.map(AddressBalanceWithUsd::balance)?.reduce { a, b -> a + b }?.orElse(BigDecimal.ZERO) + ) + } + + override suspend fun getAssetBalance(cryptoCurrencyCommand: CryptoCurrencyCommand): OmniBalance { + return OmniBalance( + cryptoCurrencyCommand.currencySymbol, + cryptoCurrencyCommand.chain, + omniWalletProxy.getAssetBalance(cryptoCurrencyCommand.chain)?.balance ?: BigDecimal.ZERO + ) + } +} \ No newline at end of file diff --git a/bc-gateway/bc-gateway-ports/bc-gateway-omniwallet-proxy/src/main/kotlin/co/nilin/opex/bcgateway/omniwallet/model/AddressBalanceWithUsd.kt b/bc-gateway/bc-gateway-ports/bc-gateway-omniwallet-proxy/src/main/kotlin/co/nilin/opex/bcgateway/omniwallet/model/AddressBalanceWithUsd.kt new file mode 100644 index 000000000..29f74ea17 --- /dev/null +++ b/bc-gateway/bc-gateway-ports/bc-gateway-omniwallet-proxy/src/main/kotlin/co/nilin/opex/bcgateway/omniwallet/model/AddressBalanceWithUsd.kt @@ -0,0 +1,8 @@ +package co.nilin.opex.bcgateway.omniwallet.model + +import java.math.BigDecimal + +data class AddressBalanceWithUsd(val address: String, val balance: BigDecimal, val balanceUsd: BigDecimal) + + +data class ChainBalanceResponse(val data: List) \ No newline at end of file diff --git a/bc-gateway/bc-gateway-ports/bc-gateway-omniwallet-proxy/src/main/kotlin/co/nilin/opex/bcgateway/omniwallet/proxy/OmniWalletProxy.kt b/bc-gateway/bc-gateway-ports/bc-gateway-omniwallet-proxy/src/main/kotlin/co/nilin/opex/bcgateway/omniwallet/proxy/OmniWalletProxy.kt new file mode 100644 index 000000000..fe5fd9fef --- /dev/null +++ b/bc-gateway/bc-gateway-ports/bc-gateway-omniwallet-proxy/src/main/kotlin/co/nilin/opex/bcgateway/omniwallet/proxy/OmniWalletProxy.kt @@ -0,0 +1,69 @@ +package co.nilin.opex.bcgateway.omniwallet.proxy + +import co.nilin.opex.bcgateway.omniwallet.model.AddressBalanceWithUsd +import kotlinx.coroutines.reactive.awaitFirst +import org.slf4j.Logger +import org.slf4j.LoggerFactory +import org.springframework.beans.factory.annotation.Value +import org.springframework.core.ParameterizedTypeReference +import org.springframework.http.HttpHeaders +import org.springframework.http.MediaType +import org.springframework.stereotype.Component +import org.springframework.web.reactive.function.client.WebClient +import java.math.BigDecimal + +inline fun typeRef(): ParameterizedTypeReference = object : ParameterizedTypeReference() {} +data class TotalAssetByChainWithUsd( + val balance: BigDecimal, + val chain: String? = null, + val symbol: String? = null, + val balanceUsd: BigDecimal? = null +) + +@Component +class OmniWalletProxy(private val webClient: WebClient) { + + + @Value("\${app.omni-wallet.url}") + private lateinit var baseUrl: String + + private val logger: Logger = LoggerFactory.getLogger(OmniWalletProxy::class.java) + + suspend fun getAssetBalance(network: String): TotalAssetByChainWithUsd? { +// return TotalAssetByChainWithUsd(BigDecimal(15),network,"", BigDecimal(65)) +// + logger.info("----&&&&&&&&&&&----") + + return webClient.get() + .uri("${baseUrl}/v1/balance/chain/${network}/total") + { + it.queryParam("excludeZero", false) + it.build() + } + .header(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE) + .retrieve() + .bodyToMono(typeRef()) + .doOnError { e -> logger.info("An error happened during get balance of chain $network : ${e.message}") } + .onErrorReturn(TotalAssetByChainWithUsd(balance = BigDecimal.ZERO)) + .log() + .awaitFirst() + } + + suspend fun getTokenBalance(tokenAddress: String, network: String): List? { +// return listOf( AddressBalanceWithUsd("", BigDecimal.TEN, BigDecimal.TEN)) + return webClient.get() + .uri("${baseUrl}/v1/balance/token/address/${tokenAddress}") + { + it.queryParam("excludeZero", false) + it.build() + } + .header(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE) + .retrieve() + .bodyToMono(typeRef?>()) + .doOnError { e -> logger.info("An error happened during get balance of token $tokenAddress : ${e.message}") } + .onErrorReturn(listOf(AddressBalanceWithUsd(tokenAddress, BigDecimal.ZERO, BigDecimal.ZERO))) + .log() + .awaitFirst() + + } +} diff --git a/bc-gateway/bc-gateway-ports/bc-gateway-persister-postgres/pom.xml b/bc-gateway/bc-gateway-ports/bc-gateway-persister-postgres/pom.xml index ba0b4b5af..3f3cea67f 100644 --- a/bc-gateway/bc-gateway-ports/bc-gateway-persister-postgres/pom.xml +++ b/bc-gateway/bc-gateway-ports/bc-gateway-persister-postgres/pom.xml @@ -1,5 +1,5 @@ - 4.0.0 @@ -55,6 +55,11 @@ reactor-test test + + org.modelmapper + modelmapper + 3.2.0 + diff --git a/bc-gateway/bc-gateway-ports/bc-gateway-persister-postgres/src/main/kotlin/co/nilin/opex/bcgateway/ports/postgres/dao/AssignedAddressRepository.kt b/bc-gateway/bc-gateway-ports/bc-gateway-persister-postgres/src/main/kotlin/co/nilin/opex/bcgateway/ports/postgres/dao/AssignedAddressRepository.kt index 42854193a..de431c1d4 100644 --- a/bc-gateway/bc-gateway-ports/bc-gateway-persister-postgres/src/main/kotlin/co/nilin/opex/bcgateway/ports/postgres/dao/AssignedAddressRepository.kt +++ b/bc-gateway/bc-gateway-ports/bc-gateway-persister-postgres/src/main/kotlin/co/nilin/opex/bcgateway/ports/postgres/dao/AssignedAddressRepository.kt @@ -17,7 +17,7 @@ interface AssignedAddressRepository : ReactiveCrudRepository, - @Param("status") status:AddressStatus?=null + @Param("status") status: AddressStatus? = null ): Flow @Query("select * from assigned_addresses where address = :address and (memo is null or memo = '' or memo = :memo)") @@ -27,18 +27,17 @@ interface AssignedAddressRepository : ReactiveCrudRepository - @Query("select * from assigned_addresses where address = :address and (memo is null or memo = '' or memo = :memo) and (:status is null or status =:status)") fun findByAddressAndMemoAndStatus( - @Param("address") address: String, - @Param("memo") memo: String?, - @Param("status") status:AddressStatus?=null + @Param("address") address: String, + @Param("memo") memo: String?, + @Param("status") status: AddressStatus? = null ): Mono @Query("select * from assigned_addresses where (:windowPoint is null or assigned_date > :windowPoint ) and (:now is null or exp_time< :now ) and (:status is null or status =:status) ") fun findPotentialExpAddress( - @Param("windowPoint") windowPont: LocalDateTime?, - @Param("now") now: LocalDateTime?, - @Param("status") status:AddressStatus?=null + @Param("windowPoint") windowPont: LocalDateTime?, + @Param("now") now: LocalDateTime?, + @Param("status") status: AddressStatus? = null ): Flow? } \ No newline at end of file diff --git a/bc-gateway/bc-gateway-ports/bc-gateway-persister-postgres/src/main/kotlin/co/nilin/opex/bcgateway/ports/postgres/dao/CurrencyImplementationRepository.kt b/bc-gateway/bc-gateway-ports/bc-gateway-persister-postgres/src/main/kotlin/co/nilin/opex/bcgateway/ports/postgres/dao/CurrencyImplementationRepository.kt index e480905c5..5b7f81e48 100644 --- a/bc-gateway/bc-gateway-ports/bc-gateway-persister-postgres/src/main/kotlin/co/nilin/opex/bcgateway/ports/postgres/dao/CurrencyImplementationRepository.kt +++ b/bc-gateway/bc-gateway-ports/bc-gateway-persister-postgres/src/main/kotlin/co/nilin/opex/bcgateway/ports/postgres/dao/CurrencyImplementationRepository.kt @@ -1,29 +1,45 @@ package co.nilin.opex.bcgateway.ports.postgres.dao import co.nilin.opex.bcgateway.core.model.WithdrawData -import co.nilin.opex.bcgateway.ports.postgres.model.CurrencyImplementationModel -import kotlinx.coroutines.flow.Flow +import co.nilin.opex.bcgateway.ports.postgres.model.CurrencyOnChainGatewayModel 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.math.BigDecimal @Repository -interface CurrencyImplementationRepository : ReactiveCrudRepository { +interface CurrencyImplementationRepository : ReactiveCrudRepository { - fun findByCurrencySymbol(currencySymbol: String): Flow + fun findByGatewayUuid(uuid: String): Mono? - fun findByChain(chain: String): Flow + @Query("select * from currency_on_chain_gateway where (:gatewayUuid is null or gateway_uuid=:gatewayUuid) and (:currencySymbol is null or currency_symbol=:currencySymbol ) and (:implementationSymbol is null or implementation_symbol=:implementationSymbol ) and (:chain is null or chain=:chain ) ") + fun findGateways( + currencySymbol: String? = null, + gatewayUuid: String? = null, + chain: String? = null, + implementationSymbol: String? = null + ): Flux? - fun findByCurrencySymbolAndChain(currencySymbol: String, chain: String): Mono + fun deleteByGatewayUuid(uuid: String): Mono - fun findByChainAndTokenAddress(chain: String, tokenAddress: String?): Mono - - @Query(""" + @Query( + """ select withdraw_enabled as is_enabled, withdraw_fee as fee, withdraw_min as minimum from currency_implementations where implementation_symbol = :symbol and chain = :chain - """) + """ + ) + fun findWithdrawDataBySymbolAndChain(symbol: String, chain: String): Mono -} + + fun findByCurrencySymbolAndChain(symbol: String, chain: String): Mono + + fun findByGatewayUuidAndCurrencySymbol(gatewayUuid: String?, symbol: String?): Mono? + + @Query("select * from currency_on_chain_gateway where chain = :chain and is_token is false") + fun findMainAssetGateway(chain: String): Mono + + @Query("select * from currency_on_chain_gateway where chain = :chain and is_token is true and token_address = :tokenAddress") + fun findTokenGateway(chain: String, tokenAddress: String): Mono +} \ No newline at end of file diff --git a/bc-gateway/bc-gateway-ports/bc-gateway-persister-postgres/src/main/kotlin/co/nilin/opex/bcgateway/ports/postgres/dao/CurrencyRepository.kt b/bc-gateway/bc-gateway-ports/bc-gateway-persister-postgres/src/main/kotlin/co/nilin/opex/bcgateway/ports/postgres/dao/CurrencyRepository.kt index 2dd1e4517..41a6fccd1 100644 --- a/bc-gateway/bc-gateway-ports/bc-gateway-persister-postgres/src/main/kotlin/co/nilin/opex/bcgateway/ports/postgres/dao/CurrencyRepository.kt +++ b/bc-gateway/bc-gateway-ports/bc-gateway-persister-postgres/src/main/kotlin/co/nilin/opex/bcgateway/ports/postgres/dao/CurrencyRepository.kt @@ -1,19 +1,13 @@ package co.nilin.opex.bcgateway.ports.postgres.dao -import co.nilin.opex.bcgateway.ports.postgres.model.CurrencyModel -import org.springframework.data.r2dbc.repository.Query -import org.springframework.data.repository.reactive.ReactiveCrudRepository -import org.springframework.stereotype.Repository -import reactor.core.publisher.Mono - -@Repository -interface CurrencyRepository : ReactiveCrudRepository { - - fun findBySymbol(symbol: String): Mono - - @Query("insert into currency values (:symbol, :name) on conflict do nothing") - fun insert(name: String, symbol: String): Mono - - @Query("delete from currency where name = :name") - fun deleteByName(name: String): Mono -} +//@Repository +//interface CurrencyRepository : ReactiveCrudRepository { +// +//// fun findBySymbol(symbol: String): Mono +//// +//// @Query("insert into currency values (:symbol, :name) on conflict do nothing") +//// fun insert(name: String, symbol: String): Mono +//// +//// @Query("delete from currency where name = :name") +//// fun deleteByName(name: String): Mono +//} diff --git a/bc-gateway/bc-gateway-ports/bc-gateway-persister-postgres/src/main/kotlin/co/nilin/opex/bcgateway/ports/postgres/impl/AddressManagerImpl.kt b/bc-gateway/bc-gateway-ports/bc-gateway-persister-postgres/src/main/kotlin/co/nilin/opex/bcgateway/ports/postgres/impl/AddressManagerImpl.kt index b68f382b4..f12c3c08d 100644 --- a/bc-gateway/bc-gateway-ports/bc-gateway-persister-postgres/src/main/kotlin/co/nilin/opex/bcgateway/ports/postgres/impl/AddressManagerImpl.kt +++ b/bc-gateway/bc-gateway-ports/bc-gateway-persister-postgres/src/main/kotlin/co/nilin/opex/bcgateway/ports/postgres/impl/AddressManagerImpl.kt @@ -3,22 +3,23 @@ package co.nilin.opex.bcgateway.ports.postgres.impl import co.nilin.opex.bcgateway.core.model.AddressStatus import co.nilin.opex.bcgateway.core.model.ReservedAddress import co.nilin.opex.bcgateway.core.spi.AddressManager -import co.nilin.opex.bcgateway.core.spi.CurrencyHandler import org.slf4j.LoggerFactory import org.springframework.stereotype.Component import java.time.LocalDateTime @Component -class AddressManagerImpl(private val addressHandlerImpl: AssignedAddressHandlerImpl, - private val reservedAddressHandlerImpl: ReservedAddressHandlerImpl) : AddressManager { +class AddressManagerImpl( + private val addressHandlerImpl: AssignedAddressHandlerImpl, + private val reservedAddressHandlerImpl: ReservedAddressHandlerImpl +) : AddressManager { private val logger = LoggerFactory.getLogger(AddressManagerImpl::class.java) override suspend fun revokeExpiredAddress() { addressHandlerImpl.fetchExpiredAssignedAddresses()?.map { addressHandlerImpl.revoke(it.apply { - id=it.id + id = it.id status = AddressStatus.Revoked - revokedDate= LocalDateTime.now() + revokedDate = LocalDateTime.now() }) reservedAddressHandlerImpl.addReservedAddress(listOf(ReservedAddress(it.address, it.memo, it.type))) diff --git a/bc-gateway/bc-gateway-ports/bc-gateway-persister-postgres/src/main/kotlin/co/nilin/opex/bcgateway/ports/postgres/impl/AssignedAddressHandlerImpl.kt b/bc-gateway/bc-gateway-ports/bc-gateway-persister-postgres/src/main/kotlin/co/nilin/opex/bcgateway/ports/postgres/impl/AssignedAddressHandlerImpl.kt index 3974b6c04..8c5220a3d 100644 --- a/bc-gateway/bc-gateway-ports/bc-gateway-persister-postgres/src/main/kotlin/co/nilin/opex/bcgateway/ports/postgres/impl/AssignedAddressHandlerImpl.kt +++ b/bc-gateway/bc-gateway-ports/bc-gateway-persister-postgres/src/main/kotlin/co/nilin/opex/bcgateway/ports/postgres/impl/AssignedAddressHandlerImpl.kt @@ -19,27 +19,27 @@ import org.slf4j.Logger import org.springframework.beans.factory.annotation.Value import org.springframework.stereotype.Service import java.time.LocalDateTime -import java.time.ZoneId @Service class AssignedAddressHandlerImpl( - val assignedAddressRepository: AssignedAddressRepository, - val addressTypeRepository: AddressTypeRepository, - val assignedAddressChainRepository: AssignedAddressChainRepository, - val chainLoader: ChainLoader + val assignedAddressRepository: AssignedAddressRepository, + val addressTypeRepository: AddressTypeRepository, + val assignedAddressChainRepository: AssignedAddressChainRepository, + val chainLoader: ChainLoader ) : AssignedAddressHandler { - @Value("\${app.address.life-time.value}") - private var lifeTime: Long? = null + @Value("\${app.address.life-time}") + private var addressLifeTime: Long? = null private val logger: Logger by LoggerDelegate() override suspend fun fetchAssignedAddresses(user: String, addressTypes: List): List { + addressLifeTime = 7200 if (addressTypes.isEmpty()) return emptyList() val addressTypeMap = addressTypeRepository.findAll().map { aam -> AddressType(aam.id!!, aam.type, aam.addressRegex, aam.memoRegex) }.collectMap { it.id }.awaitFirst() return assignedAddressRepository.findByUuidAndAddressTypeAndStatus( - user, addressTypes.map(AddressType::id), AddressStatus.Assigned + user, addressTypes.map(AddressType::id), AddressStatus.Assigned ).map { model -> model.toDto(addressTypeMap).apply { id = model.id } }.filter { it.expTime?.let { it > LocalDateTime.now() } ?: true }.toList() @@ -49,19 +49,19 @@ class AssignedAddressHandlerImpl( logger.info("going to save new address .............") assignedAddressRepository.save( - AssignedAddressModel( - assignedAddress.id ?: null, - assignedAddress.uuid, - assignedAddress.address, - assignedAddress.memo, - assignedAddress.type.id, - assignedAddress.id?.let { assignedAddress.expTime } - ?: (lifeTime?.let { (LocalDateTime.now().plusSeconds(lifeTime!!)) } - ?: null), - assignedAddress.id?.let { assignedAddress.assignedDate } ?: LocalDateTime.now(), - null, - assignedAddress.status - ) + AssignedAddressModel( + assignedAddress.id ?: null, + assignedAddress.uuid, + assignedAddress.address, + assignedAddress.memo, + assignedAddress.type.id, + assignedAddress.id?.let { assignedAddress.expTime } + ?: (addressLifeTime?.let { (LocalDateTime.now().plusSeconds(addressLifeTime!!)) } + ?: null), + assignedAddress.id?.let { assignedAddress.assignedDate } ?: LocalDateTime.now(), + null, + assignedAddress.status + ) ).awaitFirstOrNull() } @@ -69,23 +69,24 @@ class AssignedAddressHandlerImpl( override suspend fun revoke(assignedAddress: AssignedAddress) { assignedAddressRepository.save( - AssignedAddressModel( - assignedAddress.id, - assignedAddress.uuid, - assignedAddress.address, - assignedAddress.memo, - assignedAddress.type.id, - assignedAddress.expTime, - assignedAddress.assignedDate, - assignedAddress.revokedDate, - assignedAddress.status - ) + AssignedAddressModel( + assignedAddress.id, + assignedAddress.uuid, + assignedAddress.address, + assignedAddress.memo, + assignedAddress.type.id, + assignedAddress.expTime, + assignedAddress.assignedDate, + assignedAddress.revokedDate, + assignedAddress.status + ) ).awaitFirst() } override suspend fun findUuid(address: String, memo: String?): String? { - return assignedAddressRepository.findByAddressAndMemoAndStatus(address, memo, AddressStatus.Assigned).awaitFirstOrNull()?.uuid + return assignedAddressRepository.findByAddressAndMemoAndStatus(address, memo, AddressStatus.Assigned) + .awaitFirstOrNull()?.uuid } override suspend fun fetchExpiredAssignedAddresses(): List? { @@ -95,9 +96,9 @@ class AssignedAddressHandlerImpl( }.collectMap { it.id }.awaitFirst() //for having significant margin : (minus(5 mints) return assignedAddressRepository.findPotentialExpAddress( - (now.minusSeconds(lifeTime!!)).minusMinutes(5), - now, - AddressStatus.Assigned + (now.minusSeconds(addressLifeTime!!)).minusMinutes(5), + now, + AddressStatus.Assigned )?.filter { it.expTime != null }?.map { @@ -107,18 +108,18 @@ class AssignedAddressHandlerImpl( private suspend fun AssignedAddressModel.toDto(addressTypeMap: MutableMap): AssignedAddress { return AssignedAddress( - this.uuid, - this.address, - this.memo, - addressTypeMap.getValue(this.addressTypeId), - assignedAddressChainRepository.findByAssignedAddress(this.id!!).map { cm -> - chainLoader.fetchChainInfo(cm.chain) - }.toList().toMutableList(), - this.expTime, - this.assignedDate, - this.revokedDate, - this.status, - null + this.uuid, + this.address, + this.memo, + addressTypeMap.getValue(this.addressTypeId), + assignedAddressChainRepository.findByAssignedAddress(this.id!!).map { cm -> + chainLoader.fetchChainInfo(cm.chain) + }.toList().toMutableList(), + this.expTime, + this.assignedDate, + this.revokedDate, + this.status, + null ) } } \ No newline at end of file diff --git a/bc-gateway/bc-gateway-ports/bc-gateway-persister-postgres/src/main/kotlin/co/nilin/opex/bcgateway/ports/postgres/impl/ChainHandler.kt b/bc-gateway/bc-gateway-ports/bc-gateway-persister-postgres/src/main/kotlin/co/nilin/opex/bcgateway/ports/postgres/impl/ChainHandler.kt index 2bde53614..4114bdb01 100644 --- a/bc-gateway/bc-gateway-ports/bc-gateway-persister-postgres/src/main/kotlin/co/nilin/opex/bcgateway/ports/postgres/impl/ChainHandler.kt +++ b/bc-gateway/bc-gateway-ports/bc-gateway-persister-postgres/src/main/kotlin/co/nilin/opex/bcgateway/ports/postgres/impl/ChainHandler.kt @@ -7,6 +7,7 @@ import co.nilin.opex.bcgateway.ports.postgres.dao.AddressTypeRepository import co.nilin.opex.bcgateway.ports.postgres.dao.ChainAddressTypeRepository import co.nilin.opex.bcgateway.ports.postgres.dao.ChainRepository import co.nilin.opex.bcgateway.ports.postgres.model.ChainAddressTypeModel +import co.nilin.opex.common.OpexError import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.toList import kotlinx.coroutines.reactive.awaitFirst @@ -14,7 +15,6 @@ import kotlinx.coroutines.reactive.awaitFirstOrElse import kotlinx.coroutines.reactive.awaitFirstOrNull import kotlinx.coroutines.reactive.awaitSingle import org.springframework.stereotype.Component -import co.nilin.opex.common.OpexError @Component class ChainHandler( diff --git a/bc-gateway/bc-gateway-ports/bc-gateway-persister-postgres/src/main/kotlin/co/nilin/opex/bcgateway/ports/postgres/impl/CurrencyHandlerImpl.kt b/bc-gateway/bc-gateway-ports/bc-gateway-persister-postgres/src/main/kotlin/co/nilin/opex/bcgateway/ports/postgres/impl/CurrencyHandlerImpl.kt index f19a84256..e69de29bb 100644 --- a/bc-gateway/bc-gateway-ports/bc-gateway-persister-postgres/src/main/kotlin/co/nilin/opex/bcgateway/ports/postgres/impl/CurrencyHandlerImpl.kt +++ b/bc-gateway/bc-gateway-ports/bc-gateway-persister-postgres/src/main/kotlin/co/nilin/opex/bcgateway/ports/postgres/impl/CurrencyHandlerImpl.kt @@ -1,246 +0,0 @@ -package co.nilin.opex.bcgateway.ports.postgres.impl - -import co.nilin.opex.bcgateway.core.model.* -import co.nilin.opex.bcgateway.core.spi.CurrencyHandler -import co.nilin.opex.bcgateway.ports.postgres.dao.ChainRepository -import co.nilin.opex.bcgateway.ports.postgres.dao.CurrencyImplementationRepository -import co.nilin.opex.bcgateway.ports.postgres.dao.CurrencyRepository -import co.nilin.opex.bcgateway.ports.postgres.model.CurrencyImplementationModel -import co.nilin.opex.bcgateway.ports.postgres.model.CurrencyModel -import co.nilin.opex.common.OpexError -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.reactive.awaitSingle -import kotlinx.coroutines.reactor.awaitSingleOrNull -import org.slf4j.LoggerFactory -import org.springframework.stereotype.Component -import java.math.BigDecimal - -@Component -class CurrencyHandlerImpl( - private val chainRepository: ChainRepository, - private val currencyRepository: CurrencyRepository, - private val currencyImplementationRepository: CurrencyImplementationRepository -) : CurrencyHandler { - - private val logger = LoggerFactory.getLogger(CurrencyHandler::class.java) - - override suspend fun addCurrency(name: String, symbol: String) { - try { - currencyRepository.insert(name, symbol.uppercase()).awaitSingleOrNull() - } catch (e: Exception) { - logger.error("Could not insert new currency $name", e) - } - } - - override suspend fun addCurrencyImplementationV2( - currencySymbol: String, - implementationSymbol: String, - currencyName: String, - chain: String, - tokenName: String?, - tokenAddress: String?, - isToken: Boolean, - withdrawFee: BigDecimal, - minimumWithdraw: BigDecimal, - isWithdrawEnabled: Boolean, - decimal: Int - ): CurrencyImplementation { - currencyRepository.findBySymbol(currencySymbol).awaitFirstOrNull()?.let { - throw OpexError.CurrencyIsExist.exception() - } ?: run { - addCurrency(currencyName, currencySymbol) - return addCurrencyImplementation( - currencySymbol, - implementationSymbol, - chain, - tokenName, - tokenAddress, - isToken, - withdrawFee, - minimumWithdraw, - isWithdrawEnabled, - decimal - ) - } - } - - override suspend fun updateCurrencyImplementation( - currencySymbol: String, - implementationSymbol: String, - currencyName: String, - newChain: String?, - tokenName: String?, - tokenAddress: String?, - isToken: Boolean, - withdrawFee: BigDecimal, - minimumWithdraw: BigDecimal, - isWithdrawEnabled: Boolean, - decimal: Int, - oldChain: String - ): CurrencyImplementation? { - currencyRepository.findBySymbol(currencySymbol).awaitFirstOrNull()?.let { cm -> - currencyRepository.save(CurrencyModel(currencySymbol, currencyName)).awaitSingleOrNull() - return currencyImplementationRepository.findByCurrencySymbolAndChain(currencySymbol, oldChain) - ?.awaitSingleOrNull() - ?.let { - it.apply { - this.implementationSymbol = implementationSymbol - this.chain = newChain ?: oldChain - this.decimal = decimal - this.token = isToken - this.tokenAddress = tokenAddress - this.tokenName = tokenName - this.withdrawEnabled = isWithdrawEnabled - this.withdrawFee = withdrawFee - this.withdrawMin = minimumWithdraw - } - currencyImplementationRepository.save(it).awaitSingleOrNull() - ?.let { icm -> projectCurrencyImplementation(icm, cm) } - } - - } ?: throw OpexError.CurrencyNotFound.exception() - } - - override suspend fun editCurrency(name: String, symbol: String) { - val currency = currencyRepository.findBySymbol(symbol).awaitFirstOrNull() - if (currency != null) { - currency.name = name - currencyRepository.save(currency).awaitFirst() - } - } - - override suspend fun deleteCurrency(name: String) { - try { - currencyRepository.deleteByName(name).awaitFirstOrNull() - } catch (e: Exception) { - logger.error("Could not delete currency $name", e) - } - } - - override suspend fun addCurrencyImplementation( - currencySymbol: String, - implementationSymbol: String, - chain: String, - tokenName: String?, - tokenAddress: String?, - isToken: Boolean, - withdrawFee: BigDecimal, - minimumWithdraw: BigDecimal, - isWithdrawEnabled: Boolean, - decimal: Int - ): CurrencyImplementation { - val chainModel = chainRepository.findByName(chain).awaitFirstOrNull() - ?: throw OpexError.ChainNotFound.exception() - - currencyImplementationRepository.findByCurrencySymbolAndChain(currencySymbol.uppercase(), chain) - .awaitFirstOrNull() - ?.let { throw OpexError.DuplicateToken.exception() } - - val currency = currencyRepository.findBySymbol(currencySymbol.uppercase()).awaitFirstOrNull() - ?: throw OpexError.CurrencyNotFoundBC.exception() - - val model = currencyImplementationRepository.save( - CurrencyImplementationModel( - null, - currencySymbol.uppercase(), - implementationSymbol, - chainModel.name, - isToken, - tokenAddress, - tokenName, - isWithdrawEnabled, - withdrawFee, - minimumWithdraw, - decimal - ) - ).awaitFirst() - - logger.info("Add currency implementation: ${model.currencySymbol} - ${model.chain}") - - return projectCurrencyImplementation(model, currency) - } - - override suspend fun fetchAllImplementations(): List { - return currencyImplementationRepository.findAll() - .collectList() - .awaitFirstOrElse { emptyList() } - .map { - val currency = currencyRepository.findBySymbol(it.currencySymbol).awaitFirstOrNull() - projectCurrencyImplementation(it, currency) - } - } - - override suspend fun fetchCurrencyInfo(symbol: String): CurrencyInfo { - val symbolUpperCase = symbol.uppercase() - val currencyModel = currencyRepository.findBySymbol(symbolUpperCase).awaitSingleOrNull() - if (currencyModel === null) { - return CurrencyInfo(Currency("", symbolUpperCase), emptyList()) - } - val currencyImplModel = currencyImplementationRepository.findByCurrencySymbol(symbolUpperCase) - val currency = Currency(currencyModel.symbol, currencyModel.name) - val implementations = currencyImplModel.map { projectCurrencyImplementation(it, currencyModel) } - return CurrencyInfo(currency, implementations.toList()) - } - - override suspend fun findByChainAndTokenAddress(chain: String, address: String?): CurrencyImplementation? { - val impl = currencyImplementationRepository.findByChainAndTokenAddress(chain, address) - .awaitFirstOrNull() - - return if (impl != null) - projectCurrencyImplementation(impl) - else - null - } - - override suspend fun findImplementationsWithTokenOnChain(chain: String): List { - return currencyImplementationRepository.findByChain(chain).map { projectCurrencyImplementation(it) }.toList() - } - - override suspend fun findImplementationsByCurrency(currency: String): List { - return currencyImplementationRepository.findByCurrencySymbol(currency) - .map { projectCurrencyImplementation(it) } - .toList() - } - - override suspend fun changeWithdrawStatus(symbol: String, chain: String, status: Boolean) { - val impl = currencyImplementationRepository.findByCurrencySymbolAndChain(symbol, chain).awaitSingleOrNull() - ?: throw OpexError.TokenNotFound.exception() - - impl.apply { - withdrawEnabled = status - currencyImplementationRepository.save(impl).awaitFirstOrNull() - } - } - - override suspend fun getWithdrawData(symbol: String, network: String): WithdrawData { - return currencyImplementationRepository.findWithdrawDataBySymbolAndChain(symbol, network) - .awaitSingleOrNull() ?: throw OpexError.CurrencyNotFound.exception() - } - - private suspend fun projectCurrencyImplementation( - currencyImplementationModel: CurrencyImplementationModel, - currencyModel: CurrencyModel? = null - ): CurrencyImplementation { - val addressTypesModel = chainRepository.findAddressTypesByName(currencyImplementationModel.chain) - val addressTypes = - addressTypesModel.map { AddressType(it.id!!, it.type, it.addressRegex, it.memoRegex) }.toList() - val currencyModelVal = - currencyModel ?: currencyRepository.findBySymbol(currencyImplementationModel.currencySymbol).awaitSingle() - return CurrencyImplementation( - Currency(currencyModelVal.symbol, currencyModelVal.name), - Currency(currencyImplementationModel.implementationSymbol, currencyModelVal.name), - Chain(currencyImplementationModel.chain, addressTypes), - currencyImplementationModel.token, - currencyImplementationModel.tokenAddress, - currencyImplementationModel.tokenName, - currencyImplementationModel.withdrawEnabled, - currencyImplementationModel.withdrawFee, - currencyImplementationModel.withdrawMin, - currencyImplementationModel.decimal - ) - } -} diff --git a/bc-gateway/bc-gateway-ports/bc-gateway-persister-postgres/src/main/kotlin/co/nilin/opex/bcgateway/ports/postgres/impl/CurrencyHandlerImplV2.kt b/bc-gateway/bc-gateway-ports/bc-gateway-persister-postgres/src/main/kotlin/co/nilin/opex/bcgateway/ports/postgres/impl/CurrencyHandlerImplV2.kt new file mode 100644 index 000000000..1745cfd42 --- /dev/null +++ b/bc-gateway/bc-gateway-ports/bc-gateway-persister-postgres/src/main/kotlin/co/nilin/opex/bcgateway/ports/postgres/impl/CurrencyHandlerImplV2.kt @@ -0,0 +1,121 @@ +package co.nilin.opex.bcgateway.ports.postgres.impl + +import co.nilin.opex.bcgateway.core.model.CryptoCurrencyCommand +import co.nilin.opex.bcgateway.core.model.FetchGateways +import co.nilin.opex.bcgateway.core.model.WithdrawData +import co.nilin.opex.bcgateway.core.spi.CryptoCurrencyHandlerV2 +import co.nilin.opex.bcgateway.ports.postgres.dao.ChainRepository +import co.nilin.opex.bcgateway.ports.postgres.dao.CurrencyImplementationRepository +import co.nilin.opex.bcgateway.ports.postgres.model.CurrencyOnChainGatewayModel +import co.nilin.opex.bcgateway.ports.postgres.util.toDto +import co.nilin.opex.bcgateway.ports.postgres.util.toModel +import co.nilin.opex.common.OpexError +import kotlinx.coroutines.reactive.awaitFirstOrElse +import kotlinx.coroutines.reactive.awaitFirstOrNull +import kotlinx.coroutines.reactor.awaitSingleOrNull +import org.slf4j.LoggerFactory +import org.springframework.stereotype.Component +import reactor.core.publisher.Flux +import reactor.core.publisher.Mono +import java.util.stream.Collectors + +@Component +class CurrencyHandlerImplV2( + private val chainRepository: ChainRepository, + private val currencyImplementationRepository: CurrencyImplementationRepository +) : CryptoCurrencyHandlerV2 { + + private val logger = LoggerFactory.getLogger(CurrencyHandlerImplV2::class.java) + + override suspend fun createOnChainGateway(request: CryptoCurrencyCommand): CryptoCurrencyCommand? { + chainRepository.findByName(request.chain) + ?.awaitFirstOrElse { throw OpexError.ChainNotFound.exception() } + currencyImplementationRepository.findGateways( + currencySymbol = request.currencySymbol, + chain = request.chain, + implementationSymbol = request.implementationSymbol + ) + ?.awaitFirstOrNull()?.let { throw OpexError.GatewayIsExist.exception() } + return doSave(request.toModel())?.toDto(); + } + + override suspend fun updateOnChainGateway(request: CryptoCurrencyCommand): CryptoCurrencyCommand? { + return loadImpls(FetchGateways(gatewayUuid = request.gatewayUuid, currencySymbol = request.currencySymbol)) + ?.awaitFirstOrElse { throw OpexError.GatewayNotFount.exception() }?.let { oldGateway -> + doSave(oldGateway.toDto().updateTo(request).toModel().apply { id = oldGateway.id })?.toDto() + } + } + + override suspend fun deleteOnChainGateway(gatewayUuid: String, currency: String): Void? { + + loadImpls(FetchGateways(gatewayUuid = gatewayUuid, currencySymbol = currency)) + ?.awaitFirstOrElse { throw OpexError.GatewayNotFount.exception() }?.let { + try { + return currencyImplementationRepository.deleteByGatewayUuid(gatewayUuid)?.awaitFirstOrNull() + } catch (e: Exception) { + throw OpexError.BadRequest.exception() + + } + } + return null + } + + override suspend fun fetchCurrencyOnChainGateways(data: FetchGateways?): List? { + logger.info("going to fetch impls of ${data?.currencySymbol ?: "all currencies"}") + return loadImpls(data)?.map { it.toDto() } + ?.collect(Collectors.toList())?.awaitFirstOrNull() + } + + override suspend fun fetchOnChainGateway(gatewayUuid: String, symbol: String): CryptoCurrencyCommand? { + return loadImpl(gatewayUuid, symbol)?.awaitFirstOrNull()?.toDto() + } + + private suspend fun loadImpls(request: FetchGateways?): Flux? { + var resp = currencyImplementationRepository.findGateways( + request?.currencySymbol, + request?.gatewayUuid, + request?.chain, + request?.currencyImplementationName + ) + return resp + ?: throw OpexError.ImplNotFound.exception() + } + + private suspend fun loadImpl(gateway: String, symbol: String): Mono? { + return currencyImplementationRepository.findByGatewayUuidAndCurrencySymbol(gateway, symbol) + ?: throw OpexError.ImplNotFound.exception() + } + + private suspend fun doSave(request: CurrencyOnChainGatewayModel): CurrencyOnChainGatewayModel? { + return currencyImplementationRepository.save(request).awaitSingleOrNull() + } + + override suspend fun changeWithdrawStatus(symbol: String, chain: String, status: Boolean) { + val onChainGateway = + currencyImplementationRepository.findByCurrencySymbolAndChain(symbol, chain).awaitSingleOrNull() + ?: throw OpexError.TokenNotFound.exception() + + onChainGateway.apply { + withdrawAllowed = status + currencyImplementationRepository.save(onChainGateway).awaitFirstOrNull() + } + } + + override suspend fun getWithdrawData(symbol: String, network: String): WithdrawData { + return currencyImplementationRepository.findWithdrawDataBySymbolAndChain(symbol, network) + .awaitSingleOrNull() ?: throw OpexError.CurrencyNotFound.exception() + } + + override suspend fun fetchGatewayWithoutSymbol( + chain: String, + isToken: Boolean, + tokenAddress: String? + ): CryptoCurrencyCommand? { + chainRepository.findByName(chain).awaitFirstOrElse { throw OpexError.ChainNotFound.exception() } + + return if (isToken) + currencyImplementationRepository.findTokenGateway(chain, tokenAddress!!).awaitSingleOrNull()?.toDto() + else + currencyImplementationRepository.findMainAssetGateway(chain).awaitSingleOrNull()?.toDto() + } +} diff --git a/bc-gateway/bc-gateway-ports/bc-gateway-persister-postgres/src/main/kotlin/co/nilin/opex/bcgateway/ports/postgres/impl/DepositHandlerImpl.kt b/bc-gateway/bc-gateway-ports/bc-gateway-persister-postgres/src/main/kotlin/co/nilin/opex/bcgateway/ports/postgres/impl/DepositHandlerImpl.kt index 9e475a2f3..839f2ecba 100644 --- a/bc-gateway/bc-gateway-ports/bc-gateway-persister-postgres/src/main/kotlin/co/nilin/opex/bcgateway/ports/postgres/impl/DepositHandlerImpl.kt +++ b/bc-gateway/bc-gateway-ports/bc-gateway-persister-postgres/src/main/kotlin/co/nilin/opex/bcgateway/ports/postgres/impl/DepositHandlerImpl.kt @@ -7,15 +7,15 @@ import co.nilin.opex.bcgateway.ports.postgres.model.DepositModel import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.toList import kotlinx.coroutines.reactor.awaitSingle -import kotlinx.coroutines.reactor.awaitSingleOrNull import org.springframework.stereotype.Component @Component class DepositHandlerImpl(private val depositRepository: DepositRepository) : DepositHandler { + override suspend fun findDepositsByHash(hash: List): List { return depositRepository.findAllByHash(hash).map { Deposit( - it.id, it.hash, it.depositor, it.depositorMemo, it.amount, it.chain, it.token, it.tokenAddress + it.id, it.hash, it.depositor, it.depositorMemo, it.amount, it.chain, it.token, it.tokenAddress ) }.toList() } @@ -23,11 +23,24 @@ class DepositHandlerImpl(private val depositRepository: DepositRepository) : Dep override suspend fun saveAll(deposits: List) { depositRepository.saveAll(deposits.map { DepositModel( - null, it.hash, it.depositor, it.depositorMemo, it.amount, it.chain, it.token, it.tokenAddress + null, it.hash, it.depositor, it.depositorMemo, it.amount, it.chain, it.token, it.tokenAddress ) }).collectList().awaitSingle() } - + override suspend fun save(deposit: Deposit) { + depositRepository.save( + DepositModel( + null, + deposit.hash, + deposit.depositor, + deposit.depositorMemo, + deposit.amount, + deposit.chain, + deposit.token, + deposit.tokenAddress + ) + ).awaitSingle() + } } diff --git a/bc-gateway/bc-gateway-ports/bc-gateway-persister-postgres/src/main/kotlin/co/nilin/opex/bcgateway/ports/postgres/model/AssignedAddressModel.kt b/bc-gateway/bc-gateway-ports/bc-gateway-persister-postgres/src/main/kotlin/co/nilin/opex/bcgateway/ports/postgres/model/AssignedAddressModel.kt index 3494e4c79..f35480806 100644 --- a/bc-gateway/bc-gateway-ports/bc-gateway-persister-postgres/src/main/kotlin/co/nilin/opex/bcgateway/ports/postgres/model/AssignedAddressModel.kt +++ b/bc-gateway/bc-gateway-ports/bc-gateway-persister-postgres/src/main/kotlin/co/nilin/opex/bcgateway/ports/postgres/model/AssignedAddressModel.kt @@ -8,16 +8,16 @@ import java.time.LocalDateTime @Table("assigned_addresses") data class AssignedAddressModel( - @Id val id: Long?, - val uuid: String, - val address: String, - val memo: String?, - @Column("addr_type_id") val addressTypeId: Long, - @Column("exp_time") val expTime: LocalDateTime?=null, - @Column("assigned_Date") val assignedDate: LocalDateTime?=null, - @Column("revoked_Date") val revokedDate: LocalDateTime?=null, - val status: AddressStatus?=null, + @Id val id: Long?, + val uuid: String, + val address: String, + val memo: String?, + @Column("addr_type_id") val addressTypeId: Long, + @Column("exp_time") val expTime: LocalDateTime? = null, + @Column("assigned_Date") val assignedDate: LocalDateTime? = null, + @Column("revoked_Date") val revokedDate: LocalDateTime? = null, + val status: AddressStatus? = null, -) + ) diff --git a/bc-gateway/bc-gateway-ports/bc-gateway-persister-postgres/src/main/kotlin/co/nilin/opex/bcgateway/ports/postgres/model/CurrencyImplementationModel.kt b/bc-gateway/bc-gateway-ports/bc-gateway-persister-postgres/src/main/kotlin/co/nilin/opex/bcgateway/ports/postgres/model/CurrencyImplementationModel.kt deleted file mode 100644 index 4a17aa2b6..000000000 --- a/bc-gateway/bc-gateway-ports/bc-gateway-persister-postgres/src/main/kotlin/co/nilin/opex/bcgateway/ports/postgres/model/CurrencyImplementationModel.kt +++ /dev/null @@ -1,22 +0,0 @@ -package co.nilin.opex.bcgateway.ports.postgres.model - - -import org.springframework.data.annotation.Id -import org.springframework.data.relational.core.mapping.Column -import org.springframework.data.relational.core.mapping.Table -import java.math.BigDecimal - -@Table("currency_implementations") -class CurrencyImplementationModel( - @Id var id: Long?, - @Column("currency_symbol") val currencySymbol: String, - @Column("implementation_symbol") var implementationSymbol: String, - @Column("chain") var chain: String, - @Column("token") var token: Boolean, - @Column("token_address") var tokenAddress: String?, - @Column("token_name") var tokenName: String?, - @Column("withdraw_enabled") var withdrawEnabled: Boolean, - @Column("withdraw_fee") var withdrawFee: BigDecimal, - @Column("withdraw_min") var withdrawMin: BigDecimal, - @Column("decimal") var decimal: Int -) diff --git a/bc-gateway/bc-gateway-ports/bc-gateway-persister-postgres/src/main/kotlin/co/nilin/opex/bcgateway/ports/postgres/model/CurrencyOnChainGatewayModel.kt b/bc-gateway/bc-gateway-ports/bc-gateway-persister-postgres/src/main/kotlin/co/nilin/opex/bcgateway/ports/postgres/model/CurrencyOnChainGatewayModel.kt new file mode 100644 index 000000000..c954a3540 --- /dev/null +++ b/bc-gateway/bc-gateway-ports/bc-gateway-persister-postgres/src/main/kotlin/co/nilin/opex/bcgateway/ports/postgres/model/CurrencyOnChainGatewayModel.kt @@ -0,0 +1,33 @@ +package co.nilin.opex.bcgateway.ports.postgres.model + + +import org.springframework.data.annotation.Id +import org.springframework.data.relational.core.mapping.Column +import org.springframework.data.relational.core.mapping.Table +import java.math.BigDecimal + +@Table("currency_on_chain_gateway") +class CurrencyOnChainGatewayModel( + @Id var id: Long?, + @Column("gateway_uuid") val gatewayUuid: String, + @Column("currency_symbol") val currencySymbol: String, + @Column("implementation_symbol") var implementationSymbol: String? = currencySymbol, + @Column("chain") var chain: String, + @Column("is_token") var isToken: Boolean? = false, + @Column("token_address") var tokenAddress: String? = null, + @Column("token_name") var tokenName: String? = null, + @Column("withdraw_allowed") var withdrawAllowed: Boolean, + @Column("deposit_allowed") var depositAllowed: Boolean, + @Column("withdraw_fee") var withdrawFee: BigDecimal, + @Column("withdraw_min") var withdrawMin: BigDecimal? = BigDecimal.ZERO, + @Column("withdraw_max") var withdrawMax: BigDecimal? = BigDecimal.ZERO, + @Column("deposit_min") var depositMin: BigDecimal? = BigDecimal.ZERO, + @Column("deposit_max") var depositMax: BigDecimal? = BigDecimal.ZERO, @Column("decimal") var decimal: Int, + @Column("is_active") var isActive: Boolean? = true, + + + ) + + + + diff --git a/bc-gateway/bc-gateway-ports/bc-gateway-persister-postgres/src/main/kotlin/co/nilin/opex/bcgateway/ports/postgres/model/DepositModel.kt b/bc-gateway/bc-gateway-ports/bc-gateway-persister-postgres/src/main/kotlin/co/nilin/opex/bcgateway/ports/postgres/model/DepositModel.kt index 6b6c411a2..070f9b746 100644 --- a/bc-gateway/bc-gateway-ports/bc-gateway-persister-postgres/src/main/kotlin/co/nilin/opex/bcgateway/ports/postgres/model/DepositModel.kt +++ b/bc-gateway/bc-gateway-ports/bc-gateway-persister-postgres/src/main/kotlin/co/nilin/opex/bcgateway/ports/postgres/model/DepositModel.kt @@ -4,7 +4,6 @@ import org.springframework.data.annotation.Id import org.springframework.data.relational.core.mapping.Column import org.springframework.data.relational.core.mapping.Table import java.math.BigDecimal -import java.time.LocalDateTime @Table("deposits") data class DepositModel( diff --git a/bc-gateway/bc-gateway-ports/bc-gateway-persister-postgres/src/main/kotlin/co/nilin/opex/bcgateway/ports/postgres/model/NewCurrencyImplementationModel.kt b/bc-gateway/bc-gateway-ports/bc-gateway-persister-postgres/src/main/kotlin/co/nilin/opex/bcgateway/ports/postgres/model/NewCurrencyImplementationModel.kt new file mode 100644 index 000000000..2cd08b2ce --- /dev/null +++ b/bc-gateway/bc-gateway-ports/bc-gateway-persister-postgres/src/main/kotlin/co/nilin/opex/bcgateway/ports/postgres/model/NewCurrencyImplementationModel.kt @@ -0,0 +1,28 @@ +//package co.nilin.opex.bcgateway.ports.postgres.model +// +// +//import org.springframework.data.annotation.Id +//import org.springframework.data.relational.core.mapping.Column +//import org.springframework.data.relational.core.mapping.Table +//import java.math.BigDecimal +//import java.util.* +// +//@Table("new_currency_implementations") +//class NewCurrencyImplementationModel( +// @Id var id: Long?, +// @Column("currency_uuid") val currencyUuid: String, +// //todo unique +// @Column("uuid") val currencyImplUuid: String, +// @Column("implementation_symbol") var implementationSymbol: String, +// @Column("chain") var chain: String, +// @Column("is_token") var isToken: Boolean?=false, +// @Column("is_active") var isActive: Boolean?=true, +// @Column("token_address") var tokenAddress: String?, +// @Column("token_name") var tokenName: String?, +// @Column("withdraw_is_enable") var withdrawIsEnable: Boolean?=true, +// @Column("withdraw_fee") var withdrawFee: BigDecimal, +// @Column("withdraw_min") var withdrawMin: BigDecimal, +// @Column("decimal") var decimal: Int, +// @Column("deposit_is_enable") var depositIsEnable: Boolean? = true +// +//) diff --git a/bc-gateway/bc-gateway-ports/bc-gateway-persister-postgres/src/main/kotlin/co/nilin/opex/bcgateway/ports/postgres/util/convertor.kt b/bc-gateway/bc-gateway-ports/bc-gateway-persister-postgres/src/main/kotlin/co/nilin/opex/bcgateway/ports/postgres/util/convertor.kt new file mode 100644 index 000000000..3123e9d74 --- /dev/null +++ b/bc-gateway/bc-gateway-ports/bc-gateway-persister-postgres/src/main/kotlin/co/nilin/opex/bcgateway/ports/postgres/util/convertor.kt @@ -0,0 +1,50 @@ +package co.nilin.opex.bcgateway.ports.postgres.util + +import co.nilin.opex.bcgateway.core.model.CryptoCurrencyCommand +import co.nilin.opex.bcgateway.ports.postgres.model.CurrencyOnChainGatewayModel + + +fun CryptoCurrencyCommand.toModel(): CurrencyOnChainGatewayModel { + return CurrencyOnChainGatewayModel( + null, gatewayUuid!!, + currencySymbol, + implementationSymbol, + chain, + isToken, + tokenAddress, + tokenName, + withdrawAllowed!!, + depositAllowed!!, + withdrawFee!!, + withdrawMin, + withdrawMax, + depositMin, + depositMax, + decimal, + isActive + ) +} + +fun CurrencyOnChainGatewayModel.toDto(): CryptoCurrencyCommand { + + return CryptoCurrencyCommand( + currencySymbol, + gatewayUuid!!, + implementationSymbol, + isActive, + isToken, + tokenName, + tokenAddress, + withdrawFee, + withdrawAllowed, + depositAllowed, + withdrawMin, + withdrawMax, + depositMin, + depositMax, + decimal, + chain + ) + +} + diff --git a/bc-gateway/bc-gateway-ports/bc-gateway-persister-postgres/src/main/resources/schema.sql b/bc-gateway/bc-gateway-ports/bc-gateway-persister-postgres/src/main/resources/schema.sql index 2bbbb39af..1fb51670b 100644 --- a/bc-gateway/bc-gateway-ports/bc-gateway-persister-postgres/src/main/resources/schema.sql +++ b/bc-gateway/bc-gateway-ports/bc-gateway-persister-postgres/src/main/resources/schema.sql @@ -1,3 +1,5 @@ +CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; + CREATE TABLE IF NOT EXISTS address_types ( id SERIAL PRIMARY KEY, @@ -8,24 +10,18 @@ CREATE TABLE IF NOT EXISTS address_types CREATE TABLE IF NOT EXISTS assigned_addresses ( - id SERIAL PRIMARY KEY, - uuid VARCHAR(72) NOT NULL, - address VARCHAR(72) NOT NULL, - memo VARCHAR(72) NOT NULL, - addr_type_id INTEGER NOT NULL REFERENCES address_types (id), + id SERIAL PRIMARY KEY, + uuid VARCHAR(72) NOT NULL, + address VARCHAR(72) NOT NULL, + memo VARCHAR(72) NOT NULL, + addr_type_id INTEGER NOT NULL REFERENCES address_types (id), assigned_date TIMESTAMP, - revoked_date TIMESTAMP, - status VARCHAR(25), - exp_time TIMESTAMP, + revoked_date TIMESTAMP, + status VARCHAR(25), + exp_time TIMESTAMP, UNIQUE (address, memo, exp_time) ); -ALTER TABLE assigned_addresses ADD COLUMN IF NOT EXISTS assigned_date TIMESTAMP; -ALTER TABLE assigned_addresses ADD COLUMN IF NOT EXISTS revoked_date TIMESTAMP; -ALTER TABLE assigned_addresses ADD COLUMN IF NOT EXISTS exp_time TIMESTAMP; -ALTER TABLE assigned_addresses ADD COLUMN IF NOT EXISTS status VARCHAR(25); - - CREATE TABLE IF NOT EXISTS reserved_addresses @@ -44,51 +40,59 @@ CREATE TABLE IF NOT EXISTS chains CREATE TABLE IF NOT EXISTS assigned_address_chains ( - id SERIAL PRIMARY KEY, + id SERIAL PRIMARY KEY, assigned_address_id INTEGER NOT NULL REFERENCES assigned_addresses (id), chain VARCHAR(72) NOT NULL REFERENCES chains (name) ); CREATE TABLE IF NOT EXISTS chain_address_types ( - id SERIAL PRIMARY KEY, + id SERIAL PRIMARY KEY, chain_name VARCHAR(72) NOT NULL REFERENCES chains (name), addr_type_id INTEGER NOT NULL REFERENCES address_types (id), UNIQUE (chain_name, addr_type_id) ); -CREATE TABLE IF NOT EXISTS currency -( - symbol VARCHAR(72) PRIMARY KEY, - name VARCHAR(72) NOT NULL -); +-- CREATE TABLE IF NOT EXISTS currency +-- ( +-- symbol VARCHAR(72) PRIMARY KEY, +-- name VARCHAR(72) NOT NULL +-- ); -CREATE TABLE IF NOT EXISTS currency_implementations +CREATE TABLE IF NOT EXISTS currency_on_chain_gateway ( id SERIAL PRIMARY KEY, - currency_symbol VARCHAR(72) NOT NULL REFERENCES currency (symbol), - implementation_symbol VARCHAR(72) NOT NULL, - chain VARCHAR(72) NOT NULL REFERENCES chains (name), - token BOOLEAN NOT NULL, + currency_symbol VARCHAR(72) NOT NULL, + implementation_symbol VARCHAR(72) NOT NULL, + gateway_uuid VARCHAR(256) NOT NULL UNIQUE DEFAULT uuid_generate_v4(), + chain VARCHAR(72) NOT NULL REFERENCES chains (name), + is_token BOOLEAN NOT NULL, token_address VARCHAR(72), token_name VARCHAR(72), - withdraw_enabled BOOLEAN NOT NULL, - withdraw_fee DECIMAL NOT NULL, - withdraw_min DECIMAL NOT NULL, - decimal INTEGER NOT NULL, + withdraw_allowed BOOLEAN NOT NULL, + deposit_allowed BOOLEAN NOT NULL, + withdraw_fee DECIMAL NOT NULL, + withdraw_min DECIMAL NOT NULL, + withdraw_max DECIMAL NOT NULL, + deposit_min DECIMAL NOT NULL, + deposit_max DECIMAL NOT NULL, + decimal INTEGER NOT NULL, + is_active BOOLEAN NOT NULL DEFAULT TRUE, UNIQUE (currency_symbol, chain, implementation_symbol) ); + + CREATE TABLE IF NOT EXISTS deposits ( - id SERIAL PRIMARY KEY, - hash VARCHAR(100) UNIQUE NOT NULL, - chain VARCHAR(72) NOT NULL REFERENCES chains (name), - token BOOLEAN NOT NULL, - token_address VARCHAR(72), - amount DECIMAL NOT NULL, - depositor VARCHAR(72) NOT NULL, - depositor_memo VARCHAR(72) + id SERIAL PRIMARY KEY, + hash VARCHAR(100) UNIQUE NOT NULL, + chain VARCHAR(72) NOT NULL REFERENCES chains (name), + token BOOLEAN NOT NULL, + token_address VARCHAR(72), + amount DECIMAL NOT NULL, + depositor VARCHAR(72) NOT NULL, + depositor_memo VARCHAR(72) ); diff --git a/bc-gateway/bc-gateway-ports/bc-gateway-wallet-proxy/pom.xml b/bc-gateway/bc-gateway-ports/bc-gateway-wallet-proxy/pom.xml index 3bc027eee..401349381 100644 --- a/bc-gateway/bc-gateway-ports/bc-gateway-wallet-proxy/pom.xml +++ b/bc-gateway/bc-gateway-ports/bc-gateway-wallet-proxy/pom.xml @@ -1,6 +1,6 @@ - 4.0.0 diff --git a/bc-gateway/bc-gateway-ports/bc-gateway-wallet-proxy/src/main/kotlin/co/nilin/opex/bcgateway/ports/walletproxy/impl/ExtractBackgroundAuth.kt b/bc-gateway/bc-gateway-ports/bc-gateway-wallet-proxy/src/main/kotlin/co/nilin/opex/bcgateway/ports/walletproxy/impl/ExtractBackgroundAuth.kt index 048392ca6..77308d779 100644 --- a/bc-gateway/bc-gateway-ports/bc-gateway-wallet-proxy/src/main/kotlin/co/nilin/opex/bcgateway/ports/walletproxy/impl/ExtractBackgroundAuth.kt +++ b/bc-gateway/bc-gateway-ports/bc-gateway-wallet-proxy/src/main/kotlin/co/nilin/opex/bcgateway/ports/walletproxy/impl/ExtractBackgroundAuth.kt @@ -4,13 +4,10 @@ package co.nilin.opex.bcgateway.ports.walletproxy.impl import co.nilin.opex.bcgateway.core.model.otc.LoginRequest import co.nilin.opex.bcgateway.core.spi.AuthProxy import org.springframework.beans.factory.annotation.Value -import org.springframework.context.annotation.Profile import org.springframework.core.env.Environment - import org.springframework.stereotype.Component - @Component class ExtractBackgroundAuth(private val authProxy: AuthProxy, private val environment: Environment) { @@ -29,7 +26,6 @@ class ExtractBackgroundAuth(private val authProxy: AuthProxy, private val enviro } - //save for config Reactive Security context instead of using api diff --git a/bc-gateway/bc-gateway-ports/bc-gateway-wallet-proxy/src/main/kotlin/co/nilin/opex/bcgateway/ports/walletproxy/impl/WalletProxyImpl.kt b/bc-gateway/bc-gateway-ports/bc-gateway-wallet-proxy/src/main/kotlin/co/nilin/opex/bcgateway/ports/walletproxy/impl/WalletProxyImpl.kt index 1f824d9a5..7e46a51ab 100644 --- a/bc-gateway/bc-gateway-ports/bc-gateway-wallet-proxy/src/main/kotlin/co/nilin/opex/bcgateway/ports/walletproxy/impl/WalletProxyImpl.kt +++ b/bc-gateway/bc-gateway-ports/bc-gateway-wallet-proxy/src/main/kotlin/co/nilin/opex/bcgateway/ports/walletproxy/impl/WalletProxyImpl.kt @@ -3,7 +3,6 @@ package co.nilin.opex.bcgateway.ports.walletproxy.impl import co.nilin.opex.bcgateway.core.spi.WalletProxy import co.nilin.opex.bcgateway.ports.walletproxy.model.TransferResult import kotlinx.coroutines.reactive.awaitFirst -import org.springframework.beans.factory.annotation.Qualifier import org.springframework.beans.factory.annotation.Value import org.springframework.core.ParameterizedTypeReference import org.springframework.stereotype.Component @@ -14,38 +13,36 @@ import java.net.URI inline fun typeRef(): ParameterizedTypeReference = object : ParameterizedTypeReference() {} @Component -class WalletProxyImpl(private val webClient: WebClient, - private val extractBackgroundAuth: ExtractBackgroundAuth) : WalletProxy { +class WalletProxyImpl( + private val webClient: WebClient, + private val extractBackgroundAuth: ExtractBackgroundAuth +) : WalletProxy { @Value("\${app.wallet.url}") private lateinit var baseUrl: String -// override suspend fun transfer(uuid: String, symbol: String, amount: BigDecimal, hash: String) { -// webClient.post() -// .uri(URI.create("$baseUrl/deposit/${amount}_${symbol}/${uuid}_main?transferRef=$hash")) -// .header("Content-Type", "application/json") -// .header("Authorization", "Bearer ${extractBackgroundAuth.extractToken()}") -// .retrieve() -// .onStatus({ t -> t.isError }, { it.createException() }) -// .bodyToMono(typeRef()) -// .awaitFirst() -// } - - override suspend fun transfer(uuid: String, symbol: String, amount: BigDecimal, hash: String, chain: String) { + override suspend fun transfer( + uuid: String, + symbol: String, + amount: BigDecimal, + hash: String, + chain: String, + gatewayUuid: String? + ) { val token = extractBackgroundAuth.extractToken() webClient.post() - .uri(URI.create("$baseUrl/deposit/${amount}_${chain}_${symbol}/${uuid}_MAIN?transferRef=$hash")) - .headers { httpHeaders -> - run { - httpHeaders.add("Content-Type", "application/json"); - token?.let { httpHeaders.add("Authorization", "Bearer $it") } - } + .uri(URI.create("$baseUrl/deposit/${amount}_${chain}_${symbol}/${uuid}_MAIN?transferRef=$hash&gatewayUuid=$gatewayUuid")) + .headers { httpHeaders -> + run { + httpHeaders.add("Content-Type", "application/json"); + token?.let { httpHeaders.add("Authorization", "Bearer $it") } } - .retrieve() - .onStatus({ t -> t.isError }, { it.createException() }) - .bodyToMono(typeRef()) - .awaitFirst() + } + .retrieve() + .onStatus({ t -> t.isError }, { it.createException() }) + .bodyToMono(typeRef()) + .awaitFirst() } } diff --git a/bc-gateway/pom.xml b/bc-gateway/pom.xml index cc2ddb897..a4d416185 100644 --- a/bc-gateway/pom.xml +++ b/bc-gateway/pom.xml @@ -1,5 +1,5 @@ - core @@ -20,6 +20,7 @@ bc-gateway-ports/bc-gateway-persister-postgres bc-gateway-ports/bc-gateway-wallet-proxy bc-gateway-ports/bc-gateway-auth-proxy + bc-gateway-ports/bc-gateway-omniwallet-proxy bc-gateway-ports/bc-gateway-eventlistener-kafka @@ -56,6 +57,11 @@ bc-gateway-auth-proxy ${project.version} + + co.nilin.opex.bcgateway.ports.omniwallet + bc-gateway-omniwallet-proxy + ${project.version} + co.nilin.opex.bcgateway.ports.kafka.listener bc-gateway-eventlistener-kafka diff --git a/common/pom.xml b/common/pom.xml index ce854d4a3..5cdcf628e 100644 --- a/common/pom.xml +++ b/common/pom.xml @@ -1,6 +1,6 @@ - 4.0.0 diff --git a/common/src/main/kotlin/co/nilin/opex/common/OpexError.kt b/common/src/main/kotlin/co/nilin/opex/common/OpexError.kt index 5e3b1d774..0ffe13929 100644 --- a/common/src/main/kotlin/co/nilin/opex/common/OpexError.kt +++ b/common/src/main/kotlin/co/nilin/opex/common/OpexError.kt @@ -71,6 +71,15 @@ enum class OpexError(val code: Int, val message: String?, val status: HttpStatus WithdrawAmountLessThanMinimum(6025, "Withdraw amount is less than minimum", HttpStatus.BAD_REQUEST), WithdrawCannotBeCanceled(6026, "Withdraw cannot be canceled", HttpStatus.BAD_REQUEST), WithdrawCannotBeRejected(6027, "Withdraw cannot be rejected", HttpStatus.BAD_REQUEST), + WithdrawAmountMoreThanMinimum(6028, "Withdraw amount is more than minimum", HttpStatus.BAD_REQUEST), + ImplNotFound(6029, null, HttpStatus.NOT_FOUND), + InvalidWithdrawStatus(6030, "Withdraw status is invalid", HttpStatus.NOT_FOUND), + GatewayNotFount(6031, null, HttpStatus.NOT_FOUND), + GatewayIsExist(6032, null, HttpStatus.NOT_FOUND), + InvalidDeposit(6033, "Invalid deposit", HttpStatus.BAD_REQUEST), + TerminalIsExist(6034, "This identifier is exist", HttpStatus.BAD_REQUEST), + TerminalNotFound(6035, "Object not found", HttpStatus.BAD_REQUEST), + // code 7000: api OrderNotFound(7001, "No order found", HttpStatus.NOT_FOUND), diff --git a/common/src/main/kotlin/co/nilin/opex/common/utils/CustomErrorTranslator.kt b/common/src/main/kotlin/co/nilin/opex/common/utils/CustomErrorTranslator.kt new file mode 100644 index 000000000..d7d6bab05 --- /dev/null +++ b/common/src/main/kotlin/co/nilin/opex/common/utils/CustomErrorTranslator.kt @@ -0,0 +1,22 @@ +package co.nilin.opex.common.utils + +import co.nilin.opex.utility.error.data.DefaultExceptionResponse +import co.nilin.opex.utility.error.data.OpexException +import co.nilin.opex.utility.error.spi.ErrorTranslator +import co.nilin.opex.utility.error.spi.ExceptionResponse +import org.springframework.context.MessageSource +import java.util.* + + +class CustomErrorTranslator(private val messageSource: MessageSource) : ErrorTranslator { + override fun translate(ex: OpexException): ExceptionResponse { + return DefaultExceptionResponse( + ex.error.errorName(), + ex.error.code(), + messageSource.getMessage(ex.error.errorName().toString(), null, "", Locale("fa")), + ex.status ?: ex.error.status(), + ex.data, + ex.crimeScene + ) + } +} \ No newline at end of file diff --git a/common/src/main/resources/messages_en.properties b/common/src/main/resources/messages_en.properties new file mode 100644 index 000000000..0837188fd --- /dev/null +++ b/common/src/main/resources/messages_en.properties @@ -0,0 +1,76 @@ +# Generic errors +Error=Generic error +InternalServerError=Internal server error +BadRequest=Bad request +UnAuthorized=Unauthorized +Forbidden=Forbidden +NotFound=Not found +ServiceUnavailable=Service unavailable +# Parameter errors +InvalidRequestParam=Parameter '%s' is either missing or invalid +InvalidRequestBody=Request body is invalid +NoRecordFound=No record found for this service +# Accountant errors +InvalidPair=%s is not available +InvalidPairFee=%s fee is not available +PairFeeNotFound=No fee for requested pair found +# Matching-engine errors (code block omitted) +# Matching-gateway errors +SubmitOrderForbiddenByAccountant=Submitting order is forbidden by accountant +# User-management errors +EmailAlreadyVerified=Email is already verified +GroupNotFound=Group not found +OTPAlreadyEnabled=2FA/OTP already configured +UserNotFound=User not found +InvalidOTP=Invalid OTP +OTPRequired=OTP Required +AlreadyInKYC=KYC flow for this user has executed +UserKYCBlocked=User is blocked from KYC +InvalidPassword=Password is not valid +UserAlreadyExists=User with email is already registered +LoginIsLimited=Your email is not in whitelist +RegisterIsLimited=Your email is not in whitelist +# Wallet errors +WalletOwnerNotFound=Wallet owner not found +WalletNotFound=Wallet not found +CurrencyNotFound=Currency not found +InvalidCashOutUsage=Use withdraw services +WithdrawNotFound=Withdraw not found +NOT_EXCHANGEABLE_CURRENCIES=These two currencies can't be exchanged +CurrencyIsExist=Currency already exists +PairIsExist=Pair already exists +ForbiddenPair=Forbidden pair +InvalidRate=Invalid rate +PairNotFound=Pair not found +SourceIsEqualDest=Source and destination currency are the same +AtLeastNeedOneTransitiveSymbol=At least one transitive symbol is needed +CurrencyIsDisable=Currency is disabled +CurrencyIsTransitiveAndDisablingIsImpossible=Disabling transitive currency is impossible +InvalidReserveNumber=Invalid reserve number +CurrentSystemAssetsAreNotEnough=Current system assets are not enough +NotEnoughBalance=Not enough balance +WithdrawNotAllowed=Withdraw is not allowed +# Deposit errors +DepositLimitExceeded=Deposit limit exceeded +InvalidAmount=Invalid amount +# Implementation errors +ImplNotFound=Implementation not found +InvalidWithdrawStatus=Withdraw status is invalid +# API errors +OrderNotFound=No order found +SymbolNotFound=No symbol found +InvalidLimitForOrderBook=Valid limits: [5, 10, 20, 50, 100, 500, 1000, 5000] +InvalidLimitForRecentTrades=Valid limits: 1 min - 1000 max +InvalidPriceChangeDuration=Valid durations: [24h, 7d, 1m] +CancelOrderNotAllowed=Canceling this order is not allowed +InvalidInterval=Invalid interval +APIKeyLimitReached=Reached API key limit. Maximum number of API key is 10 +# Blockchain-gateway errors +ReservedAddressNotAvailable=No reserved address available +DuplicateToken=Asset already exists +ChainNotFound=Chain not found +CurrencyNotFoundBC=Currency not found +TokenNotFound=Coin/Token not found +InvalidAddressType=Address type is invalid +# Captcha errors +InvalidCaptcha=Captcha is not valid diff --git a/common/src/main/resources/messages_fa.properties b/common/src/main/resources/messages_fa.properties new file mode 100644 index 000000000..e54bb81ca --- /dev/null +++ b/common/src/main/resources/messages_fa.properties @@ -0,0 +1,78 @@ +# Generic errors +Error=خطای عمومی +InternalServerError=خطای سرور داخلی +BadRequest=درخواست نامعتبر +UnAuthorized=مجوز لازم نیست +Forbidden=دسترسی ممنوع +NotFound=یافت نشد +ServiceUnavailable=سرویس در دسترس نیست +# Parameter errors +InvalidRequestParam=پارامتر '%s' یا وجود ندارد یا نامعتبر است +InvalidRequestBody=بدنه درخواست نامعتبر است +NoRecordFound=رکوردی برای این سرویس یافت نشد +# Accountant errors +InvalidPair=%s در دسترس نیست +InvalidPairFee=کارمزد %s در دسترس نیست +PairFeeNotFound=کارمزد برای جفت درخواست شده یافت نشد +# Matching-engine errors (code block omitted) +# Matching-gateway errors +SubmitOrderForbiddenByAccountant=ثبت سفارش توسط حسابدار ممنوع است +# User-management errors +EmailAlreadyVerified=ایمیل قبلاً تأیید شده است +GroupNotFound=گروه یافت نشد +OTPAlreadyEnabled=تأیید دو مرحله ای (OTP) قبلاً پیکربندی شده است +UserNotFound=کاربر یافت نشد +InvalidOTP=کد تأیید نامعتبر است +OTPRequired=کد تأیید لازم است +AlreadyInKYC=فرایند احراز هویت برای این کاربر اجرا شده است +UserKYCBlocked=کاربر از احراز هویت مسدود شده است +InvalidPassword=رمز عبور نامعتبر است +UserAlreadyExists=کاربری با این ایمیل قبلاً ثبت نام کرده است +LoginIsLimited=ایمیل شما در لیست سفید نیست +RegisterIsLimited=ایمیل شما در لیست سفید نیست +# Wallet errors +WalletOwnerNotFound=مالک کیف پول یافت نشد +WalletNotFound=کیف پول یافت نشد +CurrencyNotFound=ارز یافت نشد +InvalidCashOutUsage=از خدمات برداشت استفاده کنید +WithdrawNotFound=برداشت یافت نشد +NOT_EXCHANGEABLE_CURRENCIES=این دو ارز قابل تبادل نیستند +CurrencyIsExist=ارز وجود دارد +PairIsExist=جفت وجود دارد +ForbiddenPair=جفت ممنوع +InvalidRate=نرخ نامعتبر است +PairNotFound=جفت یافت نشد +SourceIsEqualDest=ارز مبدا و مقصد یکسان هستند +AtLeastNeedOneTransitiveSymbol=حداقل به یک نماد انتقالی نیاز است +CurrencyIsDisable=ارز غیرفعال است +CurrencyIsTransitiveAndDisablingIsImpossible=غیرفعال کردن ارز انتقالی امکان پذیر نیست +InvalidReserveNumber=تعداد رزرو نامعتبر است +CurrentSystemAssetsAreNotEnough=دارایی های فعلی سیستم کافی نیست +NotEnoughBalance=موجودی کافی نیست +WithdrawNotAllowed=برداشت مجاز نیست +# Deposit errors +DepositLimitExceeded=حداقل سپرده فراتر رفته است +InvalidAmount=مبلغ نامعتبر است +# Implementation errors +ImplNotFound=پیاده سازی یافت نشد +InvalidWithdrawStatus=وضعیت برداشت نامعتبر است +GatewayIsExist=درگاه مورد نظر پیش از این در سییستم تعریف شده است +GatewayNotFount=درگاه مورد نظر یافت نشد +# API errors +OrderNotFound=سفارش یافت نشد +SymbolNotFound=نماد یافت نشد +InvalidLimitForOrderBook=محدوده های معتبر: [5, 10, 20, 50, 100, 500, 1000, 5000] +InvalidLimitForRecentTrades=محدوده های معتبر: 1 دقیقه - 1000 حداکثر +InvalidPriceChangeDuration=مدت های معتبر: [24 ساعت، 7 روز، 1 ماه] +CancelOrderNotAllowed=لغو این سفارش مجاز نیست +InvalidInterval=فاصله زمانی نامعتبر است +APIKeyLimitReached=به محدودیت کلید API رسیدید. حداکثر تعداد کلید API 10 است +# Blockchain-gateway errors +ReservedAddressNotAvailable=آدرس رزرو شده در دسترس نیست +DuplicateToken=دارایی قبلاً وجود دارد +ChainNotFound=زنجیره یافت نشد +CurrencyNotFoundBC=ارز یافت نشد +TokenNotFound=سکه/توکن یافت نشد +InvalidAddressType=نوع آدرس نامعتبر است +# Captcha errors +InvalidCaptcha=کد امنیتی نامعتبر است \ No newline at end of file diff --git a/docker-compose-otc.yml b/docker-compose-otc.yml index 59bbbec0b..62bcbcea3 100644 --- a/docker-compose-otc.yml +++ b/docker-compose-otc.yml @@ -33,10 +33,12 @@ services: - DRIVE_FOLDER_ID=$DRIVE_FOLDER_ID - BACKUP_ENABLED=$WALLET_BACKUP_ENABLED - SPRING_PROFILES_ACTIVE=otc - - auth_url=${AUTH_URL} - - auth_jwk_endpoint=${JWK_ENDPOINT} - configs: - - preferences.yml + - AUTH_URL=${AUTH_URL} + - AUTH_JWK_ENDPOINT=${JWK_ENDPOINT} + extra_hosts: + - "host.docker.internal:host-gateway" + # configs: + # - preferences.yml depends_on: - postgres-wallet - vault @@ -51,6 +53,8 @@ services: deploy: restart_policy: condition: on-failure + volumes: + - documents:/Documents vault: image: ghcr.io/opexdev/vault-opex:${TAG} volumes: @@ -89,14 +93,15 @@ services: - VAULT_HOST=vault - SWAGGER_AUTH_URL=$KEYCLOAK_FRONTEND_URL - PREFERENCES=$PREFERENCES - - ADDRESS_EXP_TIME=120 + - ADDRESS_EXP_TIME=7200 - SPRING_PROFILES_ACTIVE=otc - - auth_url=${AUTH_URL} - - auth_jwk_endpoint=${JWK_ENDPOINT} - dns: - - "8.8.8.8" - configs: - - preferences.yml + - AUTH_URL=${AUTH_URL} + - AUTH_JWK_ENDPOINT=${JWK_ENDPOINT} + - OMNI_URL=${OMNI_URL} + extra_hosts: + - "host.docker.internal:host-gateway" + # configs: + # - preferences.yml depends_on: - vault - postgres-bc-gateway @@ -120,6 +125,7 @@ volumes: wallet-data: vault-data: bc-gateway-data: + documents: networks: default: diff --git a/docker-images/kafka/kafka-jmx-exporter.yml b/docker-images/kafka/kafka-jmx-exporter.yml index 4de5dad60..4ef7bcd6d 100644 --- a/docker-images/kafka/kafka-jmx-exporter.yml +++ b/docker-images/kafka/kafka-jmx-exporter.yml @@ -172,20 +172,20 @@ rules: "$3": "$4" # Quotas - - pattern : 'kafka.server<>(.+):' + - pattern: 'kafka.server<>(.+):' name: kafka_server_$1_$4 type: GAUGE labels: user: "$2" client-id: "$3" - - pattern : 'kafka.server<>(.+):' + - pattern: 'kafka.server<>(.+):' name: kafka_server_$1_$3 type: GAUGE labels: user: "$2" - - pattern : 'kafka.server<>(.+):' + - pattern: 'kafka.server<>(.+):' name: kafka_server_$1_$3 type: GAUGE labels: diff --git a/docker-images/vault/workflow-vault.sh b/docker-images/vault/workflow-vault.sh index 3d11ed140..ad614eb28 100755 --- a/docker-images/vault/workflow-vault.sh +++ b/docker-images/vault/workflow-vault.sh @@ -62,6 +62,7 @@ init_secrets() { vault write auth/app-id/map/app-id/opex-referral value=backend-policy display_name=opex-referral vault write auth/app-id/map/app-id/opex-profile value=backend-policy display_name=opex-profile vault write auth/app-id/map/app-id/opex-kyc value=backend-policy display_name=opex-kyc + vault write auth/app-id/map/app-id/opex-kyc value=backend-policy display_name=opex-kyc ## Enable user-id diff --git a/eventlog/eventlog-app/pom.xml b/eventlog/eventlog-app/pom.xml index 161a09170..ae93544bc 100644 --- a/eventlog/eventlog-app/pom.xml +++ b/eventlog/eventlog-app/pom.xml @@ -1,5 +1,5 @@ - 4.0.0 diff --git a/eventlog/eventlog-app/src/main/kotlin/co/nilin/opex/eventlog/app/listeners/DeadLetterListener.kt b/eventlog/eventlog-app/src/main/kotlin/co/nilin/opex/eventlog/app/listeners/DeadLetterListener.kt index 0a9ce8f5b..9309af238 100644 --- a/eventlog/eventlog-app/src/main/kotlin/co/nilin/opex/eventlog/app/listeners/DeadLetterListener.kt +++ b/eventlog/eventlog-app/src/main/kotlin/co/nilin/opex/eventlog/app/listeners/DeadLetterListener.kt @@ -19,28 +19,29 @@ class DeadLetterListener(private val persister: DeadLetterPersister) : DLTListen return "EventLogDeadLetterListener" } - override fun onEvent(event: String?, partition: Int, offset: Long, timestamp: Long, headers: Headers) = runBlocking { - logger.info("Dead letter event received: $event") - val map = hashMapOf().apply { - headers.forEach { - put(it.key(), it.value().toString(Charsets.UTF_8)) + override fun onEvent(event: String?, partition: Int, offset: Long, timestamp: Long, headers: Headers) = + runBlocking { + logger.info("Dead letter event received: $event") + val map = hashMapOf().apply { + headers.forEach { + put(it.key(), it.value().toString(Charsets.UTF_8)) + } } - } - val dlt = DeadLetterEvent( - map["dlt-origin-module"]!!, - map[KafkaHeaders.DLT_ORIGINAL_TOPIC], - map[KafkaHeaders.DLT_ORIGINAL_CONSUMER_GROUP], - map[KafkaHeaders.DLT_EXCEPTION_MESSAGE], - map[KafkaHeaders.DLT_EXCEPTION_STACKTRACE], - map[KafkaHeaders.DLT_EXCEPTION_FQCN], - event, - LocalDateTime.ofInstant(Instant.ofEpochMilli(timestamp), TimeZone.getDefault().toZoneId()) - ) - - persister.save(dlt) - logger.info("DLT persisted") - } + val dlt = DeadLetterEvent( + map["dlt-origin-module"]!!, + map[KafkaHeaders.DLT_ORIGINAL_TOPIC], + map[KafkaHeaders.DLT_ORIGINAL_CONSUMER_GROUP], + map[KafkaHeaders.DLT_EXCEPTION_MESSAGE], + map[KafkaHeaders.DLT_EXCEPTION_STACKTRACE], + map[KafkaHeaders.DLT_EXCEPTION_FQCN], + event, + LocalDateTime.ofInstant(Instant.ofEpochMilli(timestamp), TimeZone.getDefault().toZoneId()) + ) + + persister.save(dlt) + logger.info("DLT persisted") + } } \ No newline at end of file diff --git a/eventlog/eventlog-app/src/main/resources/application.yml b/eventlog/eventlog-app/src/main/resources/application.yml index 964e5cf10..38f52cf59 100644 --- a/eventlog/eventlog-app/src/main/resources/application.yml +++ b/eventlog/eventlog-app/src/main/resources/application.yml @@ -5,7 +5,7 @@ spring: main: allow-circular-references: true kafka: - bootstrap-servers: ${KAFKA_IP_PORT:localhost:9092} + bootstrap-servers: ${KAFKA_IP_PORT:localhost:9092} consumer: group-id: eventlog r2dbc: @@ -34,7 +34,7 @@ management: web: base-path: /actuator exposure: - include: ["health", "prometheus", "metrics"] + include: [ "health", "prometheus", "metrics" ] endpoint: health: show-details: when_authorized diff --git a/eventlog/eventlog-core/pom.xml b/eventlog/eventlog-core/pom.xml index 0b8ad9765..ef376ebc5 100644 --- a/eventlog/eventlog-core/pom.xml +++ b/eventlog/eventlog-core/pom.xml @@ -1,5 +1,5 @@ - 4.0.0 diff --git a/eventlog/eventlog-ports/eventlog-eventlistener-kafka/pom.xml b/eventlog/eventlog-ports/eventlog-eventlistener-kafka/pom.xml index 9a6857784..6f88e8565 100644 --- a/eventlog/eventlog-ports/eventlog-eventlistener-kafka/pom.xml +++ b/eventlog/eventlog-ports/eventlog-eventlistener-kafka/pom.xml @@ -1,5 +1,5 @@ - 4.0.0 diff --git a/eventlog/eventlog-ports/eventlog-eventlistener-kafka/src/main/kotlin/co/nilin/opex/eventlog/ports/kafka/listener/consumer/DLTKafkaListener.kt b/eventlog/eventlog-ports/eventlog-eventlistener-kafka/src/main/kotlin/co/nilin/opex/eventlog/ports/kafka/listener/consumer/DLTKafkaListener.kt index aa9ee7a69..6c09d4555 100644 --- a/eventlog/eventlog-ports/eventlog-eventlistener-kafka/src/main/kotlin/co/nilin/opex/eventlog/ports/kafka/listener/consumer/DLTKafkaListener.kt +++ b/eventlog/eventlog-ports/eventlog-eventlistener-kafka/src/main/kotlin/co/nilin/opex/eventlog/ports/kafka/listener/consumer/DLTKafkaListener.kt @@ -12,7 +12,15 @@ class DLTKafkaListener : MessageListener { override fun onMessage(data: ConsumerRecord) { - listeners.forEach { it.onEvent(data.value(), data.partition(), data.offset(), data.timestamp(), data.headers()) } + listeners.forEach { + it.onEvent( + data.value(), + data.partition(), + data.offset(), + data.timestamp(), + data.headers() + ) + } } fun addEventListener(tl: DLTListener) { diff --git a/eventlog/eventlog-ports/eventlog-eventlistener-kafka/src/main/kotlin/co/nilin/opex/eventlog/ports/kafka/listener/inout/OrderRequestEvent.kt b/eventlog/eventlog-ports/eventlog-eventlistener-kafka/src/main/kotlin/co/nilin/opex/eventlog/ports/kafka/listener/inout/OrderRequestEvent.kt index d0d6381cf..d569df4d1 100644 --- a/eventlog/eventlog-ports/eventlog-eventlistener-kafka/src/main/kotlin/co/nilin/opex/eventlog/ports/kafka/listener/inout/OrderRequestEvent.kt +++ b/eventlog/eventlog-ports/eventlog-eventlistener-kafka/src/main/kotlin/co/nilin/opex/eventlog/ports/kafka/listener/inout/OrderRequestEvent.kt @@ -2,4 +2,4 @@ package co.nilin.opex.eventlog.ports.kafka.listener.inout import co.nilin.opex.matching.engine.core.model.Pair -abstract class OrderRequestEvent(val ouid:String, val uuid: String, val pair: Pair) \ No newline at end of file +abstract class OrderRequestEvent(val ouid: String, val uuid: String, val pair: Pair) \ No newline at end of file diff --git a/eventlog/eventlog-ports/eventlog-persister-postgres/pom.xml b/eventlog/eventlog-ports/eventlog-persister-postgres/pom.xml index 9df95effb..811952e9c 100644 --- a/eventlog/eventlog-ports/eventlog-persister-postgres/pom.xml +++ b/eventlog/eventlog-ports/eventlog-persister-postgres/pom.xml @@ -1,5 +1,5 @@ - 4.0.0 diff --git a/eventlog/eventlog-ports/eventlog-persister-postgres/src/main/resources/schema.sql b/eventlog/eventlog-ports/eventlog-persister-postgres/src/main/resources/schema.sql index f4c381101..3f58a1c7f 100644 --- a/eventlog/eventlog-ports/eventlog-persister-postgres/src/main/resources/schema.sql +++ b/eventlog/eventlog-ports/eventlog-persister-postgres/src/main/resources/schema.sql @@ -1,79 +1,189 @@ CREATE TABLE IF NOT EXISTS opex_orders ( - id SERIAL PRIMARY KEY, - ouid VARCHAR(72) NOT NULL UNIQUE, - symbol VARCHAR(20) NOT NULL, - direction VARCHAR(20) NOT NULL, - match_constraint VARCHAR(20) NOT NULL, - order_type VARCHAR(20) NOT NULL, - uuid VARCHAR(72) NOT NULL, - agent VARCHAR(20), - ip VARCHAR(11), - order_date TIMESTAMP NOT NULL, - create_date TIMESTAMP NOT NULL -); + id + SERIAL + PRIMARY + KEY, + ouid + VARCHAR +( + 72 +) NOT NULL UNIQUE, + symbol VARCHAR +( + 20 +) NOT NULL, + direction VARCHAR +( + 20 +) NOT NULL, + match_constraint VARCHAR +( + 20 +) NOT NULL, + order_type VARCHAR +( + 20 +) NOT NULL, + uuid VARCHAR +( + 72 +) NOT NULL, + agent VARCHAR +( + 20 +), + ip VARCHAR +( + 11 +), + order_date TIMESTAMP NOT NULL, + create_date TIMESTAMP NOT NULL + ); CREATE TABLE IF NOT EXISTS opex_order_events ( - id SERIAL PRIMARY KEY, - ouid VARCHAR(72) NOT NULL, + id + SERIAL + PRIMARY + KEY, + ouid + VARCHAR +( + 72 +) NOT NULL, matching_orderid BIGINT, - price BIGINT, - quantity BIGINT, - filled_quantity BIGINT, - uuid VARCHAR(72) NOT NULL, - event VARCHAR(30) NOT NULL, - agent VARCHAR(20), - ip VARCHAR(11), - event_date TIMESTAMP NOT NULL, - create_date TIMESTAMP NOT NULL -); + price BIGINT, + quantity BIGINT, + filled_quantity BIGINT, + uuid VARCHAR +( + 72 +) NOT NULL, + event VARCHAR +( + 30 +) NOT NULL, + agent VARCHAR +( + 20 +), + ip VARCHAR +( + 11 +), + event_date TIMESTAMP NOT NULL, + create_date TIMESTAMP NOT NULL + ); CREATE TABLE IF NOT EXISTS opex_events ( - id SERIAL PRIMARY KEY, - correlation_id VARCHAR(72) NOT NULL, - ouid VARCHAR(72) NOT NULL, - uuid VARCHAR(72) NOT NULL, - symbol VARCHAR(20) NOT NULL, - event VARCHAR(30) NOT NULL, - event_json TEXT NOT NULL, - agent VARCHAR(20), - ip VARCHAR(11), - event_date TIMESTAMP NOT NULL, - create_date TIMESTAMP NOT NULL -); + id + SERIAL + PRIMARY + KEY, + correlation_id + VARCHAR +( + 72 +) NOT NULL, + ouid VARCHAR +( + 72 +) NOT NULL, + uuid VARCHAR +( + 72 +) NOT NULL, + symbol VARCHAR +( + 20 +) NOT NULL, + event VARCHAR +( + 30 +) NOT NULL, + event_json TEXT NOT NULL, + agent VARCHAR +( + 20 +), + ip VARCHAR +( + 11 +), + event_date TIMESTAMP NOT NULL, + create_date TIMESTAMP NOT NULL + ); CREATE TABLE IF NOT EXISTS opex_trades ( - id SERIAL PRIMARY KEY, - symbol VARCHAR(20) NOT NULL, - taker_ouid VARCHAR(72) NOT NULL, - taker_uuid VARCHAR(72) NOT NULL, - taker_matching_orderid BIGINT NOT NULL, - taker_direction VARCHAR(20) NOT NULL, - taker_price BIGINT NOT NULL, - taker_remained_quantity BIGINT NOT NULL, - maker_ouid VARCHAR(72) NOT NULL, - maker_uuid VARCHAR(72) NOT NULL, - maker_matching_orderid BIGINT NOT NULL, - maker_direction VARCHAR(20) NOT NULL, - maker_price BIGINT NOT NULL, - maker_remained_quantity BIGINT NOT NULL, - matched_quantity BIGINT NOT NULL, - trade_date TIMESTAMP NOT NULL, - create_date TIMESTAMP NOT NULL -); + id + SERIAL + PRIMARY + KEY, + symbol + VARCHAR +( + 20 +) NOT NULL, + taker_ouid VARCHAR +( + 72 +) NOT NULL, + taker_uuid VARCHAR +( + 72 +) NOT NULL, + taker_matching_orderid BIGINT NOT NULL, + taker_direction VARCHAR +( + 20 +) NOT NULL, + taker_price BIGINT NOT NULL, + taker_remained_quantity BIGINT NOT NULL, + maker_ouid VARCHAR +( + 72 +) NOT NULL, + maker_uuid VARCHAR +( + 72 +) NOT NULL, + maker_matching_orderid BIGINT NOT NULL, + maker_direction VARCHAR +( + 20 +) NOT NULL, + maker_price BIGINT NOT NULL, + maker_remained_quantity BIGINT NOT NULL, + matched_quantity BIGINT NOT NULL, + trade_date TIMESTAMP NOT NULL, + create_date TIMESTAMP NOT NULL + ); CREATE TABLE IF NOT EXISTS dead_letter_events ( - id SERIAL PRIMARY KEY, - origin_module VARCHAR(72) NOT NULL, - origin_topic VARCHAR(72), - consumer_group VARCHAR(72), - exception_message TEXT, + id + SERIAL + PRIMARY + KEY, + origin_module + VARCHAR +( + 72 +) NOT NULL, + origin_topic VARCHAR +( + 72 +), + consumer_group VARCHAR +( + 72 +), + exception_message TEXT, exception_stacktrace TEXT, exception_class_name TEXT, - timestamp TIMESTAMP NOT NULL, - value TEXT -) + timestamp TIMESTAMP NOT NULL, + value TEXT + ) diff --git a/eventlog/pom.xml b/eventlog/pom.xml index bc56375fa..0619de2ec 100644 --- a/eventlog/pom.xml +++ b/eventlog/pom.xml @@ -1,5 +1,5 @@ - 4.0.0 diff --git a/market/market-app/src/main/kotlin/co/nilin/opex/market/app/MarketAppApplication.kt b/market/market-app/src/main/kotlin/co/nilin/opex/market/app/MarketAppApplication.kt index c8413c59d..f992edac6 100644 --- a/market/market-app/src/main/kotlin/co/nilin/opex/market/app/MarketAppApplication.kt +++ b/market/market-app/src/main/kotlin/co/nilin/opex/market/app/MarketAppApplication.kt @@ -11,5 +11,5 @@ import org.springframework.scheduling.annotation.EnableScheduling class MarketAppApplication fun main(args: Array) { - runApplication(*args) + runApplication(*args) } diff --git a/market/market-app/src/main/kotlin/co/nilin/opex/market/app/config/InitializeService.kt b/market/market-app/src/main/kotlin/co/nilin/opex/market/app/config/InitializeService.kt index edeba1083..acf04c094 100644 --- a/market/market-app/src/main/kotlin/co/nilin/opex/market/app/config/InitializeService.kt +++ b/market/market-app/src/main/kotlin/co/nilin/opex/market/app/config/InitializeService.kt @@ -1,14 +1,11 @@ package co.nilin.opex.market.app.config -import co.nilin.opex.market.core.inout.RateSource import co.nilin.opex.market.ports.postgres.dao.CurrencyRateRepository import co.nilin.opex.utility.preferences.Preferences -import kotlinx.coroutines.reactor.awaitSingleOrNull import kotlinx.coroutines.runBlocking import org.springframework.beans.factory.annotation.Autowired import org.springframework.context.annotation.DependsOn import org.springframework.stereotype.Component -import java.math.BigDecimal import javax.annotation.PostConstruct @Component diff --git a/market/market-app/src/main/kotlin/co/nilin/opex/market/app/config/WebClientConfig.kt b/market/market-app/src/main/kotlin/co/nilin/opex/market/app/config/WebClientConfig.kt index 3ac945a3e..1548b9677 100644 --- a/market/market-app/src/main/kotlin/co/nilin/opex/market/app/config/WebClientConfig.kt +++ b/market/market-app/src/main/kotlin/co/nilin/opex/market/app/config/WebClientConfig.kt @@ -1,12 +1,10 @@ package co.nilin.opex.market.app.config import org.springframework.cloud.client.ServiceInstance -import org.springframework.cloud.client.loadbalancer.LoadBalancerProperties import org.springframework.cloud.client.loadbalancer.reactive.ReactiveLoadBalancer import org.springframework.cloud.client.loadbalancer.reactive.ReactorLoadBalancerExchangeFilterFunction import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration -import org.springframework.http.client.reactive.ReactorClientHttpConnector import org.springframework.web.reactive.function.client.WebClient import org.zalando.logbook.Logbook import org.zalando.logbook.netty.LogbookClientHandler diff --git a/market/market-app/src/main/kotlin/co/nilin/opex/market/app/controller/MarketStatsController.kt b/market/market-app/src/main/kotlin/co/nilin/opex/market/app/controller/MarketStatsController.kt index ecd3401f7..a3c125119 100644 --- a/market/market-app/src/main/kotlin/co/nilin/opex/market/app/controller/MarketStatsController.kt +++ b/market/market-app/src/main/kotlin/co/nilin/opex/market/app/controller/MarketStatsController.kt @@ -3,15 +3,11 @@ package co.nilin.opex.market.app.controller import co.nilin.opex.common.utils.Interval import co.nilin.opex.market.core.inout.PriceStat import co.nilin.opex.market.core.inout.TradeVolumeStat -import co.nilin.opex.market.core.inout.Transaction -import co.nilin.opex.market.core.inout.TxOfTrades import co.nilin.opex.market.core.spi.MarketQueryHandler import org.springframework.web.bind.annotation.GetMapping -import org.springframework.web.bind.annotation.PathVariable import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RequestParam import org.springframework.web.bind.annotation.RestController -import java.time.LocalDateTime import java.util.* @RestController @@ -39,5 +35,4 @@ class MarketStatsController(private val marketQueryHandler: MarketQueryHandler) } - } \ No newline at end of file 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 b65fa1503..4c3d41c24 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 @@ -23,9 +23,9 @@ class UserDataController(private val userQueryHandler: UserQueryHandler) { @GetMapping("/{uuid}/orders/{symbol}/open") suspend fun getUserOpenOrders( - @PathVariable uuid: String, - @PathVariable symbol: String, - @RequestParam limit: Int + @PathVariable uuid: String, + @PathVariable symbol: String, + @RequestParam limit: Int ): List { return userQueryHandler.openOrders(uuid, symbol, limit) } diff --git a/market/market-app/src/main/kotlin/co/nilin/opex/market/app/service/ReportingService.kt b/market/market-app/src/main/kotlin/co/nilin/opex/market/app/service/ReportingService.kt index 38c05cbf0..f4a952100 100644 --- a/market/market-app/src/main/kotlin/co/nilin/opex/market/app/service/ReportingService.kt +++ b/market/market-app/src/main/kotlin/co/nilin/opex/market/app/service/ReportingService.kt @@ -1,13 +1,11 @@ package co.nilin.opex.market.app.service import co.nilin.opex.common.utils.Interval -import co.nilin.opex.market.app.utils.asLocalDateTime import co.nilin.opex.market.core.spi.MarketQueryHandler import kotlinx.coroutines.runBlocking import org.slf4j.LoggerFactory import org.springframework.scheduling.annotation.Scheduled import org.springframework.stereotype.Service -import java.time.LocalDateTime @Service class ReportingService(private val marketQueryHandler: MarketQueryHandler) { diff --git a/market/market-app/src/main/kotlin/co/nilin/opex/market/app/utils/PrometheusHealthExtension.kt b/market/market-app/src/main/kotlin/co/nilin/opex/market/app/utils/PrometheusHealthExtension.kt index 90fe2b630..ab1ca9aa0 100644 --- a/market/market-app/src/main/kotlin/co/nilin/opex/market/app/utils/PrometheusHealthExtension.kt +++ b/market/market-app/src/main/kotlin/co/nilin/opex/market/app/utils/PrometheusHealthExtension.kt @@ -6,7 +6,6 @@ import org.springframework.boot.actuate.health.HealthComponent import org.springframework.boot.actuate.health.HealthEndpoint import org.springframework.boot.actuate.health.SystemHealth import org.springframework.context.annotation.Profile -import org.springframework.scheduling.annotation.EnableScheduling import org.springframework.scheduling.annotation.Scheduled import org.springframework.stereotype.Component diff --git a/market/market-core/src/main/kotlin/co/nilin/opex/market/core/inout/Transaction.kt b/market/market-core/src/main/kotlin/co/nilin/opex/market/core/inout/Transaction.kt index 39b85d1b9..72f715fb0 100644 --- a/market/market-core/src/main/kotlin/co/nilin/opex/market/core/inout/Transaction.kt +++ b/market/market-core/src/main/kotlin/co/nilin/opex/market/core/inout/Transaction.kt @@ -4,14 +4,14 @@ import java.math.BigDecimal import java.time.LocalDateTime data class Transaction( - var createDate: LocalDateTime, - var volume: BigDecimal, - val transactionPrice: BigDecimal, - var matchedPrice: BigDecimal, - var side: String, - var symbol: String, - var fee: BigDecimal, - var user: String?=null + var createDate: LocalDateTime, + var volume: BigDecimal, + val transactionPrice: BigDecimal, + var matchedPrice: BigDecimal, + var side: String, + var symbol: String, + var fee: BigDecimal, + var user: String? = null ) -data class TxOfTrades(var transactions:List?) \ No newline at end of file +data class TxOfTrades(var transactions: List?) \ No newline at end of file diff --git a/market/market-core/src/main/kotlin/co/nilin/opex/market/core/inout/TransactionRequest.kt b/market/market-core/src/main/kotlin/co/nilin/opex/market/core/inout/TransactionRequest.kt index d9f66d6a4..2dd1ec454 100644 --- a/market/market-core/src/main/kotlin/co/nilin/opex/market/core/inout/TransactionRequest.kt +++ b/market/market-core/src/main/kotlin/co/nilin/opex/market/core/inout/TransactionRequest.kt @@ -1,12 +1,12 @@ package co.nilin.opex.market.core.inout data class TransactionRequest( - val coin: String?, - val category: String?, - val startTime: Long? = null, - val endTime: Long? = null, - val limit: Int? = 10, - val offset: Int? = 0, - val ascendingByTime: Boolean? = false, - var owner: String? = null + val coin: String?, + val category: String?, + val startTime: Long? = null, + val endTime: Long? = null, + val limit: Int? = 10, + val offset: Int? = 0, + val ascendingByTime: Boolean? = false, + var owner: String? = null ) \ No newline at end of file diff --git a/market/market-core/src/main/kotlin/co/nilin/opex/market/core/inout/TransactionResponse.kt b/market/market-core/src/main/kotlin/co/nilin/opex/market/core/inout/TransactionResponse.kt index bc50f7f80..b78e4eec0 100644 --- a/market/market-core/src/main/kotlin/co/nilin/opex/market/core/inout/TransactionResponse.kt +++ b/market/market-core/src/main/kotlin/co/nilin/opex/market/core/inout/TransactionResponse.kt @@ -1,19 +1,18 @@ package co.nilin.opex.market.core.inout import java.math.BigDecimal -import java.time.LocalDateTime -import java.util.Date +import java.util.* data class TransactionDto( - var createDate: Date, - var volume: BigDecimal, - val transactionPrice: BigDecimal, - var matchedPrice: BigDecimal, - var side: String, - var symbol: String, - var fee: BigDecimal, - var user: String?=null + var createDate: Date, + var volume: BigDecimal, + val transactionPrice: BigDecimal, + var matchedPrice: BigDecimal, + var side: String, + var symbol: String, + var fee: BigDecimal, + var user: String? = null ) -data class TransactionResponse(var transactions:List?) \ No newline at end of file +data class TransactionResponse(var transactions: List?) \ 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 1a7d097d9..96d8f4265 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 @@ -1,7 +1,6 @@ package co.nilin.opex.market.core.spi import co.nilin.opex.market.core.inout.* -import java.time.LocalDateTime interface UserQueryHandler { 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 801df16cd..648c8ab9e 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 @@ -25,7 +25,7 @@ interface TradeRepository : ReactiveCrudRepository { fun findMostRecentBySymbol(symbol: String): Flow @Query( - """ + """ select * from trades where :uuid in (taker_uuid, maker_uuid) and (:fromTrade is null or id > :fromTrade) and (:symbol is null or symbol = :symbol) @@ -36,29 +36,29 @@ interface TradeRepository : ReactiveCrudRepository { """ ) fun findByUuidAndSymbolAndTimeBetweenAndTradeIdGreaterThan( - @Param("uuid") - uuid: String, - @Param("symbol") - symbol: String?, - @Param("fromTrade") - fromTrade: Long?, - @Param("startTime") - startTime: Date?, - @Param("endTime") - endTime: Date?, - limit: Int + @Param("uuid") + uuid: String, + @Param("symbol") + symbol: String?, + @Param("fromTrade") + fromTrade: Long?, + @Param("startTime") + startTime: Date?, + @Param("endTime") + endTime: Date?, + limit: Int ): Flow @Query("select * from trades where symbol = :symbol order by create_date desc limit :limit") fun findBySymbolSortDescendingByCreateDate( - @Param("symbol") - symbol: String, - @Param("limit") - limit: Int + @Param("symbol") + symbol: String, + @Param("limit") + limit: Int ): Flow @Query( - """ + """ with first_trade as (select id, symbol, matched_price, matched_quantity from trades where id in (select min(id) from trades where create_date > :date group by symbol)), last_trade as (select id, symbol, matched_price, matched_quantity from trades where id in (select max(id) from trades where create_date > :date group by symbol)) select symbol, @@ -99,7 +99,7 @@ interface TradeRepository : ReactiveCrudRepository { fun tradeTicker(@Param("date") createDate: LocalDateTime): Flux @Query( - """ + """ with first_trade as (select * from trades where create_date > :date and symbol = :symbol order by create_date limit 1), last_trade as (select * from trades where create_date > :date and symbol = :symbol order by create_date desc limit 1) select symbol, @@ -138,14 +138,14 @@ interface TradeRepository : ReactiveCrudRepository { """ ) fun tradeTickerBySymbol( - @Param("symbol") - symbol: String, - @Param("date") - createDate: LocalDateTime, + @Param("symbol") + symbol: String, + @Param("date") + createDate: LocalDateTime, ): Mono @Query( - """ + """ select symbol, ( select price from orders @@ -166,7 +166,7 @@ interface TradeRepository : ReactiveCrudRepository { fun bestAskAndBidPrice(): Flux @Query( - """ + """ select symbol, ( select price from orders @@ -188,7 +188,7 @@ interface TradeRepository : ReactiveCrudRepository { fun bestAskAndBidPrice(symbols: List): Flux @Query( - """ + """ select symbol, ( select price from orders @@ -216,7 +216,7 @@ interface TradeRepository : ReactiveCrudRepository { fun findAllGroupBySymbol(): Flux @Query( - """ + """ WITH intervals AS (SELECT * FROM interval_generator((TO_TIMESTAMP(:startTime)) ::TIMESTAMP WITHOUT TIME ZONE, (:endTime), :interval ::INTERVAL)), first_trade AS ( SELECT DISTINCT ON (f.start_time) f.start_time, f.end_time, t.matched_price AS open_price FROM intervals f @@ -248,16 +248,16 @@ interface TradeRepository : ReactiveCrudRepository { """ ) suspend fun candleData( - @Param("symbol") - symbol: String, - @Param("interval") - interval: String, - @Param("startTime") - startTime: LocalDateTime, - @Param("endTime") - endTime: LocalDateTime, - @Param("limit") - limit: Int, + @Param("symbol") + symbol: String, + @Param("interval") + interval: String, + @Param("startTime") + startTime: LocalDateTime, + @Param("endTime") + endTime: LocalDateTime, + @Param("limit") + limit: Int, ): Flux @Query("select * from trades order by create_date desc limit 1") @@ -273,7 +273,7 @@ interface TradeRepository : ReactiveCrudRepository { fun countBySymbolNewerThan(interval: LocalDateTime, symbol: String): Flow @Query( - """ + """ WITH first_trade AS (SELECT symbol, MIN(id) AS min_id FROM trades WHERE create_date > :since GROUP BY symbol), last_trade AS (SELECT symbol, MAX(id) AS max_id FROM trades WHERE create_date > :since GROUP BY symbol), first_trade_details AS (SELECT ft.symbol, t.matched_price AS first_price FROM first_trade ft JOIN trades t ON ft.min_id = t.id), @@ -295,7 +295,7 @@ interface TradeRepository : ReactiveCrudRepository { fun findByMostIncreasedPrice(since: LocalDateTime, limit: Int): Flux @Query( - """ + """ WITH first_trade AS (SELECT symbol, MIN(id) AS min_id FROM trades WHERE create_date > :since GROUP BY symbol), last_trade AS (SELECT symbol, MAX(id) AS max_id FROM trades WHERE create_date > :since GROUP BY symbol), first_trade_details AS (SELECT ft.symbol, t.matched_price AS first_price FROM first_trade ft JOIN trades t ON ft.min_id = t.id), @@ -317,7 +317,7 @@ interface TradeRepository : ReactiveCrudRepository { fun findByMostDecreasedPrice(since: LocalDateTime, limit: Int): Flux @Query( - """ + """ with first_trade as (select symbol, matched_quantity mq from trades where id in (select min(id) from trades where create_date > :since group by symbol)), last_trade as (select symbol, matched_quantity mq from trades where id in (select max(id) from trades where create_date > :since group by symbol)) select @@ -341,7 +341,7 @@ interface TradeRepository : ReactiveCrudRepository { fun findByMostVolume(since: LocalDateTime): Mono @Query( - """ + """ with first_trade as (select symbol, matched_quantity mq from trades where id in (select min(id) from trades where create_date > :since group by symbol)), last_trade as (select symbol, matched_quantity mq from trades where id in (select max(id) from trades where create_date > :since group by symbol)) select @@ -365,7 +365,8 @@ interface TradeRepository : ReactiveCrudRepository { fun findByMostTrades(since: LocalDateTime): Mono - @Query(""" select t.trade_date As create_date, + @Query( + """ select t.trade_date As create_date, t.matched_quantity AS volume, t.matched_price AS matched_price, CASE @@ -407,13 +408,20 @@ interface TradeRepository : ReactiveCrudRepository { and (:startDate is null or trade_date >=:startDate) and (:endDate is null or trade_date <=:endDate) - order by create_date ASC offset :offset limit :limit """) - - fun findTxOfTradesAsc(user: String, startDate: LocalDateTime?, endDate: LocalDateTime?, offset: Int?, limit: Int?): Flux + order by create_date ASC offset :offset limit :limit """ + ) + fun findTxOfTradesAsc( + user: String, + startDate: LocalDateTime?, + endDate: LocalDateTime?, + offset: Int?, + limit: Int? + ): Flux - @Query(""" select t.trade_date As create_date, + @Query( + """ select t.trade_date As create_date, t.matched_quantity AS volume, t.matched_price AS matched_price, CASE @@ -455,9 +463,16 @@ interface TradeRepository : ReactiveCrudRepository { and (:startDate is null or trade_date >=:startDate) and (:endDate is null or trade_date <=:endDate) - order by create_date DESC offset :offset limit :limit """) + order by create_date DESC offset :offset limit :limit """ + ) - fun findTxOfTradesDesc(user: String, startDate: LocalDateTime?, endDate: LocalDateTime?, offset: Int?, limit: Int?): Flux + fun findTxOfTradesDesc( + user: String, + startDate: LocalDateTime?, + endDate: LocalDateTime?, + offset: Int?, + limit: Int? + ): Flux @Query( """ 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 bf2c934d6..6b3b5b97b 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 @@ -14,8 +14,6 @@ import kotlinx.coroutines.flow.toList import kotlinx.coroutines.reactive.awaitFirst import kotlinx.coroutines.reactive.awaitFirstOrNull import kotlinx.coroutines.reactor.awaitSingleOrNull -import org.springframework.data.domain.PageRequest -import org.springframework.data.domain.Sort import org.springframework.stereotype.Component import java.time.Instant import java.time.LocalDateTime @@ -24,17 +22,17 @@ import java.util.* @Component class UserQueryHandlerImpl( - private val orderRepository: OrderRepository, - private val tradeRepository: TradeRepository, - private val orderStatusRepository: OrderStatusRepository + private val orderRepository: OrderRepository, + private val tradeRepository: TradeRepository, + private val orderStatusRepository: OrderStatusRepository ) : UserQueryHandler { //TODO merge order and status fetching in query override suspend fun getOrder(uuid: String, ouid: String): Order? { return orderRepository.findByUUIDAndOUID(uuid, ouid) - .awaitSingleOrNull() - ?.asOrderDTO(orderStatusRepository.findMostRecentByOUID(ouid).awaitFirstOrNull()) + .awaitSingleOrNull() + ?.asOrderDTO(orderStatusRepository.findMostRecentByOUID(ouid).awaitFirstOrNull()) } override suspend fun queryOrder(uuid: String, request: QueryOrderRequest): Order? { @@ -53,51 +51,51 @@ class UserQueryHandlerImpl( override suspend fun openOrders(uuid: String, symbol: String?, limit: Int): List { return orderRepository.findByUuidAndSymbolAndStatus( - uuid, - symbol, - listOf(OrderStatus.NEW.code, OrderStatus.PARTIALLY_FILLED.code), - limit + uuid, + symbol, + listOf(OrderStatus.NEW.code, OrderStatus.PARTIALLY_FILLED.code), + limit ).filter { orderModel -> orderModel.constraint != null } - .map { it.asOrderDTO(orderStatusRepository.findMostRecentByOUID(it.ouid).awaitFirstOrNull()) } - .toList() + .map { it.asOrderDTO(orderStatusRepository.findMostRecentByOUID(it.ouid).awaitFirstOrNull()) } + .toList() } override suspend fun allOrders(uuid: String, allOrderRequest: AllOrderRequest): List { return orderRepository.findByUuidAndSymbolAndTimeBetween( - uuid, - allOrderRequest.symbol, - allOrderRequest.startTime, - allOrderRequest.endTime, - allOrderRequest.limit + uuid, + allOrderRequest.symbol, + allOrderRequest.startTime, + allOrderRequest.endTime, + allOrderRequest.limit ).filter { orderModel -> orderModel.constraint != null } - .map { it.asOrderDTO(orderStatusRepository.findMostRecentByOUID(it.ouid).awaitFirstOrNull()) } - .toList() + .map { it.asOrderDTO(orderStatusRepository.findMostRecentByOUID(it.ouid).awaitFirstOrNull()) } + .toList() } override suspend fun allTrades(uuid: String, request: TradeRequest): List { return tradeRepository.findByUuidAndSymbolAndTimeBetweenAndTradeIdGreaterThan( - uuid, request.symbol, request.fromTrade, request.startTime, request.endTime, request.limit + uuid, request.symbol, request.fromTrade, request.startTime, request.endTime, request.limit ).map { val takerOrder = orderRepository.findByOuid(it.takerOuid).awaitFirst() val makerOrder = orderRepository.findByOuid(it.makerOuid).awaitFirst() val isMakerBuyer = makerOrder.direction == OrderDirection.BID Trade( - it.symbol, - it.tradeId, - if (it.takerUuid == uuid) takerOrder.orderId!! else makerOrder.orderId!!, - if (it.takerUuid == uuid) it.takerPrice else it.makerPrice, - it.matchedQuantity, - if (isMakerBuyer) makerOrder.quoteQuantity!! else takerOrder.quoteQuantity!!, - if (it.takerUuid == uuid) it.takerCommission!! else it.makerCommission!!, - if (it.takerUuid == uuid) it.takerCommissionAsset!! else it.makerCommissionAsset!!, - Date.from(it.createDate.atZone(ZoneId.systemDefault()).toInstant()), - if (it.takerUuid == uuid) - OrderDirection.ASK == takerOrder.direction - else - OrderDirection.ASK == makerOrder.direction, - it.makerUuid == uuid, - true, - isMakerBuyer + it.symbol, + it.tradeId, + if (it.takerUuid == uuid) takerOrder.orderId!! else makerOrder.orderId!!, + if (it.takerUuid == uuid) it.takerPrice else it.makerPrice, + it.matchedQuantity, + if (isMakerBuyer) makerOrder.quoteQuantity!! else takerOrder.quoteQuantity!!, + if (it.takerUuid == uuid) it.takerCommission!! else it.makerCommission!!, + if (it.takerUuid == uuid) it.takerCommissionAsset!! else it.makerCommissionAsset!!, + Date.from(it.createDate.atZone(ZoneId.systemDefault()).toInstant()), + if (it.takerUuid == uuid) + OrderDirection.ASK == takerOrder.direction + else + OrderDirection.ASK == makerOrder.direction, + it.makerUuid == uuid, + true, + isMakerBuyer ) }.toList() } @@ -106,19 +104,41 @@ class UserQueryHandlerImpl( if (transactionRequest.ascendingByTime == true) return TransactionResponse(tradeRepository.findTxOfTradesAsc(transactionRequest.owner!!, - transactionRequest.startTime?.let { LocalDateTime.ofInstant(Instant.ofEpochMilli(transactionRequest.startTime!!), ZoneId.systemDefault()) } - ?: null, - transactionRequest.endTime?.let { LocalDateTime.ofInstant(Instant.ofEpochMilli(transactionRequest.endTime!!), ZoneId.systemDefault()) } - ?: null, - transactionRequest.offset, transactionRequest.limit - ).map { it.toDto() }.collectList()?.awaitFirstOrNull()) + transactionRequest.startTime?.let { + LocalDateTime.ofInstant( + Instant.ofEpochMilli(transactionRequest.startTime!!), + ZoneId.systemDefault() + ) + } + ?: null, + transactionRequest.endTime?.let { + LocalDateTime.ofInstant( + Instant.ofEpochMilli(transactionRequest.endTime!!), + ZoneId.systemDefault() + ) + } + ?: null, + transactionRequest.offset, transactionRequest.limit + ).map { it.toDto() }.collectList()?.awaitFirstOrNull() + ) else return TransactionResponse(tradeRepository.findTxOfTradesDesc(transactionRequest.owner!!, - transactionRequest.startTime?.let { LocalDateTime.ofInstant(Instant.ofEpochMilli(transactionRequest.startTime!!), ZoneId.systemDefault()) } - ?: null, - transactionRequest.endTime?.let { LocalDateTime.ofInstant(Instant.ofEpochMilli(transactionRequest.endTime!!), ZoneId.systemDefault()) } - ?: null, - transactionRequest.offset, transactionRequest.limit - ).map { it.toDto() }.collectList()?.awaitFirstOrNull()) + transactionRequest.startTime?.let { + LocalDateTime.ofInstant( + Instant.ofEpochMilli(transactionRequest.startTime!!), + ZoneId.systemDefault() + ) + } + ?: null, + transactionRequest.endTime?.let { + LocalDateTime.ofInstant( + Instant.ofEpochMilli(transactionRequest.endTime!!), + ZoneId.systemDefault() + ) + } + ?: null, + transactionRequest.offset, transactionRequest.limit + ).map { it.toDto() }.collectList()?.awaitFirstOrNull() + ) } } \ No newline at end of file diff --git a/market/market-ports/market-persister-postgres/src/main/kotlin/co/nilin/opex/market/ports/postgres/model/CandleInfoData.kt b/market/market-ports/market-persister-postgres/src/main/kotlin/co/nilin/opex/market/ports/postgres/model/CandleInfoData.kt index f8c106add..d86457ade 100644 --- a/market/market-ports/market-persister-postgres/src/main/kotlin/co/nilin/opex/market/ports/postgres/model/CandleInfoData.kt +++ b/market/market-ports/market-persister-postgres/src/main/kotlin/co/nilin/opex/market/ports/postgres/model/CandleInfoData.kt @@ -1,6 +1,5 @@ package co.nilin.opex.market.ports.postgres.model -import org.springframework.data.relational.core.mapping.Column import java.math.BigDecimal import java.time.LocalDateTime diff --git a/market/market-ports/market-persister-postgres/src/main/kotlin/co/nilin/opex/market/ports/postgres/model/LastPrice.kt b/market/market-ports/market-persister-postgres/src/main/kotlin/co/nilin/opex/market/ports/postgres/model/LastPrice.kt index 5e9799e9d..ef43d7d9c 100644 --- a/market/market-ports/market-persister-postgres/src/main/kotlin/co/nilin/opex/market/ports/postgres/model/LastPrice.kt +++ b/market/market-ports/market-persister-postgres/src/main/kotlin/co/nilin/opex/market/ports/postgres/model/LastPrice.kt @@ -2,4 +2,4 @@ package co.nilin.opex.market.ports.postgres.model import java.math.BigDecimal -data class LastPrice(val symbol:String, val matchedPrice: BigDecimal) \ No newline at end of file +data class LastPrice(val symbol: String, val matchedPrice: BigDecimal) \ No newline at end of file diff --git a/market/market-ports/market-persister-postgres/src/main/kotlin/co/nilin/opex/market/ports/postgres/model/TradeModel.kt b/market/market-ports/market-persister-postgres/src/main/kotlin/co/nilin/opex/market/ports/postgres/model/TradeModel.kt index e434f1c43..7c6bccaa9 100644 --- a/market/market-ports/market-persister-postgres/src/main/kotlin/co/nilin/opex/market/ports/postgres/model/TradeModel.kt +++ b/market/market-ports/market-persister-postgres/src/main/kotlin/co/nilin/opex/market/ports/postgres/model/TradeModel.kt @@ -1,7 +1,6 @@ package co.nilin.opex.market.ports.postgres.model import org.springframework.data.annotation.Id -import org.springframework.data.relational.core.mapping.Column import org.springframework.data.relational.core.mapping.Table import java.math.BigDecimal import java.time.LocalDateTime diff --git a/market/market-ports/market-persister-postgres/src/main/kotlin/co/nilin/opex/market/ports/postgres/util/Convertor.kt b/market/market-ports/market-persister-postgres/src/main/kotlin/co/nilin/opex/market/ports/postgres/util/Convertor.kt index ddb42a1b9..0cb69e71d 100644 --- a/market/market-ports/market-persister-postgres/src/main/kotlin/co/nilin/opex/market/ports/postgres/util/Convertor.kt +++ b/market/market-ports/market-persister-postgres/src/main/kotlin/co/nilin/opex/market/ports/postgres/util/Convertor.kt @@ -2,20 +2,21 @@ package co.nilin.opex.market.ports.postgres.util import co.nilin.opex.market.core.inout.Transaction import co.nilin.opex.market.core.inout.TransactionDto -import java.math.BigDecimal import java.time.ZoneId import java.util.* - fun Transaction.toDto(): TransactionDto { - return TransactionDto(createDate = Date.from(createDate.atZone(ZoneId.systemDefault()).toInstant()), - volume, - transactionPrice, - matchedPrice, - side, - symbol, - fee, - user) +fun Transaction.toDto(): TransactionDto { + return TransactionDto( + createDate = Date.from(createDate.atZone(ZoneId.systemDefault()).toInstant()), + volume, + transactionPrice, + matchedPrice, + side, + symbol, + fee, + user + ) - } +} diff --git a/market/market-ports/market-persister-postgres/src/main/resources/schema.sql b/market/market-ports/market-persister-postgres/src/main/resources/schema.sql index 8d9195525..e90dda326 100644 --- a/market/market-ports/market-persister-postgres/src/main/resources/schema.sql +++ b/market/market-ports/market-persister-postgres/src/main/resources/schema.sql @@ -1,83 +1,184 @@ CREATE TABLE IF NOT EXISTS orders ( - id SERIAL PRIMARY KEY, - ouid VARCHAR(72) NOT NULL UNIQUE, - uuid VARCHAR(72) NOT NULL, - client_order_id VARCHAR(72), - symbol VARCHAR(20) NOT NULL, - order_id INTEGER, - maker_fee DECIMAL, - taker_fee DECIMAL, - left_side_fraction DECIMAL, + id + SERIAL + PRIMARY + KEY, + ouid + VARCHAR +( + 72 +) NOT NULL UNIQUE, + uuid VARCHAR +( + 72 +) NOT NULL, + client_order_id VARCHAR +( + 72 +), + symbol VARCHAR +( + 20 +) NOT NULL, + order_id INTEGER, + maker_fee DECIMAL, + taker_fee DECIMAL, + left_side_fraction DECIMAL, right_side_fraction DECIMAL, - user_level VARCHAR(20), - side VARCHAR(20), - match_constraint VARCHAR(20), - order_type VARCHAR(20), - price DECIMAL, - quantity DECIMAL, - quote_quantity DECIMAL, - create_date TIMESTAMP, - update_date TIMESTAMP NOT NULL, - version INTEGER -); + user_level VARCHAR +( + 20 +), + side VARCHAR +( + 20 +), + match_constraint VARCHAR +( + 20 +), + order_type VARCHAR +( + 20 +), + price DECIMAL, + quantity DECIMAL, + quote_quantity DECIMAL, + create_date TIMESTAMP, + update_date TIMESTAMP NOT NULL, + version INTEGER + ); CREATE TABLE IF NOT EXISTS order_status ( - id SERIAL PRIMARY KEY, - ouid VARCHAR(72) NOT NULL, - executed_quantity DECIMAL, + id + SERIAL + PRIMARY + KEY, + ouid + VARCHAR +( + 72 +) NOT NULL, + executed_quantity DECIMAL, accumulative_quote_qty DECIMAL, - status INTEGER NOT NULL, - appearance INTEGER NOT NULL, - date TIMESTAMP NOT NULL, - UNIQUE (ouid, status, appearance, executed_quantity) -); + status INTEGER NOT NULL, + appearance INTEGER NOT NULL, + date TIMESTAMP NOT NULL, + UNIQUE +( + ouid, + status, + appearance, + executed_quantity +) + ); CREATE TABLE IF NOT EXISTS open_orders ( - id SERIAL PRIMARY KEY, - ouid VARCHAR(72) NOT NULL UNIQUE, + id + SERIAL + PRIMARY + KEY, + ouid + VARCHAR +( + 72 +) NOT NULL UNIQUE, executed_quantity DECIMAL, - status INTEGER NOT NULL -); + status INTEGER NOT NULL + ); CREATE TABLE IF NOT EXISTS trades ( - id SERIAL PRIMARY KEY, - trade_id INTEGER NOT NULL, - symbol VARCHAR(20) NOT NULL, - base_asset VARCHAR(20) NOT NULL, - quote_asset VARCHAR(20) NOT NULL, - matched_price DECIMAL NOT NULL, - matched_quantity DECIMAL NOT NULL, - taker_price DECIMAL NOT NULL, - maker_price DECIMAL NOT NULL, - taker_commission DECIMAL, - maker_commission DECIMAL, - taker_commission_asset VARCHAR(20), - maker_commission_asset VARCHAR(20), - trade_date TIMESTAMP NOT NULL, - maker_ouid VARCHAR(72) NOT NULL, - taker_ouid VARCHAR(72) NOT NULL, - maker_uuid VARCHAR(72) NOT NULL, - taker_uuid VARCHAR(72) NOT NULL, - create_date TIMESTAMP -); + id + SERIAL + PRIMARY + KEY, + trade_id + INTEGER + NOT + NULL, + symbol + VARCHAR +( + 20 +) NOT NULL, + base_asset VARCHAR +( + 20 +) NOT NULL, + quote_asset VARCHAR +( + 20 +) NOT NULL, + matched_price DECIMAL NOT NULL, + matched_quantity DECIMAL NOT NULL, + taker_price DECIMAL NOT NULL, + maker_price DECIMAL NOT NULL, + taker_commission DECIMAL, + maker_commission DECIMAL, + taker_commission_asset VARCHAR +( + 20 +), + maker_commission_asset VARCHAR +( + 20 +), + trade_date TIMESTAMP NOT NULL, + maker_ouid VARCHAR +( + 72 +) NOT NULL, + taker_ouid VARCHAR +( + 72 +) NOT NULL, + maker_uuid VARCHAR +( + 72 +) NOT NULL, + taker_uuid VARCHAR +( + 72 +) NOT NULL, + create_date TIMESTAMP + ); CREATE INDEX IF NOT EXISTS idx_trades_symbol on trades (symbol); CREATE INDEX IF NOT EXISTS idx_trades_create_date on trades (create_date); CREATE TABLE IF NOT EXISTS currency_rate ( - id SERIAL PRIMARY KEY, - base VARCHAR(25) NOT NULL, - quote VARCHAR(25) NOT NULL, - source VARCHAR(25) NOT NULL, - rate DECIMAL NOT NULL, - UNIQUE (base, quote, source) -); + id + SERIAL + PRIMARY + KEY, + base + VARCHAR +( + 25 +) NOT NULL, + quote VARCHAR +( + 25 +) NOT NULL, + source VARCHAR +( + 25 +) NOT NULL, + rate DECIMAL NOT NULL, + UNIQUE +( + base, + quote, + source +) + ); -CREATE OR REPLACE FUNCTION interval_generator( +CREATE +OR REPLACE FUNCTION interval_generator( start_ts TIMESTAMP without TIME ZONE, end_ts TIMESTAMP without TIME ZONE, round_interval INTERVAL @@ -90,15 +191,16 @@ CREATE OR REPLACE FUNCTION interval_generator( as $$ BEGIN - RETURN QUERY - SELECT (n) start_time, - (n + round_interval) end_time - FROM generate_series( - date_trunc('minute', start_ts), - end_ts, - round_interval - ) n; +RETURN QUERY +SELECT (n) start_time, + (n + round_interval) end_time +FROM generate_series( + date_trunc('minute', start_ts), + end_ts, + round_interval + ) n; END; -$$ LANGUAGE 'plpgsql'; +$$ +LANGUAGE 'plpgsql'; diff --git a/market/market-ports/market-persister-postgres/src/test/kotlin/co/nilin/opex/market/ports/postgres/impl/MarketQueryHandlerTest.kt b/market/market-ports/market-persister-postgres/src/test/kotlin/co/nilin/opex/market/ports/postgres/impl/MarketQueryHandlerTest.kt index 6b64ebeea..6de56844a 100644 --- a/market/market-ports/market-persister-postgres/src/test/kotlin/co/nilin/opex/market/ports/postgres/impl/MarketQueryHandlerTest.kt +++ b/market/market-ports/market-persister-postgres/src/test/kotlin/co/nilin/opex/market/ports/postgres/impl/MarketQueryHandlerTest.kt @@ -1,6 +1,9 @@ package co.nilin.opex.market.ports.postgres.impl -import co.nilin.opex.market.core.inout.* +import co.nilin.opex.market.core.inout.MarketTrade +import co.nilin.opex.market.core.inout.Order +import co.nilin.opex.market.core.inout.OrderDirection +import co.nilin.opex.market.core.inout.OrderStatus import co.nilin.opex.market.ports.postgres.dao.OrderRepository import co.nilin.opex.market.ports.postgres.dao.OrderStatusRepository import co.nilin.opex.market.ports.postgres.dao.TradeRepository diff --git a/market/market-ports/market-persister-postgres/src/test/kotlin/co/nilin/opex/market/ports/postgres/impl/UserQueryHandlerTest.kt b/market/market-ports/market-persister-postgres/src/test/kotlin/co/nilin/opex/market/ports/postgres/impl/UserQueryHandlerTest.kt index c30d04944..26eda70c6 100644 --- a/market/market-ports/market-persister-postgres/src/test/kotlin/co/nilin/opex/market/ports/postgres/impl/UserQueryHandlerTest.kt +++ b/market/market-ports/market-persister-postgres/src/test/kotlin/co/nilin/opex/market/ports/postgres/impl/UserQueryHandlerTest.kt @@ -7,8 +7,6 @@ import co.nilin.opex.market.ports.postgres.dao.TradeRepository import co.nilin.opex.market.ports.postgres.impl.sample.VALID import io.mockk.every import io.mockk.mockk -import kotlinx.coroutines.flow.count -import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.flow import kotlinx.coroutines.runBlocking import org.assertj.core.api.Assertions.assertThat diff --git a/market/market-ports/market-persister-postgres/src/test/kotlin/co/nilin/opex/market/ports/postgres/impl/sample/Samples.kt b/market/market-ports/market-persister-postgres/src/test/kotlin/co/nilin/opex/market/ports/postgres/impl/sample/Samples.kt index c5538f441..f0d550546 100644 --- a/market/market-ports/market-persister-postgres/src/test/kotlin/co/nilin/opex/market/ports/postgres/impl/sample/Samples.kt +++ b/market/market-ports/market-persister-postgres/src/test/kotlin/co/nilin/opex/market/ports/postgres/impl/sample/Samples.kt @@ -8,7 +8,6 @@ import co.nilin.opex.market.ports.postgres.model.LastPrice import co.nilin.opex.market.ports.postgres.model.OrderModel import co.nilin.opex.market.ports.postgres.model.OrderStatusModel import co.nilin.opex.market.ports.postgres.model.TradeModel -import co.nilin.opex.market.ports.postgres.util.isWorking import java.math.BigDecimal import java.security.Principal import java.time.LocalDateTime diff --git a/matching-engine/matching-engine-app/pom.xml b/matching-engine/matching-engine-app/pom.xml index 1ca63381a..6bc3a6e20 100644 --- a/matching-engine/matching-engine-app/pom.xml +++ b/matching-engine/matching-engine-app/pom.xml @@ -1,5 +1,5 @@ - 4.0.0 diff --git a/matching-engine/matching-engine-app/src/main/resources/application.yml b/matching-engine/matching-engine-app/src/main/resources/application.yml index 4b384fdef..9a4ed5b32 100644 --- a/matching-engine/matching-engine-app/src/main/resources/application.yml +++ b/matching-engine/matching-engine-app/src/main/resources/application.yml @@ -16,7 +16,7 @@ management: web: base-path: /actuator exposure: - include: ["health", "prometheus", "metrics"] + include: [ "health", "prometheus", "metrics" ] endpoint: health: show-details: when_authorized diff --git a/matching-engine/matching-engine-core/pom.xml b/matching-engine/matching-engine-core/pom.xml index 25c222bae..e9c95993c 100644 --- a/matching-engine/matching-engine-core/pom.xml +++ b/matching-engine/matching-engine-core/pom.xml @@ -1,5 +1,5 @@ - 4.0.0 diff --git a/matching-engine/matching-engine-core/src/main/kotlin/co/nilin/opex/matching/engine/core/inout/OrderRequestEvent.kt b/matching-engine/matching-engine-core/src/main/kotlin/co/nilin/opex/matching/engine/core/inout/OrderRequestEvent.kt index 3ec793a34..236a74b36 100644 --- a/matching-engine/matching-engine-core/src/main/kotlin/co/nilin/opex/matching/engine/core/inout/OrderRequestEvent.kt +++ b/matching-engine/matching-engine-core/src/main/kotlin/co/nilin/opex/matching/engine/core/inout/OrderRequestEvent.kt @@ -2,4 +2,4 @@ package co.nilin.opex.matching.engine.core.inout import co.nilin.opex.matching.engine.core.model.Pair -abstract class OrderRequestEvent(val ouid:String, val uuid: String, val pair: Pair) \ No newline at end of file +abstract class OrderRequestEvent(val ouid: String, val uuid: String, val pair: Pair) \ No newline at end of file diff --git a/matching-engine/matching-engine-ports/matching-engine-eventlistener-kafka/pom.xml b/matching-engine/matching-engine-ports/matching-engine-eventlistener-kafka/pom.xml index 981aaeb33..876f69b94 100644 --- a/matching-engine/matching-engine-ports/matching-engine-eventlistener-kafka/pom.xml +++ b/matching-engine/matching-engine-ports/matching-engine-eventlistener-kafka/pom.xml @@ -1,5 +1,5 @@ - 4.0.0 diff --git a/matching-engine/matching-engine-ports/matching-engine-eventlistener-kafka/src/main/kotlin/co/nilin/opex/matching/engine/ports/kafka/listener/config/OrderKafkaConfig.kt b/matching-engine/matching-engine-ports/matching-engine-eventlistener-kafka/src/main/kotlin/co/nilin/opex/matching/engine/ports/kafka/listener/config/OrderKafkaConfig.kt index 6262ba1df..ec63df8aa 100644 --- a/matching-engine/matching-engine-ports/matching-engine-eventlistener-kafka/src/main/kotlin/co/nilin/opex/matching/engine/ports/kafka/listener/config/OrderKafkaConfig.kt +++ b/matching-engine/matching-engine-ports/matching-engine-eventlistener-kafka/src/main/kotlin/co/nilin/opex/matching/engine/ports/kafka/listener/config/OrderKafkaConfig.kt @@ -2,7 +2,6 @@ package co.nilin.opex.matching.engine.ports.kafka.listener.config import co.nilin.opex.matching.engine.core.eventh.events.CoreEvent import co.nilin.opex.matching.engine.core.inout.OrderRequestEvent -import co.nilin.opex.matching.engine.core.inout.OrderSubmitRequestEvent import co.nilin.opex.matching.engine.ports.kafka.listener.consumer.EventKafkaListener import co.nilin.opex.matching.engine.ports.kafka.listener.consumer.OrderKafkaListener import org.apache.kafka.clients.consumer.ConsumerConfig diff --git a/matching-engine/matching-engine-ports/matching-engine-snapshots-redis/pom.xml b/matching-engine/matching-engine-ports/matching-engine-snapshots-redis/pom.xml index 042b22c13..1dd1e88ca 100644 --- a/matching-engine/matching-engine-ports/matching-engine-snapshots-redis/pom.xml +++ b/matching-engine/matching-engine-ports/matching-engine-snapshots-redis/pom.xml @@ -1,5 +1,5 @@ - 4.0.0 diff --git a/matching-engine/matching-engine-ports/matching-engine-submitter-kafka/pom.xml b/matching-engine/matching-engine-ports/matching-engine-submitter-kafka/pom.xml index b13662c63..ad9220e32 100644 --- a/matching-engine/matching-engine-ports/matching-engine-submitter-kafka/pom.xml +++ b/matching-engine/matching-engine-ports/matching-engine-submitter-kafka/pom.xml @@ -1,5 +1,5 @@ - 4.0.0 diff --git a/matching-engine/matching-engine-ports/matching-engine-submitter-kafka/src/main/kotlin/co/nilin/opex/matching/engine/ports/kafka/submitter/config/EventsKafkaConfig.kt b/matching-engine/matching-engine-ports/matching-engine-submitter-kafka/src/main/kotlin/co/nilin/opex/matching/engine/ports/kafka/submitter/config/EventsKafkaConfig.kt index 6fdf44e04..c11c225e8 100644 --- a/matching-engine/matching-engine-ports/matching-engine-submitter-kafka/src/main/kotlin/co/nilin/opex/matching/engine/ports/kafka/submitter/config/EventsKafkaConfig.kt +++ b/matching-engine/matching-engine-ports/matching-engine-submitter-kafka/src/main/kotlin/co/nilin/opex/matching/engine/ports/kafka/submitter/config/EventsKafkaConfig.kt @@ -2,7 +2,6 @@ package co.nilin.opex.matching.engine.ports.kafka.submitter.config import co.nilin.opex.matching.engine.core.eventh.events.CoreEvent import co.nilin.opex.matching.engine.core.inout.OrderRequestEvent -import co.nilin.opex.matching.engine.core.inout.OrderSubmitRequestEvent import org.apache.kafka.clients.producer.ProducerConfig import org.apache.kafka.common.serialization.StringSerializer import org.springframework.beans.factory.annotation.Qualifier diff --git a/matching-engine/pom.xml b/matching-engine/pom.xml index 737dabe1d..55bf761ac 100644 --- a/matching-engine/pom.xml +++ b/matching-engine/pom.xml @@ -1,5 +1,5 @@ - 4.0.0 diff --git a/matching-gateway/matching-gateway-app/pom.xml b/matching-gateway/matching-gateway-app/pom.xml index 821456c1b..e8ad0d672 100644 --- a/matching-gateway/matching-gateway-app/pom.xml +++ b/matching-gateway/matching-gateway-app/pom.xml @@ -1,5 +1,5 @@ - 4.0.0 diff --git a/matching-gateway/matching-gateway-app/src/main/kotlin/co/nilin/opex/matching/gateway/app/config/WebClientConfig.kt b/matching-gateway/matching-gateway-app/src/main/kotlin/co/nilin/opex/matching/gateway/app/config/WebClientConfig.kt index 0fd266d83..9a7e82138 100644 --- a/matching-gateway/matching-gateway-app/src/main/kotlin/co/nilin/opex/matching/gateway/app/config/WebClientConfig.kt +++ b/matching-gateway/matching-gateway-app/src/main/kotlin/co/nilin/opex/matching/gateway/app/config/WebClientConfig.kt @@ -5,7 +5,6 @@ import org.springframework.cloud.client.loadbalancer.reactive.ReactiveLoadBalanc import org.springframework.cloud.client.loadbalancer.reactive.ReactorLoadBalancerExchangeFilterFunction import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration -import org.springframework.http.client.reactive.ReactorClientHttpConnector import org.springframework.web.reactive.function.client.WebClient import org.zalando.logbook.Logbook import org.zalando.logbook.netty.LogbookClientHandler diff --git a/matching-gateway/matching-gateway-app/src/main/resources/application.yml b/matching-gateway/matching-gateway-app/src/main/resources/application.yml index 15e19d34e..5cc443811 100644 --- a/matching-gateway/matching-gateway-app/src/main/resources/application.yml +++ b/matching-gateway/matching-gateway-app/src/main/resources/application.yml @@ -25,7 +25,7 @@ management: web: base-path: /actuator exposure: - include: ["health", "prometheus", "metrics"] + include: [ "health", "prometheus", "metrics" ] endpoint: health: show-details: when_authorized diff --git a/matching-gateway/matching-gateway-app/src/test/kotlin/co/nilin/opex/matching/gateway/app/service/OrderServiceTest.kt b/matching-gateway/matching-gateway-app/src/test/kotlin/co/nilin/opex/matching/gateway/app/service/OrderServiceTest.kt index 306586dff..0b7898c61 100644 --- a/matching-gateway/matching-gateway-app/src/test/kotlin/co/nilin/opex/matching/gateway/app/service/OrderServiceTest.kt +++ b/matching-gateway/matching-gateway-app/src/test/kotlin/co/nilin/opex/matching/gateway/app/service/OrderServiceTest.kt @@ -5,10 +5,12 @@ import co.nilin.opex.matching.gateway.app.service.sample.VALID import co.nilin.opex.matching.gateway.app.spi.AccountantApiProxy import co.nilin.opex.matching.gateway.app.spi.PairConfigLoader import co.nilin.opex.matching.gateway.ports.kafka.submitter.inout.OrderSubmitResult -import co.nilin.opex.matching.gateway.ports.kafka.submitter.service.EventSubmitter import co.nilin.opex.matching.gateway.ports.kafka.submitter.service.KafkaHealthIndicator import co.nilin.opex.matching.gateway.ports.kafka.submitter.service.OrderRequestEventSubmitter -import io.mockk.* +import io.mockk.MockKException +import io.mockk.clearMocks +import io.mockk.coEvery +import io.mockk.mockk import kotlinx.coroutines.runBlocking import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThatThrownBy diff --git a/matching-gateway/matching-gateway-port/matching-gateway-submitter-kafka/pom.xml b/matching-gateway/matching-gateway-port/matching-gateway-submitter-kafka/pom.xml index 9ef385922..bd520bfd6 100644 --- a/matching-gateway/matching-gateway-port/matching-gateway-submitter-kafka/pom.xml +++ b/matching-gateway/matching-gateway-port/matching-gateway-submitter-kafka/pom.xml @@ -1,5 +1,5 @@ - 4.0.0 diff --git a/matching-gateway/matching-gateway-port/matching-gateway-submitter-kafka/src/main/kotlin/co/nilin/opex/matching/gateway/ports/kafka/submitter/config/OrderKafkaConfig.kt b/matching-gateway/matching-gateway-port/matching-gateway-submitter-kafka/src/main/kotlin/co/nilin/opex/matching/gateway/ports/kafka/submitter/config/OrderKafkaConfig.kt index 0e0bf5189..4f1e96623 100644 --- a/matching-gateway/matching-gateway-port/matching-gateway-submitter-kafka/src/main/kotlin/co/nilin/opex/matching/gateway/ports/kafka/submitter/config/OrderKafkaConfig.kt +++ b/matching-gateway/matching-gateway-port/matching-gateway-submitter-kafka/src/main/kotlin/co/nilin/opex/matching/gateway/ports/kafka/submitter/config/OrderKafkaConfig.kt @@ -2,7 +2,6 @@ package co.nilin.opex.matching.gateway.ports.kafka.submitter.config import co.nilin.opex.matching.engine.core.eventh.events.CoreEvent import co.nilin.opex.matching.gateway.ports.kafka.submitter.inout.OrderRequestEvent -import co.nilin.opex.matching.gateway.ports.kafka.submitter.inout.OrderSubmitRequestEvent import org.apache.kafka.clients.producer.ProducerConfig import org.apache.kafka.common.serialization.StringSerializer import org.springframework.beans.factory.annotation.Qualifier diff --git a/matching-gateway/matching-gateway-port/matching-gateway-submitter-kafka/src/main/kotlin/co/nilin/opex/matching/gateway/ports/kafka/submitter/inout/OrderRequestEvent.kt b/matching-gateway/matching-gateway-port/matching-gateway-submitter-kafka/src/main/kotlin/co/nilin/opex/matching/gateway/ports/kafka/submitter/inout/OrderRequestEvent.kt index 462f2f58a..88bb3f7b7 100644 --- a/matching-gateway/matching-gateway-port/matching-gateway-submitter-kafka/src/main/kotlin/co/nilin/opex/matching/gateway/ports/kafka/submitter/inout/OrderRequestEvent.kt +++ b/matching-gateway/matching-gateway-port/matching-gateway-submitter-kafka/src/main/kotlin/co/nilin/opex/matching/gateway/ports/kafka/submitter/inout/OrderRequestEvent.kt @@ -2,4 +2,4 @@ package co.nilin.opex.matching.gateway.ports.kafka.submitter.inout import co.nilin.opex.matching.engine.core.model.Pair -abstract class OrderRequestEvent(val ouid:String, val uuid: String, val pair: Pair) \ No newline at end of file +abstract class OrderRequestEvent(val ouid: String, val uuid: String, val pair: Pair) \ No newline at end of file diff --git a/matching-gateway/pom.xml b/matching-gateway/pom.xml index 3fd2fe323..b443226d7 100644 --- a/matching-gateway/pom.xml +++ b/matching-gateway/pom.xml @@ -1,5 +1,5 @@ - 4.0.0 diff --git a/pom.xml b/pom.xml index b9edcf743..b8b1799a5 100644 --- a/pom.xml +++ b/pom.xml @@ -1,6 +1,6 @@ - 4.0.0 diff --git a/preferences-demo.yml b/preferences-demo.yml index 825039c7c..05de5f7de 100644 --- a/preferences-demo.yml +++ b/preferences-demo.yml @@ -216,7 +216,7 @@ markets: userLimits: - owner: 1 action: withdraw - walletType: main + walletType: MAIN withdrawFee: 0.0001 dailyTotal: 1000 dailyCount: 100 diff --git a/preferences.yml b/preferences.yml new file mode 100644 index 000000000..0a661761d --- /dev/null +++ b/preferences.yml @@ -0,0 +1,319 @@ +addressTypes: + - addressType: ethereum + addressRegex: "*" + - addressType: test-bitcoin + addressRegex: "*" +chains: + - name: test-bitcoin + addressType: test-bitcoin + scanners: + - url: http://bitcoin-scanner:8080 + maxBlockRange: 30 + delayOnRateLimit: 5 + maxParallelCall: 2 + schedules: + - workerType: MAIN + delay: 600 + timeout: 30 + maxRetries: 5 + confirmations: 0 + maxBlockCount: 4 + enabled: false + - workerType: ERROR + delay: 600 + timeout: 30 + maxRetries: 5 + confirmations: 0 + maxBlockCount: 4 + enabled: false + - workerType: DELAYED + delay: 300 + timeout: 30 + maxRetries: 5 + confirmations: 0 + maxBlockCount: 2 + enabled: false + - name: test-ethereum + addressType: ethereum + scanners: + - url: http://ethereum-scanner:8080 + maxBlockRange: 30 + delayOnRateLimit: 5 + maxParallelCall: 3 + schedules: + - workerType: MAIN + delay: 15 + timeout: 30 + maxRetries: 5 + confirmations: 0 + maxBlockCount: 10 + enabled: false + - workerType: ERROR + delay: 7 + timeout: 30 + maxRetries: 5 + confirmations: 0 + maxBlockCount: 10 + enabled: false + - workerType: DELAYED + delay: 15 + timeout: 30 + maxRetries: 5 + confirmations: 0 + maxBlockCount: 5 + enabled: false + - name: test-bsc + addressType: ethereum + scanners: + - url: http://bsc-scanner:8080 + maxBlockRange: 10 + delayOnRateLimit: 300 + maxParallelCall: 5 + schedules: + - workerType: MAIN + delay: 6 + timeout: 30 + maxRetries: 5 + confirmations: 0 + maxBlockCount: 30 + - workerType: ERROR + delay: 3 + timeout: 30 + maxRetries: 5 + confirmations: 0 + maxBlockCount: 20 + - workerType: DELAYED + delay: 10 + timeout: 30 + maxRetries: 5 + confirmations: 0 + maxBlockCount: 10 +currencies: + - symbol: IRT + name: Toman + precision: 0.1 + mainBalance: 10000 + dailyTotal: 1000 + dailyCount: 100 + monthlyTotal: 30000 + monthlyCount: 3000 + gift: 1000000 + - symbol: BTC + name: Bitcoin (Test) + precision: 0.000001 + mainBalance: 10000 + dailyTotal: 1000 + dailyCount: 100 + monthlyTotal: 30000 + monthlyCount: 3000 + implementations: + - chain: test-bitcoin + withdrawFee: 0.0001 + withdrawMin: 0.0001 + decimal: 0 + gift: 5 + - symbol: ETH + name: Ethereum (Test) + precision: 0.000001 + mainBalance: 10000 + dailyTotal: 1000 + dailyCount: 100 + monthlyTotal: 30000 + monthlyCount: 3000 + implementations: + - chain: test-ethereum + withdrawFee: 0.00001 + withdrawMin: 0.000001 + decimal: 18 + gift: 100 + - symbol: USDT + name: Tether (Test) + precision: 0.01 + mainBalance: 10000 + dailyTotal: 1000 + dailyCount: 100 + monthlyTotal: 30000 + monthlyCount: 3000 + implementations: + - chain: test-ethereum + token: true + tokenAddress: 0x110a13FC3efE6A245B50102D2d79B3E76125Ae83 + tokenName: Tether USD + withdrawFee: 0.01 + withdrawMin: 0.01 + decimal: 6 + gift: 1000000 + - symbol: BUSD + name: Binance USD (Test) + precision: 0.01 + mainBalance: 10000 + dailyTotal: 1000 + dailyCount: 100 + monthlyTotal: 30000 + monthlyCount: 3000 + implementations: + - chain: test-bsc + token: true + tokenAddress: 0xeD24FC36d5Ee211Ea25A80239Fb8C4Cfd80f12Ee + tokenName: BUSD Token + withdrawFee: 0.01 + withdrawMin: 0.01 + decimal: 18 + gift: 1000000 + - symbol: BNB + name: Binance (Test) + precision: 0.0001 + mainBalance: 10000 + dailyTotal: 1000 + dailyCount: 100 + monthlyTotal: 30000 + monthlyCount: 3000 + implementations: + - chain: test-bsc + withdrawFee: 0.00001 + withdrawMin: 0.000001 + decimal: 18 + - chain: test-bsc + symbol: WBNB + token: true + tokenAddress: 0x5b3e2bc1da86ff6235d9ead4504d598cae77dbcb + tokenName: Wrapped BNB (Test Net) + withdrawFee: 0.01 + withdrawMin: 0.01 + decimal: 18 + gift: 2000 +markets: + - leftSide: BTC + rightSide: USDT + aliases: + - key: binance + alias: BTCUSDT + feeConfigs: + - direction: ASK + userLevel: "*" + makerFee: 0.01 + takerFee: 0.01 + - direction: BID + userLevel: "*" + makerFee: 0.01 + takerFee: 0.01 + - leftSide: ETH + rightSide: USDT + aliases: + - key: binance + alias: ETHUSDT + feeConfigs: + - direction: ASK + userLevel: "*" + makerFee: 0.01 + takerFee: 0.01 + - direction: BID + userLevel: "*" + makerFee: 0.01 + takerFee: 0.01 + - leftSide: BTC + rightSide: IRT + aliases: + - key: binance + alias: BTCIRT + feeConfigs: + - direction: ASK + userLevel: "*" + makerFee: 0.01 + takerFee: 0.01 + - direction: BID + userLevel: "*" + makerFee: 0.01 + takerFee: 0.01 + - leftSide: ETH + rightSide: IRT + aliases: + - key: binance + alias: ETHIRT + feeConfigs: + - direction: ASK + userLevel: "*" + makerFee: 0.01 + takerFee: 0.01 + - direction: BID + userLevel: "*" + makerFee: 0.01 + takerFee: 0.01 + - leftSide: USDT + rightSide: IRT + aliases: + - key: binance + alias: USDIRT + feeConfigs: + - direction: ASK + userLevel: "*" + makerFee: 0.01 + takerFee: 0.01 + - direction: BID + userLevel: "*" + makerFee: 0.01 + takerFee: 0.01 + - leftSide: ETH + rightSide: BUSD + aliases: + - key: binance + alias: ETHBUSD + feeConfigs: + - direction: ASK + userLevel: "*" + makerFee: 0.01 + takerFee: 0.01 + - direction: BID + userLevel: "*" + makerFee: 0.01 + takerFee: 0.01 + - leftSide: BTC + rightSide: BUSD + aliases: + - key: binance + alias: BTCBUSD + feeConfigs: + - direction: ASK + userLevel: "*" + makerFee: 0.01 + takerFee: 0.01 + - direction: BID + userLevel: "*" + makerFee: 0.01 + takerFee: 0.01 + - leftSide: BNB + rightSide: BUSD + aliases: + - key: binance + alias: BNBBUSD + feeConfigs: + - direction: ASK + userLevel: "*" + makerFee: 0.01 + takerFee: 0.01 + - direction: BID + userLevel: "*" + makerFee: 0.01 + takerFee: 0.01 +userLimits: + - owner: 1 + action: withdraw + walletType: MAIN + withdrawFee: 0.0001 + dailyTotal: 1000 + dailyCount: 100 + monthlyTotal: 30000 + monthlyCount: 3000 +userLevels: + - "*" + - "nofee" +system: + walletTitle: system + walletLevel: system +admin: + walletTitle: admin + walletLevel: admin +auth: + whitelist: + enabled: false + file: /whitelist.txt \ No newline at end of file diff --git a/user-management/keycloak-gateway/pom.xml b/user-management/keycloak-gateway/pom.xml index 94be9f19c..9023304ca 100644 --- a/user-management/keycloak-gateway/pom.xml +++ b/user-management/keycloak-gateway/pom.xml @@ -1,5 +1,5 @@ - 4.0.0 diff --git a/user-management/keycloak-gateway/src/main/kotlin/co/nilin/opex/auth/gateway/KeycloakGatewayApp.kt b/user-management/keycloak-gateway/src/main/kotlin/co/nilin/opex/auth/gateway/KeycloakGatewayApp.kt index 67ec6be6a..be3a628dc 100644 --- a/user-management/keycloak-gateway/src/main/kotlin/co/nilin/opex/auth/gateway/KeycloakGatewayApp.kt +++ b/user-management/keycloak-gateway/src/main/kotlin/co/nilin/opex/auth/gateway/KeycloakGatewayApp.kt @@ -7,7 +7,6 @@ import org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfigurati import org.springframework.boot.context.properties.EnableConfigurationProperties import org.springframework.boot.runApplication import org.springframework.context.annotation.ComponentScan -import org.springframework.data.jpa.repository.config.EnableJpaRepositories import org.springframework.scheduling.annotation.EnableScheduling @SpringBootApplication(exclude = [LiquibaseAutoConfiguration::class]) diff --git a/user-management/keycloak-gateway/src/main/kotlin/co/nilin/opex/auth/gateway/config/EmbeddedKeycloakConfig.kt b/user-management/keycloak-gateway/src/main/kotlin/co/nilin/opex/auth/gateway/config/EmbeddedKeycloakConfig.kt index dfef8a24e..415a7cb60 100644 --- a/user-management/keycloak-gateway/src/main/kotlin/co/nilin/opex/auth/gateway/config/EmbeddedKeycloakConfig.kt +++ b/user-management/keycloak-gateway/src/main/kotlin/co/nilin/opex/auth/gateway/config/EmbeddedKeycloakConfig.kt @@ -2,12 +2,8 @@ package co.nilin.opex.auth.gateway.config import org.jboss.resteasy.plugins.server.servlet.HttpServlet30Dispatcher import org.jboss.resteasy.plugins.server.servlet.ResteasyContextParameters -import org.keycloak.admin.client.Keycloak -import org.keycloak.admin.client.resource.RealmResource import org.keycloak.connections.jpa.updater.liquibase.ThreadLocalSessionContext import org.keycloak.models.KeycloakSession -import org.keycloak.services.DefaultKeycloakSessionFactory -import org.springframework.beans.factory.annotation.Qualifier import org.springframework.boot.web.servlet.FilterRegistrationBean import org.springframework.boot.web.servlet.ServletRegistrationBean import org.springframework.context.annotation.Bean @@ -54,14 +50,13 @@ class EmbeddedKeycloakConfig { filter.addUrlPatterns(keycloakServerProperties.contextPath + "/*") return filter } + @Bean fun keycloakSession(): KeycloakSession? { - return ThreadLocalSessionContext.getCurrentSession(); + return ThreadLocalSessionContext.getCurrentSession(); } - - @Throws(NamingException::class) private fun mockJndiEnvironment() { NamingManager.setInitialContextFactoryBuilder { diff --git a/user-management/keycloak-gateway/src/main/kotlin/co/nilin/opex/auth/gateway/config/KafkaConfig.kt b/user-management/keycloak-gateway/src/main/kotlin/co/nilin/opex/auth/gateway/config/KafkaConfig.kt index a5eca210d..b1d80756f 100644 --- a/user-management/keycloak-gateway/src/main/kotlin/co/nilin/opex/auth/gateway/config/KafkaConfig.kt +++ b/user-management/keycloak-gateway/src/main/kotlin/co/nilin/opex/auth/gateway/config/KafkaConfig.kt @@ -28,11 +28,11 @@ class KafkaConfig { @Bean("authProducerConfigs") fun producerConfigs(): Map { return mapOf( - ProducerConfig.BOOTSTRAP_SERVERS_CONFIG to bootstrapServers, - ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG to StringSerializer::class.java, - ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG to JsonSerializer::class.java, - ProducerConfig.ACKS_CONFIG to "all", - JsonSerializer.TYPE_MAPPINGS to "user_created_event:co.nilin.opex.auth.gateway.model.UserCreatedEvent" + ProducerConfig.BOOTSTRAP_SERVERS_CONFIG to bootstrapServers, + ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG to StringSerializer::class.java, + ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG to JsonSerializer::class.java, + ProducerConfig.ACKS_CONFIG to "all", + JsonSerializer.TYPE_MAPPINGS to "user_created_event:co.nilin.opex.auth.gateway.model.UserCreatedEvent" ) } @@ -50,17 +50,17 @@ class KafkaConfig { fun createUserCreatedTopics(applicationContext: GenericApplicationContext) { applicationContext.registerBean("topic_auth_user_created", NewTopic::class.java, Supplier { TopicBuilder.name("auth_user_created") - .partitions(1) - .replicas(1) - .build() + .partitions(1) + .replicas(1) + .build() }) } @Autowired fun configureEventListeners( - kycLevelUpdatedKafkaListener: KycLevelUpdatedKafkaListener, - kycLevelUpdatedEventListener: KycLevelUpdatedEventListener + kycLevelUpdatedKafkaListener: KycLevelUpdatedKafkaListener, + kycLevelUpdatedEventListener: KycLevelUpdatedEventListener ) { kycLevelUpdatedKafkaListener.addEventListener(kycLevelUpdatedEventListener) diff --git a/user-management/keycloak-gateway/src/main/kotlin/co/nilin/opex/auth/gateway/data/ChangePasswordRequest.kt b/user-management/keycloak-gateway/src/main/kotlin/co/nilin/opex/auth/gateway/data/ChangePasswordRequest.kt index df866b20f..2b1716dec 100644 --- a/user-management/keycloak-gateway/src/main/kotlin/co/nilin/opex/auth/gateway/data/ChangePasswordRequest.kt +++ b/user-management/keycloak-gateway/src/main/kotlin/co/nilin/opex/auth/gateway/data/ChangePasswordRequest.kt @@ -1,10 +1,10 @@ package co.nilin.opex.auth.gateway.data -class ChangePasswordRequest{ +class ChangePasswordRequest { - var password: String?=null - var newPassword: String?=null - var confirmation: String?=null + var password: String? = null + var newPassword: String? = null + var confirmation: String? = null constructor() diff --git a/user-management/keycloak-gateway/src/main/kotlin/co/nilin/opex/auth/gateway/data/WhiteListAdaptor.kt b/user-management/keycloak-gateway/src/main/kotlin/co/nilin/opex/auth/gateway/data/WhiteListAdaptor.kt index 45287565d..c8a5663f2 100644 --- a/user-management/keycloak-gateway/src/main/kotlin/co/nilin/opex/auth/gateway/data/WhiteListAdaptor.kt +++ b/user-management/keycloak-gateway/src/main/kotlin/co/nilin/opex/auth/gateway/data/WhiteListAdaptor.kt @@ -1,7 +1,7 @@ package co.nilin.opex.auth.gateway.data class WhiteListAdaptor { - var data: MutableList?=null + var data: MutableList? = null constructor() constructor(data: MutableList) { diff --git a/user-management/keycloak-gateway/src/main/kotlin/co/nilin/opex/auth/gateway/extension/ExtendedEventListenerProvider.kt b/user-management/keycloak-gateway/src/main/kotlin/co/nilin/opex/auth/gateway/extension/ExtendedEventListenerProvider.kt index 496e4c6c0..248b9944a 100644 --- a/user-management/keycloak-gateway/src/main/kotlin/co/nilin/opex/auth/gateway/extension/ExtendedEventListenerProvider.kt +++ b/user-management/keycloak-gateway/src/main/kotlin/co/nilin/opex/auth/gateway/extension/ExtendedEventListenerProvider.kt @@ -51,7 +51,7 @@ class ExtendedEventListenerProvider(private val session: KeycloakSession) : Even val realm = model.getRealm(event.realmId) val user = session.users().getUserById(event.userId, realm) if (user != null && user.email != null && user.isEmailVerified) { - logger.info("USER HAS VERIFIED EMAIL : ${event.userId}" ) + logger.info("USER HAS VERIFIED EMAIL : ${event.userId}") // Example of adding an attribute when this event happens user.setSingleAttribute("attribute-key", "attribute-value") diff --git a/user-management/keycloak-gateway/src/main/kotlin/co/nilin/opex/auth/gateway/extension/HashicorpVaultProvider.java b/user-management/keycloak-gateway/src/main/kotlin/co/nilin/opex/auth/gateway/extension/HashicorpVaultProvider.java index 735858fef..443ffdb5c 100644 --- a/user-management/keycloak-gateway/src/main/kotlin/co/nilin/opex/auth/gateway/extension/HashicorpVaultProvider.java +++ b/user-management/keycloak-gateway/src/main/kotlin/co/nilin/opex/auth/gateway/extension/HashicorpVaultProvider.java @@ -20,6 +20,15 @@ public class HashicorpVaultProvider implements VaultProvider { private String vaultSecretEngineName; private VaultService service; + public HashicorpVaultProvider(String vaultUrl, String vaultAppId, String vaultUserId, String realmName, String vaultSecretEngineName, VaultService service) { + this.vaultUrl = vaultUrl; + this.vaultAppId = vaultAppId; + this.vaultUserId = vaultUserId; + this.realmName = realmName; + this.vaultSecretEngineName = vaultSecretEngineName; + this.service = service; + } + @Override public VaultRawSecret obtainSecret(String vaultSecretId) { int secretVersion = 0; @@ -40,13 +49,4 @@ public VaultRawSecret obtainSecret(String vaultSecretId) { public void close() { } - public HashicorpVaultProvider(String vaultUrl, String vaultAppId, String vaultUserId, String realmName, String vaultSecretEngineName, VaultService service) { - this.vaultUrl = vaultUrl; - this.vaultAppId = vaultAppId; - this.vaultUserId = vaultUserId; - this.realmName = realmName; - this.vaultSecretEngineName = vaultSecretEngineName; - this.service = service; - } - } \ No newline at end of file diff --git a/user-management/keycloak-gateway/src/main/kotlin/co/nilin/opex/auth/gateway/extension/HashicorpVaultProviderFactory.java b/user-management/keycloak-gateway/src/main/kotlin/co/nilin/opex/auth/gateway/extension/HashicorpVaultProviderFactory.java index c546f1646..2a9aad484 100644 --- a/user-management/keycloak-gateway/src/main/kotlin/co/nilin/opex/auth/gateway/extension/HashicorpVaultProviderFactory.java +++ b/user-management/keycloak-gateway/src/main/kotlin/co/nilin/opex/auth/gateway/extension/HashicorpVaultProviderFactory.java @@ -9,68 +9,66 @@ import org.keycloak.vault.VaultProviderFactory; public class HashicorpVaultProviderFactory implements VaultProviderFactory { - private static final Logger logger = Logger.getLogger(HashicorpVaultProviderFactory.class); + public static final String PROVIDER_ID = "hachicorp-vault"; + private static final Logger logger = Logger.getLogger(HashicorpVaultProviderFactory.class); + private String vaultAppId; + private String vaultUserId; + private String vaultUrl; + private String vaultSecretEngineName; - public static final String PROVIDER_ID = "hachicorp-vault"; + private static String format(String url) { + if (!(url.charAt(url.length() - 1) == '/')) { + return url.concat("/"); + } else { + return url; + } + } - private String vaultAppId; - private String vaultUserId; - private String vaultUrl; - private String vaultSecretEngineName; + @Override + public VaultProvider create(KeycloakSession session) { + VaultService service = new VaultService(session); + if (!service.isVaultAvailable(vaultUrl, vaultAppId, vaultUserId)) { + logger.error("Vault unavailable : " + vaultUrl); + throw new VaultNotFoundException("Vault unavailable : " + vaultUrl); + } else { + logger.info("Vault available : " + vaultUrl); + } + return new HashicorpVaultProvider(vaultUrl, vaultAppId, vaultUserId, session.getContext().getRealm().getName(), vaultSecretEngineName, service); - @Override - public VaultProvider create(KeycloakSession session) { - VaultService service = new VaultService(session); - if (!service.isVaultAvailable(vaultUrl, vaultAppId, vaultUserId)) { - logger.error("Vault unavailable : " + vaultUrl); - throw new VaultNotFoundException("Vault unavailable : " + vaultUrl); - } else { - logger.info("Vault available : " + vaultUrl); - } - return new HashicorpVaultProvider(vaultUrl, vaultAppId, vaultUserId, session.getContext().getRealm().getName(), vaultSecretEngineName, service); + } - } + @Override + public void init(Scope config) { + if (System.getenv("BACKEND_APP") != null) { + vaultAppId = System.getenv("BACKEND_APP"); + } else { + vaultAppId = config.get("appId"); + } + if (System.getenv("BACKEND_USER") != null) { + vaultUserId = System.getenv("BACKEND_USER"); + } else { + vaultUserId = config.get("userId"); + } + vaultUrl = config.get("url") != null ? format(config.get("url")) : null; + vaultSecretEngineName = config.get("engine-name"); + logger.info("Init Hashicorp: " + vaultUrl); + } - private static String format(String url) { - if (!(url.charAt(url.length() - 1) == '/')) { - return url.concat("/"); - } else { - return url; - } - } + @Override + public void postInit(KeycloakSessionFactory factory) { + // TODO Auto-generated method stub - @Override - public void init(Scope config) { - if (System.getenv("BACKEND_APP") != null) { - vaultAppId = System.getenv("BACKEND_APP"); - } else { - vaultAppId = config.get("appId"); - } - if (System.getenv("BACKEND_USER") != null) { - vaultUserId = System.getenv("BACKEND_USER"); - } else { - vaultUserId = config.get("userId"); - } - vaultUrl = config.get("url") != null ? format(config.get("url")) : null; - vaultSecretEngineName = config.get("engine-name"); - logger.info("Init Hashicorp: " + vaultUrl); - } + } - @Override - public void postInit(KeycloakSessionFactory factory) { - // TODO Auto-generated method stub + @Override + public void close() { + // TODO Auto-generated method stub - } + } - @Override - public void close() { - // TODO Auto-generated method stub - - } - - @Override - public String getId() { - return PROVIDER_ID; - } + @Override + public String getId() { + return PROVIDER_ID; + } } diff --git a/user-management/keycloak-gateway/src/main/kotlin/co/nilin/opex/auth/gateway/extension/UserManagementResource.kt b/user-management/keycloak-gateway/src/main/kotlin/co/nilin/opex/auth/gateway/extension/UserManagementResource.kt index b85d744d6..15fcd7e7c 100644 --- a/user-management/keycloak-gateway/src/main/kotlin/co/nilin/opex/auth/gateway/extension/UserManagementResource.kt +++ b/user-management/keycloak-gateway/src/main/kotlin/co/nilin/opex/auth/gateway/extension/UserManagementResource.kt @@ -32,7 +32,6 @@ import org.keycloak.urls.UrlType import org.keycloak.utils.CredentialHelper import org.keycloak.utils.TotpUtils import org.slf4j.LoggerFactory -import org.springframework.beans.factory.annotation.Value import org.springframework.kafka.core.KafkaTemplate import java.util.concurrent.TimeUnit import java.util.stream.Collectors diff --git a/user-management/keycloak-gateway/src/main/kotlin/co/nilin/opex/auth/gateway/extension/VaultService.java b/user-management/keycloak-gateway/src/main/kotlin/co/nilin/opex/auth/gateway/extension/VaultService.java index d6fe61a78..7b0f6e732 100644 --- a/user-management/keycloak-gateway/src/main/kotlin/co/nilin/opex/auth/gateway/extension/VaultService.java +++ b/user-management/keycloak-gateway/src/main/kotlin/co/nilin/opex/auth/gateway/extension/VaultService.java @@ -15,22 +15,13 @@ */ public class VaultService { - private final KeycloakSession session; private static final Logger logger = Logger.getLogger(VaultService.class); + private final KeycloakSession session; public VaultService(KeycloakSession session) { this.session = session; } - static class UserId { - @JsonProperty("user_id") - public String userId; - - public UserId(String userId) { - this.userId = userId; - } - } - public ByteBuffer getSecretFromVault(String vaultUrl, String realm, String vaultSecretEngineName, String secretName, String vaultAppId, String vaultUserId, int secretVersion) { try { //curl \ --method POST \ --data '{"user_id": ":user_id"}' \ http://127.0.0.1:8200/v1/auth/app-id/login/:app_id @@ -57,4 +48,13 @@ public boolean isVaultAvailable(String vaultUrl, String vaultAppId, String vault } } + static class UserId { + @JsonProperty("user_id") + public String userId; + + public UserId(String userId) { + this.userId = userId; + } + } + } \ No newline at end of file diff --git a/user-management/keycloak-gateway/src/main/kotlin/co/nilin/opex/auth/gateway/listener/KycLevelUpdatedListener.kt b/user-management/keycloak-gateway/src/main/kotlin/co/nilin/opex/auth/gateway/listener/KycLevelUpdatedListener.kt index a4425cef6..4a30719e7 100644 --- a/user-management/keycloak-gateway/src/main/kotlin/co/nilin/opex/auth/gateway/listener/KycLevelUpdatedListener.kt +++ b/user-management/keycloak-gateway/src/main/kotlin/co/nilin/opex/auth/gateway/listener/KycLevelUpdatedListener.kt @@ -27,8 +27,10 @@ class KycLevelUpdatedListener : KycLevelUpdatedEventListener { return "KycLevelUpdatedListener" } - override fun onEvent(event: KycLevelUpdatedEvent, - partition: Int, offset: Long, timestamp: Long, eventId: String) { + override fun onEvent( + event: KycLevelUpdatedEvent, + partition: Int, offset: Long, timestamp: Long, eventId: String + ) { val factory: KeycloakSessionFactory = KeycloakApplication.getSessionFactory() this.kcSession = factory.create() kcSession!!.transactionManager.begin() diff --git a/user-management/keycloak-gateway/src/main/kotlin/co/nilin/opex/auth/gateway/model/UserCreatedEvent.kt b/user-management/keycloak-gateway/src/main/kotlin/co/nilin/opex/auth/gateway/model/UserCreatedEvent.kt index 76a201345..67ea792ee 100644 --- a/user-management/keycloak-gateway/src/main/kotlin/co/nilin/opex/auth/gateway/model/UserCreatedEvent.kt +++ b/user-management/keycloak-gateway/src/main/kotlin/co/nilin/opex/auth/gateway/model/UserCreatedEvent.kt @@ -13,6 +13,7 @@ class UserCreatedEvent : AuthEvent { this.lastName = lastName this.email = email } + constructor() : super() override fun toString(): String { diff --git a/user-management/keycloak-gateway/src/main/kotlin/co/nilin/opex/auth/gateway/model/WhiteListModel.kt b/user-management/keycloak-gateway/src/main/kotlin/co/nilin/opex/auth/gateway/model/WhiteListModel.kt index 5d8a25fb9..493eccb70 100644 --- a/user-management/keycloak-gateway/src/main/kotlin/co/nilin/opex/auth/gateway/model/WhiteListModel.kt +++ b/user-management/keycloak-gateway/src/main/kotlin/co/nilin/opex/auth/gateway/model/WhiteListModel.kt @@ -1,7 +1,9 @@ package co.nilin.opex.auth.gateway.model -import javax.persistence.* +import javax.persistence.Entity +import javax.persistence.Id +import javax.persistence.Table @Entity(name = "whitelist") diff --git a/user-management/keycloak-gateway/src/main/resources/META-INF/whitelisttt-changelog.xml b/user-management/keycloak-gateway/src/main/resources/META-INF/whitelisttt-changelog.xml index 7b069bcd5..cc0ede79b 100644 --- a/user-management/keycloak-gateway/src/main/resources/META-INF/whitelisttt-changelog.xml +++ b/user-management/keycloak-gateway/src/main/resources/META-INF/whitelisttt-changelog.xml @@ -1,5 +1,7 @@ - + diff --git a/user-management/keycloak-gateway/src/main/resources/application.yml b/user-management/keycloak-gateway/src/main/resources/application.yml index 07e9bca92..24c57609b 100644 --- a/user-management/keycloak-gateway/src/main/resources/application.yml +++ b/user-management/keycloak-gateway/src/main/resources/application.yml @@ -61,7 +61,7 @@ management: web: base-path: /actuator exposure: - include: ["health", "prometheus", "metrics"] + include: [ "health", "prometheus", "metrics" ] endpoint: health: show-details: when_authorized @@ -94,6 +94,6 @@ app: forgot-redirect-url: ${FORGOT_REDIRECT_URL} whitelist: register: - enabled: ${WHITELIST_REGISTER_ENABLED:true} + enabled: ${WHITELIST_REGISTER_ENABLED:true} login: - enabled: ${WHITELIST_LOGIN_ENABLED:true} + enabled: ${WHITELIST_LOGIN_ENABLED:true} diff --git a/user-management/keycloak-gateway/src/main/resources/email-templates/execute-action.html b/user-management/keycloak-gateway/src/main/resources/email-templates/execute-action.html index 939b8a962..e964e1e3f 100644 --- a/user-management/keycloak-gateway/src/main/resources/email-templates/execute-action.html +++ b/user-management/keycloak-gateway/src/main/resources/email-templates/execute-action.html @@ -1,16 +1,17 @@ - - + + Email Verification - - + +