diff --git a/src/main/java/com/nynja/walletservice/controller/EthereumController.java b/src/main/java/com/nynja/walletservice/controller/EthereumController.java index fa0d70488593e9fe448ed04e1beb05e8fa308b91..265191e53a73d85aea16d1c6e4096090e6ad1868 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 3533898258fe8373d0a569e86b6bf16fae3c33d9..2b1016f10163cb34635c88c4de4bc9230e34846a 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 5903a3c3c624f6d090207ecd283c234a8465cb29..fca19df2b4455f7d4c2dad32469f646f61a46501 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 0000000000000000000000000000000000000000..5272637826f5fe1963ea2d312c8ddf7146a40a8c --- /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 0000000000000000000000000000000000000000..0ff2a780f285f661f8d78e7ec072cad7f5fa19d5 --- /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 45b07c6359bffcf9187979956b8b84c62fd1e99a..de4fda0c0e4720dfd4a8f68289d0e5e9c6bb8f35 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 25483e81e6e3a16908c29173de2f6c349cd0605a..03b7b00c0c1cb50b4ca469c84f3ace2b3376f5d9 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);