From 90767d00a48a343f4b0ef2d05c6ef432febc94fa Mon Sep 17 00:00:00 2001 From: chengpengxiang <15503679582@163.com> Date: Mon, 15 Apr 2024 23:24:16 +0800 Subject: [PATCH] feat: 1. add whale amountUSD/tokenNumber query --- .../defi/controller/DeFiController.java | 11 ++ .../defi/dao/WhaleChainTokenRepository.java | 22 +++ .../defi/dao/WhaleChainValueRepository.java | 20 +++ .../defi/entity/WhaleChainToken.java | 38 +++++ .../defi/entity/WhaleChainValue.java | 36 +++++ .../defi/service/WhaleService.java | 131 +++++++++++++++++- 6 files changed, 253 insertions(+), 5 deletions(-) create mode 100644 src/main/java/com/dl/officialsite/defi/dao/WhaleChainTokenRepository.java create mode 100644 src/main/java/com/dl/officialsite/defi/dao/WhaleChainValueRepository.java create mode 100644 src/main/java/com/dl/officialsite/defi/entity/WhaleChainToken.java create mode 100644 src/main/java/com/dl/officialsite/defi/entity/WhaleChainValue.java diff --git a/src/main/java/com/dl/officialsite/defi/controller/DeFiController.java b/src/main/java/com/dl/officialsite/defi/controller/DeFiController.java index daaa29bd..a519cc05 100644 --- a/src/main/java/com/dl/officialsite/defi/controller/DeFiController.java +++ b/src/main/java/com/dl/officialsite/defi/controller/DeFiController.java @@ -137,6 +137,17 @@ public BaseResponse queryWhaleProtocol( return BaseResponse.successWithData(whaleProtocolService.queryWhaleProtocol(address, pageable)); } + @GetMapping("/query/whale/chain/token") + public BaseResponse queryWhaleChainToken(@RequestParam String whaleAddress, + @RequestParam Integer update) { + return BaseResponse.successWithData(whaleService.getUserTotalBalance(whaleAddress, update)); + } + + @GetMapping("/query/whale/chain/value") + public BaseResponse queryWhaleChainValue(@RequestParam String whaleAddress,@RequestParam Integer update) { + return BaseResponse.successWithData(whaleService.getUserTokenList(whaleAddress,update)); + } + } diff --git a/src/main/java/com/dl/officialsite/defi/dao/WhaleChainTokenRepository.java b/src/main/java/com/dl/officialsite/defi/dao/WhaleChainTokenRepository.java new file mode 100644 index 00000000..9f6d3ce9 --- /dev/null +++ b/src/main/java/com/dl/officialsite/defi/dao/WhaleChainTokenRepository.java @@ -0,0 +1,22 @@ +package com.dl.officialsite.defi.dao; + +import com.dl.officialsite.defi.entity.WhaleChainToken; +import java.util.List; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import org.springframework.data.jpa.repository.Query; + +/** + * @ClassName whaleChainTokenRepository + * @Author jackchen + * @Date 2024/4/15 22:52 + * @Description TODO + **/ +public interface WhaleChainTokenRepository extends JpaRepository, + JpaSpecificationExecutor { + + List findByWhaleAddress(String whaleAddress); + + @Query(value = "select * from whale_chain_token order by id DESC limit 1", nativeQuery = true) + WhaleChainToken findAgoWhaleChainToken(); +} diff --git a/src/main/java/com/dl/officialsite/defi/dao/WhaleChainValueRepository.java b/src/main/java/com/dl/officialsite/defi/dao/WhaleChainValueRepository.java new file mode 100644 index 00000000..6faa8da6 --- /dev/null +++ b/src/main/java/com/dl/officialsite/defi/dao/WhaleChainValueRepository.java @@ -0,0 +1,20 @@ +package com.dl.officialsite.defi.dao; + +import com.dl.officialsite.defi.entity.WhaleChainValue; +import java.util.List; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import org.springframework.data.jpa.repository.Query; + +/** + * @ClassName WhaleChainValueRepository + * @Author jackchen + * @Date 2024/4/15 22:27 + * @Description WhaleChainValueRepository + **/ +public interface WhaleChainValueRepository extends JpaRepository, + JpaSpecificationExecutor { + + @Query(value = "select * from whale_chain_value where whale_address = ?1", nativeQuery = true) + List findByWhaleAddress(String whaleAddress); +} diff --git a/src/main/java/com/dl/officialsite/defi/entity/WhaleChainToken.java b/src/main/java/com/dl/officialsite/defi/entity/WhaleChainToken.java new file mode 100644 index 00000000..cb46bf0e --- /dev/null +++ b/src/main/java/com/dl/officialsite/defi/entity/WhaleChainToken.java @@ -0,0 +1,38 @@ +package com.dl.officialsite.defi.entity; + +import javax.persistence.Entity; +import javax.persistence.EntityListeners; +import javax.persistence.Id; +import javax.persistence.Table; +import lombok.Data; +import org.springframework.data.jpa.domain.support.AuditingEntityListener; + +/** + * @ClassName WhaleChainToken + * @Author jackchen + * @Date 2024/4/15 22:46 + * @Description WhaleChainToken + **/ +@Data +@Entity +@Table(name = "whale_chain_token") +@EntityListeners(AuditingEntityListener.class) +public class WhaleChainToken { + + @Id + private Long id; + + private String whaleAddress; + + private String chainName; + + private String tokenAddress; + + private String tokenSymbol; + + private String amount; + + private String price; + + private Integer decimals; +} diff --git a/src/main/java/com/dl/officialsite/defi/entity/WhaleChainValue.java b/src/main/java/com/dl/officialsite/defi/entity/WhaleChainValue.java new file mode 100644 index 00000000..956c35f1 --- /dev/null +++ b/src/main/java/com/dl/officialsite/defi/entity/WhaleChainValue.java @@ -0,0 +1,36 @@ +package com.dl.officialsite.defi.entity; + +import javax.persistence.Entity; +import javax.persistence.EntityListeners; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; +import lombok.Data; +import org.springframework.data.jpa.domain.support.AuditingEntityListener; + +/** + * @ClassName WhaleChainValue + * @Author jackchen + * @Date 2024/4/15 22:16 + * @Description WhaleChainValue + **/ +@Data +@Entity +@Table(name = "whale_chain_value") +@EntityListeners(AuditingEntityListener.class) +public class WhaleChainValue { + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + + private String whaleAddress; + + private String chainId; + + private String chainName; + + private String value; + +} diff --git a/src/main/java/com/dl/officialsite/defi/service/WhaleService.java b/src/main/java/com/dl/officialsite/defi/service/WhaleService.java index bae01f98..1ba7f8c3 100644 --- a/src/main/java/com/dl/officialsite/defi/service/WhaleService.java +++ b/src/main/java/com/dl/officialsite/defi/service/WhaleService.java @@ -4,9 +4,13 @@ import cn.hutool.json.JSONObject; import cn.hutool.json.JSONUtil; import com.dl.officialsite.defi.dao.BatchRepository; +import com.dl.officialsite.defi.dao.WhaleChainTokenRepository; +import com.dl.officialsite.defi.dao.WhaleChainValueRepository; import com.dl.officialsite.defi.dao.WhaleRepository; import com.dl.officialsite.defi.dao.WhaleTxRowRepository; import com.dl.officialsite.defi.entity.Whale; +import com.dl.officialsite.defi.entity.WhaleChainToken; +import com.dl.officialsite.defi.entity.WhaleChainValue; import com.dl.officialsite.defi.entity.WhaleTxRow; import com.dl.officialsite.defi.vo.params.QueryWhaleParams; import java.io.IOException; @@ -17,6 +21,8 @@ import java.util.HashSet; import java.util.List; import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.Predicate; @@ -57,6 +63,10 @@ public class WhaleService { private final BatchRepository batchRepository; + private final WhaleChainValueRepository whaleChainValueRepository; + + private final WhaleChainTokenRepository whaleChainTokenRepository; + private static String aaveUrl = "https://api.thegraph.com/subgraphs/name/messari/aave-v3" + "-ethereum"; @@ -67,10 +77,13 @@ public class WhaleService { private static Set addressSet = new HashSet<>(); public WhaleService(WhaleRepository whaleRepository, WhaleTxRowRepository whaleTxRowRepository, - BatchRepository batchRepository) { + BatchRepository batchRepository, WhaleChainValueRepository whaleChainValueRepository, + WhaleChainTokenRepository whaleChainTokenRepository) { this.whaleRepository = whaleRepository; this.whaleTxRowRepository = whaleTxRowRepository; this.batchRepository = batchRepository; + this.whaleChainValueRepository = whaleChainValueRepository; + this.whaleChainTokenRepository = whaleChainTokenRepository; } @Scheduled(cron = "${jobs.defi.corn: 0 30 * * * * ?}") @@ -311,12 +324,21 @@ private String requestAaveGraph(Integer first, Integer skip) { } //getUserTotalBalance - public void getUserTotalBalance(Whale whale) { + public List getUserTotalBalance(String whaleAddress,Integer update) { + if (update == 0) { + Whale whale = whaleRepository.findByAddress(whaleAddress); + if (!ObjectUtils.isEmpty(whale)) { + List chainValues = whaleChainValueRepository.findByWhaleAddress(whaleAddress); + return chainValues; + } + } + List chainIds = Stream.of("1", "56", "137", "250", "43114", "43113") + .collect(Collectors.toList()); String baseUrl = "https://pro-openapi.debank.com/v1/user/total_balance"; OkHttpClient client = new OkHttpClient(); // 构建URL HttpUrl.Builder urlBuilder = HttpUrl.parse(baseUrl).newBuilder(); - urlBuilder.addQueryParameter("id", whale.getAddress()); // 添加参数 + urlBuilder.addQueryParameter("id", whaleAddress); // 添加参数 String url = urlBuilder.build().toString(); Request request = new Request.Builder() .url(url) @@ -327,16 +349,115 @@ public void getUserTotalBalance(Whale whale) { try { response = client.newCall(request).execute(); } catch (IOException e) { - log.error("请求aave的graph失败"); + log.error("请求debank失败"); throw new RuntimeException(e); }; + //.code 200 String jsonStr = null; try { jsonStr = response.body().string(); } catch (IOException e) { - log.error("解析aave的graph返回失败"); + log.error("解析debank返回失败"); throw new RuntimeException(e); } + Whale whale = whaleRepository.findByAddress(whaleAddress); + JSONObject jsonObject = JSONUtil.parseObj(jsonStr); + String totalUsdValue = jsonObject.getStr("total_usd_value"); + BigDecimal amountUsd = new BigDecimal(totalUsdValue); + whale.setAmountUsd(amountUsd); + whaleRepository.save(whale); + JSONArray chainList = jsonObject.getJSONArray("chain_list"); + List chainValues = new ArrayList<>(); + for (int i = 0; i < chainList.size(); i++) { + JSONObject chainInfo = (JSONObject) chainList.get(i); + String chainId = chainInfo.getStr("community_id"); + String chainName = chainInfo.getStr("name"); + String usdValue = chainInfo.getStr("usd_value"); + if (chainIds.contains(chainId)) { + WhaleChainValue whaleChainValue = new WhaleChainValue(); + whaleChainValue.setWhaleAddress(whaleAddress); + whaleChainValue.setChainId(chainId); + whaleChainValue.setChainName(chainName); + whaleChainValue.setValue(usdValue); + chainValues.add(whaleChainValue); + + } + } + whaleChainValueRepository.saveAll(chainValues); + return chainValues; + } + + //getUserTokenList + public List getUserTokenList(String whaleAddress,Integer update) { + List chainNames = Stream.of("eth", "base", "op", "arb", "matic") + .collect(Collectors.toList()); + if (update == 0) { + Whale whale = whaleRepository.findByAddress(whaleAddress); + if (!ObjectUtils.isEmpty(whale)) { + List chainTokens = whaleChainTokenRepository.findByWhaleAddress(whaleAddress); + return chainTokens; + } + } + String baseUrl = "https://pro-openapi.debank.com/v1/user/all_token_list"; + OkHttpClient client = new OkHttpClient(); + // 构建URL + HttpUrl.Builder urlBuilder = HttpUrl.parse(baseUrl).newBuilder(); + urlBuilder.addQueryParameter("id", whaleAddress); // 添加参数 + String url = urlBuilder.build().toString(); + Request request = new Request.Builder() + .url(url) + .get() + .addHeader("AccessKey", key) + .build(); + Response response = null; + try { + response = client.newCall(request).execute(); + } catch (IOException e) { + log.error("请求debank失败"); + throw new RuntimeException(e); + }; + //.code 200 + String jsonStr = null; + try { + jsonStr = response.body().string(); + } catch (IOException e) { + log.error("解析debank返回失败"); + throw new RuntimeException(e); + } + JSONArray data = JSONUtil.parseArray(jsonStr); + List chainTokens = new ArrayList<>(); + for (int i = 0; i < data.size(); i++) { + JSONObject tokenInfo = (JSONObject) data.get(i); + String chainName = tokenInfo.getStr("chain"); + String tokenAddress = tokenInfo.getStr("id"); + String tokenSymbol = tokenInfo.getStr("symbol"); + String amount = tokenInfo.getStr("amount"); + String price = tokenInfo.getStr("price"); + String decimals = tokenInfo.getStr("decimals"); + if (chainNames.contains(chainName)) { + WhaleChainToken whaleChainToken = new WhaleChainToken(); + whaleChainToken.setWhaleAddress(whaleAddress); + whaleChainToken.setChainName(chainName); + whaleChainToken.setTokenAddress(tokenAddress); + whaleChainToken.setTokenSymbol(tokenSymbol); + whaleChainToken.setAmount(amount); + whaleChainToken.setPrice(price); + whaleChainToken.setDecimals(Integer.parseInt(decimals)); + chainTokens.add(whaleChainToken); + } + } + WhaleChainToken agoWhaleChainToken = whaleChainTokenRepository.findAgoWhaleChainToken(); + for (int i = 0; i < chainTokens.size(); i++) { + WhaleChainToken whaleChainToken = chainTokens.get(i); + if (ObjectUtils.isEmpty(agoWhaleChainToken)) { + whaleChainToken.setId((long) i + 1); + } else { + whaleChainToken.setId((long) i + agoWhaleChainToken.getId() + 1); + } + } + batchRepository.batchInsert(chainTokens); + //whaleChainTokenRepository.saveAll(chainTokens); + return chainTokens; } public Page queryWhale(Pageable pageable, QueryWhaleParams query) {