package yu_okx import ( "crypto/hmac" "crypto/sha256" "encoding/json" yu_base64 "gogs.qqck.cn/s/tools/base64" yu_curl "gogs.qqck.cn/s/tools/curl" yu_fast "gogs.qqck.cn/s/tools/fast" yu_json "gogs.qqck.cn/s/tools/json" "hash" "time" ) type V5Rest struct { host string key struct { APIKey string SecretKey string Passphrase string SecretKey_hash hash.Hash } curl *yu_curl.Request } func NewV5Rest() (t *V5Rest) { t = &V5Rest{} t.host = "https://www.okx.com" t.curl = yu_curl.NewRequest() t.curl.SetHeader("Accept-Language", "zh-CN,zh;q=0.9") return } func (t *V5Rest) Close() { t.curl.Close() } // SetProxy 设置代理 // // @Description: // @param proxy 格式 ProxyType://user:pass@host:port,ProxyType: http, socks4, socks4a, socks5, socks5h,设置为""以取消代理 func (t *V5Rest) SetProxy(proxy string) *V5Rest { t.curl.SetProxy(proxy) return t } func (t *V5Rest) SetKey(APIKey string, SecretKey string, Passphrase string) *V5Rest { t.key.APIKey, t.key.SecretKey, t.key.Passphrase = APIKey, SecretKey, Passphrase t.key.SecretKey_hash = hmac.New(sha256.New, yu_fast.S2B(t.key.SecretKey)) t.curl.SetHeader("OK-ACCESS-KEY", t.key.APIKey) t.curl.SetHeader("OK-ACCESS-PASSPHRASE", t.key.Passphrase) return t } func (t *V5Rest) request(method string, path string, post any, resp any) bool { j_timestamp := time.Now().UTC().Format("2006-01-02T15:04:05.000Z") t.curl.SetHeader("OK-ACCESS-TIMESTAMP", j_timestamp) switch method { case "GET": t.getAccessSign(j_timestamp, method, path, "") t.curl.Get(t.host + path) case "POST": j_json, j_err := json.Marshal(post) if j_err != nil { return false } t.getAccessSign(j_timestamp, method, path, yu_fast.B2S(j_json)) t.curl.Post(t.host+path, j_json) } if t.curl.RespStatusCode() != 200 { return false } if resp == nil { return true } // Code string `json:"code"` // Msg string `json:"msg"` // Data any `json:"data"` // fmt.Println(t.curl.RespBodyS()) j_data := yu_json.GetBytes(t.curl.RespBody(), "data").String() if j_data == "" { return false } return json.Unmarshal(yu_fast.S2B(j_data), resp) == nil } func (t *V5Rest) getAccessSign(timestamp string, method string, path string, body string) { if t.key.APIKey == "" || t.key.SecretKey == "" { t.curl.SetHeader("OK-ACCESS-SIGN", "") return } // OK-ACCESS-SIGN的请求头是对timestamp + method + requestPath + body字符串(+表示字符串连接),以及SecretKey,使用HMAC SHA256方法加密,通过Base-64编码输出而得到的。 // // 如:sign=CryptoJS.enc.Base64.stringify(CryptoJS.HmacSHA256(timestamp + 'GET' + '/api/v5/account/balance?ccy=BTC', SecretKey)) // // 其中,timestamp的值与OK-ACCESS-TIMESTAMP请求头相同,为ISO格式,如2020-12-08T09:08:57.715Z。 // // method是请求方法,字母全部大写:GET/POST。 // // requestPath是请求接口路径。如:/api/v5/account/balance // // body是指请求主体的字符串,如果请求没有主体(通常为GET请求)则body可省略。如:{"instId":"BTC-USDT","lever":"5","mgnMode":"isolated"} // t.key.SecretKey_hash.Reset() j_data := timestamp + method + path + body t.key.SecretKey_hash.Reset() t.key.SecretKey_hash.Write(yu_fast.S2B(j_data)) t.curl.SetHeader("OK-ACCESS-SIGN", yu_base64.Std.Encode2S(t.key.SecretKey_hash.Sum(nil))) }