交易所接口
This commit is contained in:
parent
754a8910f2
commit
f5e8a4b990
200
jtt_tool/jtt_client.go
Normal file
200
jtt_tool/jtt_client.go
Normal file
@ -0,0 +1,200 @@
|
||||
package jtt_tool
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto"
|
||||
"crypto/md5"
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"crypto/x509"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"encoding/pem"
|
||||
"fmt"
|
||||
"github.com/pkg/errors"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type JttClient struct {
|
||||
AppId string
|
||||
ApiUrl string
|
||||
PublicKey string
|
||||
PrivateKey string
|
||||
}
|
||||
|
||||
func NewJttClient(appId, apiUrl, publicKey, privateKey string) *JttClient {
|
||||
return &JttClient{
|
||||
AppId: appId,
|
||||
ApiUrl: apiUrl,
|
||||
PublicKey: publicKey,
|
||||
PrivateKey: privateKey,
|
||||
}
|
||||
}
|
||||
|
||||
func (j *JttClient) FindUserForTokenMessage(address string) (res *FindUserForTokenMessageRes, err error) {
|
||||
if address == "" {
|
||||
return nil, fmt.Errorf("address is empty")
|
||||
}
|
||||
fmt.Println("address", address)
|
||||
|
||||
paramMap := make(map[string]any)
|
||||
|
||||
paramMap["appId"] = j.AppId
|
||||
paramMap["timestamp"] = time.Now().Unix()
|
||||
paramMap["publicKey"] = j.PublicKey
|
||||
paramMap["address"] = address
|
||||
|
||||
postRes, err := j.JttPost(paramMap)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = json.Unmarshal(postRes, &res)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("转换FindUserForTokenMessageRes结构体失败: %s", string(postRes))
|
||||
return
|
||||
}
|
||||
|
||||
if res == nil {
|
||||
err = fmt.Errorf("查询交易所数据失败: %w, 地址:%s", err, address)
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
|
||||
}
|
||||
|
||||
type FindUserForTokenMessageRes struct {
|
||||
Data *Data `json:"data"`
|
||||
}
|
||||
|
||||
type Data struct {
|
||||
UserTokenList []*UserToken `json:"userTokenList"`
|
||||
}
|
||||
|
||||
type UserToken struct {
|
||||
Code int `json:"code"`
|
||||
Mes string `json:"mes"`
|
||||
TokenNum float64 `json:"tokenNum"`
|
||||
WalletAddress string `json:"walletAddress"`
|
||||
}
|
||||
|
||||
func (j *JttClient) JttPost(paramMap map[string]any) (res []byte, err error) {
|
||||
|
||||
bodyByte, _ := json.Marshal(paramMap)
|
||||
|
||||
req, err := http.NewRequest(http.MethodPost, j.ApiUrl+"/findUserForTokenMessage", bytes.NewBuffer(bodyByte))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
sign, err := j.ToSign(paramMap)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
paramMap["sign"] = sign
|
||||
|
||||
// 创建 HTTP 客户端
|
||||
client := &http.Client{}
|
||||
|
||||
// 发送请求
|
||||
resp, err := client.Do(req)
|
||||
//log.Printf("WPSPost resp: %+v\n", resp)
|
||||
if err != nil {
|
||||
log.Printf("发送请求失败: %+v\n", err)
|
||||
return
|
||||
}
|
||||
defer func(Body io.ReadCloser) {
|
||||
_ = Body.Close()
|
||||
}(resp.Body)
|
||||
|
||||
// 读取响应体
|
||||
res, err = io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Printf("res: %s\n", string(res))
|
||||
|
||||
if !json.Valid(res) {
|
||||
return nil, errors.New("响应体不是有效的JSON格式")
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (s *JttClient) ToSign(reqData map[string]interface{}) (sign []byte, errs error) {
|
||||
sortedStr, err := s.GetSortedStr(reqData)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
privateKeyStr := "-----BEGIN PRIVATE KEY-----\r\n" + s.PrivateKey + "\r\n-----END PRIVATE KEY-----"
|
||||
sign, err = s.Sign(sortedStr, privateKeyStr)
|
||||
return
|
||||
}
|
||||
|
||||
func (s *JttClient) Sign(signData string, privateKeyStr string) (sign []byte, errs error) {
|
||||
hashedMessage := md5.Sum([]byte(signData))
|
||||
if privateKeyStr == "" {
|
||||
return nil, errors.New("private key is empty")
|
||||
}
|
||||
|
||||
block, _ := pem.Decode([]byte(privateKeyStr))
|
||||
privateKey, err := x509.ParsePKCS8PrivateKey(block.Bytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
sign, err = rsa.SignPKCS1v15(rand.Reader, privateKey.(*rsa.PrivateKey), crypto.MD5, hashedMessage[:])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
sign = []byte(base64.StdEncoding.EncodeToString(sign))
|
||||
return
|
||||
}
|
||||
|
||||
func (s *JttClient) GetSortedStr(data any) (str string, err error) {
|
||||
tmp := map[string]interface{}{}
|
||||
if reflect.ValueOf(data).Kind() == reflect.Struct {
|
||||
jsStr, _ := json.Marshal(data)
|
||||
_ = json.Unmarshal(jsStr, &tmp)
|
||||
} else {
|
||||
ok := false
|
||||
tmp, ok = data.(map[string]interface{})
|
||||
if !ok {
|
||||
err = errors.New("data type error")
|
||||
}
|
||||
}
|
||||
|
||||
keys := []string{}
|
||||
for key := range tmp {
|
||||
keys = append(keys, key)
|
||||
}
|
||||
|
||||
sort.Strings(keys)
|
||||
sortedParams := []string{}
|
||||
|
||||
for _, key := range keys {
|
||||
value := tmp[key]
|
||||
if key == "sign" {
|
||||
continue
|
||||
}
|
||||
|
||||
switch v := value.(type) {
|
||||
case int, uint, int16, int32, int64:
|
||||
sortedParams = append(sortedParams, fmt.Sprintf("%s=%d", key, v))
|
||||
case float64, float32:
|
||||
sortedParams = append(sortedParams, fmt.Sprintf("%s=%f", key, v))
|
||||
default:
|
||||
sortedParams = append(sortedParams, key+"="+value.(string))
|
||||
}
|
||||
}
|
||||
str = strings.Join(sortedParams, "&")
|
||||
return
|
||||
}
|
1
jtt_tool/jtt_client_test.go
Normal file
1
jtt_tool/jtt_client_test.go
Normal file
@ -0,0 +1 @@
|
||||
package jtt_tool
|
Loading…
x
Reference in New Issue
Block a user