mirror of
https://github.com/d0zingcat/gocryptotrader.git
synced 2026-05-14 07:26:47 +00:00
* codebase: Rid base64/hex to string common funcs * codebase: Rid local scope variable usage and other improvements * codebase: Refactor currency pair usage across multiple exchanges - Updated HitBTC tests to use the new currency pair format. - Modified Kraken futures types to use currency.Pair instead of string for Symbol. - Adjusted Kraken wrapper methods to handle currency pairs correctly. - Refined OKX tests and types to utilize currency.Pair for instrument IDs. - Enhanced Poloniex tests to consistently use predefined currency pairs. - Streamlined order and orderbook tests to replace string pairs with currency.NewBTCUSD(). - Improved Yobit tests to utilize a standardized currency pair format. - Updated validator wrapper to use currency pairs directly instead of string conversions. * codebase: Use types.Number where possible * refactor: update PayoutFee type to types.Number for consistency * Refactor: Remove crypto functions to use standard library and other minor changes - Removed custom crypto functions for SHA256, SHA512, and MD5 from the common/crypto package. - Replaced usages of removed functions with standard library implementations in various files including: - cmd/websocket_client/main.go - engine/apiserver.go - exchanges/kraken/kraken.go - exchanges/lbank/lbank.go - exchanges/okx/okx_business_websocket.go - exchanges/kucoin/kucoin_websocket.go - gctscript/vm/vm.go - Updated tests to reflect changes in the crypto functions. - Renamed several functions for clarity, particularly in the context of order book updates across multiple exchanges. * refactor: replace assert with require for consistency in test assertions * refactor: Improve Binance futures candlestick test, standardise orderbook update function names and improve test parallelism * refactor: Replace require.Len with require.Equal for better output in TestGetFuturesKlineData
201 lines
4.5 KiB
Go
201 lines
4.5 KiB
Go
package main
|
|
|
|
import (
|
|
"crypto/sha256"
|
|
"encoding/hex"
|
|
"errors"
|
|
"fmt"
|
|
"log"
|
|
"net"
|
|
"net/http"
|
|
"strconv"
|
|
|
|
gws "github.com/gorilla/websocket"
|
|
"github.com/thrasher-corp/gocryptotrader/common"
|
|
"github.com/thrasher-corp/gocryptotrader/config"
|
|
"github.com/thrasher-corp/gocryptotrader/encoding/json"
|
|
"github.com/thrasher-corp/gocryptotrader/exchanges/asset"
|
|
)
|
|
|
|
// Vars for the websocket client
|
|
var (
|
|
WSConn *gws.Conn
|
|
)
|
|
|
|
// WebsocketEvent is the struct used for websocket events
|
|
type WebsocketEvent struct {
|
|
Exchange string `json:"exchange,omitempty"`
|
|
AssetType string `json:"assetType,omitempty"`
|
|
Event string
|
|
Data any
|
|
}
|
|
|
|
// WebsocketAuth is the struct used for a websocket auth request
|
|
type WebsocketAuth struct {
|
|
Username string `json:"username"`
|
|
Password string `json:"password"`
|
|
}
|
|
|
|
// WebsocketEventResponse is the struct used for websocket event responses
|
|
type WebsocketEventResponse struct {
|
|
Event string `json:"event"`
|
|
Data any `json:"data"`
|
|
Error string `json:"error"`
|
|
}
|
|
|
|
// WebsocketOrderbookTickerRequest is a struct used for ticker and orderbook
|
|
// requests
|
|
type WebsocketOrderbookTickerRequest struct {
|
|
Exchange string `json:"exchangeName"`
|
|
Currency string `json:"currency"`
|
|
AssetType asset.Item `json:"assetType"`
|
|
}
|
|
|
|
// SendWebsocketEvent sends a websocket event message
|
|
func SendWebsocketEvent(event string, reqData any, result *WebsocketEventResponse) error {
|
|
req := WebsocketEvent{
|
|
Event: event,
|
|
}
|
|
|
|
if reqData != nil {
|
|
req.Data = reqData
|
|
}
|
|
|
|
err := WSConn.WriteJSON(req)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
err = WSConn.ReadJSON(&result)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if result.Error != "" {
|
|
return errors.New(result.Error)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func main() {
|
|
cfg := config.GetConfig()
|
|
err := cfg.LoadConfig(config.File, true)
|
|
if err != nil {
|
|
log.Fatalf("Failed to load config file: %s", err)
|
|
}
|
|
|
|
listenAddr := cfg.RemoteControl.WebsocketRPC.ListenAddress
|
|
wsHost := fmt.Sprintf("ws://%s/ws", net.JoinHostPort(common.ExtractHostOrDefault(listenAddr),
|
|
strconv.Itoa(common.ExtractPortOrDefault(listenAddr))))
|
|
log.Printf("Connecting to websocket host: %s", wsHost)
|
|
|
|
var dialer gws.Dialer
|
|
var resp *http.Response
|
|
WSConn, resp, err = dialer.Dial(wsHost, http.Header{})
|
|
if err != nil {
|
|
log.Println("Unable to connect to websocket server")
|
|
return
|
|
}
|
|
resp.Body.Close()
|
|
log.Println("Connected to websocket!")
|
|
|
|
log.Println("Authenticating..")
|
|
shasum := sha256.Sum256([]byte(cfg.RemoteControl.Password))
|
|
reqData := WebsocketAuth{
|
|
Username: cfg.RemoteControl.Username,
|
|
Password: hex.EncodeToString(shasum[:]),
|
|
}
|
|
var wsResp WebsocketEventResponse
|
|
err = SendWebsocketEvent("auth", reqData, &wsResp)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
log.Println("Authenticated successfully")
|
|
|
|
log.Println("Getting config..")
|
|
err = SendWebsocketEvent("GetConfig", nil, &wsResp)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
log.Printf("Fetched config.")
|
|
|
|
dataJSON, err := json.Marshal(&wsResp.Data)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
var resultCfg config.Config
|
|
err = json.Unmarshal(dataJSON, &resultCfg)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
log.Println("Saving config..")
|
|
origBotName := resultCfg.Name
|
|
resultCfg.Name = "TEST"
|
|
err = SendWebsocketEvent("SaveConfig", resultCfg, &wsResp)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
log.Println("Saved config!")
|
|
resultCfg.Name = origBotName
|
|
err = SendWebsocketEvent("SaveConfig", resultCfg, &wsResp)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
log.Println("Saved config (restored original bot name)!")
|
|
|
|
log.Println("Getting account info..")
|
|
err = SendWebsocketEvent("GetAccountInfo", nil, &wsResp)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
log.Println("Got account info!")
|
|
|
|
log.Println("Getting tickers..")
|
|
err = SendWebsocketEvent("GetTickers", nil, &wsResp)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
log.Println("Got tickers!")
|
|
|
|
log.Println("Getting specific ticker..")
|
|
dataReq := WebsocketOrderbookTickerRequest{
|
|
Exchange: "Bitfinex",
|
|
Currency: "BTCUSD",
|
|
AssetType: asset.Spot,
|
|
}
|
|
|
|
err = SendWebsocketEvent("GetTicker", dataReq, &wsResp)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
log.Println("Got ticker!")
|
|
|
|
log.Println("Getting orderbooks..")
|
|
err = SendWebsocketEvent("GetOrderbooks", nil, &wsResp)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
log.Println("Got orderbooks!")
|
|
|
|
log.Println("Getting specific orderbook..")
|
|
err = SendWebsocketEvent("GetOrderbook", dataReq, &wsResp)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
log.Println("Got orderbook!")
|
|
|
|
for {
|
|
var wsEvent WebsocketEvent
|
|
err = WSConn.ReadJSON(&wsEvent)
|
|
if err != nil {
|
|
break
|
|
}
|
|
|
|
log.Printf("Recv'd: %s", wsEvent.Event)
|
|
}
|
|
WSConn.Close()
|
|
}
|