A production-ready Go SDK for interacting with the MEXC REST and WebSocket APIs, built specifically for low-latency applications, 24/7 bots, and high-load systems.
The library is under active development. We welcome contributions and Pull Requests.
| API | Coverage | Status |
|---|---|---|
| WebSocket API | Full Coverage (100%): Spot (spot_v3) and Futures (contract_v1). |
✅ Ready |
| REST API | Partial coverage of public and private methods (e.g., Futures trading and specific private account history are pending). | 🟡 In Development |
| Feature | User Benefit |
|---|---|
| Unified Transport Abstraction (DI) | Full control over the network stack for REST and WebSocket. Simplifies testing, allows injecting mocks, custom proxies, and HFT/low-latency optimized clients. |
Financial Precision (decimal) |
decimal.Decimal is used for all price and quantity data throughout the SDK. This eliminates rounding errors and ensures the safety of trading strategies. |
| Typed Error Model | The use of typed errors allows for writing clean retry/backoff logic using Go's standard errors.Is/errors.As mechanism, reacting precisely to the error type (e.g., Auth, Validation, Rate Limit). |
| WS: Promises & Handles | The asynchronous request/response matching logic is abstracted using a Promise pattern. Subscribe() is synchronous from the user's perspective, and the subscription is managed as an object (SubscriptionHandle). |
| WS: Low-Latency Monitoring | Built-in PING/PONG RTT monitoring allows the bot to react to network degradation. |
| Thread-Safety | All operations and internal data structures are protected, ensuring correct concurrent execution across multiple goroutines. |
go get github.com/IvanTurko/mexc-sdk-goImportant: All examples use context with a timeout to follow Go best practices. Example #2 shows the robust, production-ready error handling required for reliable applications, while Example #1 is focused purely on quick setup.
Demonstrating API Key usage and the Fluent Interface (Quick Start).
package main
import (
"context"
"fmt"
"time"
"github.com/IvanTurko/mexc-sdk-go/spot/rest"
"github.com/shopspring/decimal"
)
func main() {
const timeout = 5 * time.Second
ctx, cancel := context.WithTimeout(context.Background(), timeout)
defer cancel()
// 1. Create order service with API keys
svc := rest.NewCreateOrderService("YOUR_API_KEY_HERE", "YOUR_SECRET_KEY_HERE").
Symbol("BTCUSDT").
Side(rest.OrderSideBuy).
Type(rest.OrderTypeLimit).
Quantity(decimal.NewFromFloat(0.001)). // e.g., 0.001 BTC
Price(decimal.NewFromFloat(60000.0)) // limit price
// 2. Send order (omitting error handling for brevity)
// NOTE: In production, always check the error returned here!
order, _ := svc.Do(ctx)
// 3. Print result
fmt.Printf("Order placed! ID: %s, Type: %s, Qty: %s\n",
order.OrderID, order.Type, order.OrigQty.String())
}Demonstrating DI, Transport Tuning, and Production Error Handling.
package main
import (
"context"
"errors"
"fmt"
"log"
"net/http"
"time"
"github.com/IvanTurko/mexc-sdk-go/sdkerr"
"github.com/IvanTurko/mexc-sdk-go/spot/rest"
"github.com/IvanTurko/mexc-sdk-go/transport"
)
func main() {
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
// 1. Configure and create custom HTTP transport.
baseHTTP := &http.Client{
Timeout: 5 * time.Second,
Transport: &http.Transport{
MaxIdleConns: 50,
MaxConnsPerHost: 50,
},
}
// 2. Wrap the custom client for SDK compatibility.
customClient := transport.NewHTTPClient(baseHTTP)
// 3. Build service with dependency injection.
svc := rest.NewOrderBookService().
WithClient(customClient).
Symbol("BTCUSDT").
Limit(5)
// 4. Validate parameters before executing the request.
if err := svc.Validate(); err != nil {
log.Fatalf("Validation failed: %v", err)
}
// 5. Perform the request.
book, err := svc.Do(ctx)
if err != nil {
handleSDKError(err)
return
}
fmt.Println("Best Ask:", book.Asks[0].Price)
}
// handleSDKError processes and logs typed SDK errors (used for production code).
func handleSDKError(err error) {
var sdkErr *sdkerr.SDKError
if !errors.As(err, &sdkErr) {
log.Fatalf("System error: %v", err)
}
switch {
case errors.Is(sdkErr.Kind(), sdkerr.ErrValidation):
log.Fatalf("Validation error: %s", sdkErr.Message())
case errors.Is(sdkErr.Kind(), sdkerr.ErrAPIError):
log.Printf("API error: %s", sdkErr.Message())
case errors.Is(sdkErr.Kind(), sdkerr.ErrRequestFailed),
errors.Is(sdkErr.Kind(), sdkerr.ErrDecodeError):
log.Printf("Transport/Decode error: %s", sdkErr.Cause())
default:
log.Printf("Unknown SDK error: %s", err)
}
}Demonstrating SubscriptionHandle, Asynchronous Handlers, and RTT monitoring.
package main
import (
"context"
"fmt"
"os"
"os/signal"
"time"
"github.com/IvanTurko/mexc-sdk-go/spot/wsmarket"
)
func handleDepthSnapshot(snapshot *wsmarket.DepthSnapshot) {
bestAskPrice := "N/A"
bestBidPrice := "N/A"
if len(snapshot.Asks) > 0 {
bestAskPrice = snapshot.Asks[0].Price.String()
}
if len(snapshot.Bids) > 0 {
bestBidPrice = snapshot.Bids[0].Price.String()
}
fmt.Printf(">>> [%s v%d] | ASK: %s | BID: %s\n",
snapshot.Symbol,
snapshot.Version,
bestAskPrice,
bestBidPrice,
)
}
func main() {
// Set up context to handle interrupt signals (Ctrl+C)
ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt)
defer cancel()
// 1. Create WebSocket client with latency monitoring
client := wsmarket.NewWSMarket(
wsmarket.WithPingLatencyHandler(func(latency time.Duration) {
fmt.Printf("Current RTT latency: %v\n", latency)
}),
)
// Connect to the exchange
if err := client.Connect(ctx); err != nil {
panic(err)
}
// Ensure client is safely closed when main exits
defer func() {
fmt.Println("Closing WS client...")
client.Close()
}()
// 2. Prepare subscription
sub := wsmarket.NewBookDepthSub(
"BTCUSDT",
wsmarket.DepthLevel5,
handleDepthSnapshot,
)
// 3. Subscribe and obtain handle
handle, err := client.Subscribe(ctx, sub)
if err != nil {
panic(err)
}
// Ensure we unsubscribe safely when main exits
defer func() {
fmt.Println("Unsubscribing from WS...")
handle.Unsubscribe(context.Background())
}()
fmt.Println("Successfully subscribed to BTCUSDT DepthLevel5!")
<-ctx.Done() // Wait until context is canceled (Ctrl+C)
fmt.Println("Shutdown signal received, exiting...")
}The entire SDK follows unified design principles, ensuring the maturity, accuracy, and flexibility required for a production environment.
The transport layer is abstracted through interfaces (transport.HTTPClient, WSConnFactory). This enables:
- Testability: Mock injection for unit testing without network dependence.
- Flexibility: Swapping implementations for custom stacks (mTLS, proxies, low-level optimizations).
Using the decimal.Decimal type for all price and quantity data eliminates precision drift and is a mandatory requirement for any financial application.
The SDK provides a strictly typed error model. Every API error is mapped to an ErrorCode, which allows for:
- Programmatic Reaction: Filtering errors by category (Auth, Trading, Validation).
- Clear Code: Eliminating "magic numbers" and string parsing.
This section explains key architectural choices that differentiate the SDK from most standard Go client implementations and demonstrate the focus on reliability and low-latency.
| Decision | Engineering Goal |
|---|---|
Idempotent Closing with sync.Once |
Guarantees correct, exactly-once resource cleanup during concurrent or repeated Close() calls. |
| Synchronous API over WS (Promises) | Simplifies developer logic by abstracting the asynchronous request/response matching using a Promise pattern (Future/Promise). |
| Buffered Channel for Outgoing WS Messages | Prevents the user's goroutine from blocking, mitigating backpressure and increasing stability during temporary network slowdowns. |
| Built-in RTT Monitoring | Embeds PING/PONG handlers for constant control over the actual latency to the exchange. Critical for HFT bots. |
Clear Separation of Client / Conn |
Separates high-level client logic from low-level connection logic, maximizing modularity and testability. |
| Functional Options Pattern | Ensures configurability and API extensibility without breaking existing compatibility (e.g., WithLogger, WithWriteTimeout). |
| Item | Description |
|---|---|
| Full REST API Coverage | Key Priority: Finalizing the implementation of all public and private REST API methods for Spot and Futures markets. |
We welcome community contributions! Please feel free to open an issue or submit a Pull Request.
This project is licensed under the MIT License - see the LICENSE file for details.