gRPC API Overview

High-performance gRPC API for LX internal node communication

gRPC API Overview

The LX gRPC API provides high-performance, strongly-typed communication for internal node operations. Built on Protocol Buffers 3, it offers sub-millisecond latency for order execution and real-time market data streaming.

Why gRPC

FeaturegRPCRESTWebSocket
Latency~50us~1ms~500us
Type SafetyStrong (protobuf)Weak (JSON)None
StreamingBidirectionalNoneServer-push
Code GenerationNativeManualManual
Binary ProtocolYesNoOptional

Service Definition

The LX exposes a single unified service with multiple RPC methods:

syntax = "proto3";

package lxdex;

option go_package = "github.com/luxfi/dex/pkg/grpc/pb";

// LX gRPC Service for internal Lux Network IPC
service LXDEXService {
  // Order Management
  rpc PlaceOrder(PlaceOrderRequest) returns (PlaceOrderResponse);
  rpc CancelOrder(CancelOrderRequest) returns (CancelOrderResponse);
  rpc GetOrder(GetOrderRequest) returns (Order);
  rpc GetOrders(GetOrdersRequest) returns (GetOrdersResponse);

  // Market Data
  rpc GetOrderBook(GetOrderBookRequest) returns (OrderBook);
  rpc StreamOrderBook(StreamOrderBookRequest) returns (stream OrderBookUpdate);
  rpc GetTrades(GetTradesRequest) returns (GetTradesResponse);
  rpc StreamTrades(StreamTradesRequest) returns (stream Trade);

  // Account Management
  rpc GetBalance(GetBalanceRequest) returns (Balance);
  rpc GetPositions(GetPositionsRequest) returns (GetPositionsResponse);

  // Node Management
  rpc GetNodeInfo(GetNodeInfoRequest) returns (NodeInfo);
  rpc GetPeers(GetPeersRequest) returns (GetPeersResponse);
  rpc Ping(PingRequest) returns (PingResponse);
}

Endpoint Configuration

Default Ports

EnvironmentPortTLS
Development50051No
Staging50051Yes
Production50051Yes (mTLS)

Connection String

# Plaintext (development only)
localhost:50051

# TLS
dns:///dex.lux.network:50051

# Load-balanced
dns:///dex-grpc.lux.network:443

Protocol Buffer Schema Location

proto/
  lxdex.proto           # Main service definition
  buf.yaml              # Buf configuration
  buf.gen.yaml          # Code generation config

buf.yaml Configuration

version: v2
name: buf.build/luxfi/dex
deps:
  - buf.build/googleapis/googleapis
breaking:
  use:
    - FILE
lint:
  use:
    - DEFAULT
  except:
    - PACKAGE_VERSION_SUFFIX
  rpc_allow_same_request_response: false
  rpc_allow_google_protobuf_empty_request: true
  rpc_allow_google_protobuf_empty_response: false

buf.gen.yaml Configuration

version: v2
managed:
  enabled: true
  override:
    - file_option: go_package_prefix
      value: github.com/luxfi/dex/pkg/grpc/gen
plugins:
  # Go
  - remote: buf.build/protocolbuffers/go
    out: pkg/grpc/gen
    opt: paths=source_relative
  - remote: buf.build/grpc/go
    out: pkg/grpc/gen
    opt: paths=source_relative

  # Python
  - remote: buf.build/protocolbuffers/python
    out: sdk/python/lxdex_grpc
  - remote: buf.build/grpc/python
    out: sdk/python/lxdex_grpc

  # TypeScript
  - remote: buf.build/connectrpc/es
    out: sdk/typescript/src/grpc
    opt: target=ts

  # Rust
  - remote: buf.build/community/neoeinstein-tonic
    out: sdk/rust/src/grpc
    opt:
      - compile_well_known_types
      - extern_path=.google.protobuf=::pbjson_types

Common Enums

OrderType

enum OrderType {
  LIMIT = 0;       // Standard limit order
  MARKET = 1;      // Execute at best available price
  STOP = 2;        // Market order triggered at stop price
  STOP_LIMIT = 3;  // Limit order triggered at stop price
  ICEBERG = 4;     // Large order split into visible chunks
  PEG = 5;         // Order pegged to reference price
}

OrderSide

enum OrderSide {
  BUY = 0;   // Bid side
  SELL = 1;  // Ask side
}

OrderStatus

enum OrderStatus {
  OPEN = 0;       // Order is active in book
  PARTIAL = 1;    // Partially filled
  FILLED = 2;     // Completely filled
  CANCELLED = 3;  // Cancelled by user
  REJECTED = 4;   // Rejected by matching engine
}

TimeInForce

enum TimeInForce {
  GTC = 0;  // Good Till Cancelled
  IOC = 1;  // Immediate Or Cancel
  FOK = 2;  // Fill Or Kill
  DAY = 3;  // Day Order (expires at EOD)
}

Error Handling

gRPC uses standard status codes. LX maps domain errors to appropriate codes:

gRPC CodeHTTPDescriptionExample
OK200SuccessOrder placed
INVALID_ARGUMENT400Bad requestInvalid price
NOT_FOUND404Resource missingOrder not found
ALREADY_EXISTS409DuplicateClient order ID exists
PERMISSION_DENIED403UnauthorizedInvalid API key
RESOURCE_EXHAUSTED429Rate limitedToo many requests
FAILED_PRECONDITION400State conflictInsufficient balance
ABORTED409ConcurrencyOrder already cancelled
UNAVAILABLE503Service downMatching engine offline
INTERNAL500Server errorUnexpected failure

Error Details

// Standard error response structure
message ErrorDetail {
  string code = 1;           // Machine-readable error code
  string message = 2;        // Human-readable message
  map<string, string> metadata = 3;  // Additional context
}
// Go error handling example
resp, err := client.PlaceOrder(ctx, req)
if err != nil {
    st, ok := status.FromError(err)
    if !ok {
        return fmt.Errorf("unknown error: %w", err)
    }

    switch st.Code() {
    case codes.InvalidArgument:
        return fmt.Errorf("invalid order: %s", st.Message())
    case codes.ResourceExhausted:
        return fmt.Errorf("rate limited, retry after backoff")
    case codes.FailedPrecondition:
        return fmt.Errorf("insufficient balance")
    default:
        return fmt.Errorf("grpc error %s: %s", st.Code(), st.Message())
    }
}

Performance Characteristics

Latency Benchmarks

OperationP50P99P999
PlaceOrder45us120us350us
CancelOrder25us80us200us
GetOrderBook15us50us150us
StreamOrderBook (per update)10us30us80us

Throughput

MetricValue
Orders/second (single node)100,000
Orders/second (cluster)1,000,000+
Concurrent streams10,000
Max message size4MB

Connection Management

Keep-Alive Settings

// Recommended client configuration
conn, err := grpc.Dial(
    "dex.lux.network:50051",
    grpc.WithKeepaliveParams(keepalive.ClientParameters{
        Time:                10 * time.Second,  // Ping interval
        Timeout:             3 * time.Second,   // Ping timeout
        PermitWithoutStream: true,              // Ping even without active streams
    }),
    grpc.WithDefaultCallOptions(
        grpc.MaxCallRecvMsgSize(4*1024*1024),  // 4MB receive
        grpc.MaxCallSendMsgSize(4*1024*1024),  // 4MB send
    ),
)

Connection Pooling

For high-throughput applications, use connection pooling:

type ConnectionPool struct {
    conns []*grpc.ClientConn
    idx   uint64
}

func (p *ConnectionPool) Get() *grpc.ClientConn {
    n := atomic.AddUint64(&p.idx, 1)
    return p.conns[n%uint64(len(p.conns))]
}

Quick Start

Go Client

package main

import (
    "context"
    "log"

    pb "github.com/luxfi/dex/pkg/grpc/gen"
    "google.golang.org/grpc"
    "google.golang.org/grpc/credentials/insecure"
)

func main() {
    conn, err := grpc.Dial(
        "localhost:50051",
        grpc.WithTransportCredentials(insecure.NewCredentials()),
    )
    if err != nil {
        log.Fatal(err)
    }
    defer conn.Close()

    client := pb.NewLXDEXServiceClient(conn)

    // Place an order
    resp, err := client.PlaceOrder(context.Background(), &pb.PlaceOrderRequest{
        Symbol:      "LUX-USDC",
        Type:        pb.OrderType_LIMIT,
        Side:        pb.OrderSide_BUY,
        Price:       100.50,
        Size:        10.0,
        UserId:      "user123",
        TimeInForce: pb.TimeInForce_GTC,
    })
    if err != nil {
        log.Fatal(err)
    }

    log.Printf("Order placed: ID=%d Status=%s", resp.OrderId, resp.Status)
}

Python Client

import grpc
from lxdex_grpc import lxdex_pb2, lxdex_pb2_grpc

channel = grpc.insecure_channel('localhost:50051')
stub = lxdex_pb2_grpc.LXDEXServiceStub(channel)

response = stub.PlaceOrder(lxdex_pb2.PlaceOrderRequest(
    symbol="LUX-USDC",
    type=lxdex_pb2.LIMIT,
    side=lxdex_pb2.BUY,
    price=100.50,
    size=10.0,
    user_id="user123",
    time_in_force=lxdex_pb2.GTC,
))

print(f"Order placed: ID={response.order_id} Status={response.status}")

Next Steps