Skip to content

Commit

Permalink
MEED-3806 Add ERC20 verification token API
Browse files Browse the repository at this point in the history
  • Loading branch information
MayTekayaa committed Mar 8, 2024
1 parent 5c2a4b7 commit 12090b0
Show file tree
Hide file tree
Showing 4 changed files with 145 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,11 @@
package io.meeds.gamification.evm.blockchain;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import org.exoplatform.wallet.contract.ERC20;
import org.web3j.protocol.Web3j;
import org.web3j.protocol.http.HttpService;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package io.meeds.gamification.evm.model;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.math.BigInteger;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class ERC20Token {

private String name;

private String symbol;

private BigInteger totalSupply;

private BigInteger decimals;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package io.meeds.gamification.evm.rest;

import io.meeds.gamification.evm.model.ERC20Token;
import io.meeds.gamification.evm.service.BlockchainService;
import org.exoplatform.commons.exception.ObjectNotFoundException;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.server.ResponseStatusException;

import java.io.IOException;

@RestController
@RequestMapping("tokens")
public class TokensController {

@Autowired
BlockchainService blockchainService;

@GetMapping
@Operation(summary = "Retrieves ERC20 Token details", method = "GET")
@ApiResponse(responseCode = "200", description = "Request fulfilled")
@ApiResponse(responseCode = "404", description = "Not found")
@ApiResponse(responseCode = "503", description = "Service unavailable")
public ERC20Token getERC20Token(@Parameter(description = "erc20 contract address", required = true)
@RequestParam("contractAddress")
String contractAddress) {
if (contractAddress == null) {
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Contract address is missing");
}
try {
return blockchainService.getERC20TokenDetails(contractAddress);
} catch (IOException e) {
throw new ResponseStatusException(HttpStatus.NOT_FOUND, "ERC20 doesn't exist");
}

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@
package io.meeds.gamification.evm.service;

import io.meeds.gamification.evm.blockchain.BlockchainConfigurationProperties;
import io.meeds.gamification.evm.model.ERC20Token;
import io.meeds.gamification.evm.model.TokenTransferEvent;
import io.micrometer.common.util.StringUtils;
import org.apache.commons.collections.CollectionUtils;
import org.exoplatform.wallet.contract.ERC20;
import org.springframework.beans.factory.annotation.Autowired;
Expand Down Expand Up @@ -48,9 +50,6 @@ public class BlockchainService {
@Qualifier("polygonNetwork")
private Web3j polygonWeb3j;

@Autowired
BlockchainConfigurationProperties blockchainProperties;

public static final Event TRANSFER_EVENT = new Event("Transfer",
Arrays.<TypeReference<?>>asList(new TypeReference<Address>(true) {}, new TypeReference<Address>(true) {}, new TypeReference<Uint256>(false) {}));

Expand Down Expand Up @@ -89,6 +88,26 @@ public Set<TokenTransferEvent> getTransferredTokensTransactions(long fromBlock,
}
}

public ERC20Token getERC20TokenDetails(String contractAddress) throws IOException {
String name = erc20Name(contractAddress);
String symbol = erc20Symbol(contractAddress);
BigInteger totalSupply = erc20TotalSupply(contractAddress);
BigInteger decimals = erc20Decimals(contractAddress);
ERC20Token erc20Token = new ERC20Token();
if (StringUtils.isNotBlank(name)
&& StringUtils.isNotBlank(symbol)
&& !totalSupply.equals(BigInteger.ZERO)
&& !decimals.equals(BigInteger.ZERO)) {
erc20Token.setSymbol(symbol);
erc20Token.setDecimals(decimals);
erc20Token.setTotalSupply(totalSupply);
erc20Token.setName(name);
return erc20Token;
}
return null;

}

/**
* @return last block number
*/
Expand All @@ -100,6 +119,61 @@ public long getLastBlock() {
}
}

/**
* @return ERC20 token name
*/
public String erc20Name(String contractAddress) {
try {
ERC20 erc20Token = loadPolygonERC20Token(contractAddress);
return erc20Token.name().send();
} catch (Exception e) {
throw new IllegalStateException("Error calling symbol name", e);
}
}

/**
* @return ERC20 token symbol
*/
public String erc20Symbol(String contractAddress) {
try {
ERC20 erc20Token = loadPolygonERC20Token(contractAddress);
return erc20Token.symbol().send();
} catch (Exception e) {
throw new IllegalStateException("Error calling symbol method", e);
}
}

/**
* @return ERC20 token decimals
*/
public BigInteger erc20Decimals(String contractAddress) {
try {
ERC20 erc20Token = loadPolygonERC20Token(contractAddress);
return erc20Token.decimals().send();
} catch (Exception e) {
throw new IllegalStateException("Error calling decimals method", e);
}
}

/**
* @return ERC20 token totalSupply
*/
public BigInteger erc20TotalSupply(String contractAddress) {
try {
ERC20 erc20Token = loadPolygonERC20Token(contractAddress);
return erc20Token.totalSupply().send();
} catch (Exception e) {
throw new IllegalStateException("Error calling totalSupply method", e);
}
}

public ERC20 loadPolygonERC20Token(String contractAddress) {
return ERC20.load(contractAddress,
polygonWeb3j,
new ReadonlyTransactionManager(polygonWeb3j, Address.DEFAULT.toString()),
new StaticGasProvider(BigInteger.valueOf(20000000000l), BigInteger.valueOf(300000l)));
}

private Stream<TokenTransferEvent> getTransferEvents(TransactionReceipt transactionReceipt, String contractAddress) {
ERC20 erc20Token = ERC20.load(contractAddress,
polygonWeb3j,
Expand Down

0 comments on commit 12090b0

Please sign in to comment.