v5_rest.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. package yu_okx
  2. import (
  3. "crypto/hmac"
  4. "crypto/sha256"
  5. "encoding/json"
  6. yu_base64 "gogs.qqck.cn/s/tools/base64"
  7. yu_curl "gogs.qqck.cn/s/tools/curl"
  8. yu_fast "gogs.qqck.cn/s/tools/fast"
  9. yu_json "gogs.qqck.cn/s/tools/json"
  10. "hash"
  11. "time"
  12. )
  13. type V5Rest struct {
  14. host string
  15. key struct {
  16. APIKey string
  17. SecretKey string
  18. Passphrase string
  19. SecretKey_hash hash.Hash
  20. }
  21. curl *yu_curl.Request
  22. }
  23. func NewV5Rest() (t *V5Rest) {
  24. t = &V5Rest{}
  25. t.host = "https://www.okx.com"
  26. t.curl = yu_curl.NewRequest()
  27. t.curl.SetHeader("Accept-Language", "zh-CN,zh;q=0.9")
  28. return
  29. }
  30. func (t *V5Rest) Close() {
  31. t.curl.Close()
  32. }
  33. // SetProxy 设置代理
  34. //
  35. // @Description:
  36. // @param proxy 格式 ProxyType://user:pass@host:port,ProxyType: http, socks4, socks4a, socks5, socks5h,设置为""以取消代理
  37. func (t *V5Rest) SetProxy(proxy string) *V5Rest {
  38. t.curl.SetProxy(proxy)
  39. return t
  40. }
  41. func (t *V5Rest) SetKey(APIKey string, SecretKey string, Passphrase string) *V5Rest {
  42. t.key.APIKey, t.key.SecretKey, t.key.Passphrase = APIKey, SecretKey, Passphrase
  43. t.key.SecretKey_hash = hmac.New(sha256.New, yu_fast.S2B(t.key.SecretKey))
  44. t.curl.SetHeader("OK-ACCESS-KEY", t.key.APIKey)
  45. t.curl.SetHeader("OK-ACCESS-PASSPHRASE", t.key.Passphrase)
  46. return t
  47. }
  48. func (t *V5Rest) request(method string, path string, post any, resp any) bool {
  49. j_timestamp := time.Now().UTC().Format("2006-01-02T15:04:05.000Z")
  50. t.curl.SetHeader("OK-ACCESS-TIMESTAMP", j_timestamp)
  51. switch method {
  52. case "GET":
  53. t.getAccessSign(j_timestamp, method, path, "")
  54. t.curl.Get(t.host + path)
  55. case "POST":
  56. j_json, j_err := json.Marshal(post)
  57. if j_err != nil {
  58. return false
  59. }
  60. t.getAccessSign(j_timestamp, method, path, yu_fast.B2S(j_json))
  61. t.curl.Post(t.host+path, j_json)
  62. }
  63. if t.curl.RespStatusCode() != 200 {
  64. return false
  65. }
  66. if resp == nil {
  67. return true
  68. }
  69. // Code string `json:"code"`
  70. // Msg string `json:"msg"`
  71. // Data any `json:"data"`
  72. // fmt.Println(t.curl.RespBodyS())
  73. j_data := yu_json.GetBytes(t.curl.RespBody(), "data").String()
  74. if j_data == "" {
  75. return false
  76. }
  77. return json.Unmarshal(yu_fast.S2B(j_data), resp) == nil
  78. }
  79. func (t *V5Rest) getAccessSign(timestamp string, method string, path string, body string) {
  80. if t.key.APIKey == "" || t.key.SecretKey == "" {
  81. t.curl.SetHeader("OK-ACCESS-SIGN", "")
  82. return
  83. }
  84. // OK-ACCESS-SIGN的请求头是对timestamp + method + requestPath + body字符串(+表示字符串连接),以及SecretKey,使用HMAC SHA256方法加密,通过Base-64编码输出而得到的。
  85. //
  86. // 如:sign=CryptoJS.enc.Base64.stringify(CryptoJS.HmacSHA256(timestamp + 'GET' + '/api/v5/account/balance?ccy=BTC', SecretKey))
  87. //
  88. // 其中,timestamp的值与OK-ACCESS-TIMESTAMP请求头相同,为ISO格式,如2020-12-08T09:08:57.715Z。
  89. //
  90. // method是请求方法,字母全部大写:GET/POST。
  91. //
  92. // requestPath是请求接口路径。如:/api/v5/account/balance
  93. //
  94. // body是指请求主体的字符串,如果请求没有主体(通常为GET请求)则body可省略。如:{"instId":"BTC-USDT","lever":"5","mgnMode":"isolated"}
  95. // t.key.SecretKey_hash.Reset()
  96. j_data := timestamp + method + path + body
  97. t.key.SecretKey_hash.Reset()
  98. t.key.SecretKey_hash.Write(yu_fast.S2B(j_data))
  99. t.curl.SetHeader("OK-ACCESS-SIGN", yu_base64.Std.Encode2S(t.key.SecretKey_hash.Sum(nil)))
  100. }