Go SDK

Encrypted Go client for the GoDark API. Module: github.com/gq-godark/gdx-go-sdk (import as godark).

Requirements: Go 1.22+
Status: Beta — clone the public examples repo to get started.

Get the SDK

Clone gdx-go-sdk-examples. The repo vendors the SDK under sdk/ (replace in go.mod) so no private module proxy is required:

git clone https://github.com/gq-godark/gdx-go-sdk-examples.git
cd gdx-go-sdk-examples
cp .env.example .env
# set GODARK_API_KEY_ID, GODARK_API_SECRET, GODARK_PASSPHRASE

go build ./examples/...
go run ./examples/quickstart
go run ./examples/full_trader_example

You can also point an LLM / coding agent at the cloned repo and ask it to build a strategy using your credentials in .env. See the repo README for full setup, examples, and packaging details.

Public module proxy release is not yet available; until then this repo is the supported distribution.

Quickstart

Set credentials, then place a limit order over encrypted WebSocket (godark.NewClient). Subscribe to orders before placing so book confirmation can wait on private updates. Limit prices must stay near the oracle or the venue rejects — see Error Codes.

package main

import (
	"context"
	"fmt"
	"log"
	"os"
	"time"

	"github.com/gq-godark/gdx-go-sdk"
)

func main() {
	client, err := godark.NewClient(godark.ClientConfig{
		APIKeyID:    os.Getenv("GODARK_API_KEY_ID"),
		APISecret:   os.Getenv("GODARK_API_SECRET"),
		Passphrase:  os.Getenv("GODARK_PASSPHRASE"),
		Environment: godark.the default environment preset,
		BaseURL:     os.Getenv("GODARK_EDGE_URL"), // empty => the configured host preset
	})
	if err != nil {
		log.Fatal(err)
	}

	ctx := context.Background()
	if err := client.Connect(ctx); err != nil {
		log.Fatal(err)
	}
	defer func() { _ = client.Disconnect() }()

	if err := client.Subscribe(ctx, "orders"); err != nil {
		log.Fatal(err)
	}

	ack, err := client.PlaceOrder(ctx, godark.PlaceOrderRequest{
		Symbol:    "BTC-USDC-PERP",
		Side:      godark.SideSell,
		OrderType: godark.OrderTypeLimit,
		Price:     "68000", // decimal string; within ~10% of oracle
		Quantity:  "0.01",
	})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("placed %s\n", ack.OrderID)

	time.Sleep(500 * time.Millisecond)

	cancel, err := client.CancelOrder(ctx, ack.OrderID, "BTC-USDC-PERP")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("cancelled %s\n", cancel.OrderID)
}

See WebSocket Trading and Place Order for request fields.

Clients

TypeDescription
GodarkClient (NewClient)WebSocket trading + order/position streams on /ws/v1
GodarkRestClient (NewRestClient)Bearer-authenticated REST trading, order lookup, leverage, account/position snapshots, and public-market queries; trading bodies use one-shot HPKE
MarketDataClient (NewMarketDataClient)Public market snapshots on /ws/v1 by default; set GODARK_MARKET_DATA_USE_GOMARKET=1 or GODARK_MARKET_DATA_WS_URL to opt in to /ws/gomarket order-book feeds

Construct with godark.NewClient(cfg). With APIKeyID + APISecret + Passphrase, Connect mints POST /api/v1/auth/token (client_credentials) and logs in with the returned access_token (the raw key triple is never sent on the socket). Legacy APIKey is still sent as-is for local test-key-*. NewRestClient / GodarkRestClient place / cancel / modify with bearer + one-shot HPKE. GodarkClient uses a sealed HPKE WebSocket session for the same ops. WebSocket PlaceOrder with ClientOrderID registers that id immediately after a successful place, sending that place's header correlation_id as a non-zero decimal string. The edge stores the mapping only when POST /api/v1/orders/_register_coid returns HTTP 200. A 400 (including unknown place correlation) is returned with the order ack and is not cached. REST PlaceOrder does not register client order ids: this edge arms place correlation only for WebSocket place, so a REST forward cannot complete _register_coid. Passing ClientOrderID to REST PlaceOrder returns an error and does not place.

Public place/modify/mass-quote/batch-modify/TP-SL prices and sizes are decimal strings only (for example "68000", "0.01"), including QuoteNotional, min fill, and trigger — typed as string / *string. float64 / int inputs are not accepted on the trading API; format locally with strconv / math/big / shopspring/decimal if needed. The SDK normalizes each string against the instrument's price_decimals / quantity_decimals from GET /api/v1/instruments and does not convert from float64 on the trading path (PlaceOrderInput.price field 23, quantity field 24; modify and related commands likewise).

the default environment preset is the hosted default and an alternate environment preset selects the configured host. The trading client's EdgeURL normalization upgrades a trailing /ws and otherwise appends /ws/v1; pass a WebSocket URL. See Base URLs.

GodarkClient methods

MethodDocs reference
Connect(ctx) / Disconnect()Authentication, Encryption
Subscribe(ctx, ...)WebSocket Trading
PlaceOrder(ctx, req)Place Order, WebSocket Trading
CancelOrder(ctx, orderID, symbol)Cancel Order
ModifyOrder(ctx, ...)Modify Order
MassQuote(ctx, ...)Mass Quote
BatchCancel(ctx, ...)Cancel Order
OrderUpdates()Orders Channel
PositionUpdates()Positions Channel

Callbacks (OnOrderUpdate, etc.) run on the WebSocket receive goroutine — keep them fast or hand off to your own queue. Automatic reconnect and resubscribe are enabled by default; set ClientConfig.DisableAutoReconnect (or MarketDataConfig.DisableAutoReconnect) to disable them.

Types and errors

Exported enums: Environment, Side, OrderType, TimeInForce, OrderStatus, and related request/ack types.

Error types (use errors.As): AuthenticationError, SessionError, OrderError, EncryptionError, ConnectionError, TimeoutError. See Error Codes.

The HPKE login conn_id is uint64.

Environment variables: OS GODARK_*, then OS GDX_*, then .env GODARK_*, then .env GDX_*. The process environment always wins over .env. Quickstart snippets use the canonical GODARK_* names.

Bundled examples

Runnable under examples/ in the examples repo: quickstart (connect → subscribe → place → cancel) and full_trader_example (modify, mass quote, batch cancel).

go run ./examples/quickstart

See also


Shared trading fields

Prices, sizes, quote notional, trigger, take-profit, and stop-loss are decimal strings.

Place options (names follow each language): reduce_only, post_only, stp_mode (UNSPECIFIED, CANCEL_RESTING, CANCEL_AGGRESSOR, CANCEL_BOTH), quote_notional, peg_offset_bps, trigger_price, take_profit_price, stop_loss_price, slippage_bps, client_order_id.

confirmation: ack returns on the sequencer acknowledgement. book waits for a terminal private order update until the place timeout.

Time in force: GTC, IOC, FOK, GTD. Order types: MARKET, LIMIT, PEG, STOP_MARKET, STOP_LIMIT. Side: BUY, SELL.

Mass quote: 1 to 20 legs. Each leg has side, price, quantity, optional cancel_order_id, time_in_force, expiry_time. post_only omitted uses the venue default.

Batch modify legs: order_id plus at least one of new_price, new_quantity.

WebSocket implements cancel-all, close-all, reverse, and TP/SL amend or cancel. REST implements one-shot encrypted place, cancel, modify, mass quote, batch cancel, batch modify, plus snapshots. REST does not implement cancel-all, close-all, reverse, or TP/SL amend.

A WebSocket place that sets client_order_id registers it after the ack. REST leaves that id unregistered.

Errors: authentication, session, connection, encryption, timeout, and order rejection with a numeric code and symbolic name. See Error Codes.

Go reference

NewClient, NewRestClient, and NewMarketDataClient return (*Client, error). Methods take context.Context.

ClientConfig: APIKey, APIKeyID, APISecret, Passphrase, Environment, BaseURL, Account, HpkeStaticPublicKeyHex, SymbolMap, Transport, DisableAutoReconnect, HTTPClient, StreamBufferSize, PlaceOrderTerminalTimeout.

PlaceOrderRequest: Symbol, Side, OrderType, Quantity, Price, TimeInForce, AON, MinFillSize, ExpiryTime, Options, Confirmation, ClientOrderID.

PlaceOrderOptions: ReduceOnly, PostOnly, StpMode, PegOffsetBps, TriggerPrice, TakeProfitPrice, StopLossPrice, SlippageBps, QuoteNotional.

Socket: Connect, Disconnect, PlaceOrder, CancelOrder, ModifyOrder, CancelAllOrders, CloseAll, ReversePosition, AmendTpsl, CancelTpsl, Subscribe, Unsubscribe, MassQuote, UpdateLeverage, BatchCancel, BatchModify. Channels: orders, positions, snapshots, health, balance, margin alerts, funding, settlement, leverage, open orders. Setters cover those events plus error, disconnect, and reconnect.

REST PlaceOrder returns an error if a client order id is set. REST adds GetOrder, GetOrderByClientID, GetMe, GetBalance, GetLeverage, GetFundingRates, GetOpenInterest, GetVolume, GetTime, GetInstruments, snapshots, mass quote, batch commands, UpdateLeverage, and AwaitTerminalStatus.

Error values: AuthenticationError, SessionError, OrderError, ConnectionError, EncryptionError, TimeoutError. Catalogs: OrderErrorCodes, WsAdmitErrorCodes.