package bybit import ( "bytes" "context" "encoding/json" "fmt" "io" "net/http" "net/url" ) type response struct { RetCode int `json:"retCode"` RetMsg string `json:"retMsg"` Result json.RawMessage `json:"result"` Time int64 `json:"time"` RetExtInfo json.RawMessage `json:"retExtInfo"` } func (b *Bybit) makeRequest(ctx context.Context, method string, endpoint string, params any, v any) error { // send request var ( body []byte err error ) switch method { case http.MethodGet: body, err = b.getRequest(ctx, endpoint, params) case http.MethodPost: body, err = b.postRequest(ctx, endpoint, params) default: return fmt.Errorf("method not correct") } if err != nil { return fmt.Errorf("failed to make request: %w", err) } b.log.Debug("bybit request", "endpoint", endpoint, "params", params, "body", string(body)) var resp response if err := json.Unmarshal(body, &resp); err != nil { return fmt.Errorf("failed to parse response: %w", err) } if resp.RetCode != 0 { return fmt.Errorf("response not ok: code: %d, msg: %s, info: %s, result: %s", resp.RetCode, resp.RetMsg, resp.RetExtInfo, resp.Result) } if v == nil { return nil } if err := json.Unmarshal(resp.Result, v); err != nil { return fmt.Errorf("failed to parse result: %w", err) } return nil } func (b *Bybit) getRequest(ctx context.Context, endPoint string, params any) ([]byte, error) { // params to query queryString := "" if params != nil { b, err := json.Marshal(params) if err != nil { return nil, err } var q map[string]any if err := json.Unmarshal(b, &q); err != nil { return nil, err } query := make(url.Values) for k, v := range q { query.Add(k, fmt.Sprint(v)) } queryString = query.Encode() } // make request request, err := http.NewRequest("GET", b.cfg.BaseURL+endPoint+"?"+queryString, nil) if err != nil { return nil, fmt.Errorf("failed to make request: %w", err) } request = request.WithContext(ctx) request.Header.Set("Content-Type", "application/json") // b.setRequestAPIHeaders(request, []byte(queryString)) // get response response, err := b.client.Do(request) if err != nil { return nil, fmt.Errorf("failed to make request: %w", err) } defer response.Body.Close() body, err := io.ReadAll(response.Body) if err != nil { return nil, fmt.Errorf("failed to read response: %w", err) } return body, nil } func (b *Bybit) postRequest(ctx context.Context, endPoint string, params any) ([]byte, error) { // params to json jsonData, err := json.Marshal(params) if err != nil { return nil, fmt.Errorf("failed to marshal params: %w", err) } // make request request, err := http.NewRequest("POST", b.cfg.BaseURL+endPoint, bytes.NewBuffer(jsonData)) if err != nil { return nil, fmt.Errorf("failed to make request: %w", err) } request = request.WithContext(ctx) request.Header.Set("Content-Type", "application/json") // b.setRequestAPIHeaders(request, jsonData) // get response response, err := b.client.Do(request) if err != nil { return nil, fmt.Errorf("failed to make request: %w", err) } defer response.Body.Close() body, err := io.ReadAll(response.Body) if err != nil { return nil, fmt.Errorf("failed to read response: %w", err) } return body, nil }