Documentation
¶
Overview ¶
Package lighter is a low-latency Go SDK for the Lighter exchange (zkLighter: a perpetuals DEX on its own zk-rollup with an on-chain order book and sequencer-side matching).
Architecture ¶
The SDK follows the two-layer principle shared by the sibling SDKs (go-okx, go-bybit, go-hyperliquid): ONE common layer implements every request, and each exchange section is a thin specialisation that contributes only its own specifics. Sections never import each other.
lighter (root) public face of the common layer: Client, Config, errors,
logger, metrics, rate-limit events, TxTracker
types layer-1 public types: Fixed, Precision, enums, requests,
market / order / account / transaction views
perpetuals section "Perpetuals" (market_type "perp"):
Trading / Account / MarketData / Stream
Two confirmation levels ¶
Every write is a signed L2 transaction sent with sendTx / sendTxBatch. The API server answers with a receipt (types.TxReceipt) that only means the transaction was accepted and forwarded; the sequencer executes it later and reports the outcome on the account_tx WebSocket channel (types.TxOutcome). TxTracker correlates the two.
Quick start ¶
var cfg lighter.Config = lighter.DefaultConfig()
cfg.AccountIndex = 123
cfg.APIKeyIndex = 3
cfg.PrivateKey = os.Getenv("LIGHTER_PERPETUALS_SECRET_KEY")
client, err := lighter.NewClient(cfg)
perps := perpetuals.NewClient(client)
receipt, err := perps.Trading().CreateOrder(ctx, types.CreateOrderRequest{
Symbol: "ETH", ClientOrderIndex: 1, IsAsk: false,
Price: types.MustParseFixed("2000.00"), Size: types.MustParseFixed("0.01"),
Type: types.OrderTypeLimit, TimeInForce: types.TimeInForcePostOnly,
}, types.SendOptions{})
Prices and sizes are types.Fixed (int64 with 8 decimals) and must lie on the market's grid (types.Precision, from orderBookDetails); the SDK never rounds silently.
Index ¶
- Constants
- Variables
- func CodeOf(err error) int
- func EndpointWeight(endpoint string) int64
- func IsAuth(err error) bool
- func IsCode(err error, code int) bool
- func IsExchange(err error) bool
- func IsInvalidRequest(err error) bool
- func IsMissingOrder(err error) bool
- func IsNetwork(err error) bool
- func IsNonceError(err error) bool
- func IsRateLimit(err error) bool
- type APIKeyConfig
- type Client
- func (c *Client) APIKeyIndexes() []uint8
- func (c *Client) AccountIndex() int64
- func (c *Client) AuthToken() (string, error)
- func (c *Client) CanSign() bool
- func (c *Client) Close() error
- func (c *Client) Config() Config
- func (c *Client) Engine() *engine.Engine
- func (c *Client) IsTestnet() bool
- func (c *Client) LifeContext() context.Context
- func (c *Client) Logger() Logger
- func (c *Client) Metrics() CounterFactory
- func (c *Client) PostConn() *ws.Conn
- func (c *Client) PublicKeyHex(apiKeyIndex uint8) string
- func (c *Client) RateLimits() RateLimitSnapshot
- func (c *Client) StreamConn() *ws.Conn
- func (c *Client) StreamConnected() bool
- func (c *Client) WarmUpPost(ctx context.Context) error
- func (c *Client) WarmUpStream(ctx context.Context) error
- type Config
- type Counter
- type CounterFactory
- type Error
- type ErrorKind
- type Field
- type FieldKind
- type Logger
- type NonceMode
- type RateLimitBudget
- type RateLimitConfig
- type RateLimitEvent
- type RateLimitSnapshot
- type RateLimitTier
- type RestConfig
- type Transport
- type TxTracker
- type WsConfig
Constants ¶
const ( // MainnetChainID — 304. MainnetChainID uint32 = 304 // TestnetChainID — 300. TestnetChainID uint32 = 300 )
Chain ids signed into every transaction.
const ( CodeInvalidNonce int = lterr.CodeInvalidNonce CodeNonIncreasingNonce int = lterr.CodeNonIncreasingNonce CodeInvalidSignature int = lterr.CodeInvalidSignature CodeAPIKeyNotFound int = lterr.CodeAPIKeyNotFound CodeInactiveCancel int = lterr.CodeInactiveCancel CodeInactiveOrder int = lterr.CodeInactiveOrder CodeInvalidOrderIndex int = lterr.CodeInvalidOrderIndex CodeClientOrderIndexExists int = lterr.CodeClientOrderIndexExists CodeNotEnoughOrderMargin int = lterr.CodeNotEnoughOrderMargin CodeTooManyRequests int = lterr.CodeTooManyRequests )
Exchange error codes the SDK reacts to (see internal/lterr for the list).
const ( RateLimitCategoryPlace string = ratelimit.CategoryPlace RateLimitCategoryAmend string = ratelimit.CategoryAmend RateLimitCategoryCancel string = ratelimit.CategoryCancel RateLimitCategoryQuery string = ratelimit.CategoryQuery RateLimitCategoryMarket string = ratelimit.CategoryMarket RateLimitCategoryOther string = ratelimit.CategoryOther )
Rate-limit categories (RateLimitEvent.Category).
Variables ¶
var ( // MainnetRestURL — production REST base URL (scheme + host). MainnetRestURL string = "https://mainnet.zklighter.elliot.ai" // MainnetWsURL — production WebSocket URL. MainnetWsURL string = "wss://mainnet.zklighter.elliot.ai/stream" // TestnetRestURL — testnet REST base URL. TestnetRestURL string = "https://testnet.zklighter.elliot.ai" // TestnetWsURL — testnet WebSocket URL. TestnetWsURL string = "wss://testnet.zklighter.elliot.ai/stream" )
Lighter endpoints. Declared as vars rather than const so tests can override them (e.g. to point at a mock server).
Functions ¶
func EndpointWeight ¶
EndpointWeight returns the documented REST weight of an endpoint name (path without /api/v1/), 300 for unlisted endpoints.
func IsExchange ¶
IsExchange reports whether err is a state-dependent exchange rejection.
func IsInvalidRequest ¶
IsInvalidRequest reports whether err is a request-validation error.
func IsMissingOrder ¶
IsMissingOrder reports whether a cancel / modify failed because the order is not active any more or does not belong to the account.
func IsNonceError ¶
IsNonceError reports whether the API server rejected the nonce; the SDK has already scheduled a resynchronisation of the key's nonce.
func IsRateLimit ¶
IsRateLimit reports whether err is a rate-limit error.
Types ¶
type APIKeyConfig ¶
type APIKeyConfig struct {
// Index — API key index (2..254).
Index uint8
// PrivateKey — 40-byte hex private key, optional 0x prefix.
PrivateKey string
}
APIKeyConfig — one additional API key of the account.
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client — root SDK object. Safe for concurrent use.
func NewClient ¶
NewClient creates the root SDK client. cfg goes through withDefaults + validate. When PrivateKey is set the client can sign transactions and read private data; otherwise it can only access public endpoints.
func (*Client) APIKeyIndexes ¶
APIKeyIndexes returns the indexes of the configured signing keys (the first one is the default).
func (*Client) AccountIndex ¶
AccountIndex returns the configured account index.
func (*Client) AuthToken ¶
AuthToken returns a cached authentication token of the default key (for callers that talk to the exchange outside the SDK).
func (*Client) Close ¶
Close stops the background work (WebSocket connections, metadata refresh) and zeroes the signing keys. Safe to call multiple times.
func (*Client) Config ¶
Config returns a copy of the effective configuration (defaults applied, key material removed).
func (*Client) Engine ¶
Engine returns the unified request layer. Sections use it; applications normally do not need it.
func (*Client) LifeContext ¶
LifeContext returns the context that is cancelled by Close. Background work of sections (metadata refresh, streams) is bound to it.
func (*Client) Metrics ¶
func (c *Client) Metrics() CounterFactory
Metrics returns the configured counter factory.
func (*Client) PostConn ¶
PostConn returns the connection used for jsonapi transactions, starting it on first use. Kept separate from StreamConn so market-data bursts never delay a transaction reply.
func (*Client) PublicKeyHex ¶
PublicKeyHex returns the public key of a configured signing key, in the form the apikeys endpoint prints ("" when the index is not configured).
func (*Client) RateLimits ¶
func (c *Client) RateLimits() RateLimitSnapshot
RateLimits returns the current SDK-side budgets.
func (*Client) StreamConn ¶
StreamConn returns the shared subscription connection, starting it on first use. It reconnects until Close.
func (*Client) StreamConnected ¶
StreamConnected reports whether the subscription socket is live right now.
func (*Client) WarmUpPost ¶
WarmUpPost connects the transaction socket and waits until it is live, so the first WebSocket transaction does not pay for the handshake.
type Config ¶
type Config struct {
// AccountIndex — account (or sub-account) index. Required for private
// endpoints and transactions.
AccountIndex int64
// APIKeyIndex — index of the default signing key (2..254).
APIKeyIndex uint8
// PrivateKey — private key of the default signing key. Empty → read-only
// client. Never logged, never echoed in errors.
PrivateKey string
// ExtraKeys — additional signing keys (v2.0 key pool).
ExtraKeys []APIKeyConfig
// Testnet — selects testnet endpoints and the testnet chain id.
Testnet bool
// ChainID — explicit chain id; 0 → derived from Testnet.
ChainID uint32
// REST — REST transport settings. Empty fields take DefaultConfig().REST.
REST RestConfig
// WS — WebSocket transport settings. Empty fields take DefaultConfig().WS.
WS WsConfig
// RateLimit — SDK-side rate-limit accounting.
RateLimit RateLimitConfig
// NonceMode — sequential (default) or skip.
NonceMode NonceMode
// TxExpiry — lifetime of a transaction (ExpiredAt = now + TxExpiry).
// Default: 10 minutes minus one second (the official SDK default).
TxExpiry time.Duration
// AuthTokenLifetime — validity of generated auth tokens, at most 8 hours
// (exchange limit). Default: 7h.
AuthTokenLifetime time.Duration
// MarketRefreshInterval — how often sections refresh market metadata
// (market ids, decimals). Default: 5m. Negative disables the background
// refresh (metadata is then loaded once, on first use).
MarketRefreshInterval time.Duration
// Logger — optional logger. If nil, NoopLogger() is used.
Logger Logger
// Metrics — optional counter factory. If nil, NoopMetrics() is used.
Metrics CounterFactory
// UserAgent — User-Agent of REST requests. Default: "go-lighter/v1".
UserAgent string
// RateLimitEventObserver — optional hook called SYNCHRONOUSLY after every
// request with the SDK-side rate-limit accounting (see rate-limit-event.go
// for the contract). If nil — no-op, zero overhead.
RateLimitEventObserver func(RateLimitEvent)
}
Config — public SDK configuration. Passed to NewClient.
func DefaultConfig ¶
func DefaultConfig() Config
DefaultConfig returns a Config with all sensible defaults (mainnet endpoints + production timeouts).
type CounterFactory ¶
type CounterFactory = ltmet.CounterFactory
CounterFactory — counter factory (name + label pairs).
type ErrorKind ¶
ErrorKind — SDK error category.
const ( ErrorKindUnknown ErrorKind = lterr.ErrorKindUnknown ErrorKindNetwork ErrorKind = lterr.ErrorKindNetwork ErrorKindRateLimit ErrorKind = lterr.ErrorKindRateLimit ErrorKindAuth ErrorKind = lterr.ErrorKindAuth ErrorKindInvalidRequest ErrorKind = lterr.ErrorKindInvalidRequest ErrorKindExchange ErrorKind = lterr.ErrorKindExchange )
Error categories.
type FieldKind ¶
FieldKind — Field discriminator.
const ( FieldKindString FieldKind = ltlog.FieldKindString FieldKindInt FieldKind = ltlog.FieldKindInt FieldKindFloat FieldKind = ltlog.FieldKindFloat FieldKindBool FieldKind = ltlog.FieldKindBool FieldKindError FieldKind = ltlog.FieldKindError )
Field kinds.
type NonceMode ¶
NonceMode — nonce assignment strategy (see internal/nonce).
const ( // NonceModeSequential — old+1 nonces, one round trip at a time per key // (default; the strategy of the official SDKs). NonceModeSequential NonceMode = nonce.ModeSequential // NonceModeSkip — monotonic millisecond nonces with the SkipNonce // attribute; sends on one key need not be serialised. NonceModeSkip NonceMode = nonce.ModeSkip )
type RateLimitBudget ¶
type RateLimitBudget struct {
// WeightedPerMinute — weighted REST window (24 000; Builder 240 000).
WeightedPerMinute int64
// RequestsPerMinute — unweighted request window (Standard: 60, sendTx
// included); 0 for the other tiers.
RequestsPerMinute int64
// SendTxPerMinute — sendTx / sendTxBatch bucket of Premium (by staked LIT)
// and Plus (4000) accounts; 0 for Standard and Builder.
SendTxPerMinute int64
}
RateLimitBudget — documented per-minute budgets of an account tier. A zero field means the tier has no such window.
func TierBudget ¶
func TierBudget(tier RateLimitTier, stakedLIT int64) RateLimitBudget
TierBudget returns the documented per-minute budgets of a tier; stakedLIT (whole tokens) sizes the Premium sendTx bucket.
type RateLimitConfig ¶
type RateLimitConfig struct {
// Tier — "standard" (default), "premium", "plus" or "builder".
Tier string
// StakedLIT — whole LIT tokens staked; sizes the Premium sendTx bucket.
StakedLIT int64
// DefaultTxTypeLimit — per-minute limit applied to transaction types
// without a documented bucket (order transactions); 0 disables.
DefaultTxTypeLimit int64
// RejectWhenRateLimited — when true, a request that does not fit into the
// SDK-side budgets (or arrives during a cooldown) fails locally with
// ErrorKindRateLimit instead of being sent. Default: false (the desk's
// own rate limiter decides).
RejectWhenRateLimited bool
}
RateLimitConfig — SDK-side rate-limit accounting (see rate-limit-event.go).
type RateLimitEvent ¶
RateLimitEvent — accounting event emitted after every request.
type RateLimitSnapshot ¶
RateLimitSnapshot — point-in-time view of the SDK-side budgets.
type RateLimitTier ¶
RateLimitTier — account tier of the rate-limit policy.
const ( RateLimitTierStandard RateLimitTier = ratelimit.TierStandard RateLimitTierPremium RateLimitTier = ratelimit.TierPremium RateLimitTierPlus RateLimitTier = ratelimit.TierPlus RateLimitTierBuilder RateLimitTier = ratelimit.TierBuilder )
Account tiers.
func TierFromName ¶
func TierFromName(name string) (RateLimitTier, bool)
TierFromName maps a tier name as the exchange or an operator spells it ("standard", "Premium", "PLUS", "builder"; case-insensitive) to a RateLimitTier. ok == false when the name is empty or unknown — the caller keeps its current tier instead of silently falling back to Standard.
type RestConfig ¶
type RestConfig struct {
// BaseURL — REST base URL (scheme + host). Default: MainnetRestURL
// (TestnetRestURL when Config.Testnet).
BaseURL string
// RequestTimeout — timeout of a single REST request. Default: 10s. For
// latency-critical calls pass a ctx with its own deadline.
RequestTimeout time.Duration
// MaxIdleConns — idle connection pool size. Default: 100.
MaxIdleConns int
// MaxIdleConnsPerHost — pool size per host. Default: 100.
MaxIdleConnsPerHost int
// IdleConnTimeout — keep-alive idle timeout. Default: 90s.
IdleConnTimeout time.Duration
// Proxy — optional proxy selector. Default: http.ProxyFromEnvironment.
Proxy func(*http.Request) (*url.URL, error)
// HTTPClient — optional fully custom *http.Client (own TLS config, dialer,
// transport). When set, the pool / proxy / timeout fields are ignored.
HTTPClient *http.Client
}
RestConfig — HTTP transport settings.
type Transport ¶
Transport — how a request travelled to the exchange.
const ( // TransportREST — HTTP (default). TransportREST Transport = ratelimit.TransportREST // TransportWS — WebSocket jsonapi request. TransportWS Transport = ratelimit.TransportWS )
Transports.
type TxTracker ¶
type TxTracker struct {
// contains filtered or unexported fields
}
TxTracker — receipt ↔ outcome correlation. Safe for concurrent use.
func NewTxTracker ¶
NewTxTracker creates a tracker that remembers at most maxEntries outcomes (default 4096 when <= 0).
type WsConfig ¶
type WsConfig struct {
// URL — WebSocket URL. Default: MainnetWsURL (TestnetWsURL when Testnet).
URL string
// HandshakeTimeout — connection handshake timeout. Default: 10s.
HandshakeTimeout time.Duration
// ReadTimeout — read deadline of a single frame; refreshed by every frame
// including pong. Must exceed PingInterval. Default: 75s.
ReadTimeout time.Duration
// WriteTimeout — write timeout of a single frame. Default: 5s.
WriteTimeout time.Duration
// PingInterval — client keepalive period. The server closes a connection
// silent for 2 minutes. Default: 30s.
PingInterval time.Duration
// ReconnectInitialBackoff — initial delay between reconnects. Default: 200ms.
ReconnectInitialBackoff time.Duration
// ReconnectMaxBackoff — upper bound of the backoff. Default: 10s.
ReconnectMaxBackoff time.Duration
// ReconnectJitter — relative jitter [0..1] applied to the backoff. Default: 0.2.
ReconnectJitter float64
// ReadBufferSize — gorilla/websocket read buffer size. Default: 64KB.
ReadBufferSize int
// WriteBufferSize — gorilla/websocket write buffer size. Default: 16KB.
WriteBufferSize int
// EnableCompression — negotiate permessage-deflate. Default: false.
EnableCompression bool
// PostTimeout — how long a WS jsonapi request waits for its reply. Default: 10s.
PostTimeout time.Duration
// Proxy — optional proxy selector. Default: http.ProxyFromEnvironment.
Proxy func(*http.Request) (*url.URL, error)
}
WsConfig — WebSocket transport settings.