|
|
@@ -0,0 +1,197 @@
|
|
|
+package com.crm.manager.service.impl;
|
|
|
+
|
|
|
+import com.alibaba.fastjson2.JSON;
|
|
|
+import com.crm.manager.service.SysConfigService;
|
|
|
+import com.crm.manager.service.SysVaultodyConfigService;
|
|
|
+import com.crm.manager.service.VaultodyService;
|
|
|
+import com.crm.rely.backend.core.constant.Constants;
|
|
|
+import com.crm.rely.backend.core.dto.base.BaseResultDto;
|
|
|
+import com.crm.rely.backend.core.exception.ServiceException;
|
|
|
+import com.crm.rely.backend.core.pojo.table.SysConfigTable;
|
|
|
+import com.crm.rely.backend.model.config.VaultodyConfig;
|
|
|
+import com.crm.rely.backend.model.constant.ConfigConstants;
|
|
|
+import com.crm.rely.backend.model.dto.vaultody.vaults.VaultodyVaultsListDto;
|
|
|
+import com.crm.rely.backend.model.dto.vaultody.vaults.response.VaultsListResponseDto;
|
|
|
+import com.crm.rely.backend.model.pojo.table.SysVaultodyConfigTable;
|
|
|
+import com.crm.rely.backend.util.AESUtil;
|
|
|
+import com.crm.rely.backend.util.HttpUtil;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.jsoup.Connection;
|
|
|
+import org.springframework.beans.BeanUtils;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+
|
|
|
+import javax.crypto.Mac;
|
|
|
+import javax.crypto.spec.SecretKeySpec;
|
|
|
+import java.io.IOException;
|
|
|
+import java.nio.charset.StandardCharsets;
|
|
|
+import java.util.*;
|
|
|
+
|
|
|
+@Slf4j
|
|
|
+@Service
|
|
|
+public class VaultodyServiceImpl implements VaultodyService {
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private SysVaultodyConfigService vaultodyConfigService;
|
|
|
+ @Autowired
|
|
|
+ private SysConfigService sysConfigService;
|
|
|
+
|
|
|
+ public static String getSignature(String message, String apiSecret) {
|
|
|
+ try {
|
|
|
+ byte[] decodedSecret = Base64.getDecoder().decode(apiSecret);
|
|
|
+ Mac mac = Mac.getInstance("HmacSHA256");
|
|
|
+ SecretKeySpec secretKeySpec = new SecretKeySpec(decodedSecret, "HmacSHA256");
|
|
|
+ mac.init(secretKeySpec);
|
|
|
+ byte[] hash = mac.doFinal(message.getBytes(StandardCharsets.UTF_8));
|
|
|
+
|
|
|
+ return Base64.getEncoder().encodeToString(hash);
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static void main(String[] args) {
|
|
|
+ String s = "{\n" +
|
|
|
+ " \"apiKey\": \"6f3cc6caf513a5cde2df5d3ed805e3703d4d43b2\",\n" +
|
|
|
+ " \"apiSecret\": \"MLjTUAYgxSM2dg==\",\n" +
|
|
|
+ " \"passphrase\": \"7UGMi2*t0h\",\n" +
|
|
|
+ " \"vaultId\": \"\",\n" +
|
|
|
+ " \"baseUrl\": \"https://rest.vaultody.com\",\n" +
|
|
|
+ " \"vaultsListUrl\": \"/vaults/test\",\n" +
|
|
|
+ " \"network\": \"\",\n" +
|
|
|
+ " \"vaultsTransactionsPathTemplate\": \"/vaults/%s/transactions\",\n" +
|
|
|
+ " \"webhooksPassphrase\": \"\"\n" +
|
|
|
+ "}";
|
|
|
+ System.out.println(AESUtil.encrypt(s, "bfa5559109f94c78af615bcf00d52060"));
|
|
|
+ System.out.println(AESUtil.decrypt(AESUtil.encrypt(s, "bfa5559109f94c78af615bcf00d52060"), "bfa5559109f94c78af615bcf00d52060"));
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Coin
|
|
|
+ */
|
|
|
+ public static void main1(String[] args) {
|
|
|
+ try {
|
|
|
+ List<VaultodyVaultsListDto> dtos = new ArrayList<>();
|
|
|
+ // ------------------ 配置 ------------------
|
|
|
+ String apiKey = "6f3cc6caf513a5cde2df5d3ed805e3703d4d43b2";
|
|
|
+ String apiSecret = "MLjTUAYgxSM2dg=="; // Base64编码的secret
|
|
|
+ String passphrase = "7UGMi2*t0h";
|
|
|
+ String method = "GET";
|
|
|
+ String requestPath = "/vaults/test";
|
|
|
+ String baseUrl = "https://rest.vaultody.com";
|
|
|
+
|
|
|
+ String query = "{}"; // POST 时 query 通常为空,否则按接口要求填写
|
|
|
+ String body = "{}"; // POST 时 query 通常为空,否则按接口要求填写
|
|
|
+
|
|
|
+ // ------------------ 时间戳(秒) ------------------
|
|
|
+ String timestamp = String.valueOf(System.currentTimeMillis() / 1000);
|
|
|
+
|
|
|
+ // ------------------ 构建消息用于签名 ------------------
|
|
|
+ String message = timestamp + method + requestPath + body + query;
|
|
|
+ System.out.println("Message: " + message);
|
|
|
+
|
|
|
+ String signature = getSignature(message, apiSecret);
|
|
|
+ System.out.println("Signature: " + signature);
|
|
|
+ Map<String, String> headers = new HashMap<>();
|
|
|
+ headers.put("x-api-key", apiKey);
|
|
|
+ headers.put("x-api-sign", signature);
|
|
|
+ headers.put("x-api-timestamp", timestamp);
|
|
|
+ headers.put("x-api-passphrase", passphrase);
|
|
|
+ headers.put("Content-Type", "application/json");
|
|
|
+
|
|
|
+ try {
|
|
|
+ Connection.Response response = HttpUtil.get(baseUrl + requestPath, headers);
|
|
|
+ if (response.statusCode() != 200){
|
|
|
+ System.out.println("Error: " + response.statusMessage());
|
|
|
+ }
|
|
|
+ VaultsListResponseDto responseDto = JSON.parseObject(response.body(), VaultsListResponseDto.class);
|
|
|
+ List<VaultsListResponseDto.Item> items = responseDto.getData().getItems();
|
|
|
+ for (VaultsListResponseDto.Item item : items){
|
|
|
+ VaultodyVaultsListDto dto = new VaultodyVaultsListDto();
|
|
|
+ BeanUtils.copyProperties(item, dto);
|
|
|
+ dtos.add(dto);
|
|
|
+ }
|
|
|
+ System.out.println(JSON.toJSONString(dtos));
|
|
|
+ } catch (IOException e) {
|
|
|
+ throw new RuntimeException(e);
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 交易记录接口拼接url
|
|
|
+ */
|
|
|
+ public String getPath(String pathTemplate, String vaultId) {
|
|
|
+// String pathTemplate = "/vaults/%s/transactions";
|
|
|
+ String actualPath = String.format(pathTemplate, vaultId);
|
|
|
+ return actualPath;
|
|
|
+ }
|
|
|
+
|
|
|
+ public VaultodyConfig getVaultodyConfig() {
|
|
|
+ SysVaultodyConfigTable configTable = vaultodyConfigService.getByCode(ConfigConstants.VAULTODY_MANAGER_CONFIG);
|
|
|
+ if (configTable == null) {
|
|
|
+ throw ServiceException.exception(Constants.SYSTEM_ERROR);
|
|
|
+ }
|
|
|
+ String aesKey = getPropertyKey();
|
|
|
+
|
|
|
+ String property = AESUtil.decrypt(configTable.getValue(), aesKey);
|
|
|
+ VaultodyConfig vaultodyConfig = JSON.parseObject(property, VaultodyConfig.class);
|
|
|
+ return vaultodyConfig;
|
|
|
+ }
|
|
|
+
|
|
|
+ private String getPropertyKey() throws ServiceException {
|
|
|
+ SysConfigTable table = sysConfigService.getByCode(ConfigConstants.FINANCE_PROPERTY_KEY);
|
|
|
+ if (table == null) {
|
|
|
+ throw ServiceException.exception(Constants.SYSTEM_ERROR);
|
|
|
+ }
|
|
|
+ return table.getValue();
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public BaseResultDto vaultsList() throws Exception {
|
|
|
+ List<VaultodyVaultsListDto> dtos = new ArrayList<>();
|
|
|
+ VaultodyConfig config = getVaultodyConfig();
|
|
|
+
|
|
|
+ String apiKey = config.getApiKey();
|
|
|
+ String apiSecret = config.getApiSecret();
|
|
|
+ String passphrase = config.getPassphrase();
|
|
|
+ String method = "GET";
|
|
|
+ String requestPath = config.getVaultsListUrl();
|
|
|
+ String baseUrl = config.getBaseUrl();
|
|
|
+
|
|
|
+ String query = "{}"; // POST 时 query 通常为空,否则按接口要求填写
|
|
|
+ String body = "{}";
|
|
|
+
|
|
|
+ // ------------------ 时间戳(秒) ------------------
|
|
|
+ String timestamp = String.valueOf(System.currentTimeMillis() / 1000);
|
|
|
+
|
|
|
+ // ------------------ 构建消息用于签名 ------------------
|
|
|
+ String message = timestamp + method + requestPath + body + query;
|
|
|
+
|
|
|
+ String signature = getSignature(message, apiSecret);
|
|
|
+ System.out.println("Signature: " + signature);
|
|
|
+ Map<String, String> headers = new HashMap<>();
|
|
|
+ headers.put("x-api-key", apiKey);
|
|
|
+ headers.put("x-api-sign", signature);
|
|
|
+ headers.put("x-api-timestamp", timestamp);
|
|
|
+ headers.put("x-api-passphrase", passphrase);
|
|
|
+ headers.put("Content-Type", "application/json");
|
|
|
+
|
|
|
+ Connection.Response response = HttpUtil.get(baseUrl + requestPath, headers);
|
|
|
+ if (response.statusCode() != 200){
|
|
|
+ return BaseResultDto.error(response.statusMessage());
|
|
|
+ }
|
|
|
+ VaultsListResponseDto responseDto = JSON.parseObject(response.body(), VaultsListResponseDto.class);
|
|
|
+ List<VaultsListResponseDto.Item> items = responseDto.getData().getItems();
|
|
|
+ for (VaultsListResponseDto.Item item : items){
|
|
|
+ VaultodyVaultsListDto dto = new VaultodyVaultsListDto();
|
|
|
+ BeanUtils.copyProperties(item, dto);
|
|
|
+ dtos.add(dto);
|
|
|
+ }
|
|
|
+ return BaseResultDto.success(dtos);
|
|
|
+ }
|
|
|
+}
|