Administrator
2025-12-10 8925858fb424100acd761178bfbe30c3cbb21c2b
feat(okx): 添加OKX WebSocket认证和签名工具

- 新增ExchangeInfoEnum枚举类,用于管理OKX账户的API密钥信息
- 实现SignUtils工具类,支持REST和WebSocket的HmacSHA256签名
- 更新LoginWs类引用路径,使用新的枚举和工具类
- 修改OkxQuantWebSocketClient,使用ExchangeInfoEnum判断账户类型切换URL
- 移除旧的INTERNET布尔变量配置
- 调整包结构路径引用,统一到okxWs模块下
2 files modified
2 files added
119 ■■■■■ changed files
src/main/java/com/xcong/excoin/modules/okxNewPrice/OkxQuantWebSocketClient.java 4 ●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/okxNewPrice/okxWs/LoginWs.java 4 ●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/okxNewPrice/okxWs/enums/ExchangeInfoEnum.java 56 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/okxNewPrice/utils/SignUtils.java 55 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/okxNewPrice/OkxQuantWebSocketClient.java
@@ -7,6 +7,7 @@
import com.xcong.excoin.modules.okxNewPrice.celue.CaoZuoService;
import com.xcong.excoin.modules.okxNewPrice.okxWs.*;
import com.xcong.excoin.modules.okxNewPrice.okxWs.enums.CoinEnums;
import com.xcong.excoin.modules.okxNewPrice.okxWs.enums.ExchangeInfoEnum;
import com.xcong.excoin.modules.okxNewPrice.okxWs.enums.OrderParamEnums;
import com.xcong.excoin.modules.okxNewPrice.utils.SSLConfig;
import com.xcong.excoin.modules.okxNewPrice.wangge.WangGeService;
@@ -50,7 +51,6 @@
    private static final String WS_URL_MONIPAN = "wss://wspap.okx.com:8443/ws/v5/private";
    private static final String WS_URL_SHIPAN = "wss://ws.okx.com:8443/ws/v5/private";
    private static final boolean INTERNET = false;
    /**
     * 订阅频道指令
@@ -123,7 +123,7 @@
            SSLConfig.configureSSL();
            System.setProperty("https.protocols", "TLSv1.2,TLSv1.3");
            String WS_URL = WS_URL_MONIPAN;
            if (INTERNET){
            if (ExchangeInfoEnum.OKX_UAT.isAccountType()){
                WS_URL = WS_URL_SHIPAN;
            }
            URI uri = new URI(WS_URL);
src/main/java/com/xcong/excoin/modules/okxNewPrice/okxWs/LoginWs.java
@@ -2,8 +2,8 @@
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xcong.excoin.modules.okxNewPrice.okxpi.config.ExchangeInfoEnum;
import com.xcong.excoin.modules.okxNewPrice.okxpi.config.utils.SignUtils;
import com.xcong.excoin.modules.okxNewPrice.okxWs.enums.ExchangeInfoEnum;
import com.xcong.excoin.modules.okxNewPrice.utils.SignUtils;
import com.xcong.excoin.modules.okxNewPrice.utils.WsParamBuild;
import lombok.extern.slf4j.Slf4j;
import org.java_websocket.client.WebSocketClient;
src/main/java/com/xcong/excoin/modules/okxNewPrice/okxWs/enums/ExchangeInfoEnum.java
New file
@@ -0,0 +1,56 @@
package com.xcong.excoin.modules.okxNewPrice.okxWs.enums;
import lombok.Getter;
/**
 * 交易信息枚举类
 * 用于存储不同交易账户的密钥信息,包括实盘账户和模拟账户
 */
@Getter
public enum ExchangeInfoEnum {
    /**
     * 模拟盘账户信息
     * 存储了模拟盘交易所需的API密钥、秘钥和通过码
     */
    OKX_UAT("7a023eb2-06c0-4255-9969-b86ea1cef0d7",
            "D0106A4D63BD22BEAB9CBA8F41219661",
            "Aa12345678@",
            false);
//    /**
//     * 模拟盘账户信息
//     * 存储了模拟盘交易所需的API密钥、秘钥和通过码
//     */
//    OKX_UAT("0769b50c-2c36-4310-8bd9-cad6bc6c9d8f",
//            "7AF4A574BC44907CE76BBFF91F53852D",
//            "Aa123456@",
//            false);
    // API公钥,用于识别用户身份
    private String apiKey;
    // API秘钥,用于签名和验证请求
    private String secretKey;
    // API通过码,用于额外的身份验证
    private String passphrase;
    // 账户类型,true表示实盘账户,false表示模拟账户
    private boolean accountType;
    /**
     * 构造方法
     *
     * @param apiKey API公钥,用于识别用户身份
     * @param secretKey API秘钥,用于签名和验证请求
     * @param passphrase API通过码,用于额外的身份验证
     * @param accountType 账户类型,true表示实盘账户,false表示模拟账户
     */
    ExchangeInfoEnum(String apiKey, String secretKey, String passphrase, boolean accountType) {
        this.apiKey = apiKey;
        this.secretKey = secretKey;
        this.passphrase = passphrase;
        this.accountType = accountType;
    }
}
src/main/java/com/xcong/excoin/modules/okxNewPrice/utils/SignUtils.java
New file
@@ -0,0 +1,55 @@
package com.xcong.excoin.modules.okxNewPrice.utils;
import lombok.extern.slf4j.Slf4j;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;
@Slf4j
public class SignUtils {
    public static String signRest(String secretKey, String timestamp, String method, String path, String body) {
        String str = String.format("%s%s%s%s",
                timestamp, // timestamp
                method,  // method GET/POST
                path, // requestPath
                body // body
        );
        try {
            return Base64.getEncoder().encodeToString(hmacSHA256(secretKey.getBytes(), str.getBytes()));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    /**
     * HmacSHA256算法,返回的结果始终是32位
     *
     * @param key     加密的键,可以是任何数据
     * @param content 待加密的内容
     * @return 加密后的内容
     * @throws Exception ex
     */
    public static byte[] hmacSHA256(byte[] key, byte[] content) throws Exception {
        Mac hmacSha256 = Mac.getInstance("HmacSHA256");
        hmacSha256.init(new SecretKeySpec(key, 0, key.length, "HmacSHA256"));
        return hmacSha256.doFinal(content);
    }
    public static String signWebsocket(String timestamp, String secretKey) {
        String str = String.format("%s%s%s",
                timestamp,
                "GET",
                "/users/self/verify");
        try {
            return Base64.getEncoder().encodeToString(hmacSHA256(secretKey.getBytes(), str.getBytes()));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}