diff --git a/BlockchainGateway/bc-gateway-app/pom.xml b/BlockchainGateway/bc-gateway-app/pom.xml index 298eb2d3f..e8f17c131 100644 --- a/BlockchainGateway/bc-gateway-app/pom.xml +++ b/BlockchainGateway/bc-gateway-app/pom.xml @@ -103,6 +103,11 @@ bc-gateway-persister-postgres ${bc-gateway.version} + + co.nilin.opex.external + wallet-proxy + ${bc-gateway.version} + io.springfox springfox-boot-starter diff --git a/BlockchainGateway/bc-gateway-app/src/main/resources/application-docker.yml b/BlockchainGateway/bc-gateway-app/src/main/resources/application-docker.yml index ffbf14176..e0917e58c 100644 --- a/BlockchainGateway/bc-gateway-app/src/main/resources/application-docker.yml +++ b/BlockchainGateway/bc-gateway-app/src/main/resources/application-docker.yml @@ -19,4 +19,6 @@ spring: app: auth: - cert-url: lb://opex-auth/auth/realms/opex/protocol/openid-connect/certs \ No newline at end of file + cert-url: lb://opex-auth/auth/realms/opex/protocol/openid-connect/certs + wallet: + url: lb://wallet diff --git a/BlockchainGateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/spi/WalletProxy.kt b/BlockchainGateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/spi/WalletProxy.kt index 0437da445..98d8d16f5 100644 --- a/BlockchainGateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/spi/WalletProxy.kt +++ b/BlockchainGateway/bc-gateway-core/src/main/kotlin/co/nilin/opex/bcgateway/core/spi/WalletProxy.kt @@ -3,5 +3,5 @@ package co.nilin.opex.bcgateway.core.spi import java.math.BigDecimal interface WalletProxy { - fun transfer(uuid: String, symbol: String, amount: BigDecimal) -} \ No newline at end of file + suspend fun transfer(uuid: String, symbol: String, amount: BigDecimal) +} diff --git a/BlockchainGateway/bc-gateway-ports/wallet-proxy/.gitignore b/BlockchainGateway/bc-gateway-ports/wallet-proxy/.gitignore new file mode 100644 index 000000000..f4e066ca5 --- /dev/null +++ b/BlockchainGateway/bc-gateway-ports/wallet-proxy/.gitignore @@ -0,0 +1,36 @@ +HELP.md +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ +!/.mvn/ + +.DS_Store diff --git a/BlockchainGateway/bc-gateway-ports/wallet-proxy/pom.xml b/BlockchainGateway/bc-gateway-ports/wallet-proxy/pom.xml new file mode 100644 index 000000000..574217895 --- /dev/null +++ b/BlockchainGateway/bc-gateway-ports/wallet-proxy/pom.xml @@ -0,0 +1,100 @@ + + + + org.springframework.boot + spring-boot-starter-parent + 2.4.4 + + + 4.0.0 + + co.nilin.opex.external + wallet-proxy + 1.0-SNAPSHOT + + + 1.8 + 1.4.31 + ${version} + + + + + org.springframework.boot + spring-boot-starter + + + + io.projectreactor.kotlin + reactor-kotlin-extensions + + + org.jetbrains.kotlin + kotlin-reflect + + + org.jetbrains.kotlin + kotlin-stdlib-jdk8 + + + org.jetbrains.kotlinx + kotlinx-coroutines-reactor + + + org.jetbrains.kotlinx + kotlinx-coroutines-core + + + co.nilin.opex.external + bc-gateway-core + ${bc-gateway.version} + + + org.springframework + spring-webflux + + + co.nilin.opex + wallet-core + 1.0-SNAPSHOT + compile + + + + + ${project.basedir}/src/main/kotlin + ${project.basedir}/src/test/kotlin + + + org.jetbrains.kotlin + kotlin-maven-plugin + + + -Xjsr305=strict + + + spring + + + + + org.jetbrains.kotlin + kotlin-maven-allopen + ${kotlin.version} + + + + + + + + + spring-milestones + Spring Milestones + https://repo.spring.io/milestone + + + + diff --git a/BlockchainGateway/bc-gateway-ports/wallet-proxy/src/main/kotlin/co.nilin.opex.port.bcgateway.walletproxy/impl/WalletProxyImpl.kt b/BlockchainGateway/bc-gateway-ports/wallet-proxy/src/main/kotlin/co.nilin.opex.port.bcgateway.walletproxy/impl/WalletProxyImpl.kt new file mode 100644 index 000000000..72aaae903 --- /dev/null +++ b/BlockchainGateway/bc-gateway-ports/wallet-proxy/src/main/kotlin/co.nilin.opex.port.bcgateway.walletproxy/impl/WalletProxyImpl.kt @@ -0,0 +1,30 @@ +package co.nilin.opex.port.bcgateway.walletproxy.impl + +import co.nilin.opex.bcgateway.core.spi.WalletProxy +import co.nilin.opex.wallet.core.inout.TransferResult +import kotlinx.coroutines.reactive.awaitFirst +import org.springframework.beans.factory.annotation.Value +import org.springframework.core.ParameterizedTypeReference +import org.springframework.stereotype.Component +import org.springframework.web.reactive.function.client.WebClient +import java.math.BigDecimal +import java.net.URI + +inline fun typeRef(): ParameterizedTypeReference = object : ParameterizedTypeReference() {} + +@Component +class WalletProxyImpl(private val webClient: WebClient) : WalletProxy { + @Value("\${app.wallet.url}") + private lateinit var baseUrl: String + + override suspend fun transfer(uuid: String, symbol: String, amount: BigDecimal) { + webClient.post() + .uri(URI.create("$baseUrl/deposit/${amount}_$symbol/${uuid}_main")) + .header("Content-Type", "application/json") + .retrieve() + .onStatus({ t -> t.isError }, { it.createException() }) + .bodyToMono(typeRef()) + .log() + .awaitFirst() + } +} diff --git a/BlockchainGateway/pom.xml b/BlockchainGateway/pom.xml index 7c8b77ddf..f958f29dd 100644 --- a/BlockchainGateway/pom.xml +++ b/BlockchainGateway/pom.xml @@ -1,18 +1,19 @@ - 4.0.0 - co.nilin.opex.external - bc-gateway - 1.0-SNAPSHOT - bc-gateway - pom - Blockchain gateway root of opex + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 + co.nilin.opex.external + bc-gateway + 1.0-SNAPSHOT + bc-gateway + pom + Blockchain gateway root of opex - - bc-gateway-core - bc-gateway-app - bc-gateway-ports/bc-persister-postgres - bc-gateway-ports/bc-chain-proxy - + + bc-gateway-core + bc-gateway-app + bc-gateway-ports/bc-persister-postgres + bc-gateway-ports/bc-chain-proxy + bc-gateway-ports/wallet-proxy + diff --git a/Wallet/wallet-app/src/main/kotlin/co/nilin/opex/wallet/app/controller/TransferController.kt b/Wallet/wallet-app/src/main/kotlin/co/nilin/opex/wallet/app/controller/TransferController.kt index 0a386c48b..edfeecb52 100644 --- a/Wallet/wallet-app/src/main/kotlin/co/nilin/opex/wallet/app/controller/TransferController.kt +++ b/Wallet/wallet-app/src/main/kotlin/co/nilin/opex/wallet/app/controller/TransferController.kt @@ -19,10 +19,10 @@ import java.math.BigDecimal @RestController class TransferController( - val transferService: TransferService - , val currencyService: CurrencyService - , val walletManager: WalletManager - , val walletOwnerManager: WalletOwnerManager + val transferService: TransferService, + val currencyService: CurrencyService, + val walletManager: WalletManager, + val walletOwnerManager: WalletOwnerManager ) { @PostMapping("/transfer/{amount}_{symbol}/from/{senderUuid}_{senderWalletType}/to/{receiverUuid}_{receiverWalletType}") @ApiResponse( @@ -45,8 +45,7 @@ class TransferController( @PathVariable("description") description: String?, @PathVariable("transferRef") transferRef: String? ): TransferResult { - if ( senderWalletType.equals("cashout") - || receiverWalletType.equals("cashout") ) + if (senderWalletType == "cashout" || receiverWalletType == "cashout") throw IllegalArgumentException("Use withdraw services") val currency = currencyService.getCurrency(symbol) val sourceOwner = walletOwnerManager.findWalletOwner(senderUuid) ?: throw IllegalArgumentException() @@ -75,4 +74,53 @@ class TransferController( ) ) } -} \ No newline at end of file + + @PostMapping("/deposit/{amount}_{symbol}/{receiverUuid}_{receiverWalletType}") + @ApiResponse( + message = "OK", + code = 200, + examples = Example( + ExampleProperty( + value = "{ }", + mediaType = "application/json" + ) + ) + ) + suspend fun deposit( + @PathVariable("symbol") symbol: String, + @PathVariable("receiverUuid") receiverUuid: String, + @PathVariable("receiverWalletType") receiverWalletType: String, + @PathVariable("amount") amount: BigDecimal, + @PathVariable("description") description: String?, + @PathVariable("transferRef") transferRef: String? + ): TransferResult { + if (receiverWalletType == "cashout") throw IllegalArgumentException("Use withdraw services") + val systemUuid = "1" + val currency = currencyService.getCurrency(symbol) + val sourceOwner = walletOwnerManager.findWalletOwner(systemUuid) ?: throw IllegalArgumentException() + val sourceWallet = + walletManager.findWalletByOwnerAndCurrencyAndType(sourceOwner, "main", currency) + ?: throw IllegalArgumentException() + val receiverOwner = walletOwnerManager.findWalletOwner(receiverUuid) ?: walletOwnerManager.createWalletOwner( + systemUuid, + "not set", + "" + ) + val receiverWallet = walletManager.findWalletByOwnerAndCurrencyAndType( + receiverOwner, receiverWalletType, currency + ) ?: walletManager.createWallet( + receiverOwner, + Amount(currency, BigDecimal.ZERO), + currency, + receiverWalletType + ) + return transferService.transfer( + TransferCommand( + sourceWallet, + receiverWallet, + Amount(sourceWallet.currency(), amount), + description, transferRef, emptyMap() + ) + ) + } +} diff --git a/Wallet/wallet-app/src/main/kotlin/co/nilin/opex/wallet/app/controller/WithdrawController.kt b/Wallet/wallet-app/src/main/kotlin/co/nilin/opex/wallet/app/controller/WithdrawController.kt index e04204f23..adb38bdbb 100644 --- a/Wallet/wallet-app/src/main/kotlin/co/nilin/opex/wallet/app/controller/WithdrawController.kt +++ b/Wallet/wallet-app/src/main/kotlin/co/nilin/opex/wallet/app/controller/WithdrawController.kt @@ -23,12 +23,12 @@ import java.security.Principal @RestController class WithdrawController( - val withdrawRepository: WithdrawRepository - , val transferService: TransferService - , val walletManager: WalletManager - , val walletOwnerManager: WalletOwnerManager - , val currencyService: CurrencyService - , @Value("\${app.system.uuid}") val systemUuid: String + val withdrawRepository: WithdrawRepository, + val transferService: TransferService, + val walletManager: WalletManager, + val walletOwnerManager: WalletOwnerManager, + val currencyService: CurrencyService, + @Value("\${app.system.uuid}") val systemUuid: String ) { @GetMapping("/admin/withdraw") @@ -73,13 +73,18 @@ class WithdrawController( @RequestParam("status", required = false) status: List? ): List { return withdrawRepository - .findByCriteria(principal.name, txRef, destTxRef, destAddress, status?.isEmpty() ?: true, status ?: listOf("")) + .findByCriteria( + principal.name, + txRef, + destTxRef, + destAddress, + status?.isEmpty() ?: true, + status ?: listOf("") + ) .toList() } - @PostMapping( - "/withdraw/{amount}_{symbol}" - ) + @PostMapping("/withdraw/{amount}_{symbol}") @ApiResponse( message = "OK", code = 200, @@ -148,7 +153,8 @@ class WithdrawController( @RequestParam("statusReason", required = false) statusReason: String?, @RequestParam("destNote", required = false) destNote: String? ): TransferResult { - val withdraw = withdrawRepository.findById(withdrawId).awaitFirstOrElse { throw RuntimeException("No matching withdraw request") } + val withdraw = withdrawRepository.findById(withdrawId) + .awaitFirstOrElse { throw RuntimeException("No matching withdraw request") } val sourceWallet = walletManager.findWalletById(withdraw.wallet) ?: throw RuntimeException("Wallet not found") val receiverWallet = walletManager.findWalletByOwnerAndCurrencyAndType( sourceWallet.owner(), "main", sourceWallet.currency() @@ -173,9 +179,7 @@ class WithdrawController( ) } - @PostMapping( - "/admin/withdraw/{id}/accept" - ) + @PostMapping("/admin/withdraw/{id}/accept") @ApiResponse( message = "OK", code = 200, @@ -192,7 +196,8 @@ class WithdrawController( @RequestParam("destNote", required = false) destNote: String? ): TransferResult { val system = walletOwnerManager.findWalletOwner(systemUuid) ?: throw IllegalArgumentException() - val withdraw = withdrawRepository.findById(withdrawId).awaitFirstOrElse { throw RuntimeException("No matching withdraw request") } + val withdraw = withdrawRepository.findById(withdrawId) + .awaitFirstOrElse { throw RuntimeException("No matching withdraw request") } val sourceWallet = walletManager.findWalletById(withdraw.wallet) ?: throw RuntimeException("Wallet not found") val receiverWallet = walletManager.findWalletByOwnerAndCurrencyAndType( system, "main", sourceWallet.currency() @@ -216,4 +221,4 @@ class WithdrawController( ) ) } -} \ No newline at end of file +} diff --git a/Wallet/wallet-core/src/main/kotlin/co/nilin/opex/wallet/core/inout/TransferResult.kt b/Wallet/wallet-core/src/main/kotlin/co/nilin/opex/wallet/core/inout/TransferResult.kt index 9cdbb74dc..fea370441 100644 --- a/Wallet/wallet-core/src/main/kotlin/co/nilin/opex/wallet/core/inout/TransferResult.kt +++ b/Wallet/wallet-core/src/main/kotlin/co/nilin/opex/wallet/core/inout/TransferResult.kt @@ -3,13 +3,14 @@ package co.nilin.opex.wallet.core.inout import co.nilin.opex.wallet.core.model.Amount import java.time.LocalDateTime -data class TransferResult(val date: Long -, val sourceUuid: String -, val sourceWalletType: String -, val sourceBalanceBeforeAction: Amount -, val sourceBalanceAfterAction: Amount -, val amount: Amount -, val destUuid: String -, val destWalletType: String -, val receivedAmount: Amount -) \ No newline at end of file +data class TransferResult( + val date: Long, + val sourceUuid: String, + val sourceWalletType: String, + val sourceBalanceBeforeAction: Amount, + val sourceBalanceAfterAction: Amount, + val amount: Amount, + val destUuid: String, + val destWalletType: String, + val receivedAmount: Amount +)