From 02097643705cab15b913ec11b3bc07e023ed3221 Mon Sep 17 00:00:00 2001 From: Oleg Zhymolokhov Date: Thu, 23 Aug 2018 19:01:27 +0300 Subject: [PATCH] mint-api: Implemented funding of created accounts. --- .../controller/EthereumController.java | 3 +- .../controller/TokenController.java | 12 +++--- .../controller/WalletController.java | 2 +- .../walletservice/model/FundedAddress.java | 18 +++++++++ .../repository/FundedAddressRepository.java | 9 +++++ .../walletservice/service/TokenService.java | 39 ++++++++++++++++++- .../walletservice/service/Web3JService.java | 6 ++- 7 files changed, 77 insertions(+), 12 deletions(-) create mode 100644 src/main/java/com/nynja/walletservice/model/FundedAddress.java create mode 100644 src/main/java/com/nynja/walletservice/repository/FundedAddressRepository.java diff --git a/src/main/java/com/nynja/walletservice/controller/EthereumController.java b/src/main/java/com/nynja/walletservice/controller/EthereumController.java index fa0d704..265191e 100644 --- a/src/main/java/com/nynja/walletservice/controller/EthereumController.java +++ b/src/main/java/com/nynja/walletservice/controller/EthereumController.java @@ -8,6 +8,7 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; +import org.web3j.utils.Convert; import java.math.BigDecimal; import java.util.concurrent.CompletableFuture; @@ -64,7 +65,7 @@ public class EthereumController { @GetMapping(API_VERSION + "/eth-send") public CompletableFuture>> sendEthToAddress(@RequestParam String address, @RequestParam long amount) { return web3JService - .sendEtherAsync(ethConfig.getAdminCredentials(), address, BigDecimal.valueOf(amount)) + .sendEtherAsync(ethConfig.getAdminCredentials(), address, BigDecimal.valueOf(amount), Convert.Unit.ETHER) .thenApplyAsync(ResponseEntity::ok); } } diff --git a/src/main/java/com/nynja/walletservice/controller/TokenController.java b/src/main/java/com/nynja/walletservice/controller/TokenController.java index 3533898..2b1016f 100644 --- a/src/main/java/com/nynja/walletservice/controller/TokenController.java +++ b/src/main/java/com/nynja/walletservice/controller/TokenController.java @@ -9,7 +9,6 @@ import org.springframework.web.bind.annotation.*; import java.util.concurrent.CompletableFuture; -import static com.nynja.walletservice.constant.Constants.DataTypes.LONG; import static com.nynja.walletservice.constant.Constants.DataTypes.STRING; import static com.nynja.walletservice.constant.Constants.ParamTypes.Query; import static com.nynja.walletservice.constant.Constants.RestApi.API_VERSION; @@ -32,17 +31,16 @@ public class TokenController { } - @ApiOperation(value = "Generate an amount of tokens for provided address", httpMethod = "GET") + @ApiOperation(value = "Fund provided account with tokens", httpMethod = "GET") @ApiImplicitParams({ - @ApiImplicitParam(paramType = Query, name = "address", dataType = STRING, value = "Account address"), - @ApiImplicitParam(paramType = Query, name = "amount", dataType = LONG, value = "Amount of tokens to be minted") + @ApiImplicitParam(paramType = Query, name = "address", dataType = STRING, value = "Account address") }) @ApiResponses({ @ApiResponse(code = 200, message = RETRIEVED), @ApiResponse(code = 400, message = REQUIRED_PARAM_MISSING) }) - @GetMapping(API_VERSION + "/mint") - public CompletableFuture>> mint(@RequestParam String address, @RequestParam String amount) { - return tokenService.mint(address, amount).thenApplyAsync(ResponseEntity::ok); + @GetMapping(API_VERSION + "/fund-address") + public CompletableFuture>> fundAddress(@RequestParam String address) { + return tokenService.handleAccountCreation(address).thenApplyAsync(ResponseEntity::ok); } } diff --git a/src/main/java/com/nynja/walletservice/controller/WalletController.java b/src/main/java/com/nynja/walletservice/controller/WalletController.java index 5903a3c..fca19df 100644 --- a/src/main/java/com/nynja/walletservice/controller/WalletController.java +++ b/src/main/java/com/nynja/walletservice/controller/WalletController.java @@ -27,7 +27,7 @@ public class WalletController { @ApiOperation(value = "Import mnemonic and retrieve HD wallet addresses that participated in transactions.", httpMethod = "POST") @ApiResponse(code = 200, message = RETRIEVED) - @PostMapping(API_VERSION + "/hd-wallet-balance") + @PostMapping(API_VERSION + "/hd-wallet-scan") public CompletableFuture> getHDWalletBalance(@Valid @RequestBody WalletImportDto dto) { return handleAndRespondAsync(() -> CKDService.discoverHDWallet(dto)); } diff --git a/src/main/java/com/nynja/walletservice/model/FundedAddress.java b/src/main/java/com/nynja/walletservice/model/FundedAddress.java new file mode 100644 index 0000000..5272637 --- /dev/null +++ b/src/main/java/com/nynja/walletservice/model/FundedAddress.java @@ -0,0 +1,18 @@ +package com.nynja.walletservice.model; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; + +import javax.persistence.Entity; + +@Entity +@EqualsAndHashCode(callSuper = true) +@Data +@AllArgsConstructor +@NoArgsConstructor +public class FundedAddress extends MainEntity { + private String address; + private String amount; +} diff --git a/src/main/java/com/nynja/walletservice/repository/FundedAddressRepository.java b/src/main/java/com/nynja/walletservice/repository/FundedAddressRepository.java new file mode 100644 index 0000000..0ff2a78 --- /dev/null +++ b/src/main/java/com/nynja/walletservice/repository/FundedAddressRepository.java @@ -0,0 +1,9 @@ +package com.nynja.walletservice.repository; + +import com.nynja.walletservice.model.FundedAddress; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface FundedAddressRepository extends JpaRepository { + + boolean existsByAddress(String address); +} diff --git a/src/main/java/com/nynja/walletservice/service/TokenService.java b/src/main/java/com/nynja/walletservice/service/TokenService.java index 45b07c6..de4fda0 100644 --- a/src/main/java/com/nynja/walletservice/service/TokenService.java +++ b/src/main/java/com/nynja/walletservice/service/TokenService.java @@ -2,13 +2,17 @@ package com.nynja.walletservice.service; import com.nynja.walletservice.config.EthereumConfig; import com.nynja.walletservice.dto.TransactionResponseDto; +import com.nynja.walletservice.model.FundedAddress; import com.nynja.walletservice.provider.ContractProvider; +import com.nynja.walletservice.repository.FundedAddressRepository; import com.nynja.walletservice.service.operation.TokenOperationFactory; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.web3j.protocol.core.methods.response.TransactionReceipt; +import org.web3j.utils.Convert; +import java.math.BigDecimal; import java.math.BigInteger; import java.util.concurrent.CompletableFuture; import java.util.function.Function; @@ -23,17 +27,24 @@ import static java.lang.String.format; @Slf4j public class TokenService { + public static final String AMOUNT = "1000"; + private final ContractProvider contractProvider; private final TokenOperationFactory operationFactory; private final EthereumConfig ethConfig; + private final Web3JService web3JService; + private final FundedAddressRepository fundedAddressRepository; @Autowired public TokenService( - ContractProvider contractProvider, TokenOperationFactory operationFactory, EthereumConfig ethConfig + ContractProvider contractProvider, TokenOperationFactory operationFactory, + EthereumConfig ethConfig, Web3JService web3JService, FundedAddressRepository fundedAddressRepository ) { this.contractProvider = contractProvider; this.operationFactory = operationFactory; this.ethConfig = ethConfig; + this.web3JService = web3JService; + this.fundedAddressRepository = fundedAddressRepository; } public CompletableFuture deployTokenContract() { @@ -45,6 +56,32 @@ public class TokenService { .execute().thenApplyAsync(BigInteger::longValue); } + //TODO For demo purposes. Remove after. + public CompletableFuture> handleAccountCreation(String accountAddress) { + checkIfFunded(accountAddress); + + return mint(accountAddress, AMOUNT) + .thenApplyAsync(transactionResponseDto -> { + fundedAddressRepository.save(new FundedAddress(accountAddress, transactionResponseDto.getValue())); + return transactionResponseDto; + }).thenApplyAsync(transactionResponseDto -> { + web3JService.sendEtherAsync( + ethConfig.getAdminCredentials(), + accountAddress, + new BigDecimal(500), + Convert.Unit.FINNEY + ); + + return transactionResponseDto; + }); + } + + private void checkIfFunded(String address) { + if (fundedAddressRepository.existsByAddress(address)) { + throw new RuntimeException(String.format("The Address %s has already been funded", address)); + } + } + public CompletableFuture> mint(String address, String amount) { return operationFactory.mintOperation(ethConfig.getAdminCredentials(), address, amount).execute() .thenApplyAsync(handleTransaction(amount, format("Error during token minting. Address %s", address))); diff --git a/src/main/java/com/nynja/walletservice/service/Web3JService.java b/src/main/java/com/nynja/walletservice/service/Web3JService.java index 25483e8..03b7b00 100644 --- a/src/main/java/com/nynja/walletservice/service/Web3JService.java +++ b/src/main/java/com/nynja/walletservice/service/Web3JService.java @@ -14,6 +14,7 @@ import org.web3j.protocol.core.DefaultBlockParameterName; import org.web3j.protocol.core.methods.response.*; import org.web3j.tx.RawTransactionManager; import org.web3j.tx.Transfer; +import org.web3j.utils.Convert; import org.web3j.utils.Numeric; import java.io.IOException; @@ -60,9 +61,10 @@ public class Web3JService { return web3ClientVersion.getWeb3ClientVersion(); } - public CompletableFuture> sendEtherAsync(Credentials credentials, String toAddress, BigDecimal value) { + public CompletableFuture> sendEtherAsync(Credentials credentials, String toAddress, + BigDecimal value, Convert.Unit currency) { return new Transfer(web3j(), new RawTransactionManager(web3j(), credentials, attempts, interval)) - .sendFunds(toAddress, value, ETHER, ethConfig.gasPrice(), ethConfig.gasLimit()) + .sendFunds(toAddress, value, currency, ethConfig.gasPrice(), ethConfig.gasLimit()) .sendAsync() .thenApplyAsync(tr -> { log.info(ETH_TRANSFERRED, toAddress, value); -- GitLab