mirror of
https://github.com/luxfi/dex.git
synced 2026-09-24 00:26:31 +00:00
docs: update SDK imports to @luxfi/trading and describe LX as Lux L2 chain
- Update all SDK examples to use `import { DEX } from '@luxfi/trading'`
- Replace LXDexClient with Client, jsonRpcUrl with rpcUrl throughout
- Rename architecture/sidecar.mdx to l2-chain.mdx
- Describe LX as a dedicated Lux L2 chain that shares consensus/finality
- Document validator staking requirements for DEX node operators
- Clarify relationship to Lux L1, B-Chain bridge, and C-Chain settlement
- Update 31 documentation files with consistent patterns
This commit is contained in:
+2
-2
@@ -333,9 +333,9 @@ order = client.place_order("BTC-USDT", "buy", "limit", 50000, 0.1)
|
||||
|
||||
### TypeScript SDK
|
||||
```typescript
|
||||
import { LXDexClient } from '@luxfi/dex-sdk';
|
||||
import { Client } from '@luxfi/trading';
|
||||
|
||||
const client = new LXDexClient({
|
||||
const client = new Client({
|
||||
apiKey: 'your_key',
|
||||
apiSecret: 'your_secret'
|
||||
});
|
||||
|
||||
+6
-6
@@ -134,14 +134,14 @@ ws.send(JSON.stringify({
|
||||
### TypeScript/JavaScript SDK
|
||||
|
||||
```bash
|
||||
npm install @luxfi/dex-sdk
|
||||
npm install @luxfi/trading
|
||||
```
|
||||
|
||||
```typescript
|
||||
import { LXDexClient } from '@luxfi/dex-sdk';
|
||||
import { Client } from '@luxfi/trading';
|
||||
|
||||
const client = new LXDexClient({
|
||||
jsonRpcUrl: 'http://localhost:8080/rpc',
|
||||
const client = new Client({
|
||||
rpcUrl: 'http://localhost:8080/rpc',
|
||||
wsUrl: 'ws://localhost:8081'
|
||||
});
|
||||
|
||||
@@ -168,9 +168,9 @@ pip install luxfi-dex
|
||||
```
|
||||
|
||||
```python
|
||||
from luxfi_dex import LXDexClient
|
||||
from luxfi_dex import Client
|
||||
|
||||
client = LXDexClient(
|
||||
client = Client(
|
||||
json_rpc_url='http://localhost:8080/rpc',
|
||||
ws_url='ws://localhost:8081'
|
||||
)
|
||||
|
||||
@@ -410,7 +410,7 @@ order, err := client.PlaceOrder(ctx, &rpc.PlaceOrderParams{
|
||||
### TypeScript
|
||||
|
||||
```typescript
|
||||
import { LXRPCClient } from '@luxfi/dex-sdk';
|
||||
import { LXRPCClient } from '@luxfi/trading';
|
||||
|
||||
const client = new LXRPCClient({
|
||||
endpoint: 'https://api.lux.network/rpc',
|
||||
|
||||
@@ -11,7 +11,7 @@ The LX is a high-performance decentralized exchange built for planet-scale throu
|
||||
|
||||
### First Principles
|
||||
|
||||
1. **Separation of Concerns**: Trading engine runs as a standalone sidecar (`lxd`), separate from blockchain consensus
|
||||
1. **Native Lux Chain**: LX runs as a dedicated L2 chain on the Lux network, sharing consensus and finality with the main network
|
||||
2. **Deterministic Execution**: All state transitions are reproducible and verifiable
|
||||
3. **Lock-Free Where Possible**: Minimize contention with atomic operations and lock-free data structures
|
||||
4. **Zero-Copy Paths**: Eliminate memory copies in hot paths
|
||||
@@ -55,7 +55,7 @@ The LX is a high-performance decentralized exchange built for planet-scale throu
|
||||
| | |
|
||||
| v |
|
||||
| +================================================================+ |
|
||||
| | lxd SIDECAR DAEMON | |
|
||||
| | LX L2 CHAIN (lxd node) | |
|
||||
| | +----------------------------------------------------------+ | |
|
||||
| | | TRADING ENGINE | | |
|
||||
| | | +----------------------+ +-------------------------+ | | |
|
||||
@@ -129,9 +129,9 @@ type Gateway interface {
|
||||
- **REST/JSON**: Standard HTTP API for compatibility
|
||||
- **FIX**: Financial Information eXchange for institutional clients
|
||||
|
||||
### 2. Trading Engine (lxd Sidecar)
|
||||
### 2. Trading Engine (LX L2 Chain)
|
||||
|
||||
The trading engine is the heart of the DEX, running as a standalone daemon:
|
||||
The trading engine is the heart of the DEX, running as a dedicated Lux L2 chain that shares consensus and finality with the main Lux network:
|
||||
|
||||
```go
|
||||
// TradingEngine orchestrates all trading operations
|
||||
@@ -379,7 +379,7 @@ func (ob *OrderBook) AddOrder(ctx context.Context, order *Order) uint64 {
|
||||
|
||||
Explore detailed documentation for each component:
|
||||
|
||||
- [Sidecar Architecture](/docs/architecture/sidecar) - lxd daemon design
|
||||
- [L2 Chain Architecture](/docs/architecture/l2-chain) - LX chain design and Lux network integration
|
||||
- [6-Chain Architecture](/docs/architecture/chains) - Blockchain integration
|
||||
- [DAG Consensus](/docs/architecture/dag) - Parallel block processing
|
||||
- [State Management](/docs/architecture/state) - MerkleDB and snapshots
|
||||
|
||||
@@ -0,0 +1,604 @@
|
||||
---
|
||||
title: L2 Chain Architecture
|
||||
description: LX as a Lux L2 chain - shared consensus and finality with the Lux network
|
||||
---
|
||||
|
||||
# LX L2 Chain Architecture
|
||||
|
||||
LX runs as a dedicated **Layer 2 chain** on the Lux network. Unlike traditional sidechains or rollups, LX is a native Lux subnet that shares consensus and finality with the main network chains. Validators must stake LUX to operate DEX nodes, ensuring economic alignment with the broader Lux ecosystem.
|
||||
|
||||
## Relationship to Lux Network
|
||||
|
||||
### LX as a Lux L2
|
||||
|
||||
```
|
||||
+==============================================================================+
|
||||
| LUX NETWORK ARCHITECTURE |
|
||||
+==============================================================================+
|
||||
| |
|
||||
| PRIMARY CHAINS (L1) |
|
||||
| +------------+ +------------+ +------------+ +------------+ |
|
||||
| | D-Chain | | C-Chain | | X-Chain | | Q-Chain | |
|
||||
| | Platform | | EVM | | Exchange | | Quantum | |
|
||||
| +-----+------+ +-----+------+ +-----+------+ +-----+------+ |
|
||||
| | | | | |
|
||||
| +-------+-------+-------+-------+-------+-------+ |
|
||||
| | | | |
|
||||
| Shared Consensus & Finality (Lux FPC) |
|
||||
| | | | |
|
||||
| +-------+-------+-------+-------+-------+-------+ |
|
||||
| | | | | |
|
||||
| +-----v------+ +-----v------+ +-----v------+ +-----v------+ |
|
||||
| | B-Chain | | T-Chain | | LX Chain | | Future L2s | |
|
||||
| | Bridge | | Threshold | | DEX | | ... | |
|
||||
| +------------+ +------------+ +------------+ +------------+ |
|
||||
| |
|
||||
| LAYER 2 CHAINS (Subnets) |
|
||||
+==============================================================================+
|
||||
```
|
||||
|
||||
### Key Relationships
|
||||
|
||||
| Component | Relationship to LX |
|
||||
|-----------|-------------------|
|
||||
| **D-Chain (Platform)** | Validator registration, staking requirements, subnet management |
|
||||
| **C-Chain (EVM)** | Token contracts, DeFi integrations, smart contract settlement |
|
||||
| **X-Chain (Exchange)** | UTXO-based asset transfers, cross-chain liquidity |
|
||||
| **B-Chain (Bridge)** | Cross-chain asset bridging from external networks |
|
||||
| **Q-Chain (Quantum)** | Post-quantum signature verification for high-security trades |
|
||||
| **T-Chain (Threshold)** | MPC custody for institutional assets |
|
||||
|
||||
## Validator Requirements
|
||||
|
||||
### Staking to Run LX Nodes
|
||||
|
||||
To operate an LX DEX node, validators must:
|
||||
|
||||
1. **Stake LUX on D-Chain**: Minimum stake requirement for subnet validation
|
||||
2. **Register as Subnet Validator**: Join the LX subnet via D-Chain
|
||||
3. **Run lxd Node**: Deploy the LX DEX node software
|
||||
4. **Maintain Uptime**: Meet availability requirements for consensus participation
|
||||
|
||||
```go
|
||||
// ValidatorConfig for LX subnet
|
||||
type ValidatorConfig struct {
|
||||
// D-Chain staking
|
||||
StakeAmount *big.Int // Minimum LUX stake
|
||||
StakeDuration time.Duration
|
||||
DelegationFee uint32 // Fee for delegators (basis points)
|
||||
|
||||
// LX subnet specific
|
||||
SubnetID [32]byte // LX subnet identifier
|
||||
NodeID string // Validator node ID
|
||||
BLSPublicKey []byte // For consensus participation
|
||||
|
||||
// DEX node requirements
|
||||
MatchingBackend Backend // Go/CGO/MLX/CUDA
|
||||
MinMemory uint64 // 16GB minimum
|
||||
MinCPUCores int // 8 cores minimum
|
||||
}
|
||||
```
|
||||
|
||||
### Validator Responsibilities
|
||||
|
||||
```
|
||||
+====================================+
|
||||
| LX VALIDATOR NODE |
|
||||
+====================================+
|
||||
| |
|
||||
| +------------------------------+ |
|
||||
| | D-Chain Validator Module | |
|
||||
| | - Stake management | |
|
||||
| | - Subnet participation | |
|
||||
| | - Reward distribution | |
|
||||
| +------------------------------+ |
|
||||
| | |
|
||||
| v |
|
||||
| +------------------------------+ |
|
||||
| | LX DEX Engine (lxd) | |
|
||||
| | - Order matching | |
|
||||
| | - Market data | |
|
||||
| | - Settlement batching | |
|
||||
| +------------------------------+ |
|
||||
| | |
|
||||
| v |
|
||||
| +------------------------------+ |
|
||||
| | Consensus Participation | |
|
||||
| | - DAG vertex creation | |
|
||||
| | - Vote casting (FPC) | |
|
||||
| | - Certificate generation | |
|
||||
| +------------------------------+ |
|
||||
| |
|
||||
+====================================+
|
||||
```
|
||||
|
||||
## Shared Consensus & Finality
|
||||
|
||||
### How LX Inherits Lux Consensus
|
||||
|
||||
LX uses the same Fast Probabilistic Consensus (FPC) protocol as the main Lux network:
|
||||
|
||||
```go
|
||||
// LuxFPC implements shared consensus
|
||||
type LuxFPC struct {
|
||||
// Network-wide parameters (inherited from Lux)
|
||||
NetworkID uint32
|
||||
ValidatorSet *ValidatorSet // Shared with D-Chain
|
||||
|
||||
// LX-specific configuration
|
||||
SubnetID [32]byte
|
||||
ThetaMin float64 // 0.55 - minimum vote threshold
|
||||
ThetaMax float64 // 0.65 - maximum vote threshold
|
||||
RoundDuration time.Duration // 50ms
|
||||
|
||||
// Quantum-safe extensions
|
||||
BLSAggregator *BLSAggregator
|
||||
CoronaSigner *CoronaSigner
|
||||
}
|
||||
|
||||
// ProcessVertex handles new order vertices
|
||||
func (fpc *LuxFPC) ProcessVertex(ctx context.Context, v *OrderVertex) error {
|
||||
// 1. Validate vertex structure
|
||||
if err := v.Validate(); err != nil {
|
||||
return fmt.Errorf("invalid vertex: %w", err)
|
||||
}
|
||||
|
||||
// 2. Check parent vertices are finalized
|
||||
for _, parentID := range v.Parents {
|
||||
if !fpc.IsFinalized(parentID) {
|
||||
return ErrParentNotFinalized
|
||||
}
|
||||
}
|
||||
|
||||
// 3. Add to local DAG
|
||||
fpc.dag.AddVertex(v)
|
||||
|
||||
// 4. Begin voting rounds
|
||||
return fpc.initiateVoting(ctx, v.ID)
|
||||
}
|
||||
```
|
||||
|
||||
### Finality Flow
|
||||
|
||||
```
|
||||
LX Order → DAG Vertex → FPC Voting → Certificate → Settlement → Lux Finality
|
||||
|
||||
Timeline:
|
||||
0ms - Order received
|
||||
1ms - DAG vertex created
|
||||
50ms - First voting round complete
|
||||
100ms - Certificate generated (if consensus reached)
|
||||
150ms - Settlement batch sent to C-Chain
|
||||
200ms - Full Lux network finality
|
||||
```
|
||||
|
||||
## Integration with Lux Infrastructure
|
||||
|
||||
### Bridge Integration (B-Chain)
|
||||
|
||||
LX integrates with B-Chain for cross-chain asset deposits and withdrawals:
|
||||
|
||||
```go
|
||||
// BridgeClient handles cross-chain operations
|
||||
type BridgeClient struct {
|
||||
bChainRPC string
|
||||
lxChainID [32]byte
|
||||
|
||||
// Asset mappings
|
||||
wrappedAssets map[[32]byte]WrappedAsset
|
||||
}
|
||||
|
||||
// DepositFromExternal bridges assets to LX for trading
|
||||
func (bc *BridgeClient) DepositFromExternal(
|
||||
ctx context.Context,
|
||||
sourceChain string, // "ethereum", "bitcoin", etc.
|
||||
asset string,
|
||||
amount *big.Int,
|
||||
recipient [20]byte,
|
||||
) (*DepositReceipt, error) {
|
||||
// 1. Lock on source chain (via B-Chain bridge)
|
||||
lockTx, err := bc.lockOnSource(ctx, sourceChain, asset, amount)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("lock failed: %w", err)
|
||||
}
|
||||
|
||||
// 2. Wait for B-Chain confirmation
|
||||
proof, err := bc.waitForBridgeProof(ctx, lockTx)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("bridge proof failed: %w", err)
|
||||
}
|
||||
|
||||
// 3. Mint wrapped asset on LX
|
||||
return bc.mintOnLX(ctx, proof, recipient)
|
||||
}
|
||||
```
|
||||
|
||||
### C-Chain Settlement
|
||||
|
||||
Trade settlements are batched and committed to C-Chain smart contracts:
|
||||
|
||||
```go
|
||||
// SettlementContract interface for C-Chain
|
||||
type SettlementContract struct {
|
||||
address common.Address
|
||||
cChainRPC string
|
||||
signer *ecdsa.PrivateKey
|
||||
}
|
||||
|
||||
// BatchSettle commits trade settlements to C-Chain
|
||||
func (sc *SettlementContract) BatchSettle(
|
||||
ctx context.Context,
|
||||
settlements []*Settlement,
|
||||
) (*types.Receipt, error) {
|
||||
// Encode settlement batch
|
||||
data, err := sc.encodeSettlements(settlements)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Submit to C-Chain
|
||||
tx := types.NewTransaction(
|
||||
sc.nonce,
|
||||
sc.address,
|
||||
big.NewInt(0),
|
||||
sc.gasLimit,
|
||||
sc.gasPrice,
|
||||
data,
|
||||
)
|
||||
|
||||
signedTx, err := types.SignTx(tx, types.NewEIP155Signer(sc.chainID), sc.signer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return sc.client.SendTransaction(ctx, signedTx)
|
||||
}
|
||||
```
|
||||
|
||||
### Warp Messaging
|
||||
|
||||
LX uses Lux Warp messaging for cross-chain communication:
|
||||
|
||||
```go
|
||||
// WarpMessage for cross-chain settlement
|
||||
type WarpMessage struct {
|
||||
// Standard Warp fields
|
||||
NetworkID uint32
|
||||
SourceChainID [32]byte // LX chain ID
|
||||
DestChainID [32]byte // Target chain (C-Chain, etc.)
|
||||
|
||||
// Payload
|
||||
MessageType WarpMessageType
|
||||
Payload []byte
|
||||
|
||||
// Signatures (threshold required)
|
||||
BLSSignature []byte // Aggregated BLS signature
|
||||
RTSignature []byte // Post-quantum Corona signature
|
||||
SignerBitmap []byte // Which validators signed
|
||||
}
|
||||
|
||||
const (
|
||||
WarpSettlement WarpMessageType = iota + 1
|
||||
WarpWithdrawal
|
||||
WarpDeposit
|
||||
WarpLiquidation
|
||||
WarpOracleUpdate
|
||||
)
|
||||
```
|
||||
|
||||
## LX Node (lxd) Architecture
|
||||
|
||||
### Process Model
|
||||
|
||||
```go
|
||||
// Daemon represents the lxd node
|
||||
type Daemon struct {
|
||||
// Core components
|
||||
engine *TradingEngine
|
||||
consensus *LuxFPC
|
||||
gateway *Gateway
|
||||
|
||||
// Lux network integration
|
||||
dChainClient *DChainClient // Staking, validator set
|
||||
cChainClient *CChainClient // Settlement contracts
|
||||
bChainClient *BridgeClient // Cross-chain bridges
|
||||
warpClient *WarpClient // Warp messaging
|
||||
|
||||
// Configuration
|
||||
config *Config
|
||||
nodeID string
|
||||
subnetID [32]byte
|
||||
|
||||
// Lifecycle
|
||||
ctx context.Context
|
||||
cancel context.CancelFunc
|
||||
}
|
||||
```
|
||||
|
||||
### Startup Sequence
|
||||
|
||||
```
|
||||
1. INITIALIZATION
|
||||
+-> Load configuration
|
||||
+-> Initialize cryptographic keys (Ed25519, BLS, Corona)
|
||||
+-> Verify D-Chain stake is active
|
||||
|
||||
2. LUX NETWORK CONNECTION
|
||||
+-> Connect to D-Chain (validator set sync)
|
||||
+-> Connect to C-Chain (settlement contract)
|
||||
+-> Connect to B-Chain (bridge status)
|
||||
+-> Initialize Warp client
|
||||
|
||||
3. LX SUBNET BOOTSTRAP
|
||||
+-> Join LX subnet validator set
|
||||
+-> Sync DAG state from peers
|
||||
+-> Initialize trading engine
|
||||
+-> Start consensus participation
|
||||
|
||||
4. GATEWAY ACTIVATION
|
||||
+-> Bind gRPC server
|
||||
+-> Bind WebSocket server
|
||||
+-> Accept client connections
|
||||
+-> Begin order processing
|
||||
```
|
||||
|
||||
### Memory Layout
|
||||
|
||||
```
|
||||
lxd Process Memory (~2GB typical)
|
||||
+================================+
|
||||
| Order Pool 256MB | <- Pre-allocated order objects
|
||||
+--------------------------------+
|
||||
| Order Books 512MB | <- Per-symbol B-trees
|
||||
+--------------------------------+
|
||||
| Trade Buffer 128MB | <- Circular trade history
|
||||
+--------------------------------+
|
||||
| DAG Vertices 256MB | <- Consensus state
|
||||
+--------------------------------+
|
||||
| Warp Message Queue 64MB | <- Pending settlements
|
||||
+--------------------------------+
|
||||
| Network Buffers 128MB | <- gRPC/WS buffers
|
||||
+--------------------------------+
|
||||
| Heap / GC ~700MB | <- Dynamic allocations
|
||||
+================================+
|
||||
```
|
||||
|
||||
## Order Processing Pipeline
|
||||
|
||||
### Order Lifecycle
|
||||
|
||||
```go
|
||||
// OrderProcessor handles the full order lifecycle
|
||||
type OrderProcessor struct {
|
||||
engine *TradingEngine
|
||||
dag *LuxFPC
|
||||
warp *WarpClient
|
||||
metrics *Metrics
|
||||
}
|
||||
|
||||
// ProcessOrder handles a new order from gateway
|
||||
func (p *OrderProcessor) ProcessOrder(ctx context.Context, req *OrderRequest) (*OrderResponse, error) {
|
||||
// 1. Validate order
|
||||
order, err := p.validateOrder(req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("validation failed: %w", err)
|
||||
}
|
||||
|
||||
// 2. Risk check
|
||||
if err := p.riskCheck(ctx, order); err != nil {
|
||||
return nil, fmt.Errorf("risk check failed: %w", err)
|
||||
}
|
||||
|
||||
// 3. Add to order book
|
||||
orderID := p.engine.OrderBooks[order.Symbol].AddOrder(order)
|
||||
if orderID == 0 {
|
||||
return nil, ErrOrderRejected
|
||||
}
|
||||
|
||||
// 4. Create DAG vertex (async)
|
||||
go p.createVertex(ctx, order)
|
||||
|
||||
// 5. Return immediately
|
||||
return &OrderResponse{
|
||||
OrderID: orderID,
|
||||
Status: "accepted",
|
||||
Timestamp: time.Now(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// createVertex creates a DAG vertex for consensus
|
||||
func (p *OrderProcessor) createVertex(ctx context.Context, order *Order) {
|
||||
vertex := &OrderVertex{
|
||||
ID: generateVertexID(order),
|
||||
Order: order,
|
||||
NodeID: p.dag.NodeID(),
|
||||
Height: p.dag.Height(),
|
||||
Parents: p.dag.Frontier(),
|
||||
Timestamp: time.Now(),
|
||||
}
|
||||
|
||||
// Add to local DAG
|
||||
p.dag.AddVertex(vertex)
|
||||
|
||||
// Broadcast to peers
|
||||
p.dag.BroadcastVertex(ctx, vertex)
|
||||
}
|
||||
```
|
||||
|
||||
### Concurrency Model
|
||||
|
||||
```
|
||||
+-------------------+
|
||||
| Order Gateway |
|
||||
+--------+----------+
|
||||
|
|
||||
+--------------+--------------+
|
||||
| | |
|
||||
+-----v-----+ +-----v-----+ +-----v-----+
|
||||
| Worker 1 | | Worker 2 | | Worker N |
|
||||
+-----+-----+ +-----+-----+ +-----+-----+
|
||||
| | |
|
||||
+--------------+--------------+
|
||||
|
|
||||
+--------v--------+
|
||||
| Order Book |
|
||||
| (Lock-free) |
|
||||
+-----------------+
|
||||
|
|
||||
+--------------+--------------+
|
||||
| | |
|
||||
+-----v-----+ +-----v-----+ +-----v-----+
|
||||
| Match | | DAG | | Warp |
|
||||
| Engine | | Consensus | | Publisher |
|
||||
+-----------+ +-----------+ +-----------+
|
||||
```
|
||||
|
||||
## Security Model
|
||||
|
||||
### Inherited from Lux Network
|
||||
|
||||
LX inherits Lux's security guarantees:
|
||||
|
||||
1. **Stake-Weighted Consensus**: Attacks require controlling significant stake
|
||||
2. **Validator Slashing**: Malicious behavior results in stake loss
|
||||
3. **Quantum Resistance**: Post-quantum signatures via Q-Chain
|
||||
4. **Bridge Security**: Multi-sig and threshold custody via T-Chain
|
||||
|
||||
### LX-Specific Security
|
||||
|
||||
```go
|
||||
// SecurityConfig for LX chain
|
||||
type SecurityConfig struct {
|
||||
// Consensus security
|
||||
MinValidators int // Minimum active validators
|
||||
QuorumThreshold float64 // 0.67 for finality
|
||||
|
||||
// Trade security
|
||||
PreTradeRiskCheck bool // Enable risk checks
|
||||
MaxOrderSize *big.Int
|
||||
MaxLeverage int // For perpetuals
|
||||
|
||||
// Settlement security
|
||||
SettlementDelay time.Duration // Time before settlement final
|
||||
RequireMPC bool // Require T-Chain MPC for large trades
|
||||
}
|
||||
```
|
||||
|
||||
## Operational Considerations
|
||||
|
||||
### Running an LX Validator
|
||||
|
||||
```yaml
|
||||
# lxd.yaml - Production configuration
|
||||
daemon:
|
||||
node_id: "lxd-validator-1"
|
||||
data_dir: "/var/lib/lxd"
|
||||
log_level: "info"
|
||||
|
||||
staking:
|
||||
d_chain_rpc: "https://api.lux.network/d-chain"
|
||||
stake_amount: "2000" # LUX
|
||||
delegation_fee: 200 # 2% in basis points
|
||||
|
||||
network:
|
||||
subnet_id: "LX_SUBNET_ID_HERE"
|
||||
grpc_addr: "0.0.0.0:9100"
|
||||
websocket_addr: "0.0.0.0:9101"
|
||||
peers:
|
||||
- "lxd-validator-2:9100"
|
||||
- "lxd-validator-3:9100"
|
||||
|
||||
engine:
|
||||
backend: "go" # go, cgo, mlx, cuda
|
||||
worker_pool_size: 8
|
||||
order_pool_size: 1000000
|
||||
|
||||
consensus:
|
||||
theta_min: 0.55
|
||||
theta_max: 0.65
|
||||
round_duration: "50ms"
|
||||
|
||||
settlement:
|
||||
c_chain_rpc: "https://api.lux.network/c-chain"
|
||||
contract_address: "0x..."
|
||||
batch_size: 1000
|
||||
batch_interval: "100ms"
|
||||
|
||||
security:
|
||||
tls_cert: "/etc/lxd/tls/cert.pem"
|
||||
tls_key: "/etc/lxd/tls/key.pem"
|
||||
```
|
||||
|
||||
### Monitoring
|
||||
|
||||
```go
|
||||
var (
|
||||
validatorStake = prometheus.NewGauge(
|
||||
prometheus.GaugeOpts{
|
||||
Name: "lxd_validator_stake_lux",
|
||||
Help: "Current validator stake in LUX",
|
||||
},
|
||||
)
|
||||
|
||||
consensusParticipation = prometheus.NewCounter(
|
||||
prometheus.CounterOpts{
|
||||
Name: "lxd_consensus_votes_total",
|
||||
Help: "Total votes cast in FPC consensus",
|
||||
},
|
||||
)
|
||||
|
||||
settlementLatency = prometheus.NewHistogram(
|
||||
prometheus.HistogramOpts{
|
||||
Name: "lxd_settlement_latency_seconds",
|
||||
Help: "Time from trade to C-Chain settlement",
|
||||
Buckets: prometheus.ExponentialBuckets(0.01, 2, 10),
|
||||
},
|
||||
)
|
||||
)
|
||||
```
|
||||
|
||||
## Trade-offs and Design Decisions
|
||||
|
||||
### ADR-001: L2 Chain vs Rollup
|
||||
|
||||
**Context**: Need high-performance trading with blockchain settlement guarantees.
|
||||
|
||||
**Decision**: Implement LX as a native Lux L2 subnet rather than a rollup.
|
||||
|
||||
**Trade-off**:
|
||||
- **Pro**: Native consensus integration, shared security with Lux network
|
||||
- **Pro**: Sub-millisecond latency (no rollup batching delays)
|
||||
- **Pro**: Validators economically aligned via LUX staking
|
||||
- **Con**: Requires dedicated validator set
|
||||
- **Con**: Less decentralized than L1 (subnet validator subset)
|
||||
|
||||
**Rationale**: A native L2 chain provides the performance characteristics required for high-frequency trading while maintaining strong security guarantees through shared consensus with the Lux network.
|
||||
|
||||
### ADR-002: Warp Messaging vs Direct Bridge
|
||||
|
||||
**Context**: Need to settle trades and move assets between LX and other Lux chains.
|
||||
|
||||
**Decision**: Use Lux Warp messaging protocol for all cross-chain communication.
|
||||
|
||||
**Trade-off**:
|
||||
- **Pro**: Native Lux protocol, no additional trust assumptions
|
||||
- **Pro**: Aggregated signatures reduce verification cost
|
||||
- **Pro**: Quantum-safe with Corona signatures
|
||||
- **Con**: Requires threshold of validators to sign messages
|
||||
|
||||
**Rationale**: Warp messaging is the standard cross-chain protocol in Lux, providing security guarantees equivalent to the network itself.
|
||||
|
||||
### ADR-003: Shared vs Independent Consensus
|
||||
|
||||
**Context**: LX could run its own isolated consensus or share with the Lux network.
|
||||
|
||||
**Decision**: Share consensus and finality with the main Lux network via FPC.
|
||||
|
||||
**Trade-off**:
|
||||
- **Pro**: Inherits full network security (stake-weighted)
|
||||
- **Pro**: Consistent finality guarantees across all Lux chains
|
||||
- **Pro**: Simpler validator operation (single stake covers all chains)
|
||||
- **Con**: Bound to network-wide consensus parameters
|
||||
- **Con**: Subnet-specific optimizations limited
|
||||
|
||||
**Rationale**: Sharing consensus eliminates the need for separate security assumptions and allows LX validators to leverage their existing Lux network stake.
|
||||
@@ -2,7 +2,7 @@
|
||||
"title": "Architecture",
|
||||
"pages": [
|
||||
"index",
|
||||
"sidecar",
|
||||
"l2-chain",
|
||||
"chains",
|
||||
"dag",
|
||||
"state",
|
||||
|
||||
@@ -1,691 +0,0 @@
|
||||
---
|
||||
title: Sidecar Architecture
|
||||
description: lxd sidecar daemon architecture - Warp messaging integration with Lux node
|
||||
---
|
||||
|
||||
# Sidecar Architecture
|
||||
|
||||
The LX runs as a standalone sidecar daemon (`lxd`) separate from the Lux blockchain node. This architecture enables sub-millisecond order matching while maintaining blockchain settlement guarantees through Warp messaging.
|
||||
|
||||
## Design Rationale
|
||||
|
||||
### Why a Sidecar?
|
||||
|
||||
Traditional DEX architectures embed trading logic directly in blockchain VMs. This creates fundamental performance limitations:
|
||||
|
||||
| Approach | Latency | Throughput | Trade-off |
|
||||
|----------|---------|------------|-----------|
|
||||
| On-chain VM | 2-30s | 100-1000 TPS | Guaranteed finality, slow |
|
||||
| Hybrid | 100ms-2s | 10K TPS | Compromise |
|
||||
| **Sidecar** | `<100μs` | 10M+ TPS | Fast matching, async settlement |
|
||||
|
||||
The sidecar approach separates concerns:
|
||||
|
||||
1. **Matching**: Handled in `lxd` with native performance
|
||||
2. **Settlement**: Committed to blockchain via Warp messages
|
||||
3. **Consensus**: DAG consensus within sidecar network
|
||||
|
||||
```
|
||||
+=====================================+
|
||||
| SIDECAR NETWORK |
|
||||
| +------+ +------+ +------+ |
|
||||
| | lxd |<->| lxd |<->| lxd | |
|
||||
| +------+ +------+ +------+ |
|
||||
| | | | |
|
||||
| +----+-----+-----+----+ |
|
||||
| | | |
|
||||
| DAG Consensus | |
|
||||
| | | |
|
||||
+===========|===========|=============+
|
||||
| |
|
||||
Warp Messages |
|
||||
| |
|
||||
+===========v===========v=============+
|
||||
| LUX BLOCKCHAIN NODE |
|
||||
| +--------+ +--------+ +-------+ |
|
||||
| | D-Chain| | C-Chain| |B-Chain| |
|
||||
| +--------+ +--------+ +-------+ |
|
||||
+=====================================+
|
||||
```
|
||||
|
||||
## lxd Daemon Architecture
|
||||
|
||||
### Process Model
|
||||
|
||||
```go
|
||||
// Daemon represents the lxd sidecar daemon
|
||||
type Daemon struct {
|
||||
// Core components
|
||||
engine *TradingEngine
|
||||
consensus *DAGConsensus
|
||||
gateway *Gateway
|
||||
warpClient *WarpClient
|
||||
|
||||
// Configuration
|
||||
config *Config
|
||||
nodeID string
|
||||
|
||||
// Lifecycle
|
||||
ctx context.Context
|
||||
cancel context.CancelFunc
|
||||
wg sync.WaitGroup
|
||||
}
|
||||
|
||||
// Config holds daemon configuration
|
||||
type Config struct {
|
||||
// Network
|
||||
ListenAddr string // gRPC listen address
|
||||
WebSocketAddr string // WebSocket listen address
|
||||
PeerAddrs []string // Initial peer addresses
|
||||
|
||||
// Performance
|
||||
WorkerPoolSize int // Order processing workers
|
||||
MatchingBackend Backend // Go/CGO/MLX/CUDA
|
||||
|
||||
// Blockchain
|
||||
LuxNodeRPC string // Lux node RPC endpoint
|
||||
WarpConfig WarpConfig // Warp messaging config
|
||||
|
||||
// Security
|
||||
TLSCertFile string
|
||||
TLSKeyFile string
|
||||
APIKeyFile string
|
||||
}
|
||||
```
|
||||
|
||||
### Startup Sequence
|
||||
|
||||
```
|
||||
1. INITIALIZATION
|
||||
+-> Load configuration
|
||||
+-> Initialize cryptographic keys
|
||||
+-> Set up logging and metrics
|
||||
|
||||
2. COMPONENT BOOTSTRAP
|
||||
+-> Create TradingEngine
|
||||
+-> Initialize DAG consensus
|
||||
+-> Connect to Lux node
|
||||
+-> Start Warp client
|
||||
|
||||
3. NETWORK SETUP
|
||||
+-> Bind gRPC server
|
||||
+-> Bind WebSocket server
|
||||
+-> Connect to peer sidecars
|
||||
+-> Sync state from peers
|
||||
|
||||
4. READY
|
||||
+-> Accept client connections
|
||||
+-> Process orders
|
||||
+-> Participate in consensus
|
||||
```
|
||||
|
||||
### Memory Layout
|
||||
|
||||
```
|
||||
lxd Process Memory (~2GB typical)
|
||||
+================================+
|
||||
| Order Pool 256MB | <- Pre-allocated order objects
|
||||
+--------------------------------+
|
||||
| Order Books 512MB | <- Per-symbol B-trees
|
||||
+--------------------------------+
|
||||
| Trade Buffer 128MB | <- Circular trade history
|
||||
+--------------------------------+
|
||||
| DAG Vertices 256MB | <- Consensus state
|
||||
+--------------------------------+
|
||||
| Warp Message Queue 64MB | <- Pending settlements
|
||||
+--------------------------------+
|
||||
| Network Buffers 128MB | <- gRPC/WS buffers
|
||||
+--------------------------------+
|
||||
| Heap / GC ~700MB | <- Dynamic allocations
|
||||
+================================+
|
||||
```
|
||||
|
||||
## Trading Engine Integration
|
||||
|
||||
### Order Processing Pipeline
|
||||
|
||||
```go
|
||||
// OrderProcessor handles the full order lifecycle
|
||||
type OrderProcessor struct {
|
||||
engine *TradingEngine
|
||||
dag *DAGConsensus
|
||||
warp *WarpClient
|
||||
metrics *Metrics
|
||||
}
|
||||
|
||||
// ProcessOrder handles a new order from gateway
|
||||
func (p *OrderProcessor) ProcessOrder(ctx context.Context, req *OrderRequest) (*OrderResponse, error) {
|
||||
// 1. Validate order
|
||||
order, err := p.validateOrder(req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("validation failed: %w", err)
|
||||
}
|
||||
|
||||
// 2. Risk check
|
||||
if err := p.riskCheck(ctx, order); err != nil {
|
||||
return nil, fmt.Errorf("risk check failed: %w", err)
|
||||
}
|
||||
|
||||
// 3. Add to order book
|
||||
orderID := p.engine.OrderBooks[order.Symbol].AddOrder(order)
|
||||
if orderID == 0 {
|
||||
return nil, ErrOrderRejected
|
||||
}
|
||||
|
||||
// 4. Create DAG vertex (async)
|
||||
go p.createVertex(ctx, order)
|
||||
|
||||
// 5. Return immediately
|
||||
return &OrderResponse{
|
||||
OrderID: orderID,
|
||||
Status: "accepted",
|
||||
Timestamp: time.Now(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// createVertex creates a DAG vertex for consensus
|
||||
func (p *OrderProcessor) createVertex(ctx context.Context, order *Order) {
|
||||
vertex := &OrderVertex{
|
||||
ID: generateVertexID(order),
|
||||
Order: order,
|
||||
NodeID: p.dag.NodeID(),
|
||||
Height: p.dag.Height(),
|
||||
Parents: p.dag.Frontier(),
|
||||
Timestamp: time.Now(),
|
||||
}
|
||||
|
||||
// Add to local DAG
|
||||
p.dag.AddVertex(vertex)
|
||||
|
||||
// Broadcast to peers
|
||||
p.dag.BroadcastVertex(ctx, vertex)
|
||||
}
|
||||
```
|
||||
|
||||
### Concurrency Model
|
||||
|
||||
```
|
||||
+-------------------+
|
||||
| Order Gateway |
|
||||
+--------+----------+
|
||||
|
|
||||
+--------------+--------------+
|
||||
| | |
|
||||
+-----v-----+ +-----v-----+ +-----v-----+
|
||||
| Worker 1 | | Worker 2 | | Worker N |
|
||||
+-----+-----+ +-----+-----+ +-----+-----+
|
||||
| | |
|
||||
+--------------+--------------+
|
||||
|
|
||||
+--------v--------+
|
||||
| Order Book |
|
||||
| (Lock-free) |
|
||||
+-----------------+
|
||||
|
|
||||
+--------------+--------------+
|
||||
| | |
|
||||
+-----v-----+ +-----v-----+ +-----v-----+
|
||||
| Match | | DAG | | Warp |
|
||||
| Engine | | Consensus | | Publisher |
|
||||
+-----------+ +-----------+ +-----------+
|
||||
```
|
||||
|
||||
**Worker Pool Design:**
|
||||
|
||||
```go
|
||||
type WorkerPool struct {
|
||||
workers int
|
||||
orderChan chan *Order
|
||||
resultChan chan *OrderResult
|
||||
wg sync.WaitGroup
|
||||
}
|
||||
|
||||
func NewWorkerPool(size int) *WorkerPool {
|
||||
pool := &WorkerPool{
|
||||
workers: size,
|
||||
orderChan: make(chan *Order, 10000),
|
||||
resultChan: make(chan *OrderResult, 10000),
|
||||
}
|
||||
|
||||
for i := 0; i < size; i++ {
|
||||
pool.wg.Add(1)
|
||||
go pool.worker(i)
|
||||
}
|
||||
|
||||
return pool
|
||||
}
|
||||
|
||||
func (p *WorkerPool) worker(id int) {
|
||||
defer p.wg.Done()
|
||||
|
||||
// Pin to CPU core for cache locality
|
||||
runtime.LockOSThread()
|
||||
|
||||
for order := range p.orderChan {
|
||||
result := p.processOrder(order)
|
||||
p.resultChan <- result
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Warp Messaging
|
||||
|
||||
### Message Types
|
||||
|
||||
The sidecar uses Warp messages to communicate with the blockchain:
|
||||
|
||||
```go
|
||||
// WarpMessageType defines the type of Warp message
|
||||
type WarpMessageType uint8
|
||||
|
||||
const (
|
||||
WarpSettlement WarpMessageType = iota + 1 // Trade settlement
|
||||
WarpWithdrawal // Asset withdrawal
|
||||
WarpDeposit // Asset deposit
|
||||
WarpLiquidation // Position liquidation
|
||||
WarpStateSync // State synchronization
|
||||
)
|
||||
|
||||
// WarpMessage represents a message to the blockchain
|
||||
type WarpMessage struct {
|
||||
Type WarpMessageType
|
||||
Payload []byte
|
||||
Signature []byte // BLS signature
|
||||
RTSignature []byte // Corona (post-quantum)
|
||||
Timestamp time.Time
|
||||
SourceChain [32]byte
|
||||
DestChain [32]byte
|
||||
}
|
||||
```
|
||||
|
||||
### Settlement Flow
|
||||
|
||||
```
|
||||
SIDECAR BLOCKCHAIN
|
||||
| |
|
||||
| 1. Trade executed locally |
|
||||
| |
|
||||
| 2. Create settlement batch |
|
||||
| |
|
||||
| 3. Generate Warp message |
|
||||
| |
|
||||
| 4. Collect validator sigs |
|
||||
| |
|
||||
|-------- Warp Message ----------->|
|
||||
| |
|
||||
| 5. Verify BLS aggregate
|
||||
| |
|
||||
| 6. Update chain state
|
||||
| |
|
||||
| 7. Emit event
|
||||
| |
|
||||
|<------- Confirmation ------------|
|
||||
| |
|
||||
| 8. Update local finality |
|
||||
| |
|
||||
```
|
||||
|
||||
### Warp Client Implementation
|
||||
|
||||
```go
|
||||
// WarpClient handles blockchain communication
|
||||
type WarpClient struct {
|
||||
nodeRPC string
|
||||
chainID [32]byte
|
||||
signer *BLSSigner
|
||||
rtSigner *CoronaSigner
|
||||
pendingBatch []*Settlement
|
||||
batchMu sync.Mutex
|
||||
flushTicker *time.Ticker
|
||||
}
|
||||
|
||||
// Settlement represents a trade settlement
|
||||
type Settlement struct {
|
||||
TradeID uint64
|
||||
BuyerAddr [20]byte
|
||||
SellerAddr [20]byte
|
||||
BaseAsset [32]byte
|
||||
QuoteAsset [32]byte
|
||||
BaseAmount *big.Int
|
||||
QuoteAmount *big.Int
|
||||
Timestamp time.Time
|
||||
}
|
||||
|
||||
// BatchAndSend collects settlements and sends as Warp message
|
||||
func (c *WarpClient) BatchAndSend(ctx context.Context) error {
|
||||
c.batchMu.Lock()
|
||||
batch := c.pendingBatch
|
||||
c.pendingBatch = make([]*Settlement, 0, 1000)
|
||||
c.batchMu.Unlock()
|
||||
|
||||
if len(batch) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Encode batch
|
||||
payload, err := encodeSettlementBatch(batch)
|
||||
if err != nil {
|
||||
return fmt.Errorf("encode batch: %w", err)
|
||||
}
|
||||
|
||||
// Create unsigned message
|
||||
unsignedMsg := &warp.UnsignedMessage{
|
||||
NetworkID: c.networkID,
|
||||
SourceChainID: c.chainID[:],
|
||||
Payload: payload,
|
||||
}
|
||||
|
||||
// Sign with BLS
|
||||
blsSig, err := c.signer.Sign(unsignedMsg.Bytes())
|
||||
if err != nil {
|
||||
return fmt.Errorf("BLS sign: %w", err)
|
||||
}
|
||||
|
||||
// Sign with Corona (post-quantum)
|
||||
rtSig, err := c.rtSigner.Sign(unsignedMsg.Bytes())
|
||||
if err != nil {
|
||||
return fmt.Errorf("Corona sign: %w", err)
|
||||
}
|
||||
|
||||
// Send to blockchain
|
||||
msg := &WarpMessage{
|
||||
Type: WarpSettlement,
|
||||
Payload: payload,
|
||||
Signature: blsSig,
|
||||
RTSignature: rtSig,
|
||||
Timestamp: time.Now(),
|
||||
SourceChain: c.chainID,
|
||||
}
|
||||
|
||||
return c.sendToBlockchain(ctx, msg)
|
||||
}
|
||||
```
|
||||
|
||||
## State Synchronization
|
||||
|
||||
### Initial Sync
|
||||
|
||||
When a new sidecar joins the network:
|
||||
|
||||
```go
|
||||
// StateSyncer handles state synchronization
|
||||
type StateSyncer struct {
|
||||
peers []string
|
||||
dag *DAGConsensus
|
||||
engine *TradingEngine
|
||||
}
|
||||
|
||||
// SyncFromPeers synchronizes state from peer sidecars
|
||||
func (s *StateSyncer) SyncFromPeers(ctx context.Context) error {
|
||||
// 1. Get latest height from peers
|
||||
heights := make(map[string]uint64)
|
||||
for _, peer := range s.peers {
|
||||
h, err := s.getHeight(ctx, peer)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
heights[peer] = h
|
||||
}
|
||||
|
||||
// 2. Find peer with highest height
|
||||
bestPeer, bestHeight := s.selectBestPeer(heights)
|
||||
|
||||
// 3. Download state snapshot
|
||||
snapshot, err := s.downloadSnapshot(ctx, bestPeer, bestHeight)
|
||||
if err != nil {
|
||||
return fmt.Errorf("download snapshot: %w", err)
|
||||
}
|
||||
|
||||
// 4. Verify snapshot integrity
|
||||
if err := s.verifySnapshot(snapshot); err != nil {
|
||||
return fmt.Errorf("verify snapshot: %w", err)
|
||||
}
|
||||
|
||||
// 5. Apply snapshot
|
||||
if err := s.applySnapshot(snapshot); err != nil {
|
||||
return fmt.Errorf("apply snapshot: %w", err)
|
||||
}
|
||||
|
||||
// 6. Sync remaining blocks
|
||||
return s.syncBlocks(ctx, bestPeer, snapshot.Height, bestHeight)
|
||||
}
|
||||
|
||||
// StateSnapshot represents a point-in-time state
|
||||
type StateSnapshot struct {
|
||||
Height uint64
|
||||
Timestamp time.Time
|
||||
OrderBooks map[string]*OrderBookState
|
||||
DAGState *DAGState
|
||||
Checksum [32]byte
|
||||
}
|
||||
```
|
||||
|
||||
### Continuous Sync
|
||||
|
||||
```go
|
||||
// ContinuousSync maintains state consistency
|
||||
func (s *StateSyncer) ContinuousSync(ctx context.Context) error {
|
||||
ticker := time.NewTicker(100 * time.Millisecond)
|
||||
defer ticker.Stop()
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
|
||||
case <-ticker.C:
|
||||
// Check for new vertices from peers
|
||||
for _, peer := range s.peers {
|
||||
vertices, err := s.getNewVertices(ctx, peer)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
for _, v := range vertices {
|
||||
if err := s.dag.ProcessRemoteVertex(v); err != nil {
|
||||
log.Warn("process vertex", "err", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Fault Tolerance
|
||||
|
||||
### Health Checking
|
||||
|
||||
```go
|
||||
// HealthChecker monitors system health
|
||||
type HealthChecker struct {
|
||||
components map[string]HealthCheckable
|
||||
interval time.Duration
|
||||
}
|
||||
|
||||
// HealthCheckable interface for health checking
|
||||
type HealthCheckable interface {
|
||||
HealthCheck(ctx context.Context) error
|
||||
Name() string
|
||||
}
|
||||
|
||||
// Check performs health check on all components
|
||||
func (h *HealthChecker) Check(ctx context.Context) *HealthReport {
|
||||
report := &HealthReport{
|
||||
Timestamp: time.Now(),
|
||||
Status: "healthy",
|
||||
Components: make(map[string]*ComponentHealth),
|
||||
}
|
||||
|
||||
for name, component := range h.components {
|
||||
start := time.Now()
|
||||
err := component.HealthCheck(ctx)
|
||||
latency := time.Since(start)
|
||||
|
||||
health := &ComponentHealth{
|
||||
Name: name,
|
||||
Latency: latency,
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
health.Status = "unhealthy"
|
||||
health.Error = err.Error()
|
||||
report.Status = "degraded"
|
||||
} else {
|
||||
health.Status = "healthy"
|
||||
}
|
||||
|
||||
report.Components[name] = health
|
||||
}
|
||||
|
||||
return report
|
||||
}
|
||||
```
|
||||
|
||||
### Graceful Shutdown
|
||||
|
||||
```go
|
||||
// Shutdown gracefully stops the daemon
|
||||
func (d *Daemon) Shutdown(ctx context.Context) error {
|
||||
log.Info("initiating graceful shutdown")
|
||||
|
||||
// 1. Stop accepting new orders
|
||||
d.gateway.StopAccepting()
|
||||
|
||||
// 2. Drain pending orders
|
||||
drainCtx, cancel := context.WithTimeout(ctx, 30*time.Second)
|
||||
defer cancel()
|
||||
|
||||
if err := d.engine.DrainOrders(drainCtx); err != nil {
|
||||
log.Warn("drain orders timeout", "err", err)
|
||||
}
|
||||
|
||||
// 3. Flush pending settlements
|
||||
if err := d.warpClient.FlushBatch(ctx); err != nil {
|
||||
log.Error("flush settlements", "err", err)
|
||||
}
|
||||
|
||||
// 4. Save state checkpoint
|
||||
if err := d.saveCheckpoint(); err != nil {
|
||||
log.Error("save checkpoint", "err", err)
|
||||
}
|
||||
|
||||
// 5. Close connections
|
||||
d.gateway.Close()
|
||||
d.consensus.Stop()
|
||||
|
||||
// 6. Cancel context
|
||||
d.cancel()
|
||||
d.wg.Wait()
|
||||
|
||||
log.Info("shutdown complete")
|
||||
return nil
|
||||
}
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
### Example Configuration
|
||||
|
||||
```yaml
|
||||
# lxd.yaml
|
||||
daemon:
|
||||
node_id: "lxd-node-1"
|
||||
data_dir: "/var/lib/lxd"
|
||||
log_level: "info"
|
||||
|
||||
network:
|
||||
grpc_addr: "0.0.0.0:9100"
|
||||
websocket_addr: "0.0.0.0:9101"
|
||||
peers:
|
||||
- "lxd-node-2:9100"
|
||||
- "lxd-node-3:9100"
|
||||
|
||||
engine:
|
||||
backend: "go" # go, cgo, mlx, cuda
|
||||
worker_pool_size: 8
|
||||
order_pool_size: 1000000
|
||||
|
||||
consensus:
|
||||
theta_min: 0.55
|
||||
theta_max: 0.65
|
||||
round_duration: "50ms"
|
||||
vote_limit_per_block: 256
|
||||
|
||||
warp:
|
||||
lux_node_rpc: "http://localhost:9650"
|
||||
settlement_batch_size: 1000
|
||||
settlement_interval: "100ms"
|
||||
|
||||
security:
|
||||
tls_cert: "/etc/lxd/tls/cert.pem"
|
||||
tls_key: "/etc/lxd/tls/key.pem"
|
||||
api_key_file: "/etc/lxd/api_keys.json"
|
||||
```
|
||||
|
||||
## Monitoring
|
||||
|
||||
### Prometheus Metrics
|
||||
|
||||
```go
|
||||
var (
|
||||
sidecarUptime = prometheus.NewGauge(
|
||||
prometheus.GaugeOpts{
|
||||
Name: "lxd_uptime_seconds",
|
||||
Help: "Sidecar uptime in seconds",
|
||||
},
|
||||
)
|
||||
|
||||
peersConnected = prometheus.NewGauge(
|
||||
prometheus.GaugeOpts{
|
||||
Name: "lxd_peers_connected",
|
||||
Help: "Number of connected peer sidecars",
|
||||
},
|
||||
)
|
||||
|
||||
warpMessagesSent = prometheus.NewCounter(
|
||||
prometheus.CounterOpts{
|
||||
Name: "lxd_warp_messages_sent_total",
|
||||
Help: "Total Warp messages sent to blockchain",
|
||||
},
|
||||
)
|
||||
|
||||
settlementBatchSize = prometheus.NewHistogram(
|
||||
prometheus.HistogramOpts{
|
||||
Name: "lxd_settlement_batch_size",
|
||||
Help: "Settlement batch sizes",
|
||||
Buckets: []float64{10, 50, 100, 500, 1000, 5000},
|
||||
},
|
||||
)
|
||||
)
|
||||
```
|
||||
|
||||
## Trade-offs and Design Decisions
|
||||
|
||||
### ADR-001: Sidecar vs On-Chain Matching
|
||||
|
||||
**Context**: Need to achieve <100us order latency while maintaining settlement guarantees.
|
||||
|
||||
**Decision**: Run matching engine as standalone sidecar, settle via Warp messages.
|
||||
|
||||
**Trade-off**:
|
||||
- **Pro**: Sub-millisecond latency, 10M+ TPS
|
||||
- **Pro**: Horizontal scalability via sharding
|
||||
- **Con**: Additional operational complexity
|
||||
- **Con**: Async settlement (eventual consistency)
|
||||
|
||||
**Rationale**: The latency and throughput requirements are impossible to meet on-chain. The sidecar approach provides native performance while Warp messaging ensures eventual settlement finality.
|
||||
|
||||
### ADR-002: DAG Consensus for Order Sequencing
|
||||
|
||||
**Context**: Need to establish total ordering of trades across distributed sidecars.
|
||||
|
||||
**Decision**: Use DAG consensus with Lux FPC protocol.
|
||||
|
||||
**Trade-off**:
|
||||
- **Pro**: 50ms finality
|
||||
- **Pro**: Parallel vertex processing
|
||||
- **Con**: More complex than linear blockchain
|
||||
- **Con**: Requires quantum certificates for finality
|
||||
|
||||
**Rationale**: DAG enables parallel processing of non-conflicting orders, significantly increasing throughput compared to sequential consensus.
|
||||
@@ -150,9 +150,9 @@ console.log('Order ID:', order.orderId)
|
||||
### Using Python SDK
|
||||
|
||||
```python
|
||||
from luxfi_dex import LXDexClient
|
||||
from luxfi_dex import Client
|
||||
|
||||
client = LXDexClient(
|
||||
client = Client(
|
||||
json_rpc_url='http://localhost:8080/rpc'
|
||||
)
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ Ultra-high performance DEX with **434M+ orders/sec** on Apple Silicon.
|
||||
|
||||
## Overview
|
||||
|
||||
LX is a planet-scale, fully on-chain decentralized exchange built on Lux Network, combining ultra-low latency matching, quantum-resistant security, and support for global markets in a unified system. The DEX runs as a **standalone sidecar daemon** (`lxd`) separate from the Lux blockchain node, communicating via Warp messages for settlement.
|
||||
LX is a planet-scale, fully on-chain decentralized exchange built on Lux Network, combining ultra-low latency matching, quantum-resistant security, and support for global markets in a unified system. LX runs as a **dedicated Lux L2 chain** that shares consensus and finality with the main network. Validators stake LUX to operate DEX nodes (`lxd`), with settlements committed via Warp messages.
|
||||
|
||||
## Key Performance
|
||||
|
||||
|
||||
@@ -113,9 +113,9 @@ pip install luxfi-dex
|
||||
### Basic Usage
|
||||
|
||||
```python
|
||||
from luxfi_dex import LXDexClient
|
||||
from luxfi_dex import Client
|
||||
|
||||
client = LXDexClient(
|
||||
client = Client(
|
||||
json_rpc_url='http://localhost:8080/rpc',
|
||||
ws_url='ws://localhost:8081'
|
||||
)
|
||||
@@ -150,10 +150,10 @@ for trade in trades:
|
||||
|
||||
```python
|
||||
import asyncio
|
||||
from luxfi_dex import AsyncLXDexClient
|
||||
from luxfi_dex import AsyncClient
|
||||
|
||||
async def main():
|
||||
client = AsyncLXDexClient(
|
||||
client = AsyncClient(
|
||||
json_rpc_url='http://localhost:8080/rpc',
|
||||
ws_url='ws://localhost:8081'
|
||||
)
|
||||
@@ -360,7 +360,7 @@ const dex = await DEX({
|
||||
### JWT Authentication
|
||||
|
||||
```python
|
||||
client = LXDexClient(
|
||||
client = Client(
|
||||
jwt_token='eyJhbGciOiJIUzI1NiIs...'
|
||||
)
|
||||
```
|
||||
|
||||
@@ -1,30 +1,30 @@
|
||||
---
|
||||
title: Client
|
||||
description: LXDexClient and AsyncLXDexClient - synchronous and asynchronous clients for LX
|
||||
description: Client and AsyncClient - synchronous and asynchronous clients for LX
|
||||
---
|
||||
|
||||
# Client Classes
|
||||
|
||||
The Python SDK provides two client classes for different use cases:
|
||||
- **`LXDexClient`** - Synchronous client for scripts and simple applications
|
||||
- **`AsyncLXDexClient`** - Asynchronous client for high-performance and concurrent applications
|
||||
- **`Client`** - Synchronous client for scripts and simple applications
|
||||
- **`AsyncClient`** - Asynchronous client for high-performance and concurrent applications
|
||||
|
||||
## LXDexClient (Synchronous)
|
||||
## Client (Synchronous)
|
||||
|
||||
The synchronous client is suitable for scripts, CLI tools, and applications that do not require concurrent operations.
|
||||
|
||||
### Initialization
|
||||
|
||||
```python
|
||||
from luxfi_dex import LXDexClient
|
||||
from luxfi_dex import Client
|
||||
|
||||
# Basic initialization
|
||||
client = LXDexClient(
|
||||
client = Client(
|
||||
json_rpc_url="http://localhost:8080/rpc"
|
||||
)
|
||||
|
||||
# Full configuration
|
||||
client = LXDexClient(
|
||||
client = Client(
|
||||
json_rpc_url="http://localhost:8080/rpc",
|
||||
ws_url="ws://localhost:8081",
|
||||
api_key="your-api-key",
|
||||
@@ -34,7 +34,7 @@ client = LXDexClient(
|
||||
)
|
||||
|
||||
# From environment variables
|
||||
client = LXDexClient.from_env()
|
||||
client = Client.from_env()
|
||||
```
|
||||
|
||||
### Class Definition
|
||||
@@ -44,7 +44,7 @@ from dataclasses import dataclass
|
||||
from typing import Optional
|
||||
|
||||
@dataclass
|
||||
class LXDexClient:
|
||||
class Client:
|
||||
"""Synchronous LX client.
|
||||
|
||||
Attributes:
|
||||
@@ -67,10 +67,10 @@ class LXDexClient:
|
||||
### Core Methods
|
||||
|
||||
```python
|
||||
from luxfi_dex import LXDexClient
|
||||
from luxfi_dex import Client
|
||||
from luxfi_dex.types import NodeInfo, Order, OrderBook, Trade
|
||||
|
||||
client = LXDexClient("http://localhost:8080/rpc")
|
||||
client = Client("http://localhost:8080/rpc")
|
||||
|
||||
# Node information
|
||||
def get_info(self) -> NodeInfo:
|
||||
@@ -142,9 +142,9 @@ def get_trades(
|
||||
### Usage Examples
|
||||
|
||||
```python
|
||||
from luxfi_dex import LXDexClient, OrderType, Side
|
||||
from luxfi_dex import Client, OrderType, Side
|
||||
|
||||
client = LXDexClient("http://localhost:8080/rpc")
|
||||
client = Client("http://localhost:8080/rpc")
|
||||
|
||||
# Test connectivity
|
||||
if client.ping():
|
||||
@@ -177,7 +177,7 @@ cancelled = client.cancel_order(order.order_id)
|
||||
print(f"Order cancelled: {cancelled.status}")
|
||||
```
|
||||
|
||||
## AsyncLXDexClient (Asynchronous)
|
||||
## AsyncClient (Asynchronous)
|
||||
|
||||
The asynchronous client is designed for high-performance applications, web servers, and scenarios requiring concurrent operations.
|
||||
|
||||
@@ -185,11 +185,11 @@ The asynchronous client is designed for high-performance applications, web serve
|
||||
|
||||
```python
|
||||
import asyncio
|
||||
from luxfi_dex import AsyncLXDexClient
|
||||
from luxfi_dex import AsyncClient
|
||||
|
||||
# Basic initialization
|
||||
async def main():
|
||||
client = AsyncLXDexClient(
|
||||
client = AsyncClient(
|
||||
json_rpc_url="http://localhost:8080/rpc"
|
||||
)
|
||||
|
||||
@@ -204,10 +204,10 @@ asyncio.run(main())
|
||||
|
||||
```python
|
||||
import asyncio
|
||||
from luxfi_dex import AsyncLXDexClient
|
||||
from luxfi_dex import AsyncClient
|
||||
|
||||
async def main():
|
||||
async with AsyncLXDexClient("http://localhost:8080/rpc") as client:
|
||||
async with AsyncClient("http://localhost:8080/rpc") as client:
|
||||
info = await client.get_info()
|
||||
print(f"Connected to: {info.node_id}")
|
||||
|
||||
@@ -219,7 +219,7 @@ asyncio.run(main())
|
||||
```python
|
||||
from typing import AsyncIterator
|
||||
|
||||
class AsyncLXDexClient:
|
||||
class AsyncClient:
|
||||
"""Asynchronous LX client.
|
||||
|
||||
Supports context manager protocol for automatic resource cleanup.
|
||||
@@ -237,7 +237,7 @@ class AsyncLXDexClient:
|
||||
) -> None:
|
||||
...
|
||||
|
||||
async def __aenter__(self) -> "AsyncLXDexClient":
|
||||
async def __aenter__(self) -> "AsyncClient":
|
||||
"""Enter async context manager."""
|
||||
...
|
||||
|
||||
@@ -253,7 +253,7 @@ class AsyncLXDexClient:
|
||||
### Core Methods
|
||||
|
||||
```python
|
||||
from luxfi_dex import AsyncLXDexClient
|
||||
from luxfi_dex import AsyncClient
|
||||
from luxfi_dex.types import NodeInfo, Order, OrderBook, Trade
|
||||
|
||||
# All methods are coroutines
|
||||
@@ -324,10 +324,10 @@ async def stream_trades(
|
||||
|
||||
```python
|
||||
import asyncio
|
||||
from luxfi_dex import AsyncLXDexClient, OrderType, Side
|
||||
from luxfi_dex import AsyncClient, OrderType, Side
|
||||
|
||||
async def main():
|
||||
async with AsyncLXDexClient("http://localhost:8080/rpc") as client:
|
||||
async with AsyncClient("http://localhost:8080/rpc") as client:
|
||||
# Test connectivity
|
||||
if await client.ping():
|
||||
print("Connected to LX")
|
||||
@@ -357,10 +357,10 @@ asyncio.run(main())
|
||||
|
||||
```python
|
||||
import asyncio
|
||||
from luxfi_dex import AsyncLXDexClient
|
||||
from luxfi_dex import AsyncClient
|
||||
|
||||
async def main():
|
||||
async with AsyncLXDexClient("http://localhost:8080/rpc") as client:
|
||||
async with AsyncClient("http://localhost:8080/rpc") as client:
|
||||
# Execute multiple requests concurrently
|
||||
results = await asyncio.gather(
|
||||
client.get_order_book("BTC-USD"),
|
||||
@@ -412,7 +412,7 @@ class ClientConfig:
|
||||
### Using ClientConfig
|
||||
|
||||
```python
|
||||
from luxfi_dex import LXDexClient
|
||||
from luxfi_dex import Client
|
||||
from luxfi_dex.config import ClientConfig, RetryConfig
|
||||
|
||||
config = ClientConfig(
|
||||
@@ -428,7 +428,7 @@ config = ClientConfig(
|
||||
)
|
||||
)
|
||||
|
||||
client = LXDexClient(config=config)
|
||||
client = Client(config=config)
|
||||
```
|
||||
|
||||
## Authentication
|
||||
@@ -436,9 +436,9 @@ client = LXDexClient(config=config)
|
||||
### API Key Authentication
|
||||
|
||||
```python
|
||||
from luxfi_dex import LXDexClient
|
||||
from luxfi_dex import Client
|
||||
|
||||
client = LXDexClient(
|
||||
client = Client(
|
||||
json_rpc_url="https://api.lux.network/rpc",
|
||||
api_key="your-api-key",
|
||||
api_secret="your-api-secret"
|
||||
@@ -457,9 +457,9 @@ order = client.place_order(
|
||||
### JWT Authentication
|
||||
|
||||
```python
|
||||
from luxfi_dex import LXDexClient
|
||||
from luxfi_dex import Client
|
||||
|
||||
client = LXDexClient(
|
||||
client = Client(
|
||||
json_rpc_url="https://api.lux.network/rpc"
|
||||
)
|
||||
|
||||
@@ -467,7 +467,7 @@ client = LXDexClient(
|
||||
client.set_jwt_token("eyJhbGciOiJIUzI1NiIs...")
|
||||
|
||||
# Or initialize with token
|
||||
client = LXDexClient(
|
||||
client = Client(
|
||||
json_rpc_url="https://api.lux.network/rpc",
|
||||
jwt_token="eyJhbGciOiJIUzI1NiIs..."
|
||||
)
|
||||
@@ -499,7 +499,7 @@ def sign_request(
|
||||
## Error Handling
|
||||
|
||||
```python
|
||||
from luxfi_dex import LXDexClient
|
||||
from luxfi_dex import Client
|
||||
from luxfi_dex.exceptions import (
|
||||
LXDexError,
|
||||
ConnectionError,
|
||||
@@ -511,7 +511,7 @@ from luxfi_dex.exceptions import (
|
||||
ValidationError
|
||||
)
|
||||
|
||||
client = LXDexClient("http://localhost:8080/rpc")
|
||||
client = Client("http://localhost:8080/rpc")
|
||||
|
||||
try:
|
||||
order = client.place_order(
|
||||
@@ -543,7 +543,7 @@ except LXDexError as e:
|
||||
|
||||
```python
|
||||
import logging
|
||||
from luxfi_dex import LXDexClient
|
||||
from luxfi_dex import Client
|
||||
|
||||
# Configure logging
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
@@ -551,10 +551,10 @@ logger = logging.getLogger("luxfi_dex")
|
||||
logger.setLevel(logging.DEBUG)
|
||||
|
||||
# Client automatically logs requests and responses
|
||||
client = LXDexClient("http://localhost:8080/rpc")
|
||||
client = Client("http://localhost:8080/rpc")
|
||||
|
||||
# Or configure custom logger
|
||||
client = LXDexClient(
|
||||
client = Client(
|
||||
json_rpc_url="http://localhost:8080/rpc",
|
||||
logger=logger
|
||||
)
|
||||
@@ -568,9 +568,9 @@ The synchronous client is **thread-safe**. You can share a single client instanc
|
||||
|
||||
```python
|
||||
import threading
|
||||
from luxfi_dex import LXDexClient
|
||||
from luxfi_dex import Client
|
||||
|
||||
client = LXDexClient("http://localhost:8080/rpc")
|
||||
client = Client("http://localhost:8080/rpc")
|
||||
|
||||
def place_order_thread(symbol: str, price: float):
|
||||
order = client.place_order(
|
||||
@@ -599,10 +599,10 @@ The async client is designed for single-threaded async code. Use `asyncio.gather
|
||||
|
||||
```python
|
||||
import asyncio
|
||||
from luxfi_dex import AsyncLXDexClient
|
||||
from luxfi_dex import AsyncClient
|
||||
|
||||
async def main():
|
||||
async with AsyncLXDexClient("http://localhost:8080/rpc") as client:
|
||||
async with AsyncClient("http://localhost:8080/rpc") as client:
|
||||
# Concurrent operations in same event loop
|
||||
tasks = [
|
||||
client.place_order("BTC-USD", "limit", "buy", 50000 + i * 100, 1.0)
|
||||
@@ -620,7 +620,7 @@ asyncio.run(main())
|
||||
Both clients use connection pooling internally for efficient resource usage:
|
||||
|
||||
```python
|
||||
from luxfi_dex import LXDexClient
|
||||
from luxfi_dex import Client
|
||||
from luxfi_dex.config import ClientConfig
|
||||
|
||||
config = ClientConfig(
|
||||
@@ -631,7 +631,7 @@ config = ClientConfig(
|
||||
pool_block=True
|
||||
)
|
||||
|
||||
client = LXDexClient(config=config)
|
||||
client = Client(config=config)
|
||||
```
|
||||
|
||||
## Next Steps
|
||||
|
||||
@@ -46,10 +46,10 @@ pip install "luxfi-dex[dev]"
|
||||
### Basic Usage
|
||||
|
||||
```python
|
||||
from luxfi_dex import LXDexClient
|
||||
from luxfi_dex import Client
|
||||
|
||||
# Initialize client
|
||||
client = LXDexClient(
|
||||
client = Client(
|
||||
json_rpc_url="http://localhost:8080/rpc",
|
||||
ws_url="ws://localhost:8081"
|
||||
)
|
||||
@@ -69,9 +69,9 @@ print(f"Spread: {book.spread}")
|
||||
### Place an Order
|
||||
|
||||
```python
|
||||
from luxfi_dex import LXDexClient, OrderType, Side
|
||||
from luxfi_dex import Client, OrderType, Side
|
||||
|
||||
client = LXDexClient("http://localhost:8080/rpc")
|
||||
client = Client("http://localhost:8080/rpc")
|
||||
|
||||
# Place a limit buy order
|
||||
order = client.place_order(
|
||||
@@ -92,10 +92,10 @@ print(f"Filled: {order.filled_size}/{order.size}")
|
||||
|
||||
```python
|
||||
import asyncio
|
||||
from luxfi_dex import AsyncLXDexClient, OrderType, Side
|
||||
from luxfi_dex import AsyncClient, OrderType, Side
|
||||
|
||||
async def main() -> None:
|
||||
async with AsyncLXDexClient("http://localhost:8080/rpc") as client:
|
||||
async with AsyncClient("http://localhost:8080/rpc") as client:
|
||||
# Place order asynchronously
|
||||
order = await client.place_order(
|
||||
symbol="BTC-USD",
|
||||
@@ -120,7 +120,7 @@ asyncio.run(main())
|
||||
### Client Options
|
||||
|
||||
```python
|
||||
from luxfi_dex import LXDexClient
|
||||
from luxfi_dex import Client
|
||||
from luxfi_dex.config import ClientConfig, RetryConfig
|
||||
|
||||
config = ClientConfig(
|
||||
@@ -136,7 +136,7 @@ config = ClientConfig(
|
||||
)
|
||||
)
|
||||
|
||||
client = LXDexClient(config=config)
|
||||
client = Client(config=config)
|
||||
```
|
||||
|
||||
### Environment Variables
|
||||
@@ -149,10 +149,10 @@ export LX_DEX_API_SECRET="your-api-secret"
|
||||
```
|
||||
|
||||
```python
|
||||
from luxfi_dex import LXDexClient
|
||||
from luxfi_dex import Client
|
||||
|
||||
# Automatically reads from environment
|
||||
client = LXDexClient.from_env()
|
||||
client = Client.from_env()
|
||||
```
|
||||
|
||||
## Type Definitions
|
||||
@@ -207,7 +207,7 @@ type Timestamp = int # Unix milliseconds
|
||||
## Exception Handling
|
||||
|
||||
```python
|
||||
from luxfi_dex import LXDexClient
|
||||
from luxfi_dex import Client
|
||||
from luxfi_dex.exceptions import (
|
||||
LXDexError,
|
||||
ConnectionError,
|
||||
@@ -218,7 +218,7 @@ from luxfi_dex.exceptions import (
|
||||
ValidationError
|
||||
)
|
||||
|
||||
client = LXDexClient("http://localhost:8080/rpc")
|
||||
client = Client("http://localhost:8080/rpc")
|
||||
|
||||
try:
|
||||
order = client.place_order(
|
||||
@@ -247,11 +247,11 @@ except LXDexError as e:
|
||||
import nest_asyncio
|
||||
nest_asyncio.apply()
|
||||
|
||||
from luxfi_dex import AsyncLXDexClient
|
||||
from luxfi_dex import AsyncClient
|
||||
import pandas as pd
|
||||
|
||||
async def analyze_order_book():
|
||||
async with AsyncLXDexClient("http://localhost:8080/rpc") as client:
|
||||
async with AsyncClient("http://localhost:8080/rpc") as client:
|
||||
book = await client.get_order_book("BTC-USD", depth=20)
|
||||
|
||||
# Convert to DataFrame
|
||||
@@ -270,7 +270,7 @@ await analyze_order_book()
|
||||
### Mainnet
|
||||
|
||||
```python
|
||||
client = LXDexClient(
|
||||
client = Client(
|
||||
json_rpc_url="https://api.lux.network/rpc",
|
||||
ws_url="wss://api.lux.network/ws"
|
||||
)
|
||||
@@ -279,7 +279,7 @@ client = LXDexClient(
|
||||
### Testnet
|
||||
|
||||
```python
|
||||
client = LXDexClient(
|
||||
client = Client(
|
||||
json_rpc_url="https://testnet-api.lux.network/rpc",
|
||||
ws_url="wss://testnet-api.lux.network/ws"
|
||||
)
|
||||
@@ -288,7 +288,7 @@ client = LXDexClient(
|
||||
### Local Development
|
||||
|
||||
```python
|
||||
client = LXDexClient(
|
||||
client = Client(
|
||||
json_rpc_url="http://localhost:8080/rpc",
|
||||
ws_url="ws://localhost:8081"
|
||||
)
|
||||
@@ -298,7 +298,7 @@ client = LXDexClient(
|
||||
|
||||
| Module | Description |
|
||||
|--------|-------------|
|
||||
| [Client](/docs/sdk/python/client) | LXDexClient and AsyncLXDexClient classes |
|
||||
| [Client](/docs/sdk/python/client) | Client and AsyncClient classes |
|
||||
| [Orders](/docs/sdk/python/orders) | Order placement, cancellation, and management |
|
||||
| [Order Book](/docs/sdk/python/orderbook) | Order book data and subscriptions |
|
||||
| [Trades](/docs/sdk/python/trades) | Trade history and streaming |
|
||||
|
||||
@@ -70,9 +70,9 @@ class OrderBook:
|
||||
### Basic Usage
|
||||
|
||||
```python
|
||||
from luxfi_dex import LXDexClient
|
||||
from luxfi_dex import Client
|
||||
|
||||
client = LXDexClient("http://localhost:8080/rpc")
|
||||
client = Client("http://localhost:8080/rpc")
|
||||
|
||||
# Get order book with default depth (10 levels)
|
||||
book = client.get_order_book("BTC-USD")
|
||||
@@ -112,10 +112,10 @@ deep_book = client.get_order_book("BTC-USD", depth=100)
|
||||
|
||||
```python
|
||||
import asyncio
|
||||
from luxfi_dex import AsyncLXDexClient
|
||||
from luxfi_dex import AsyncClient
|
||||
|
||||
async def get_multiple_books():
|
||||
async with AsyncLXDexClient("http://localhost:8080/rpc") as client:
|
||||
async with AsyncClient("http://localhost:8080/rpc") as client:
|
||||
symbols = ["BTC-USD", "ETH-USD", "SOL-USD", "AVAX-USD"]
|
||||
|
||||
books = await asyncio.gather(*[
|
||||
@@ -132,9 +132,9 @@ asyncio.run(get_multiple_books())
|
||||
## Best Bid/Ask
|
||||
|
||||
```python
|
||||
from luxfi_dex import LXDexClient
|
||||
from luxfi_dex import Client
|
||||
|
||||
client = LXDexClient("http://localhost:8080/rpc")
|
||||
client = Client("http://localhost:8080/rpc")
|
||||
|
||||
# Get best bid only
|
||||
best_bid = client.get_best_bid("BTC-USD")
|
||||
@@ -158,9 +158,9 @@ print(f"Spread: {spread:.2f} ({spread_bps:.2f} bps)")
|
||||
|
||||
```python
|
||||
import pandas as pd
|
||||
from luxfi_dex import LXDexClient
|
||||
from luxfi_dex import Client
|
||||
|
||||
client = LXDexClient("http://localhost:8080/rpc")
|
||||
client = Client("http://localhost:8080/rpc")
|
||||
book = client.get_order_book("BTC-USD", depth=20)
|
||||
|
||||
# Convert bids to DataFrame
|
||||
@@ -187,9 +187,9 @@ print(df)
|
||||
### Built-in to_dataframe Method
|
||||
|
||||
```python
|
||||
from luxfi_dex import LXDexClient
|
||||
from luxfi_dex import Client
|
||||
|
||||
client = LXDexClient("http://localhost:8080/rpc")
|
||||
client = Client("http://localhost:8080/rpc")
|
||||
book = client.get_order_book("BTC-USD", depth=50)
|
||||
|
||||
# Direct conversion
|
||||
@@ -205,9 +205,9 @@ print(df.tail(10))
|
||||
```python
|
||||
import pandas as pd
|
||||
import numpy as np
|
||||
from luxfi_dex import LXDexClient
|
||||
from luxfi_dex import Client
|
||||
|
||||
client = LXDexClient("http://localhost:8080/rpc")
|
||||
client = Client("http://localhost:8080/rpc")
|
||||
book = client.get_order_book("BTC-USD", depth=100)
|
||||
df = book.to_dataframe()
|
||||
|
||||
@@ -257,9 +257,9 @@ print(f" Avg ask size: {asks['size'].mean():.4f}")
|
||||
```python
|
||||
import pandas as pd
|
||||
import numpy as np
|
||||
from luxfi_dex import LXDexClient
|
||||
from luxfi_dex import Client
|
||||
|
||||
client = LXDexClient("http://localhost:8080/rpc")
|
||||
client = Client("http://localhost:8080/rpc")
|
||||
book = client.get_order_book("BTC-USD", depth=200)
|
||||
df = book.to_dataframe()
|
||||
|
||||
@@ -289,9 +289,9 @@ print(asks.nlargest(5, "size")[["price", "size", "orders"]])
|
||||
### Synchronous Subscription
|
||||
|
||||
```python
|
||||
from luxfi_dex import LXDexClient
|
||||
from luxfi_dex import Client
|
||||
|
||||
client = LXDexClient(
|
||||
client = Client(
|
||||
json_rpc_url="http://localhost:8080/rpc",
|
||||
ws_url="ws://localhost:8081"
|
||||
)
|
||||
@@ -322,10 +322,10 @@ except KeyboardInterrupt:
|
||||
|
||||
```python
|
||||
import asyncio
|
||||
from luxfi_dex import AsyncLXDexClient
|
||||
from luxfi_dex import AsyncClient
|
||||
|
||||
async def stream_order_book():
|
||||
async with AsyncLXDexClient(
|
||||
async with AsyncClient(
|
||||
json_rpc_url="http://localhost:8080/rpc",
|
||||
ws_url="ws://localhost:8081"
|
||||
) as client:
|
||||
@@ -344,10 +344,10 @@ asyncio.run(stream_order_book())
|
||||
|
||||
```python
|
||||
import asyncio
|
||||
from luxfi_dex import AsyncLXDexClient
|
||||
from luxfi_dex import AsyncClient
|
||||
|
||||
async def stream_multiple_books():
|
||||
async with AsyncLXDexClient(
|
||||
async with AsyncClient(
|
||||
json_rpc_url="http://localhost:8080/rpc",
|
||||
ws_url="ws://localhost:8081"
|
||||
) as client:
|
||||
@@ -371,7 +371,7 @@ For high-frequency applications, use delta updates instead of full snapshots:
|
||||
|
||||
```python
|
||||
from dataclasses import dataclass
|
||||
from luxfi_dex import AsyncLXDexClient
|
||||
from luxfi_dex import AsyncClient
|
||||
from luxfi_dex.types import OrderBookDelta, DeltaType
|
||||
|
||||
@dataclass
|
||||
@@ -385,7 +385,7 @@ class OrderBookDelta:
|
||||
size: float # New size (0 for DELETE)
|
||||
|
||||
async def process_deltas():
|
||||
async with AsyncLXDexClient(
|
||||
async with AsyncClient(
|
||||
json_rpc_url="http://localhost:8080/rpc",
|
||||
ws_url="ws://localhost:8081"
|
||||
) as client:
|
||||
@@ -412,9 +412,9 @@ def apply_delta(local_book: dict, delta: OrderBookDelta) -> None:
|
||||
|
||||
```python
|
||||
import pandas as pd
|
||||
from luxfi_dex import LXDexClient
|
||||
from luxfi_dex import Client
|
||||
|
||||
client = LXDexClient("http://localhost:8080/rpc")
|
||||
client = Client("http://localhost:8080/rpc")
|
||||
|
||||
def calculate_imbalance(book: OrderBook, levels: int = 5) -> float:
|
||||
"""Calculate order book imbalance.
|
||||
@@ -448,9 +448,9 @@ else:
|
||||
|
||||
```python
|
||||
import numpy as np
|
||||
from luxfi_dex import LXDexClient
|
||||
from luxfi_dex import Client
|
||||
|
||||
client = LXDexClient("http://localhost:8080/rpc")
|
||||
client = Client("http://localhost:8080/rpc")
|
||||
book = client.get_order_book("BTC-USD", depth=100)
|
||||
|
||||
# Convert to numpy arrays
|
||||
@@ -490,11 +490,11 @@ nest_asyncio.apply()
|
||||
|
||||
import pandas as pd
|
||||
import numpy as np
|
||||
from luxfi_dex import AsyncLXDexClient
|
||||
from luxfi_dex import AsyncClient
|
||||
|
||||
# Cell 2: Fetch and analyze order book
|
||||
async def analyze_book():
|
||||
async with AsyncLXDexClient("http://localhost:8080/rpc") as client:
|
||||
async with AsyncClient("http://localhost:8080/rpc") as client:
|
||||
book = await client.get_order_book("BTC-USD", depth=50)
|
||||
return book.to_dataframe()
|
||||
|
||||
@@ -523,7 +523,7 @@ plt.show()
|
||||
# Cell 4: Continuous monitoring
|
||||
async def monitor_spread(duration_seconds: int = 60):
|
||||
spreads = []
|
||||
async with AsyncLXDexClient(
|
||||
async with AsyncClient(
|
||||
json_rpc_url="http://localhost:8080/rpc",
|
||||
ws_url="ws://localhost:8081"
|
||||
) as client:
|
||||
@@ -546,14 +546,14 @@ display(spread_df.describe())
|
||||
## Error Handling
|
||||
|
||||
```python
|
||||
from luxfi_dex import LXDexClient
|
||||
from luxfi_dex import Client
|
||||
from luxfi_dex.exceptions import (
|
||||
SymbolNotFoundError,
|
||||
ConnectionError,
|
||||
RateLimitError
|
||||
)
|
||||
|
||||
client = LXDexClient("http://localhost:8080/rpc")
|
||||
client = Client("http://localhost:8080/rpc")
|
||||
|
||||
try:
|
||||
book = client.get_order_book("INVALID-SYMBOL")
|
||||
|
||||
@@ -26,9 +26,9 @@ OrderType.PEG # Pegged to best bid/ask
|
||||
### Limit Order
|
||||
|
||||
```python
|
||||
from luxfi_dex import LXDexClient, OrderType, Side, TimeInForce
|
||||
from luxfi_dex import Client, OrderType, Side, TimeInForce
|
||||
|
||||
client = LXDexClient("http://localhost:8080/rpc")
|
||||
client = Client("http://localhost:8080/rpc")
|
||||
|
||||
# Basic limit order
|
||||
order = client.place_order(
|
||||
@@ -240,10 +240,10 @@ cancelled_orders = client.cancel_all_orders(
|
||||
|
||||
```python
|
||||
import asyncio
|
||||
from luxfi_dex import AsyncLXDexClient
|
||||
from luxfi_dex import AsyncClient
|
||||
|
||||
async def cancel_orders():
|
||||
async with AsyncLXDexClient("http://localhost:8080/rpc") as client:
|
||||
async with AsyncClient("http://localhost:8080/rpc") as client:
|
||||
# Cancel multiple orders concurrently
|
||||
order_ids = ["ord_1", "ord_2", "ord_3", "ord_4", "ord_5"]
|
||||
|
||||
@@ -377,10 +377,10 @@ for result in results:
|
||||
|
||||
```python
|
||||
import asyncio
|
||||
from luxfi_dex import AsyncLXDexClient
|
||||
from luxfi_dex import AsyncClient
|
||||
|
||||
async def place_batch_orders():
|
||||
async with AsyncLXDexClient("http://localhost:8080/rpc") as client:
|
||||
async with AsyncClient("http://localhost:8080/rpc") as client:
|
||||
# Prepare orders
|
||||
order_params = [
|
||||
("BTC-USD", 49000.0, 1.0),
|
||||
@@ -438,10 +438,10 @@ new_order = client.replace_order(
|
||||
## Order Events Subscription
|
||||
|
||||
```python
|
||||
from luxfi_dex import LXDexClient
|
||||
from luxfi_dex import Client
|
||||
from luxfi_dex.types import OrderEvent, OrderEventType
|
||||
|
||||
client = LXDexClient(
|
||||
client = Client(
|
||||
json_rpc_url="http://localhost:8080/rpc",
|
||||
ws_url="ws://localhost:8081"
|
||||
)
|
||||
@@ -476,10 +476,10 @@ while True:
|
||||
|
||||
```python
|
||||
import asyncio
|
||||
from luxfi_dex import AsyncLXDexClient
|
||||
from luxfi_dex import AsyncClient
|
||||
|
||||
async def monitor_orders():
|
||||
async with AsyncLXDexClient(
|
||||
async with AsyncClient(
|
||||
json_rpc_url="http://localhost:8080/rpc",
|
||||
ws_url="ws://localhost:8081"
|
||||
) as client:
|
||||
@@ -498,9 +498,9 @@ asyncio.run(monitor_orders())
|
||||
|
||||
```python
|
||||
import pandas as pd
|
||||
from luxfi_dex import LXDexClient
|
||||
from luxfi_dex import Client
|
||||
|
||||
client = LXDexClient("http://localhost:8080/rpc")
|
||||
client = Client("http://localhost:8080/rpc")
|
||||
|
||||
# Get orders and convert to DataFrame
|
||||
orders = client.get_orders(symbol="BTC-USD", limit=100)
|
||||
@@ -532,9 +532,9 @@ print(f"Total volume: {df['size'].sum():.4f}")
|
||||
```python
|
||||
import pandas as pd
|
||||
import numpy as np
|
||||
from luxfi_dex import LXDexClient
|
||||
from luxfi_dex import Client
|
||||
|
||||
client = LXDexClient("http://localhost:8080/rpc")
|
||||
client = Client("http://localhost:8080/rpc")
|
||||
|
||||
# Get filled orders
|
||||
filled_orders = client.get_orders(
|
||||
@@ -578,7 +578,7 @@ print(by_side)
|
||||
## Error Handling
|
||||
|
||||
```python
|
||||
from luxfi_dex import LXDexClient
|
||||
from luxfi_dex import Client
|
||||
from luxfi_dex.exceptions import (
|
||||
InsufficientBalanceError,
|
||||
OrderNotFoundError,
|
||||
@@ -587,7 +587,7 @@ from luxfi_dex.exceptions import (
|
||||
LXDexError
|
||||
)
|
||||
|
||||
client = LXDexClient("http://localhost:8080/rpc")
|
||||
client = Client("http://localhost:8080/rpc")
|
||||
|
||||
def place_order_safe(
|
||||
symbol: str,
|
||||
@@ -625,12 +625,12 @@ def place_order_safe(
|
||||
import nest_asyncio
|
||||
nest_asyncio.apply()
|
||||
|
||||
from luxfi_dex import AsyncLXDexClient, OrderType, Side
|
||||
from luxfi_dex import AsyncClient, OrderType, Side
|
||||
import pandas as pd
|
||||
|
||||
# Cell 2: Place orders
|
||||
async def trading_session():
|
||||
async with AsyncLXDexClient("http://localhost:8080/rpc") as client:
|
||||
async with AsyncClient("http://localhost:8080/rpc") as client:
|
||||
# Place ladder of buy orders
|
||||
prices = [49000, 48500, 48000, 47500, 47000]
|
||||
orders = []
|
||||
@@ -659,7 +659,7 @@ display(df)
|
||||
|
||||
# Cell 4: Cancel all orders
|
||||
async def cancel_all():
|
||||
async with AsyncLXDexClient("http://localhost:8080/rpc") as client:
|
||||
async with AsyncClient("http://localhost:8080/rpc") as client:
|
||||
for order in orders:
|
||||
try:
|
||||
await client.cancel_order(order.order_id)
|
||||
|
||||
@@ -47,9 +47,9 @@ class Trade:
|
||||
### Basic Usage
|
||||
|
||||
```python
|
||||
from luxfi_dex import LXDexClient
|
||||
from luxfi_dex import Client
|
||||
|
||||
client = LXDexClient("http://localhost:8080/rpc")
|
||||
client = Client("http://localhost:8080/rpc")
|
||||
|
||||
# Get last 100 trades (default)
|
||||
trades = client.get_trades("BTC-USD")
|
||||
@@ -129,9 +129,9 @@ print(f"Total trades: {len(all_trades)}")
|
||||
|
||||
```python
|
||||
import pandas as pd
|
||||
from luxfi_dex import LXDexClient
|
||||
from luxfi_dex import Client
|
||||
|
||||
client = LXDexClient("http://localhost:8080/rpc")
|
||||
client = Client("http://localhost:8080/rpc")
|
||||
trades = client.get_trades("BTC-USD", limit=1000)
|
||||
|
||||
# Convert to DataFrame
|
||||
@@ -155,9 +155,9 @@ print(df.head(10))
|
||||
### Built-in to_dataframe
|
||||
|
||||
```python
|
||||
from luxfi_dex import LXDexClient
|
||||
from luxfi_dex import Client
|
||||
|
||||
client = LXDexClient("http://localhost:8080/rpc")
|
||||
client = Client("http://localhost:8080/rpc")
|
||||
trades = client.get_trades("BTC-USD", limit=1000)
|
||||
|
||||
# Direct conversion using Trade list helper
|
||||
@@ -172,9 +172,9 @@ print(df.describe())
|
||||
```python
|
||||
import pandas as pd
|
||||
import numpy as np
|
||||
from luxfi_dex import LXDexClient
|
||||
from luxfi_dex import Client
|
||||
|
||||
client = LXDexClient("http://localhost:8080/rpc")
|
||||
client = Client("http://localhost:8080/rpc")
|
||||
trades = client.get_trades("BTC-USD", limit=1000)
|
||||
|
||||
df = pd.DataFrame([
|
||||
@@ -224,9 +224,9 @@ print(f"Buy/Sell imbalance: {imbalance:.3f}")
|
||||
```python
|
||||
import pandas as pd
|
||||
import numpy as np
|
||||
from luxfi_dex import LXDexClient
|
||||
from luxfi_dex import Client
|
||||
|
||||
client = LXDexClient("http://localhost:8080/rpc")
|
||||
client = Client("http://localhost:8080/rpc")
|
||||
trades = client.get_trades("BTC-USD", limit=10000)
|
||||
|
||||
df = pd.DataFrame([
|
||||
@@ -261,10 +261,10 @@ print(f"\nVolatility (1min): {ohlcv['returns'].std() * 100:.4f}%")
|
||||
```python
|
||||
import pandas as pd
|
||||
import numpy as np
|
||||
from luxfi_dex import LXDexClient
|
||||
from luxfi_dex import Client
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
client = LXDexClient("http://localhost:8080/rpc")
|
||||
client = Client("http://localhost:8080/rpc")
|
||||
|
||||
# Get last 24 hours of trades
|
||||
end_time = datetime.now()
|
||||
@@ -323,10 +323,10 @@ print(f"Hours with strong sell pressure: {len(strong_sell)}")
|
||||
### Synchronous Subscription
|
||||
|
||||
```python
|
||||
from luxfi_dex import LXDexClient
|
||||
from luxfi_dex import Client
|
||||
from luxfi_dex.types import Trade
|
||||
|
||||
client = LXDexClient(
|
||||
client = Client(
|
||||
json_rpc_url="http://localhost:8080/rpc",
|
||||
ws_url="ws://localhost:8081"
|
||||
)
|
||||
@@ -353,10 +353,10 @@ except KeyboardInterrupt:
|
||||
|
||||
```python
|
||||
import asyncio
|
||||
from luxfi_dex import AsyncLXDexClient
|
||||
from luxfi_dex import AsyncClient
|
||||
|
||||
async def stream_trades():
|
||||
async with AsyncLXDexClient(
|
||||
async with AsyncClient(
|
||||
json_rpc_url="http://localhost:8080/rpc",
|
||||
ws_url="ws://localhost:8081"
|
||||
) as client:
|
||||
@@ -382,10 +382,10 @@ asyncio.run(stream_trades())
|
||||
|
||||
```python
|
||||
import asyncio
|
||||
from luxfi_dex import AsyncLXDexClient
|
||||
from luxfi_dex import AsyncClient
|
||||
|
||||
async def stream_multiple():
|
||||
async with AsyncLXDexClient(
|
||||
async with AsyncClient(
|
||||
json_rpc_url="http://localhost:8080/rpc",
|
||||
ws_url="ws://localhost:8081"
|
||||
) as client:
|
||||
@@ -408,7 +408,7 @@ asyncio.run(stream_multiple())
|
||||
import asyncio
|
||||
from collections import deque
|
||||
from dataclasses import dataclass, field
|
||||
from luxfi_dex import AsyncLXDexClient
|
||||
from luxfi_dex import AsyncClient
|
||||
from luxfi_dex.types import Trade
|
||||
|
||||
@dataclass
|
||||
@@ -447,7 +447,7 @@ class TradeAggregator:
|
||||
async def main():
|
||||
agg = TradeAggregator(window_seconds=60)
|
||||
|
||||
async with AsyncLXDexClient(
|
||||
async with AsyncClient(
|
||||
json_rpc_url="http://localhost:8080/rpc",
|
||||
ws_url="ws://localhost:8081"
|
||||
) as client:
|
||||
@@ -464,9 +464,9 @@ asyncio.run(main())
|
||||
## User Trades
|
||||
|
||||
```python
|
||||
from luxfi_dex import LXDexClient
|
||||
from luxfi_dex import Client
|
||||
|
||||
client = LXDexClient(
|
||||
client = Client(
|
||||
json_rpc_url="http://localhost:8080/rpc",
|
||||
api_key="your-api-key",
|
||||
api_secret="your-api-secret"
|
||||
@@ -491,10 +491,10 @@ print(f"Order had {len(order_trades)} fills")
|
||||
|
||||
```python
|
||||
import asyncio
|
||||
from luxfi_dex import AsyncLXDexClient
|
||||
from luxfi_dex import AsyncClient
|
||||
|
||||
async def stream_my_trades():
|
||||
async with AsyncLXDexClient(
|
||||
async with AsyncClient(
|
||||
json_rpc_url="http://localhost:8080/rpc",
|
||||
ws_url="ws://localhost:8081",
|
||||
api_key="your-api-key",
|
||||
@@ -513,9 +513,9 @@ asyncio.run(stream_my_trades())
|
||||
```python
|
||||
import pandas as pd
|
||||
import numpy as np
|
||||
from luxfi_dex import LXDexClient
|
||||
from luxfi_dex import Client
|
||||
|
||||
client = LXDexClient("http://localhost:8080/rpc")
|
||||
client = Client("http://localhost:8080/rpc")
|
||||
trades = client.get_trades("BTC-USD", limit=5000)
|
||||
|
||||
df = pd.DataFrame([
|
||||
@@ -570,11 +570,11 @@ nest_asyncio.apply()
|
||||
|
||||
import pandas as pd
|
||||
import numpy as np
|
||||
from luxfi_dex import AsyncLXDexClient
|
||||
from luxfi_dex import AsyncClient
|
||||
|
||||
# Cell 2: Fetch trades
|
||||
async def fetch_trades(symbol: str, limit: int = 1000):
|
||||
async with AsyncLXDexClient("http://localhost:8080/rpc") as client:
|
||||
async with AsyncClient("http://localhost:8080/rpc") as client:
|
||||
trades = await client.get_trades(symbol, limit=limit)
|
||||
return pd.DataFrame([
|
||||
{
|
||||
@@ -631,7 +631,7 @@ plt.show()
|
||||
# Cell 5: Stream trades in notebook
|
||||
async def stream_and_display(duration_seconds: int = 30):
|
||||
trades = []
|
||||
async with AsyncLXDexClient(
|
||||
async with AsyncClient(
|
||||
json_rpc_url="http://localhost:8080/rpc",
|
||||
ws_url="ws://localhost:8081"
|
||||
) as client:
|
||||
@@ -656,14 +656,14 @@ print(f"Captured {len(live_df)} trades in 30 seconds")
|
||||
## Error Handling
|
||||
|
||||
```python
|
||||
from luxfi_dex import LXDexClient
|
||||
from luxfi_dex import Client
|
||||
from luxfi_dex.exceptions import (
|
||||
SymbolNotFoundError,
|
||||
ConnectionError,
|
||||
RateLimitError
|
||||
)
|
||||
|
||||
client = LXDexClient("http://localhost:8080/rpc")
|
||||
client = Client("http://localhost:8080/rpc")
|
||||
|
||||
try:
|
||||
trades = client.get_trades("INVALID-SYMBOL")
|
||||
|
||||
@@ -12,10 +12,10 @@ Access account information, balances, positions, and margin data using the TypeS
|
||||
The SDK provides access to account data through the main client and specialized sub-clients:
|
||||
|
||||
```typescript
|
||||
import { LXDexClient } from '@luxfi/dex-sdk';
|
||||
import { Client } from '@luxfi/trading';
|
||||
|
||||
const client = new LXDexClient({
|
||||
jsonRpcUrl: 'http://localhost:8080/rpc',
|
||||
const client = new Client({
|
||||
rpcUrl: 'http://localhost:8080/rpc',
|
||||
wsUrl: 'ws://localhost:8081'
|
||||
});
|
||||
|
||||
@@ -31,11 +31,11 @@ const liquidationMonitor = client.liquidationMonitor;
|
||||
### Get Margin Status
|
||||
|
||||
```typescript
|
||||
import { LXDexClient, MarginInfo } from '@luxfi/dex-sdk';
|
||||
import { Client, MarginInfo } from '@luxfi/trading';
|
||||
|
||||
async function getMarginStatus(userId: string): Promise<MarginInfo> {
|
||||
const client = new LXDexClient({
|
||||
jsonRpcUrl: 'http://localhost:8080/rpc'
|
||||
const client = new Client({
|
||||
rpcUrl: 'http://localhost:8080/rpc'
|
||||
});
|
||||
|
||||
const margin = await client.marketData.getMarginInfo(userId);
|
||||
@@ -70,11 +70,11 @@ interface MarginInfo {
|
||||
### Check Liquidation Risk
|
||||
|
||||
```typescript
|
||||
import { LXDexClient, LiquidationRisk } from '@luxfi/dex-sdk';
|
||||
import { Client, LiquidationRisk } from '@luxfi/trading';
|
||||
|
||||
async function checkLiquidationRisk(userId: string): Promise<LiquidationRisk> {
|
||||
const client = new LXDexClient({
|
||||
jsonRpcUrl: 'http://localhost:8080/rpc'
|
||||
const client = new Client({
|
||||
rpcUrl: 'http://localhost:8080/rpc'
|
||||
});
|
||||
|
||||
const risk = await client.marketData.checkLiquidationRisk(userId);
|
||||
@@ -113,7 +113,7 @@ interface LiquidationRisk {
|
||||
### Risk Level Actions
|
||||
|
||||
```typescript
|
||||
import { LiquidationRisk } from '@luxfi/dex-sdk';
|
||||
import { LiquidationRisk } from '@luxfi/trading';
|
||||
|
||||
function handleRiskLevel(risk: LiquidationRisk): void {
|
||||
switch (risk.riskLevel) {
|
||||
@@ -144,11 +144,11 @@ function handleRiskLevel(risk: LiquidationRisk): void {
|
||||
### Query Liquidations
|
||||
|
||||
```typescript
|
||||
import { LXDexClient, LiquidationInfo } from '@luxfi/dex-sdk';
|
||||
import { Client, LiquidationInfo } from '@luxfi/trading';
|
||||
|
||||
async function getRecentLiquidations(symbol: string): Promise<LiquidationInfo[]> {
|
||||
const client = new LXDexClient({
|
||||
jsonRpcUrl: 'http://localhost:8080/rpc'
|
||||
const client = new Client({
|
||||
rpcUrl: 'http://localhost:8080/rpc'
|
||||
});
|
||||
|
||||
const liquidations = await client.marketData.getLiquidations(symbol, 100);
|
||||
@@ -188,11 +188,11 @@ interface LiquidationInfo {
|
||||
### Subscribe to Liquidations
|
||||
|
||||
```typescript
|
||||
import { LXDexClient, LiquidationInfo } from '@luxfi/dex-sdk';
|
||||
import { Client, LiquidationInfo } from '@luxfi/trading';
|
||||
|
||||
async function monitorLiquidations(): Promise<void> {
|
||||
const client = new LXDexClient({
|
||||
jsonRpcUrl: 'http://localhost:8080/rpc',
|
||||
const client = new Client({
|
||||
rpcUrl: 'http://localhost:8080/rpc',
|
||||
wsUrl: 'ws://localhost:8081'
|
||||
});
|
||||
|
||||
@@ -213,7 +213,7 @@ async function monitorLiquidations(): Promise<void> {
|
||||
### Subscribe to Margin Calls
|
||||
|
||||
```typescript
|
||||
import { LXDexClient } from '@luxfi/dex-sdk';
|
||||
import { Client } from '@luxfi/trading';
|
||||
|
||||
interface MarginCallEvent {
|
||||
userId: string;
|
||||
@@ -223,8 +223,8 @@ interface MarginCallEvent {
|
||||
}
|
||||
|
||||
async function monitorMarginCalls(userId: string): Promise<void> {
|
||||
const client = new LXDexClient({
|
||||
jsonRpcUrl: 'http://localhost:8080/rpc',
|
||||
const client = new Client({
|
||||
rpcUrl: 'http://localhost:8080/rpc',
|
||||
wsUrl: 'ws://localhost:8081'
|
||||
});
|
||||
|
||||
@@ -246,11 +246,11 @@ async function monitorMarginCalls(userId: string): Promise<void> {
|
||||
### Get Settlement Batch
|
||||
|
||||
```typescript
|
||||
import { LXDexClient, SettlementBatch } from '@luxfi/dex-sdk';
|
||||
import { Client, SettlementBatch } from '@luxfi/trading';
|
||||
|
||||
async function getSettlementInfo(batchId: number): Promise<SettlementBatch> {
|
||||
const client = new LXDexClient({
|
||||
jsonRpcUrl: 'http://localhost:8080/rpc'
|
||||
const client = new Client({
|
||||
rpcUrl: 'http://localhost:8080/rpc'
|
||||
});
|
||||
|
||||
const batch = await client.marketData.getSettlementBatch(batchId);
|
||||
@@ -289,11 +289,11 @@ interface SettlementBatch {
|
||||
### Subscribe to Settlements
|
||||
|
||||
```typescript
|
||||
import { LXDexClient, SettlementBatch } from '@luxfi/dex-sdk';
|
||||
import { Client, SettlementBatch } from '@luxfi/trading';
|
||||
|
||||
async function monitorSettlements(): Promise<void> {
|
||||
const client = new LXDexClient({
|
||||
jsonRpcUrl: 'http://localhost:8080/rpc',
|
||||
const client = new Client({
|
||||
rpcUrl: 'http://localhost:8080/rpc',
|
||||
wsUrl: 'ws://localhost:8081'
|
||||
});
|
||||
|
||||
@@ -315,11 +315,11 @@ async function monitorSettlements(): Promise<void> {
|
||||
### Get Insurance Fund Status
|
||||
|
||||
```typescript
|
||||
import { LXDexClient, InsuranceFundStatus } from '@luxfi/dex-sdk';
|
||||
import { Client, InsuranceFundStatus } from '@luxfi/trading';
|
||||
|
||||
async function getInsuranceFundStatus(): Promise<InsuranceFundStatus> {
|
||||
const client = new LXDexClient({
|
||||
jsonRpcUrl: 'http://localhost:8080/rpc'
|
||||
const client = new Client({
|
||||
rpcUrl: 'http://localhost:8080/rpc'
|
||||
});
|
||||
|
||||
const fund = await client.marketData.getInsuranceFundStatus();
|
||||
@@ -353,7 +353,7 @@ interface InsuranceFundStatus {
|
||||
|
||||
```tsx
|
||||
import { useState, useEffect } from 'react';
|
||||
import { LXDexClient, MarginInfo } from '@luxfi/dex-sdk';
|
||||
import { Client, MarginInfo } from '@luxfi/trading';
|
||||
|
||||
interface UseMarginResult {
|
||||
margin: MarginInfo | null;
|
||||
@@ -363,7 +363,7 @@ interface UseMarginResult {
|
||||
}
|
||||
|
||||
export function useMargin(
|
||||
client: LXDexClient | null,
|
||||
client: Client | null,
|
||||
userId: string
|
||||
): UseMarginResult {
|
||||
const [margin, setMargin] = useState<MarginInfo | null>(null);
|
||||
@@ -405,7 +405,7 @@ export function useMargin(
|
||||
|
||||
```tsx
|
||||
import { useState, useEffect } from 'react';
|
||||
import { LXDexClient, LiquidationRisk } from '@luxfi/dex-sdk';
|
||||
import { Client, LiquidationRisk } from '@luxfi/trading';
|
||||
|
||||
interface UseLiquidationRiskResult {
|
||||
risk: LiquidationRisk | null;
|
||||
@@ -414,7 +414,7 @@ interface UseLiquidationRiskResult {
|
||||
}
|
||||
|
||||
export function useLiquidationRisk(
|
||||
client: LXDexClient | null,
|
||||
client: Client | null,
|
||||
userId: string
|
||||
): UseLiquidationRiskResult {
|
||||
const [risk, setRisk] = useState<LiquidationRisk | null>(null);
|
||||
@@ -524,7 +524,7 @@ export default AccountDashboard;
|
||||
### Complete Account Monitor
|
||||
|
||||
```typescript
|
||||
import { LXDexClient, MarginInfo, LiquidationRisk, LiquidationInfo } from '@luxfi/dex-sdk';
|
||||
import { Client, MarginInfo, LiquidationRisk, LiquidationInfo } from '@luxfi/trading';
|
||||
|
||||
interface AccountMonitorOptions {
|
||||
marginCheckInterval?: number;
|
||||
@@ -536,7 +536,7 @@ interface AccountMonitorOptions {
|
||||
}
|
||||
|
||||
export class AccountMonitor {
|
||||
private client: LXDexClient;
|
||||
private client: Client;
|
||||
private userId: string;
|
||||
private options: AccountMonitorOptions;
|
||||
private marginInterval: NodeJS.Timeout | null = null;
|
||||
@@ -544,7 +544,7 @@ export class AccountMonitor {
|
||||
private running: boolean = false;
|
||||
|
||||
constructor(
|
||||
client: LXDexClient,
|
||||
client: Client,
|
||||
userId: string,
|
||||
options: AccountMonitorOptions = {}
|
||||
) {
|
||||
@@ -631,8 +631,8 @@ export class AccountMonitor {
|
||||
|
||||
// Usage
|
||||
async function runAccountMonitor(): Promise<void> {
|
||||
const client = new LXDexClient({
|
||||
jsonRpcUrl: 'http://localhost:8080/rpc',
|
||||
const client = new Client({
|
||||
rpcUrl: 'http://localhost:8080/rpc',
|
||||
wsUrl: 'ws://localhost:8081'
|
||||
});
|
||||
|
||||
|
||||
@@ -1,63 +1,75 @@
|
||||
---
|
||||
title: Client Configuration
|
||||
description: LXDexClient class configuration, initialization options, and connection management
|
||||
description: Client class configuration, initialization options, and connection management
|
||||
---
|
||||
|
||||
# LXDexClient Configuration
|
||||
# Client Configuration
|
||||
|
||||
The `LXDexClient` class is the main entry point for interacting with LX. This guide covers all configuration options and initialization patterns.
|
||||
The `Client` class is the main entry point for interacting with LX. For simple use cases, you can use the `DEX()` factory function. This guide covers all configuration options and initialization patterns.
|
||||
|
||||
## Basic Initialization
|
||||
## Quick Start
|
||||
|
||||
```typescript
|
||||
import { LXDexClient } from '@luxfi/dex-sdk';
|
||||
import { DEX } from '@luxfi/trading'
|
||||
|
||||
const client = new LXDexClient({
|
||||
jsonRpcUrl: 'http://localhost:8080/rpc',
|
||||
// Simple initialization with DEX factory
|
||||
const dex = await DEX({ rpcUrl: 'http://localhost:8080/rpc' })
|
||||
|
||||
// Place an order
|
||||
const order = await dex.limitBuy('BTC-USD', '1.0', '50000')
|
||||
```
|
||||
|
||||
## Advanced Initialization
|
||||
|
||||
```typescript
|
||||
import { Client, ClientConfig } from '@luxfi/trading'
|
||||
|
||||
const client = new Client({
|
||||
rpcUrl: 'http://localhost:8080/rpc',
|
||||
wsUrl: 'ws://localhost:8081'
|
||||
});
|
||||
})
|
||||
```
|
||||
|
||||
## Configuration Options
|
||||
|
||||
### LXDexConfig Interface
|
||||
### ClientConfig Interface
|
||||
|
||||
```typescript
|
||||
interface LXDexConfig {
|
||||
interface ClientConfig {
|
||||
/** JSON-RPC endpoint URL */
|
||||
jsonRpcUrl?: string;
|
||||
rpcUrl?: string
|
||||
|
||||
/** WebSocket endpoint URL */
|
||||
wsUrl?: string;
|
||||
wsUrl?: string
|
||||
|
||||
/** gRPC endpoint URL (for high-performance operations) */
|
||||
grpcUrl?: string;
|
||||
grpcUrl?: string
|
||||
|
||||
/** API key for authenticated requests */
|
||||
apiKey?: string;
|
||||
apiKey?: string
|
||||
|
||||
/** API secret for request signing */
|
||||
apiSecret?: string;
|
||||
apiSecret?: string
|
||||
|
||||
/** Request timeout in milliseconds (default: 30000) */
|
||||
timeout?: number;
|
||||
timeout?: number
|
||||
|
||||
/** Retry configuration */
|
||||
retry?: {
|
||||
maxRetries: number;
|
||||
backoffMs: number;
|
||||
};
|
||||
maxRetries: number
|
||||
backoffMs: number
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Full Configuration Example
|
||||
|
||||
```typescript
|
||||
import { LXDexClient } from '@luxfi/dex-sdk';
|
||||
import { Client } from '@luxfi/trading'
|
||||
|
||||
const client = new LXDexClient({
|
||||
const client = new Client({
|
||||
// API endpoints
|
||||
jsonRpcUrl: 'https://api.lux.network/rpc',
|
||||
rpcUrl: 'https://api.lux.network/rpc',
|
||||
wsUrl: 'wss://api.lux.network/ws',
|
||||
grpcUrl: 'api.lux.network:50051',
|
||||
|
||||
@@ -71,7 +83,7 @@ const client = new LXDexClient({
|
||||
maxRetries: 3,
|
||||
backoffMs: 1000
|
||||
}
|
||||
});
|
||||
})
|
||||
```
|
||||
|
||||
## Environment-Based Configuration
|
||||
@@ -79,24 +91,24 @@ const client = new LXDexClient({
|
||||
### Configuration Factory Pattern
|
||||
|
||||
```typescript
|
||||
import { LXDexClient, LXDexConfig } from '@luxfi/dex-sdk';
|
||||
import { Client, ClientConfig } from '@luxfi/trading'
|
||||
|
||||
type Environment = 'development' | 'testnet' | 'production';
|
||||
type Environment = 'development' | 'testnet' | 'production'
|
||||
|
||||
function createConfig(env: Environment): LXDexConfig {
|
||||
const configs: Record<Environment, LXDexConfig> = {
|
||||
function createConfig(env: Environment): ClientConfig {
|
||||
const configs: Record<Environment, ClientConfig> = {
|
||||
development: {
|
||||
jsonRpcUrl: 'http://localhost:8080/rpc',
|
||||
rpcUrl: 'http://localhost:8080/rpc',
|
||||
wsUrl: 'ws://localhost:8081',
|
||||
timeout: 60000 // Longer timeout for debugging
|
||||
},
|
||||
testnet: {
|
||||
jsonRpcUrl: 'http://localhost:18080/rpc',
|
||||
rpcUrl: 'http://localhost:18080/rpc',
|
||||
wsUrl: 'ws://localhost:18081',
|
||||
timeout: 30000
|
||||
},
|
||||
production: {
|
||||
jsonRpcUrl: 'https://api.lux.network/rpc',
|
||||
rpcUrl: 'https://api.lux.network/rpc',
|
||||
wsUrl: 'wss://api.lux.network/ws',
|
||||
apiKey: process.env.LX_DEX_API_KEY,
|
||||
timeout: 15000,
|
||||
@@ -105,14 +117,14 @@ function createConfig(env: Environment): LXDexConfig {
|
||||
backoffMs: 500
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return configs[env];
|
||||
return configs[env]
|
||||
}
|
||||
|
||||
// Usage
|
||||
const env = (process.env.NODE_ENV as Environment) || 'development';
|
||||
const client = new LXDexClient(createConfig(env));
|
||||
const env = (process.env.NODE_ENV as Environment) || 'development'
|
||||
const client = new Client(createConfig(env))
|
||||
```
|
||||
|
||||
## Connection Management
|
||||
@@ -122,73 +134,73 @@ const client = new LXDexClient(createConfig(env));
|
||||
The WebSocket connection must be explicitly established for real-time subscriptions:
|
||||
|
||||
```typescript
|
||||
import { LXDexClient } from '@luxfi/dex-sdk';
|
||||
import { Client } from '@luxfi/trading'
|
||||
|
||||
async function setupClient(): Promise<LXDexClient> {
|
||||
const client = new LXDexClient({
|
||||
jsonRpcUrl: 'http://localhost:8080/rpc',
|
||||
async function setupClient(): Promise<Client> {
|
||||
const client = new Client({
|
||||
rpcUrl: 'http://localhost:8080/rpc',
|
||||
wsUrl: 'ws://localhost:8081'
|
||||
});
|
||||
})
|
||||
|
||||
// Connect WebSocket for real-time data
|
||||
await client.connect();
|
||||
console.log('WebSocket connected');
|
||||
await client.connect()
|
||||
console.log('WebSocket connected')
|
||||
|
||||
return client;
|
||||
return client
|
||||
}
|
||||
```
|
||||
|
||||
### Disconnecting
|
||||
|
||||
```typescript
|
||||
function cleanup(client: LXDexClient): void {
|
||||
function cleanup(client: Client): void {
|
||||
// Gracefully close WebSocket connection
|
||||
client.disconnect();
|
||||
console.log('Client disconnected');
|
||||
client.disconnect()
|
||||
console.log('Client disconnected')
|
||||
}
|
||||
```
|
||||
|
||||
### Connection State Management
|
||||
|
||||
```typescript
|
||||
import { LXDexClient } from '@luxfi/dex-sdk';
|
||||
import { Client, ClientConfig } from '@luxfi/trading'
|
||||
|
||||
class TradingBot {
|
||||
private client: LXDexClient;
|
||||
private connected: boolean = false;
|
||||
private client: Client
|
||||
private connected: boolean = false
|
||||
|
||||
constructor(config: LXDexConfig) {
|
||||
this.client = new LXDexClient(config);
|
||||
constructor(config: ClientConfig) {
|
||||
this.client = new Client(config)
|
||||
}
|
||||
|
||||
async connect(): Promise<void> {
|
||||
if (this.connected) {
|
||||
console.log('Already connected');
|
||||
return;
|
||||
console.log('Already connected')
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
await this.client.connect();
|
||||
this.connected = true;
|
||||
console.log('Connected to LX');
|
||||
await this.client.connect()
|
||||
this.connected = true
|
||||
console.log('Connected to LX')
|
||||
} catch (error) {
|
||||
console.error('Connection failed:', error);
|
||||
throw error;
|
||||
console.error('Connection failed:', error)
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
async disconnect(): Promise<void> {
|
||||
if (!this.connected) {
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
this.client.disconnect();
|
||||
this.connected = false;
|
||||
console.log('Disconnected from LX');
|
||||
this.client.disconnect()
|
||||
this.connected = false
|
||||
console.log('Disconnected from LX')
|
||||
}
|
||||
|
||||
isConnected(): boolean {
|
||||
return this.connected;
|
||||
return this.connected
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -200,46 +212,46 @@ The main client exposes specialized sub-clients for different operations:
|
||||
### MarketDataClient
|
||||
|
||||
```typescript
|
||||
import { LXDexClient } from '@luxfi/dex-sdk';
|
||||
import { Client } from '@luxfi/trading'
|
||||
|
||||
const client = new LXDexClient({
|
||||
jsonRpcUrl: 'http://localhost:8080/rpc'
|
||||
});
|
||||
const client = new Client({
|
||||
rpcUrl: 'http://localhost:8080/rpc'
|
||||
})
|
||||
|
||||
// Access market data sub-client
|
||||
const marketData = client.marketData;
|
||||
const marketData = client.marketData
|
||||
|
||||
// Get market statistics
|
||||
const stats = await marketData.getMarketStats('BTC-USD');
|
||||
console.log('24h Volume:', stats.volume24h);
|
||||
console.log('24h High:', stats.high24h);
|
||||
console.log('24h Low:', stats.low24h);
|
||||
const stats = await marketData.getMarketStats('BTC-USD')
|
||||
console.log('24h Volume:', stats.volume24h)
|
||||
console.log('24h High:', stats.high24h)
|
||||
console.log('24h Low:', stats.low24h)
|
||||
```
|
||||
|
||||
### LiquidationMonitor
|
||||
|
||||
```typescript
|
||||
import { LXDexClient, LiquidationInfo } from '@luxfi/dex-sdk';
|
||||
import { Client, LiquidationInfo } from '@luxfi/trading'
|
||||
|
||||
async function monitorLiquidations(): Promise<void> {
|
||||
const client = new LXDexClient({
|
||||
jsonRpcUrl: 'http://localhost:8080/rpc',
|
||||
const client = new Client({
|
||||
rpcUrl: 'http://localhost:8080/rpc',
|
||||
wsUrl: 'ws://localhost:8081'
|
||||
});
|
||||
})
|
||||
|
||||
await client.connect();
|
||||
await client.connect()
|
||||
|
||||
// Access liquidation monitor sub-client
|
||||
const monitor = client.liquidationMonitor;
|
||||
const monitor = client.liquidationMonitor
|
||||
|
||||
// Subscribe to liquidation events
|
||||
monitor.subscribeLiquidations((liquidation: LiquidationInfo) => {
|
||||
console.log('Liquidation event:', liquidation);
|
||||
console.log(' User:', liquidation.userId);
|
||||
console.log(' Symbol:', liquidation.symbol);
|
||||
console.log(' Size:', liquidation.size);
|
||||
console.log(' Price:', liquidation.liquidationPrice);
|
||||
});
|
||||
console.log('Liquidation event:', liquidation)
|
||||
console.log(' User:', liquidation.userId)
|
||||
console.log(' Symbol:', liquidation.symbol)
|
||||
console.log(' Size:', liquidation.size)
|
||||
console.log(' Price:', liquidation.liquidationPrice)
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
@@ -248,15 +260,15 @@ async function monitorLiquidations(): Promise<void> {
|
||||
### Ping Test
|
||||
|
||||
```typescript
|
||||
import { LXDexClient } from '@luxfi/dex-sdk';
|
||||
import { Client } from '@luxfi/trading'
|
||||
|
||||
async function checkHealth(client: LXDexClient): Promise<boolean> {
|
||||
async function checkHealth(client: Client): Promise<boolean> {
|
||||
try {
|
||||
const response = await client.ping();
|
||||
return response === 'pong';
|
||||
const response = await client.ping()
|
||||
return response === 'pong'
|
||||
} catch (error) {
|
||||
console.error('Health check failed:', error);
|
||||
return false;
|
||||
console.error('Health check failed:', error)
|
||||
return false
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -264,18 +276,18 @@ async function checkHealth(client: LXDexClient): Promise<boolean> {
|
||||
### Node Information
|
||||
|
||||
```typescript
|
||||
import { LXDexClient, NodeInfo } from '@luxfi/dex-sdk';
|
||||
import { Client, NodeInfo } from '@luxfi/trading'
|
||||
|
||||
async function getNodeStatus(client: LXDexClient): Promise<NodeInfo> {
|
||||
const info = await client.getInfo();
|
||||
async function getNodeStatus(client: Client): Promise<NodeInfo> {
|
||||
const info = await client.getInfo()
|
||||
|
||||
console.log('Node Version:', info.version);
|
||||
console.log('Network:', info.network);
|
||||
console.log('Order Count:', info.orderCount);
|
||||
console.log('Trade Count:', info.tradeCount);
|
||||
console.log('Timestamp:', new Date(info.timestamp));
|
||||
console.log('Node Version:', info.version)
|
||||
console.log('Network:', info.network)
|
||||
console.log('Order Count:', info.orderCount)
|
||||
console.log('Trade Count:', info.tradeCount)
|
||||
console.log('Timestamp:', new Date(info.timestamp))
|
||||
|
||||
return info;
|
||||
return info
|
||||
}
|
||||
```
|
||||
|
||||
@@ -284,46 +296,46 @@ async function getNodeStatus(client: LXDexClient): Promise<NodeInfo> {
|
||||
For applications that need a single shared client instance:
|
||||
|
||||
```typescript
|
||||
import { LXDexClient, LXDexConfig } from '@luxfi/dex-sdk';
|
||||
import { Client, ClientConfig } from '@luxfi/trading'
|
||||
|
||||
class DexClientSingleton {
|
||||
private static instance: LXDexClient | null = null;
|
||||
private static config: LXDexConfig = {
|
||||
jsonRpcUrl: 'http://localhost:8080/rpc',
|
||||
private static instance: Client | null = null
|
||||
private static config: ClientConfig = {
|
||||
rpcUrl: 'http://localhost:8080/rpc',
|
||||
wsUrl: 'ws://localhost:8081'
|
||||
};
|
||||
}
|
||||
|
||||
private constructor() {}
|
||||
|
||||
static configure(config: LXDexConfig): void {
|
||||
static configure(config: ClientConfig): void {
|
||||
if (DexClientSingleton.instance) {
|
||||
throw new Error('Client already initialized. Call reset() first.');
|
||||
throw new Error('Client already initialized. Call reset() first.')
|
||||
}
|
||||
DexClientSingleton.config = config;
|
||||
DexClientSingleton.config = config
|
||||
}
|
||||
|
||||
static getInstance(): LXDexClient {
|
||||
static getInstance(): Client {
|
||||
if (!DexClientSingleton.instance) {
|
||||
DexClientSingleton.instance = new LXDexClient(DexClientSingleton.config);
|
||||
DexClientSingleton.instance = new Client(DexClientSingleton.config)
|
||||
}
|
||||
return DexClientSingleton.instance;
|
||||
return DexClientSingleton.instance
|
||||
}
|
||||
|
||||
static reset(): void {
|
||||
if (DexClientSingleton.instance) {
|
||||
DexClientSingleton.instance.disconnect();
|
||||
DexClientSingleton.instance = null;
|
||||
DexClientSingleton.instance.disconnect()
|
||||
DexClientSingleton.instance = null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Usage
|
||||
DexClientSingleton.configure({
|
||||
jsonRpcUrl: 'https://api.lux.network/rpc',
|
||||
rpcUrl: 'https://api.lux.network/rpc',
|
||||
wsUrl: 'wss://api.lux.network/ws'
|
||||
});
|
||||
})
|
||||
|
||||
const client = DexClientSingleton.getInstance();
|
||||
const client = DexClientSingleton.getInstance()
|
||||
```
|
||||
|
||||
## React Integration
|
||||
@@ -331,75 +343,75 @@ const client = DexClientSingleton.getInstance();
|
||||
### Context Provider
|
||||
|
||||
```tsx
|
||||
import React, { createContext, useContext, useEffect, useState, ReactNode } from 'react';
|
||||
import { LXDexClient, LXDexConfig } from '@luxfi/dex-sdk';
|
||||
import React, { createContext, useContext, useEffect, useState, ReactNode } from 'react'
|
||||
import { Client, ClientConfig } from '@luxfi/trading'
|
||||
|
||||
interface DexContextType {
|
||||
client: LXDexClient | null;
|
||||
connected: boolean;
|
||||
error: Error | null;
|
||||
client: Client | null
|
||||
connected: boolean
|
||||
error: Error | null
|
||||
}
|
||||
|
||||
const DexContext = createContext<DexContextType>({
|
||||
client: null,
|
||||
connected: false,
|
||||
error: null
|
||||
});
|
||||
})
|
||||
|
||||
interface DexProviderProps {
|
||||
config: LXDexConfig;
|
||||
children: ReactNode;
|
||||
config: ClientConfig
|
||||
children: ReactNode
|
||||
}
|
||||
|
||||
export function DexProvider({ config, children }: DexProviderProps): JSX.Element {
|
||||
const [client, setClient] = useState<LXDexClient | null>(null);
|
||||
const [connected, setConnected] = useState(false);
|
||||
const [error, setError] = useState<Error | null>(null);
|
||||
const [client, setClient] = useState<Client | null>(null)
|
||||
const [connected, setConnected] = useState(false)
|
||||
const [error, setError] = useState<Error | null>(null)
|
||||
|
||||
useEffect(() => {
|
||||
const dexClient = new LXDexClient(config);
|
||||
setClient(dexClient);
|
||||
const dexClient = new Client(config)
|
||||
setClient(dexClient)
|
||||
|
||||
dexClient.connect()
|
||||
.then(() => setConnected(true))
|
||||
.catch((err) => setError(err));
|
||||
.catch((err) => setError(err))
|
||||
|
||||
return () => {
|
||||
dexClient.disconnect();
|
||||
};
|
||||
}, [config]);
|
||||
dexClient.disconnect()
|
||||
}
|
||||
}, [config])
|
||||
|
||||
return (
|
||||
<DexContext.Provider value={{ client, connected, error }}>
|
||||
{children}
|
||||
</DexContext.Provider>
|
||||
);
|
||||
)
|
||||
}
|
||||
|
||||
export function useDexClient(): DexContextType {
|
||||
const context = useContext(DexContext);
|
||||
const context = useContext(DexContext)
|
||||
if (!context) {
|
||||
throw new Error('useDexClient must be used within DexProvider');
|
||||
throw new Error('useDexClient must be used within DexProvider')
|
||||
}
|
||||
return context;
|
||||
return context
|
||||
}
|
||||
```
|
||||
|
||||
### Using the Provider
|
||||
|
||||
```tsx
|
||||
import React from 'react';
|
||||
import { DexProvider, useDexClient } from './DexProvider';
|
||||
import React from 'react'
|
||||
import { DexProvider, useDexClient } from './DexProvider'
|
||||
|
||||
function TradingPanel(): JSX.Element {
|
||||
const { client, connected, error } = useDexClient();
|
||||
const { client, connected, error } = useDexClient()
|
||||
|
||||
if (error) {
|
||||
return <div>Connection error: {error.message}</div>;
|
||||
return <div>Connection error: {error.message}</div>
|
||||
}
|
||||
|
||||
if (!connected || !client) {
|
||||
return <div>Connecting...</div>;
|
||||
return <div>Connecting...</div>
|
||||
}
|
||||
|
||||
return (
|
||||
@@ -407,18 +419,18 @@ function TradingPanel(): JSX.Element {
|
||||
<h1>Trading Panel</h1>
|
||||
{/* Trading UI components */}
|
||||
</div>
|
||||
);
|
||||
)
|
||||
}
|
||||
|
||||
function App(): JSX.Element {
|
||||
return (
|
||||
<DexProvider config={{
|
||||
jsonRpcUrl: 'http://localhost:8080/rpc',
|
||||
rpcUrl: 'http://localhost:8080/rpc',
|
||||
wsUrl: 'ws://localhost:8081'
|
||||
}}>
|
||||
<TradingPanel />
|
||||
</DexProvider>
|
||||
);
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
@@ -427,18 +439,18 @@ function App(): JSX.Element {
|
||||
The client provides static utility methods:
|
||||
|
||||
```typescript
|
||||
import { LXDexClient } from '@luxfi/dex-sdk';
|
||||
import { Client } from '@luxfi/trading'
|
||||
|
||||
// Format price with decimals
|
||||
const formattedPrice = LXDexClient.formatPrice(50123.456789, 2);
|
||||
const formattedPrice = Client.formatPrice(50123.456789, 2)
|
||||
// Result: "50123.46"
|
||||
|
||||
// Format size with decimals
|
||||
const formattedSize = LXDexClient.formatSize(1.23456789, 8);
|
||||
const formattedSize = Client.formatSize(1.23456789, 8)
|
||||
// Result: "1.23456789"
|
||||
|
||||
// Calculate order total
|
||||
const total = LXDexClient.calculateTotal(50000, 0.5);
|
||||
const total = Client.calculateTotal(50000, 0.5)
|
||||
// Result: 25000
|
||||
```
|
||||
|
||||
|
||||
@@ -29,11 +29,11 @@ interface OrderBook {
|
||||
### Basic Snapshot
|
||||
|
||||
```typescript
|
||||
import { LXDexClient, OrderBook } from '@luxfi/dex-sdk';
|
||||
import { Client, OrderBook } from '@luxfi/trading';
|
||||
|
||||
async function getOrderBookSnapshot(): Promise<void> {
|
||||
const client = new LXDexClient({
|
||||
jsonRpcUrl: 'http://localhost:8080/rpc'
|
||||
const client = new Client({
|
||||
rpcUrl: 'http://localhost:8080/rpc'
|
||||
});
|
||||
|
||||
const book = await client.getOrderBook('BTC-USD', 10);
|
||||
@@ -55,11 +55,11 @@ async function getOrderBookSnapshot(): Promise<void> {
|
||||
### Custom Depth
|
||||
|
||||
```typescript
|
||||
import { LXDexClient, OrderBook } from '@luxfi/dex-sdk';
|
||||
import { Client, OrderBook } from '@luxfi/trading';
|
||||
|
||||
async function getDeepOrderBook(): Promise<OrderBook> {
|
||||
const client = new LXDexClient({
|
||||
jsonRpcUrl: 'http://localhost:8080/rpc'
|
||||
const client = new Client({
|
||||
rpcUrl: 'http://localhost:8080/rpc'
|
||||
});
|
||||
|
||||
// Get 50 levels on each side
|
||||
@@ -69,8 +69,8 @@ async function getDeepOrderBook(): Promise<OrderBook> {
|
||||
}
|
||||
|
||||
async function getShallowOrderBook(): Promise<OrderBook> {
|
||||
const client = new LXDexClient({
|
||||
jsonRpcUrl: 'http://localhost:8080/rpc'
|
||||
const client = new Client({
|
||||
rpcUrl: 'http://localhost:8080/rpc'
|
||||
});
|
||||
|
||||
// Get just top 3 levels (best bid/ask)
|
||||
@@ -85,11 +85,11 @@ async function getShallowOrderBook(): Promise<OrderBook> {
|
||||
### Get Best Bid
|
||||
|
||||
```typescript
|
||||
import { LXDexClient } from '@luxfi/dex-sdk';
|
||||
import { Client } from '@luxfi/trading';
|
||||
|
||||
async function getBestBid(): Promise<number> {
|
||||
const client = new LXDexClient({
|
||||
jsonRpcUrl: 'http://localhost:8080/rpc'
|
||||
const client = new Client({
|
||||
rpcUrl: 'http://localhost:8080/rpc'
|
||||
});
|
||||
|
||||
const bestBid = await client.getBestBid('BTC-USD');
|
||||
@@ -102,11 +102,11 @@ async function getBestBid(): Promise<number> {
|
||||
### Get Best Ask
|
||||
|
||||
```typescript
|
||||
import { LXDexClient } from '@luxfi/dex-sdk';
|
||||
import { Client } from '@luxfi/trading';
|
||||
|
||||
async function getBestAsk(): Promise<number> {
|
||||
const client = new LXDexClient({
|
||||
jsonRpcUrl: 'http://localhost:8080/rpc'
|
||||
const client = new Client({
|
||||
rpcUrl: 'http://localhost:8080/rpc'
|
||||
});
|
||||
|
||||
const bestAsk = await client.getBestAsk('BTC-USD');
|
||||
@@ -119,7 +119,7 @@ async function getBestAsk(): Promise<number> {
|
||||
### Get Spread
|
||||
|
||||
```typescript
|
||||
import { LXDexClient } from '@luxfi/dex-sdk';
|
||||
import { Client } from '@luxfi/trading';
|
||||
|
||||
interface SpreadInfo {
|
||||
bid: number;
|
||||
@@ -130,8 +130,8 @@ interface SpreadInfo {
|
||||
}
|
||||
|
||||
async function getSpread(symbol: string): Promise<SpreadInfo> {
|
||||
const client = new LXDexClient({
|
||||
jsonRpcUrl: 'http://localhost:8080/rpc'
|
||||
const client = new Client({
|
||||
rpcUrl: 'http://localhost:8080/rpc'
|
||||
});
|
||||
|
||||
const [bid, ask] = await Promise.all([
|
||||
@@ -169,11 +169,11 @@ async function displaySpread(): Promise<void> {
|
||||
### Subscribe to Order Book Updates
|
||||
|
||||
```typescript
|
||||
import { LXDexClient, OrderBook } from '@luxfi/dex-sdk';
|
||||
import { Client, OrderBook } from '@luxfi/trading';
|
||||
|
||||
async function subscribeToOrderBook(): Promise<void> {
|
||||
const client = new LXDexClient({
|
||||
jsonRpcUrl: 'http://localhost:8080/rpc',
|
||||
const client = new Client({
|
||||
rpcUrl: 'http://localhost:8080/rpc',
|
||||
wsUrl: 'ws://localhost:8081'
|
||||
});
|
||||
|
||||
@@ -195,11 +195,11 @@ async function subscribeToOrderBook(): Promise<void> {
|
||||
### Unsubscribe
|
||||
|
||||
```typescript
|
||||
import { LXDexClient, OrderBook } from '@luxfi/dex-sdk';
|
||||
import { Client, OrderBook } from '@luxfi/trading';
|
||||
|
||||
async function unsubscribeExample(): Promise<void> {
|
||||
const client = new LXDexClient({
|
||||
jsonRpcUrl: 'http://localhost:8080/rpc',
|
||||
const client = new Client({
|
||||
rpcUrl: 'http://localhost:8080/rpc',
|
||||
wsUrl: 'ws://localhost:8081'
|
||||
});
|
||||
|
||||
@@ -226,7 +226,7 @@ async function unsubscribeExample(): Promise<void> {
|
||||
### Calculate Liquidity Depth
|
||||
|
||||
```typescript
|
||||
import { LXDexClient, OrderBook, OrderBookLevel } from '@luxfi/dex-sdk';
|
||||
import { Client, OrderBook, OrderBookLevel } from '@luxfi/trading';
|
||||
|
||||
interface LiquidityDepth {
|
||||
bidLiquidity: number;
|
||||
@@ -259,8 +259,8 @@ function calculateLiquidity(book: OrderBook): LiquidityDepth {
|
||||
}
|
||||
|
||||
async function analyzeLiquidity(): Promise<void> {
|
||||
const client = new LXDexClient({
|
||||
jsonRpcUrl: 'http://localhost:8080/rpc'
|
||||
const client = new Client({
|
||||
rpcUrl: 'http://localhost:8080/rpc'
|
||||
});
|
||||
|
||||
const book = await client.getOrderBook('BTC-USD', 50);
|
||||
@@ -278,7 +278,7 @@ async function analyzeLiquidity(): Promise<void> {
|
||||
### Calculate Market Impact
|
||||
|
||||
```typescript
|
||||
import { LXDexClient, OrderBook, OrderBookLevel } from '@luxfi/dex-sdk';
|
||||
import { Client, OrderBook, OrderBookLevel } from '@luxfi/trading';
|
||||
|
||||
interface MarketImpact {
|
||||
averagePrice: number;
|
||||
@@ -326,8 +326,8 @@ async function analyzeMarketImpact(
|
||||
orderSize: number,
|
||||
side: 'buy' | 'sell'
|
||||
): Promise<MarketImpact> {
|
||||
const client = new LXDexClient({
|
||||
jsonRpcUrl: 'http://localhost:8080/rpc'
|
||||
const client = new Client({
|
||||
rpcUrl: 'http://localhost:8080/rpc'
|
||||
});
|
||||
|
||||
const book = await client.getOrderBook(symbol, 100);
|
||||
@@ -355,7 +355,7 @@ async function displayMarketImpact(): Promise<void> {
|
||||
### Order Book Imbalance
|
||||
|
||||
```typescript
|
||||
import { LXDexClient, OrderBook } from '@luxfi/dex-sdk';
|
||||
import { Client, OrderBook } from '@luxfi/trading';
|
||||
|
||||
interface OrderBookImbalance {
|
||||
bidVolume: number;
|
||||
@@ -397,8 +397,8 @@ function calculateImbalance(book: OrderBook, depth: number = 10): OrderBookImbal
|
||||
}
|
||||
|
||||
async function monitorImbalance(): Promise<void> {
|
||||
const client = new LXDexClient({
|
||||
jsonRpcUrl: 'http://localhost:8080/rpc',
|
||||
const client = new Client({
|
||||
rpcUrl: 'http://localhost:8080/rpc',
|
||||
wsUrl: 'ws://localhost:8081'
|
||||
});
|
||||
|
||||
@@ -419,7 +419,7 @@ async function monitorImbalance(): Promise<void> {
|
||||
|
||||
```tsx
|
||||
import { useState, useEffect, useCallback } from 'react';
|
||||
import { LXDexClient, OrderBook } from '@luxfi/dex-sdk';
|
||||
import { Client, OrderBook } from '@luxfi/trading';
|
||||
|
||||
interface UseOrderBookOptions {
|
||||
depth?: number;
|
||||
@@ -435,7 +435,7 @@ interface UseOrderBookResult {
|
||||
}
|
||||
|
||||
export function useOrderBook(
|
||||
client: LXDexClient | null,
|
||||
client: Client | null,
|
||||
symbol: string,
|
||||
options: UseOrderBookOptions = {}
|
||||
): UseOrderBookResult {
|
||||
@@ -551,7 +551,7 @@ function OrderBookDisplay(): JSX.Element {
|
||||
|
||||
```tsx
|
||||
import { useState, useEffect } from 'react';
|
||||
import { LXDexClient, OrderBook } from '@luxfi/dex-sdk';
|
||||
import { Client, OrderBook } from '@luxfi/trading';
|
||||
|
||||
interface BestPrices {
|
||||
bid: number | null;
|
||||
@@ -561,7 +561,7 @@ interface BestPrices {
|
||||
}
|
||||
|
||||
export function useBestPrices(
|
||||
client: LXDexClient | null,
|
||||
client: Client | null,
|
||||
symbol: string
|
||||
): BestPrices {
|
||||
const [prices, setPrices] = useState<BestPrices>({
|
||||
@@ -598,7 +598,7 @@ export function useBestPrices(
|
||||
### Generate Depth Chart Data
|
||||
|
||||
```typescript
|
||||
import { OrderBook, OrderBookLevel } from '@luxfi/dex-sdk';
|
||||
import { OrderBook, OrderBookLevel } from '@luxfi/trading';
|
||||
|
||||
interface DepthPoint {
|
||||
price: number;
|
||||
@@ -638,7 +638,7 @@ function generateDepthChartData(book: OrderBook): DepthPoint[] {
|
||||
### Price Level Aggregation
|
||||
|
||||
```typescript
|
||||
import { OrderBook, OrderBookLevel } from '@luxfi/dex-sdk';
|
||||
import { OrderBook, OrderBookLevel } from '@luxfi/trading';
|
||||
|
||||
function aggregateOrderBook(
|
||||
book: OrderBook,
|
||||
@@ -668,8 +668,8 @@ function aggregateOrderBook(
|
||||
|
||||
// Usage: Aggregate to $100 increments
|
||||
async function getAggregatedBook(): Promise<void> {
|
||||
const client = new LXDexClient({
|
||||
jsonRpcUrl: 'http://localhost:8080/rpc'
|
||||
const client = new Client({
|
||||
rpcUrl: 'http://localhost:8080/rpc'
|
||||
});
|
||||
|
||||
const book = await client.getOrderBook('BTC-USD', 100);
|
||||
|
||||
@@ -29,28 +29,18 @@ enum OrderType {
|
||||
A limit order executes at a specific price or better:
|
||||
|
||||
```typescript
|
||||
import { LXDexClient, OrderType, OrderSide, TimeInForce } from '@luxfi/dex-sdk';
|
||||
import { DEX, OrderType, OrderSide, TimeInForce } from '@luxfi/trading'
|
||||
|
||||
async function placeLimitOrder(): Promise<void> {
|
||||
const client = new LXDexClient({
|
||||
jsonRpcUrl: 'http://localhost:8080/rpc'
|
||||
});
|
||||
const dex = await DEX({ rpcUrl: 'http://localhost:8080/rpc' })
|
||||
|
||||
try {
|
||||
const result = await client.placeOrder({
|
||||
symbol: 'BTC-USD',
|
||||
type: OrderType.LIMIT,
|
||||
side: OrderSide.BUY,
|
||||
price: 50000,
|
||||
size: 0.5,
|
||||
userID: 'trader-001',
|
||||
timeInForce: TimeInForce.GTC
|
||||
});
|
||||
|
||||
console.log('Order ID:', result.orderId);
|
||||
console.log('Status:', result.status);
|
||||
// Using convenience method
|
||||
const order = await dex.limitBuy('BTC-USD', '0.5', '50000')
|
||||
console.log('Order ID:', order.orderId)
|
||||
console.log('Status:', order.status)
|
||||
} catch (error) {
|
||||
console.error('Order placement failed:', error);
|
||||
console.error('Order placement failed:', error)
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -60,25 +50,17 @@ async function placeLimitOrder(): Promise<void> {
|
||||
A market order executes immediately at the best available price:
|
||||
|
||||
```typescript
|
||||
import { LXDexClient, OrderType, OrderSide } from '@luxfi/dex-sdk';
|
||||
import { DEX } from '@luxfi/trading'
|
||||
|
||||
async function placeMarketOrder(): Promise<void> {
|
||||
const client = new LXDexClient({
|
||||
jsonRpcUrl: 'http://localhost:8080/rpc'
|
||||
});
|
||||
const dex = await DEX({ rpcUrl: 'http://localhost:8080/rpc' })
|
||||
|
||||
try {
|
||||
const result = await client.placeOrder({
|
||||
symbol: 'BTC-USD',
|
||||
type: OrderType.MARKET,
|
||||
side: OrderSide.SELL,
|
||||
size: 1.0,
|
||||
userID: 'trader-001'
|
||||
});
|
||||
|
||||
console.log('Market order executed:', result.orderId);
|
||||
// Market buy
|
||||
const order = await dex.buy('BTC-USD', '1.0')
|
||||
console.log('Market order executed:', order.orderId)
|
||||
} catch (error) {
|
||||
console.error('Market order failed:', error);
|
||||
console.error('Market order failed:', error)
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -88,27 +70,17 @@ async function placeMarketOrder(): Promise<void> {
|
||||
A stop order triggers when the market price reaches the stop price:
|
||||
|
||||
```typescript
|
||||
import { LXDexClient, OrderType, OrderSide } from '@luxfi/dex-sdk';
|
||||
import { DEX } from '@luxfi/trading'
|
||||
|
||||
async function placeStopOrder(): Promise<void> {
|
||||
const client = new LXDexClient({
|
||||
jsonRpcUrl: 'http://localhost:8080/rpc'
|
||||
});
|
||||
const dex = await DEX({ rpcUrl: 'http://localhost:8080/rpc' })
|
||||
|
||||
try {
|
||||
// Stop-loss order: Sell when price drops to 48000
|
||||
const result = await client.placeOrder({
|
||||
symbol: 'BTC-USD',
|
||||
type: OrderType.STOP,
|
||||
side: OrderSide.SELL,
|
||||
price: 48000, // Stop price
|
||||
size: 0.5,
|
||||
userID: 'trader-001'
|
||||
});
|
||||
|
||||
console.log('Stop order placed:', result.orderId);
|
||||
const order = await dex.stopLoss('BTC-USD', '0.5', '48000')
|
||||
console.log('Stop order placed:', order.orderId)
|
||||
} catch (error) {
|
||||
console.error('Stop order failed:', error);
|
||||
console.error('Stop order failed:', error)
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -118,42 +90,38 @@ async function placeStopOrder(): Promise<void> {
|
||||
A stop-limit order becomes a limit order when triggered:
|
||||
|
||||
```typescript
|
||||
import { LXDexClient, OrderType, OrderSide } from '@luxfi/dex-sdk';
|
||||
import { DEX, OrderSide } from '@luxfi/trading'
|
||||
|
||||
interface StopLimitParams {
|
||||
symbol: string;
|
||||
side: OrderSide;
|
||||
stopPrice: number;
|
||||
limitPrice: number;
|
||||
size: number;
|
||||
symbol: string
|
||||
side: OrderSide
|
||||
stopPrice: string
|
||||
limitPrice: string
|
||||
size: string
|
||||
}
|
||||
|
||||
async function placeStopLimitOrder(params: StopLimitParams): Promise<number> {
|
||||
const client = new LXDexClient({
|
||||
jsonRpcUrl: 'http://localhost:8080/rpc'
|
||||
});
|
||||
async function placeStopLimitOrder(params: StopLimitParams): Promise<string> {
|
||||
const dex = await DEX({ rpcUrl: 'http://localhost:8080/rpc' })
|
||||
|
||||
const result = await client.placeOrder({
|
||||
symbol: params.symbol,
|
||||
type: OrderType.STOP_LIMIT,
|
||||
side: params.side,
|
||||
price: params.limitPrice,
|
||||
size: params.size,
|
||||
userID: 'trader-001'
|
||||
// Note: Stop price configuration may vary by implementation
|
||||
});
|
||||
const order = await dex.stopLimit(
|
||||
params.symbol,
|
||||
params.side,
|
||||
params.size,
|
||||
params.stopPrice,
|
||||
params.limitPrice
|
||||
)
|
||||
|
||||
return result.orderId;
|
||||
return order.orderId
|
||||
}
|
||||
|
||||
// Example: Buy BTC when price rises above 51000, but limit to 51500
|
||||
placeStopLimitOrder({
|
||||
symbol: 'BTC-USD',
|
||||
side: OrderSide.BUY,
|
||||
stopPrice: 51000,
|
||||
limitPrice: 51500,
|
||||
size: 0.25
|
||||
});
|
||||
stopPrice: '51000',
|
||||
limitPrice: '51500',
|
||||
size: '0.25'
|
||||
})
|
||||
```
|
||||
|
||||
### Iceberg Order
|
||||
@@ -161,27 +129,19 @@ placeStopLimitOrder({
|
||||
An iceberg order hides the full order quantity:
|
||||
|
||||
```typescript
|
||||
import { LXDexClient, OrderType, OrderSide } from '@luxfi/dex-sdk';
|
||||
import { DEX, OrderSide } from '@luxfi/trading'
|
||||
|
||||
async function placeIcebergOrder(): Promise<void> {
|
||||
const client = new LXDexClient({
|
||||
jsonRpcUrl: 'http://localhost:8080/rpc'
|
||||
});
|
||||
const dex = await DEX({ rpcUrl: 'http://localhost:8080/rpc' })
|
||||
|
||||
try {
|
||||
const result = await client.placeOrder({
|
||||
symbol: 'BTC-USD',
|
||||
type: OrderType.ICEBERG,
|
||||
side: OrderSide.BUY,
|
||||
price: 50000,
|
||||
size: 10.0, // Total size (hidden)
|
||||
userID: 'trader-001'
|
||||
// Display size is typically 10% of total
|
||||
});
|
||||
const order = await dex.iceberg('BTC-USD', OrderSide.BUY, '10.0', '50000', {
|
||||
displaySize: '1.0' // Show only 1 BTC at a time
|
||||
})
|
||||
|
||||
console.log('Iceberg order placed:', result.orderId);
|
||||
console.log('Iceberg order placed:', order.orderId)
|
||||
} catch (error) {
|
||||
console.error('Iceberg order failed:', error);
|
||||
console.error('Iceberg order failed:', error)
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -202,25 +162,17 @@ enum TimeInForce {
|
||||
### IOC Order Example
|
||||
|
||||
```typescript
|
||||
import { LXDexClient, OrderType, OrderSide, TimeInForce } from '@luxfi/dex-sdk';
|
||||
import { DEX, TimeInForce } from '@luxfi/trading'
|
||||
|
||||
async function placeIOCOrder(): Promise<void> {
|
||||
const client = new LXDexClient({
|
||||
jsonRpcUrl: 'http://localhost:8080/rpc'
|
||||
});
|
||||
const dex = await DEX({ rpcUrl: 'http://localhost:8080/rpc' })
|
||||
|
||||
// IOC: Execute immediately, cancel unfilled portion
|
||||
const result = await client.placeOrder({
|
||||
symbol: 'BTC-USD',
|
||||
type: OrderType.LIMIT,
|
||||
side: OrderSide.BUY,
|
||||
price: 50000,
|
||||
size: 1.0,
|
||||
userID: 'trader-001',
|
||||
const order = await dex.limitBuy('BTC-USD', '1.0', '50000', {
|
||||
timeInForce: TimeInForce.IOC
|
||||
});
|
||||
})
|
||||
|
||||
console.log('IOC order result:', result);
|
||||
console.log('IOC order result:', order)
|
||||
// Check if fully filled or partially filled
|
||||
}
|
||||
```
|
||||
@@ -228,28 +180,20 @@ async function placeIOCOrder(): Promise<void> {
|
||||
### FOK Order Example
|
||||
|
||||
```typescript
|
||||
import { LXDexClient, OrderType, OrderSide, TimeInForce } from '@luxfi/dex-sdk';
|
||||
import { DEX, TimeInForce } from '@luxfi/trading'
|
||||
|
||||
async function placeFOKOrder(): Promise<void> {
|
||||
const client = new LXDexClient({
|
||||
jsonRpcUrl: 'http://localhost:8080/rpc'
|
||||
});
|
||||
const dex = await DEX({ rpcUrl: 'http://localhost:8080/rpc' })
|
||||
|
||||
// FOK: Must fill entirely or reject
|
||||
const result = await client.placeOrder({
|
||||
symbol: 'BTC-USD',
|
||||
type: OrderType.LIMIT,
|
||||
side: OrderSide.BUY,
|
||||
price: 50000,
|
||||
size: 1.0,
|
||||
userID: 'trader-001',
|
||||
const order = await dex.limitBuy('BTC-USD', '1.0', '50000', {
|
||||
timeInForce: TimeInForce.FOK
|
||||
});
|
||||
})
|
||||
|
||||
if (result.status === 'filled') {
|
||||
console.log('Order fully filled');
|
||||
if (order.status === 'filled') {
|
||||
console.log('Order fully filled')
|
||||
} else {
|
||||
console.log('Order rejected - could not fill entirely');
|
||||
console.log('Order rejected - could not fill entirely')
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -261,24 +205,16 @@ async function placeFOKOrder(): Promise<void> {
|
||||
Post-only orders only add liquidity (maker orders):
|
||||
|
||||
```typescript
|
||||
import { LXDexClient, OrderType, OrderSide } from '@luxfi/dex-sdk';
|
||||
import { DEX } from '@luxfi/trading'
|
||||
|
||||
async function placePostOnlyOrder(): Promise<void> {
|
||||
const client = new LXDexClient({
|
||||
jsonRpcUrl: 'http://localhost:8080/rpc'
|
||||
});
|
||||
const dex = await DEX({ rpcUrl: 'http://localhost:8080/rpc' })
|
||||
|
||||
const result = await client.placeOrder({
|
||||
symbol: 'BTC-USD',
|
||||
type: OrderType.LIMIT,
|
||||
side: OrderSide.BUY,
|
||||
price: 49900, // Below best ask to ensure it's a maker order
|
||||
size: 0.5,
|
||||
userID: 'trader-001',
|
||||
const order = await dex.limitBuy('BTC-USD', '0.5', '49900', {
|
||||
postOnly: true // Reject if would take liquidity
|
||||
});
|
||||
})
|
||||
|
||||
console.log('Post-only order:', result.orderId);
|
||||
console.log('Post-only order:', order.orderId)
|
||||
}
|
||||
```
|
||||
|
||||
@@ -287,25 +223,17 @@ async function placePostOnlyOrder(): Promise<void> {
|
||||
Reduce-only orders can only reduce an existing position:
|
||||
|
||||
```typescript
|
||||
import { LXDexClient, OrderType, OrderSide } from '@luxfi/dex-sdk';
|
||||
import { DEX } from '@luxfi/trading'
|
||||
|
||||
async function placeReduceOnlyOrder(): Promise<void> {
|
||||
const client = new LXDexClient({
|
||||
jsonRpcUrl: 'http://localhost:8080/rpc'
|
||||
});
|
||||
const dex = await DEX({ rpcUrl: 'http://localhost:8080/rpc' })
|
||||
|
||||
// Close or reduce long position
|
||||
const result = await client.placeOrder({
|
||||
symbol: 'BTC-USD',
|
||||
type: OrderType.LIMIT,
|
||||
side: OrderSide.SELL,
|
||||
price: 51000,
|
||||
size: 0.5,
|
||||
userID: 'trader-001',
|
||||
const order = await dex.limitSell('BTC-USD', '0.5', '51000', {
|
||||
reduceOnly: true // Cannot increase position
|
||||
});
|
||||
})
|
||||
|
||||
console.log('Reduce-only order:', result.orderId);
|
||||
console.log('Reduce-only order:', order.orderId)
|
||||
}
|
||||
```
|
||||
|
||||
@@ -314,55 +242,51 @@ async function placeReduceOnlyOrder(): Promise<void> {
|
||||
### Cancel Single Order
|
||||
|
||||
```typescript
|
||||
import { LXDexClient } from '@luxfi/dex-sdk';
|
||||
import { DEX } from '@luxfi/trading'
|
||||
|
||||
async function cancelOrder(orderId: number): Promise<void> {
|
||||
const client = new LXDexClient({
|
||||
jsonRpcUrl: 'http://localhost:8080/rpc'
|
||||
});
|
||||
async function cancelOrder(orderId: string): Promise<void> {
|
||||
const dex = await DEX({ rpcUrl: 'http://localhost:8080/rpc' })
|
||||
|
||||
try {
|
||||
const result = await client.cancelOrder(orderId);
|
||||
const result = await dex.cancelOrder(orderId)
|
||||
|
||||
if (result.success) {
|
||||
console.log('Order cancelled successfully');
|
||||
console.log('Order cancelled successfully')
|
||||
} else {
|
||||
console.log('Cancel failed:', result.message);
|
||||
console.log('Cancel failed:', result.message)
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Cancel error:', error);
|
||||
console.error('Cancel error:', error)
|
||||
}
|
||||
}
|
||||
|
||||
// Usage
|
||||
cancelOrder(12345);
|
||||
cancelOrder('12345')
|
||||
```
|
||||
|
||||
### Cancel Multiple Orders
|
||||
|
||||
```typescript
|
||||
import { LXDexClient } from '@luxfi/dex-sdk';
|
||||
import { DEX } from '@luxfi/trading'
|
||||
|
||||
async function cancelMultipleOrders(orderIds: number[]): Promise<void> {
|
||||
const client = new LXDexClient({
|
||||
jsonRpcUrl: 'http://localhost:8080/rpc'
|
||||
});
|
||||
async function cancelMultipleOrders(orderIds: string[]): Promise<void> {
|
||||
const dex = await DEX({ rpcUrl: 'http://localhost:8080/rpc' })
|
||||
|
||||
const results = await Promise.allSettled(
|
||||
orderIds.map(id => client.cancelOrder(id))
|
||||
);
|
||||
orderIds.map(id => dex.cancelOrder(id))
|
||||
)
|
||||
|
||||
results.forEach((result, index) => {
|
||||
if (result.status === 'fulfilled') {
|
||||
console.log(`Order ${orderIds[index]}: cancelled`);
|
||||
console.log(`Order ${orderIds[index]}: cancelled`)
|
||||
} else {
|
||||
console.log(`Order ${orderIds[index]}: failed - ${result.reason}`);
|
||||
console.log(`Order ${orderIds[index]}: failed - ${result.reason}`)
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
// Usage
|
||||
cancelMultipleOrders([12345, 12346, 12347]);
|
||||
cancelMultipleOrders(['12345', '12346', '12347'])
|
||||
```
|
||||
|
||||
## Querying Orders
|
||||
@@ -370,28 +294,26 @@ cancelMultipleOrders([12345, 12346, 12347]);
|
||||
### Get Single Order
|
||||
|
||||
```typescript
|
||||
import { LXDexClient, Order } from '@luxfi/dex-sdk';
|
||||
import { DEX, Order } from '@luxfi/trading'
|
||||
|
||||
async function getOrderDetails(orderId: number): Promise<Order> {
|
||||
const client = new LXDexClient({
|
||||
jsonRpcUrl: 'http://localhost:8080/rpc'
|
||||
});
|
||||
async function getOrderDetails(orderId: string): Promise<Order> {
|
||||
const dex = await DEX({ rpcUrl: 'http://localhost:8080/rpc' })
|
||||
|
||||
const order = await client.getOrder(orderId);
|
||||
const order = await dex.getOrder(orderId)
|
||||
|
||||
console.log('Order Details:');
|
||||
console.log(' ID:', order.orderId);
|
||||
console.log(' Symbol:', order.symbol);
|
||||
console.log(' Type:', order.type);
|
||||
console.log(' Side:', order.side === 0 ? 'BUY' : 'SELL');
|
||||
console.log(' Price:', order.price);
|
||||
console.log(' Size:', order.size);
|
||||
console.log(' Filled:', order.filled);
|
||||
console.log(' Remaining:', order.remaining);
|
||||
console.log(' Status:', order.status);
|
||||
console.log(' Timestamp:', new Date(order.timestamp!));
|
||||
console.log('Order Details:')
|
||||
console.log(' ID:', order.orderId)
|
||||
console.log(' Symbol:', order.symbol)
|
||||
console.log(' Type:', order.type)
|
||||
console.log(' Side:', order.side === 0 ? 'BUY' : 'SELL')
|
||||
console.log(' Price:', order.price)
|
||||
console.log(' Size:', order.size)
|
||||
console.log(' Filled:', order.filled)
|
||||
console.log(' Remaining:', order.remaining)
|
||||
console.log(' Status:', order.status)
|
||||
console.log(' Timestamp:', new Date(order.timestamp!))
|
||||
|
||||
return order;
|
||||
return order
|
||||
}
|
||||
```
|
||||
|
||||
@@ -400,109 +322,100 @@ async function getOrderDetails(orderId: number): Promise<Order> {
|
||||
For complex order creation, use a builder pattern:
|
||||
|
||||
```typescript
|
||||
import { LXDexClient, Order, OrderType, OrderSide, TimeInForce } from '@luxfi/dex-sdk';
|
||||
import { Client, Order, OrderType, OrderSide, TimeInForce } from '@luxfi/trading'
|
||||
|
||||
class OrderBuilder {
|
||||
private order: Partial<Order> = {};
|
||||
private order: Partial<Order> = {}
|
||||
|
||||
symbol(symbol: string): OrderBuilder {
|
||||
this.order.symbol = symbol;
|
||||
return this;
|
||||
this.order.symbol = symbol
|
||||
return this
|
||||
}
|
||||
|
||||
limit(): OrderBuilder {
|
||||
this.order.type = OrderType.LIMIT;
|
||||
return this;
|
||||
this.order.type = OrderType.LIMIT
|
||||
return this
|
||||
}
|
||||
|
||||
market(): OrderBuilder {
|
||||
this.order.type = OrderType.MARKET;
|
||||
return this;
|
||||
this.order.type = OrderType.MARKET
|
||||
return this
|
||||
}
|
||||
|
||||
buy(): OrderBuilder {
|
||||
this.order.side = OrderSide.BUY;
|
||||
return this;
|
||||
this.order.side = OrderSide.BUY
|
||||
return this
|
||||
}
|
||||
|
||||
sell(): OrderBuilder {
|
||||
this.order.side = OrderSide.SELL;
|
||||
return this;
|
||||
this.order.side = OrderSide.SELL
|
||||
return this
|
||||
}
|
||||
|
||||
price(price: number): OrderBuilder {
|
||||
this.order.price = price;
|
||||
return this;
|
||||
price(price: string): OrderBuilder {
|
||||
this.order.price = price
|
||||
return this
|
||||
}
|
||||
|
||||
size(size: number): OrderBuilder {
|
||||
this.order.size = size;
|
||||
return this;
|
||||
}
|
||||
|
||||
user(userID: string): OrderBuilder {
|
||||
this.order.userID = userID;
|
||||
return this;
|
||||
size(size: string): OrderBuilder {
|
||||
this.order.size = size
|
||||
return this
|
||||
}
|
||||
|
||||
gtc(): OrderBuilder {
|
||||
this.order.timeInForce = TimeInForce.GTC;
|
||||
return this;
|
||||
this.order.timeInForce = TimeInForce.GTC
|
||||
return this
|
||||
}
|
||||
|
||||
ioc(): OrderBuilder {
|
||||
this.order.timeInForce = TimeInForce.IOC;
|
||||
return this;
|
||||
this.order.timeInForce = TimeInForce.IOC
|
||||
return this
|
||||
}
|
||||
|
||||
fok(): OrderBuilder {
|
||||
this.order.timeInForce = TimeInForce.FOK;
|
||||
return this;
|
||||
this.order.timeInForce = TimeInForce.FOK
|
||||
return this
|
||||
}
|
||||
|
||||
postOnly(): OrderBuilder {
|
||||
this.order.postOnly = true;
|
||||
return this;
|
||||
this.order.postOnly = true
|
||||
return this
|
||||
}
|
||||
|
||||
reduceOnly(): OrderBuilder {
|
||||
this.order.reduceOnly = true;
|
||||
return this;
|
||||
this.order.reduceOnly = true
|
||||
return this
|
||||
}
|
||||
|
||||
build(): Partial<Order> {
|
||||
// Validate required fields
|
||||
if (!this.order.symbol) throw new Error('Symbol is required');
|
||||
if (this.order.type === undefined) throw new Error('Type is required');
|
||||
if (this.order.side === undefined) throw new Error('Side is required');
|
||||
if (!this.order.size) throw new Error('Size is required');
|
||||
if (!this.order.symbol) throw new Error('Symbol is required')
|
||||
if (this.order.type === undefined) throw new Error('Type is required')
|
||||
if (this.order.side === undefined) throw new Error('Side is required')
|
||||
if (!this.order.size) throw new Error('Size is required')
|
||||
if (this.order.type === OrderType.LIMIT && !this.order.price) {
|
||||
throw new Error('Price is required for limit orders');
|
||||
throw new Error('Price is required for limit orders')
|
||||
}
|
||||
|
||||
return this.order;
|
||||
return this.order
|
||||
}
|
||||
}
|
||||
|
||||
// Usage
|
||||
async function placeOrderWithBuilder(): Promise<void> {
|
||||
const client = new LXDexClient({
|
||||
jsonRpcUrl: 'http://localhost:8080/rpc'
|
||||
});
|
||||
const client = new Client({ rpcUrl: 'http://localhost:8080/rpc' })
|
||||
|
||||
const order = new OrderBuilder()
|
||||
.symbol('BTC-USD')
|
||||
.limit()
|
||||
.buy()
|
||||
.price(50000)
|
||||
.size(0.5)
|
||||
.user('trader-001')
|
||||
.price('50000')
|
||||
.size('0.5')
|
||||
.gtc()
|
||||
.postOnly()
|
||||
.build();
|
||||
.build()
|
||||
|
||||
const result = await client.placeOrder(order);
|
||||
console.log('Order placed:', result.orderId);
|
||||
const result = await client.placeOrder(order)
|
||||
console.log('Order placed:', result.orderId)
|
||||
}
|
||||
```
|
||||
|
||||
@@ -511,48 +424,35 @@ async function placeOrderWithBuilder(): Promise<void> {
|
||||
Handle order-related errors appropriately:
|
||||
|
||||
```typescript
|
||||
import { LXDexClient, OrderType, OrderSide } from '@luxfi/dex-sdk';
|
||||
import { DEX } from '@luxfi/trading'
|
||||
|
||||
interface OrderError extends Error {
|
||||
code?: string;
|
||||
details?: Record<string, unknown>;
|
||||
code?: string
|
||||
details?: Record<string, unknown>
|
||||
}
|
||||
|
||||
async function placeOrderWithErrorHandling(): Promise<void> {
|
||||
const client = new LXDexClient({
|
||||
jsonRpcUrl: 'http://localhost:8080/rpc'
|
||||
});
|
||||
const dex = await DEX({ rpcUrl: 'http://localhost:8080/rpc' })
|
||||
|
||||
try {
|
||||
const result = await client.placeOrder({
|
||||
symbol: 'BTC-USD',
|
||||
type: OrderType.LIMIT,
|
||||
side: OrderSide.BUY,
|
||||
price: 50000,
|
||||
size: 1.0,
|
||||
userID: 'trader-001'
|
||||
});
|
||||
const order = await dex.limitBuy('BTC-USD', '1.0', '50000')
|
||||
|
||||
console.log('Order successful:', result.orderId);
|
||||
console.log('Order successful:', order.orderId)
|
||||
|
||||
} catch (error) {
|
||||
const orderError = error as OrderError;
|
||||
const orderError = error as OrderError
|
||||
|
||||
// Handle specific error cases
|
||||
if (orderError.message.includes('insufficient')) {
|
||||
console.error('Insufficient balance to place order');
|
||||
// Suggest reducing order size or adding funds
|
||||
console.error('Insufficient balance to place order')
|
||||
} else if (orderError.message.includes('rate limit')) {
|
||||
console.error('Rate limit exceeded - waiting before retry');
|
||||
// Implement exponential backoff
|
||||
console.error('Rate limit exceeded - waiting before retry')
|
||||
} else if (orderError.message.includes('invalid symbol')) {
|
||||
console.error('Invalid trading pair');
|
||||
// Validate symbol exists
|
||||
console.error('Invalid trading pair')
|
||||
} else if (orderError.message.includes('market closed')) {
|
||||
console.error('Market is currently closed');
|
||||
// Show market hours or queue order
|
||||
console.error('Market is currently closed')
|
||||
} else {
|
||||
console.error('Order failed:', orderError.message);
|
||||
console.error('Order failed:', orderError.message)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -563,47 +463,45 @@ async function placeOrderWithErrorHandling(): Promise<void> {
|
||||
Place multiple orders efficiently:
|
||||
|
||||
```typescript
|
||||
import { LXDexClient, Order, OrderType, OrderSide } from '@luxfi/dex-sdk';
|
||||
import { Client, Order, OrderType, OrderSide } from '@luxfi/trading'
|
||||
|
||||
interface BatchOrderResult {
|
||||
successful: Array<{ orderId: number; index: number }>;
|
||||
failed: Array<{ error: Error; index: number }>;
|
||||
successful: Array<{ orderId: string; index: number }>
|
||||
failed: Array<{ error: Error; index: number }>
|
||||
}
|
||||
|
||||
async function placeBatchOrders(orders: Partial<Order>[]): Promise<BatchOrderResult> {
|
||||
const client = new LXDexClient({
|
||||
jsonRpcUrl: 'http://localhost:8080/rpc'
|
||||
});
|
||||
const client = new Client({ rpcUrl: 'http://localhost:8080/rpc' })
|
||||
|
||||
const results = await Promise.allSettled(
|
||||
orders.map(order => client.placeOrder(order))
|
||||
);
|
||||
)
|
||||
|
||||
const successful: Array<{ orderId: number; index: number }> = [];
|
||||
const failed: Array<{ error: Error; index: number }> = [];
|
||||
const successful: Array<{ orderId: string; index: number }> = []
|
||||
const failed: Array<{ error: Error; index: number }> = []
|
||||
|
||||
results.forEach((result, index) => {
|
||||
if (result.status === 'fulfilled') {
|
||||
successful.push({ orderId: result.value.orderId, index });
|
||||
successful.push({ orderId: result.value.orderId, index })
|
||||
} else {
|
||||
failed.push({ error: result.reason, index });
|
||||
failed.push({ error: result.reason, index })
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
console.log(`Batch result: ${successful.length} successful, ${failed.length} failed`);
|
||||
console.log(`Batch result: ${successful.length} successful, ${failed.length} failed`)
|
||||
|
||||
return { successful, failed };
|
||||
return { successful, failed }
|
||||
}
|
||||
|
||||
// Usage: Place grid orders
|
||||
async function placeGridOrders(): Promise<void> {
|
||||
const basePrice = 50000;
|
||||
const gridSize = 5;
|
||||
const gridSpacing = 100;
|
||||
const orderSize = 0.1;
|
||||
const basePrice = 50000
|
||||
const gridSize = 5
|
||||
const gridSpacing = 100
|
||||
const orderSize = '0.1'
|
||||
|
||||
const buyOrders: Partial<Order>[] = [];
|
||||
const sellOrders: Partial<Order>[] = [];
|
||||
const buyOrders: Partial<Order>[] = []
|
||||
const sellOrders: Partial<Order>[] = []
|
||||
|
||||
for (let i = 1; i <= gridSize; i++) {
|
||||
// Buy orders below current price
|
||||
@@ -611,26 +509,24 @@ async function placeGridOrders(): Promise<void> {
|
||||
symbol: 'BTC-USD',
|
||||
type: OrderType.LIMIT,
|
||||
side: OrderSide.BUY,
|
||||
price: basePrice - (i * gridSpacing),
|
||||
size: orderSize,
|
||||
userID: 'grid-bot'
|
||||
});
|
||||
price: String(basePrice - (i * gridSpacing)),
|
||||
size: orderSize
|
||||
})
|
||||
|
||||
// Sell orders above current price
|
||||
sellOrders.push({
|
||||
symbol: 'BTC-USD',
|
||||
type: OrderType.LIMIT,
|
||||
side: OrderSide.SELL,
|
||||
price: basePrice + (i * gridSpacing),
|
||||
size: orderSize,
|
||||
userID: 'grid-bot'
|
||||
});
|
||||
price: String(basePrice + (i * gridSpacing)),
|
||||
size: orderSize
|
||||
})
|
||||
}
|
||||
|
||||
const allOrders = [...buyOrders, ...sellOrders];
|
||||
const result = await placeBatchOrders(allOrders);
|
||||
const allOrders = [...buyOrders, ...sellOrders]
|
||||
const result = await placeBatchOrders(allOrders)
|
||||
|
||||
console.log('Grid orders placed:', result.successful.length);
|
||||
console.log('Grid orders placed:', result.successful.length)
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -29,11 +29,11 @@ interface Trade {
|
||||
### Basic Query
|
||||
|
||||
```typescript
|
||||
import { LXDexClient, Trade } from '@luxfi/dex-sdk';
|
||||
import { Client, Trade } from '@luxfi/trading';
|
||||
|
||||
async function getRecentTrades(): Promise<void> {
|
||||
const client = new LXDexClient({
|
||||
jsonRpcUrl: 'http://localhost:8080/rpc'
|
||||
const client = new Client({
|
||||
rpcUrl: 'http://localhost:8080/rpc'
|
||||
});
|
||||
|
||||
const trades = await client.getTrades('BTC-USD', 100);
|
||||
@@ -49,7 +49,7 @@ async function getRecentTrades(): Promise<void> {
|
||||
### With Pagination
|
||||
|
||||
```typescript
|
||||
import { LXDexClient, Trade } from '@luxfi/dex-sdk';
|
||||
import { Client, Trade } from '@luxfi/trading';
|
||||
|
||||
interface TradeQueryParams {
|
||||
symbol: string;
|
||||
@@ -61,8 +61,8 @@ interface TradeQueryParams {
|
||||
async function getTradesWithPagination(
|
||||
params: TradeQueryParams
|
||||
): Promise<Trade[]> {
|
||||
const client = new LXDexClient({
|
||||
jsonRpcUrl: 'http://localhost:8080/rpc'
|
||||
const client = new Client({
|
||||
rpcUrl: 'http://localhost:8080/rpc'
|
||||
});
|
||||
|
||||
// Note: Pagination support depends on API implementation
|
||||
@@ -105,11 +105,11 @@ async function fetchAllRecentTrades(
|
||||
### Subscribe to Trades
|
||||
|
||||
```typescript
|
||||
import { LXDexClient, Trade } from '@luxfi/dex-sdk';
|
||||
import { Client, Trade } from '@luxfi/trading';
|
||||
|
||||
async function subscribeToTrades(): Promise<void> {
|
||||
const client = new LXDexClient({
|
||||
jsonRpcUrl: 'http://localhost:8080/rpc',
|
||||
const client = new Client({
|
||||
rpcUrl: 'http://localhost:8080/rpc',
|
||||
wsUrl: 'ws://localhost:8081'
|
||||
});
|
||||
|
||||
@@ -129,11 +129,11 @@ async function subscribeToTrades(): Promise<void> {
|
||||
### Multiple Symbol Subscription
|
||||
|
||||
```typescript
|
||||
import { LXDexClient, Trade } from '@luxfi/dex-sdk';
|
||||
import { Client, Trade } from '@luxfi/trading';
|
||||
|
||||
async function subscribeToMultipleSymbols(): Promise<void> {
|
||||
const client = new LXDexClient({
|
||||
jsonRpcUrl: 'http://localhost:8080/rpc',
|
||||
const client = new Client({
|
||||
rpcUrl: 'http://localhost:8080/rpc',
|
||||
wsUrl: 'ws://localhost:8081'
|
||||
});
|
||||
|
||||
@@ -154,11 +154,11 @@ async function subscribeToMultipleSymbols(): Promise<void> {
|
||||
### Unsubscribe from Trades
|
||||
|
||||
```typescript
|
||||
import { LXDexClient, Trade } from '@luxfi/dex-sdk';
|
||||
import { Client, Trade } from '@luxfi/trading';
|
||||
|
||||
async function manageTradeSubscription(): Promise<void> {
|
||||
const client = new LXDexClient({
|
||||
jsonRpcUrl: 'http://localhost:8080/rpc',
|
||||
const client = new Client({
|
||||
rpcUrl: 'http://localhost:8080/rpc',
|
||||
wsUrl: 'ws://localhost:8081'
|
||||
});
|
||||
|
||||
@@ -184,7 +184,7 @@ async function manageTradeSubscription(): Promise<void> {
|
||||
### Volume Analysis
|
||||
|
||||
```typescript
|
||||
import { LXDexClient, Trade, OrderSide } from '@luxfi/dex-sdk';
|
||||
import { Client, Trade, OrderSide } from '@luxfi/trading';
|
||||
|
||||
interface VolumeAnalysis {
|
||||
totalVolume: number;
|
||||
@@ -229,8 +229,8 @@ function analyzeVolume(trades: Trade[]): VolumeAnalysis {
|
||||
}
|
||||
|
||||
async function getVolumeAnalysis(): Promise<void> {
|
||||
const client = new LXDexClient({
|
||||
jsonRpcUrl: 'http://localhost:8080/rpc'
|
||||
const client = new Client({
|
||||
rpcUrl: 'http://localhost:8080/rpc'
|
||||
});
|
||||
|
||||
const trades = await client.getTrades('BTC-USD', 1000);
|
||||
@@ -248,7 +248,7 @@ async function getVolumeAnalysis(): Promise<void> {
|
||||
### Trade Aggregation by Time
|
||||
|
||||
```typescript
|
||||
import { Trade } from '@luxfi/dex-sdk';
|
||||
import { Trade } from '@luxfi/trading';
|
||||
|
||||
interface CandleData {
|
||||
open: number;
|
||||
@@ -308,8 +308,8 @@ function aggregateTradesToCandles(
|
||||
|
||||
// Usage: 1-minute candles
|
||||
async function getMinuteCandles(): Promise<void> {
|
||||
const client = new LXDexClient({
|
||||
jsonRpcUrl: 'http://localhost:8080/rpc'
|
||||
const client = new Client({
|
||||
rpcUrl: 'http://localhost:8080/rpc'
|
||||
});
|
||||
|
||||
const trades = await client.getTrades('BTC-USD', 1000);
|
||||
@@ -326,7 +326,7 @@ async function getMinuteCandles(): Promise<void> {
|
||||
### Large Trade Detection
|
||||
|
||||
```typescript
|
||||
import { LXDexClient, Trade } from '@luxfi/dex-sdk';
|
||||
import { Client, Trade } from '@luxfi/trading';
|
||||
|
||||
interface LargeTrade extends Trade {
|
||||
volumeUSD: number;
|
||||
@@ -337,8 +337,8 @@ async function detectLargeTrades(
|
||||
symbol: string,
|
||||
threshold: number = 2.0
|
||||
): Promise<LargeTrade[]> {
|
||||
const client = new LXDexClient({
|
||||
jsonRpcUrl: 'http://localhost:8080/rpc'
|
||||
const client = new Client({
|
||||
rpcUrl: 'http://localhost:8080/rpc'
|
||||
});
|
||||
|
||||
const trades = await client.getTrades(symbol, 1000);
|
||||
@@ -359,8 +359,8 @@ async function detectLargeTrades(
|
||||
}
|
||||
|
||||
async function monitorLargeTrades(): Promise<void> {
|
||||
const client = new LXDexClient({
|
||||
jsonRpcUrl: 'http://localhost:8080/rpc',
|
||||
const client = new Client({
|
||||
rpcUrl: 'http://localhost:8080/rpc',
|
||||
wsUrl: 'ws://localhost:8081'
|
||||
});
|
||||
|
||||
@@ -396,7 +396,7 @@ async function monitorLargeTrades(): Promise<void> {
|
||||
|
||||
```tsx
|
||||
import { useState, useEffect, useCallback } from 'react';
|
||||
import { LXDexClient, Trade } from '@luxfi/dex-sdk';
|
||||
import { Client, Trade } from '@luxfi/trading';
|
||||
|
||||
interface UseTradesOptions {
|
||||
limit?: number;
|
||||
@@ -411,7 +411,7 @@ interface UseTradesResult {
|
||||
}
|
||||
|
||||
export function useTrades(
|
||||
client: LXDexClient | null,
|
||||
client: Client | null,
|
||||
symbol: string,
|
||||
options: UseTradesOptions = {}
|
||||
): UseTradesResult {
|
||||
@@ -469,7 +469,7 @@ export function useTrades(
|
||||
import React from 'react';
|
||||
import { useTrades } from './hooks/useTrades';
|
||||
import { useDexClient } from './DexProvider';
|
||||
import { Trade, OrderSide } from '@luxfi/dex-sdk';
|
||||
import { Trade, OrderSide } from '@luxfi/trading';
|
||||
|
||||
function TradeHistory(): JSX.Element {
|
||||
const { client } = useDexClient();
|
||||
@@ -521,7 +521,7 @@ function TradeHistory(): JSX.Element {
|
||||
|
||||
```tsx
|
||||
import { useState, useEffect } from 'react';
|
||||
import { LXDexClient, Trade, OrderSide } from '@luxfi/dex-sdk';
|
||||
import { Client, Trade, OrderSide } from '@luxfi/trading';
|
||||
|
||||
interface TradeStats {
|
||||
totalVolume: number;
|
||||
@@ -535,7 +535,7 @@ interface TradeStats {
|
||||
}
|
||||
|
||||
export function useTradeStats(
|
||||
client: LXDexClient | null,
|
||||
client: Client | null,
|
||||
symbol: string
|
||||
): TradeStats {
|
||||
const [stats, setStats] = useState<TradeStats>({
|
||||
@@ -602,7 +602,7 @@ export function useTradeStats(
|
||||
### Export to CSV
|
||||
|
||||
```typescript
|
||||
import { Trade, OrderSide } from '@luxfi/dex-sdk';
|
||||
import { Trade, OrderSide } from '@luxfi/trading';
|
||||
|
||||
function tradesToCSV(trades: Trade[]): string {
|
||||
const headers = [
|
||||
@@ -652,7 +652,7 @@ function downloadTradesCSV(trades: Trade[], filename: string): void {
|
||||
### Export to JSON
|
||||
|
||||
```typescript
|
||||
import { Trade } from '@luxfi/dex-sdk';
|
||||
import { Trade } from '@luxfi/trading';
|
||||
|
||||
function tradesToJSON(trades: Trade[]): string {
|
||||
return JSON.stringify(trades, null, 2);
|
||||
@@ -665,8 +665,8 @@ async function exportTradesToFile(
|
||||
symbol: string,
|
||||
filename: string
|
||||
): Promise<void> {
|
||||
const client = new LXDexClient({
|
||||
jsonRpcUrl: 'http://localhost:8080/rpc'
|
||||
const client = new Client({
|
||||
rpcUrl: 'http://localhost:8080/rpc'
|
||||
});
|
||||
|
||||
const trades = await client.getTrades(symbol, 10000);
|
||||
|
||||
@@ -5,7 +5,7 @@ description: Complete TypeScript type definitions and interfaces for the LX SDK
|
||||
|
||||
# Type Reference
|
||||
|
||||
Complete reference of all TypeScript types, interfaces, and enums exported by `@luxfi/dex-sdk`.
|
||||
Complete reference of all TypeScript types, interfaces, and enums exported by `@luxfi/trading`.
|
||||
|
||||
## Enumerations
|
||||
|
||||
@@ -229,10 +229,10 @@ interface NodeInfo {
|
||||
|
||||
## Configuration Types
|
||||
|
||||
### LXDexConfig
|
||||
### ClientConfig
|
||||
|
||||
```typescript
|
||||
interface LXDexConfig {
|
||||
interface ClientConfig {
|
||||
/** JSON-RPC endpoint URL */
|
||||
jsonRpcUrl?: string;
|
||||
|
||||
@@ -598,19 +598,19 @@ type MarketDataProvider = typeof MarketDataProviders[keyof typeof MarketDataProv
|
||||
|
||||
## Class Exports
|
||||
|
||||
### LXDexClient
|
||||
### Client
|
||||
|
||||
Main client class for interacting with LX.
|
||||
|
||||
```typescript
|
||||
class LXDexClient {
|
||||
class Client {
|
||||
/** Market data sub-client */
|
||||
marketData: MarketDataClient;
|
||||
|
||||
/** Liquidation monitoring sub-client */
|
||||
liquidationMonitor: LiquidationMonitor;
|
||||
|
||||
constructor(config?: LXDexConfig);
|
||||
constructor(config?: ClientConfig);
|
||||
|
||||
// Connection
|
||||
connect(): Promise<void>;
|
||||
@@ -685,8 +685,8 @@ class LiquidationMonitor {
|
||||
|
||||
```typescript
|
||||
// Main export
|
||||
export { LXDexClient };
|
||||
export default LXDexClient;
|
||||
export { Client };
|
||||
export default Client;
|
||||
|
||||
// Enums
|
||||
export { OrderType, OrderSide, OrderStatus, TimeInForce };
|
||||
@@ -698,7 +698,7 @@ export {
|
||||
OrderBook,
|
||||
OrderBookLevel,
|
||||
NodeInfo,
|
||||
LXDexConfig,
|
||||
ClientConfig,
|
||||
MarketDataSource,
|
||||
MarketStats,
|
||||
MarginInfo,
|
||||
@@ -778,7 +778,7 @@ type Result<T, E = Error> =
|
||||
|
||||
// Usage
|
||||
async function safePlaceOrder(
|
||||
client: LXDexClient,
|
||||
client: Client,
|
||||
order: Partial<Order>
|
||||
): Promise<Result<PlaceOrderResponse>> {
|
||||
try {
|
||||
|
||||
@@ -12,11 +12,11 @@ The TypeScript SDK provides WebSocket support for real-time market data, order u
|
||||
### Establishing Connection
|
||||
|
||||
```typescript
|
||||
import { LXDexClient } from '@luxfi/dex-sdk';
|
||||
import { Client } from '@luxfi/trading';
|
||||
|
||||
async function connectWebSocket(): Promise<void> {
|
||||
const client = new LXDexClient({
|
||||
jsonRpcUrl: 'http://localhost:8080/rpc',
|
||||
const client = new Client({
|
||||
rpcUrl: 'http://localhost:8080/rpc',
|
||||
wsUrl: 'ws://localhost:8081'
|
||||
});
|
||||
|
||||
@@ -31,9 +31,9 @@ async function connectWebSocket(): Promise<void> {
|
||||
### Disconnecting
|
||||
|
||||
```typescript
|
||||
import { LXDexClient } from '@luxfi/dex-sdk';
|
||||
import { Client } from '@luxfi/trading';
|
||||
|
||||
function disconnectWebSocket(client: LXDexClient): void {
|
||||
function disconnectWebSocket(client: Client): void {
|
||||
client.disconnect();
|
||||
console.log('WebSocket disconnected');
|
||||
}
|
||||
@@ -44,11 +44,11 @@ function disconnectWebSocket(client: LXDexClient): void {
|
||||
### Subscribe to Channels
|
||||
|
||||
```typescript
|
||||
import { LXDexClient } from '@luxfi/dex-sdk';
|
||||
import { Client } from '@luxfi/trading';
|
||||
|
||||
async function subscribeToChannels(): Promise<void> {
|
||||
const client = new LXDexClient({
|
||||
jsonRpcUrl: 'http://localhost:8080/rpc',
|
||||
const client = new Client({
|
||||
rpcUrl: 'http://localhost:8080/rpc',
|
||||
wsUrl: 'ws://localhost:8081'
|
||||
});
|
||||
|
||||
@@ -73,11 +73,11 @@ async function subscribeToChannels(): Promise<void> {
|
||||
### Unsubscribe from Channels
|
||||
|
||||
```typescript
|
||||
import { LXDexClient, OrderBook } from '@luxfi/dex-sdk';
|
||||
import { Client, OrderBook } from '@luxfi/trading';
|
||||
|
||||
async function unsubscribeExample(): Promise<void> {
|
||||
const client = new LXDexClient({
|
||||
jsonRpcUrl: 'http://localhost:8080/rpc',
|
||||
const client = new Client({
|
||||
rpcUrl: 'http://localhost:8080/rpc',
|
||||
wsUrl: 'ws://localhost:8081'
|
||||
});
|
||||
|
||||
@@ -114,17 +114,17 @@ async function unsubscribeExample(): Promise<void> {
|
||||
### Manual Reconnection
|
||||
|
||||
```typescript
|
||||
import { LXDexClient } from '@luxfi/dex-sdk';
|
||||
import { Client } from '@luxfi/trading';
|
||||
|
||||
class ReconnectingClient {
|
||||
private client: LXDexClient;
|
||||
private client: Client;
|
||||
private connected: boolean = false;
|
||||
private reconnecting: boolean = false;
|
||||
private maxRetries: number = 5;
|
||||
private retryDelay: number = 1000;
|
||||
|
||||
constructor(config: { jsonRpcUrl: string; wsUrl: string }) {
|
||||
this.client = new LXDexClient(config);
|
||||
constructor(config: { rpcUrl: string; wsUrl: string }) {
|
||||
this.client = new Client(config);
|
||||
}
|
||||
|
||||
async connect(): Promise<void> {
|
||||
@@ -171,7 +171,7 @@ class ReconnectingClient {
|
||||
return new Promise(resolve => setTimeout(resolve, ms));
|
||||
}
|
||||
|
||||
getClient(): LXDexClient {
|
||||
getClient(): Client {
|
||||
return this.client;
|
||||
}
|
||||
}
|
||||
@@ -180,7 +180,7 @@ class ReconnectingClient {
|
||||
### Automatic Reconnection with Event Handling
|
||||
|
||||
```typescript
|
||||
import { LXDexClient, OrderBook, Trade } from '@luxfi/dex-sdk';
|
||||
import { Client, OrderBook, Trade } from '@luxfi/trading';
|
||||
|
||||
interface Subscription {
|
||||
channel: string;
|
||||
@@ -188,15 +188,15 @@ interface Subscription {
|
||||
}
|
||||
|
||||
class AutoReconnectClient {
|
||||
private client: LXDexClient;
|
||||
private config: { jsonRpcUrl: string; wsUrl: string };
|
||||
private client: Client;
|
||||
private config: { rpcUrl: string; wsUrl: string };
|
||||
private subscriptions: Subscription[] = [];
|
||||
private reconnectTimer: NodeJS.Timeout | null = null;
|
||||
private isConnected: boolean = false;
|
||||
|
||||
constructor(config: { jsonRpcUrl: string; wsUrl: string }) {
|
||||
constructor(config: { rpcUrl: string; wsUrl: string }) {
|
||||
this.config = config;
|
||||
this.client = new LXDexClient(config);
|
||||
this.client = new Client(config);
|
||||
}
|
||||
|
||||
async connect(): Promise<void> {
|
||||
@@ -217,7 +217,7 @@ class AutoReconnectClient {
|
||||
this.reconnectTimer = null;
|
||||
|
||||
try {
|
||||
this.client = new LXDexClient(this.config);
|
||||
this.client = new Client(this.config);
|
||||
await this.connect();
|
||||
} catch {
|
||||
this.scheduleReconnect();
|
||||
@@ -271,10 +271,10 @@ class AutoReconnectClient {
|
||||
### Ping-Pong Heartbeat
|
||||
|
||||
```typescript
|
||||
import { LXDexClient } from '@luxfi/dex-sdk';
|
||||
import { Client } from '@luxfi/trading';
|
||||
|
||||
class HeartbeatClient {
|
||||
private client: LXDexClient;
|
||||
private client: Client;
|
||||
private heartbeatInterval: NodeJS.Timeout | null = null;
|
||||
private missedHeartbeats: number = 0;
|
||||
private maxMissedHeartbeats: number = 3;
|
||||
@@ -282,10 +282,10 @@ class HeartbeatClient {
|
||||
private onDisconnect?: () => void;
|
||||
|
||||
constructor(
|
||||
config: { jsonRpcUrl: string; wsUrl: string },
|
||||
config: { rpcUrl: string; wsUrl: string },
|
||||
onDisconnect?: () => void
|
||||
) {
|
||||
this.client = new LXDexClient(config);
|
||||
this.client = new Client(config);
|
||||
this.onDisconnect = onDisconnect;
|
||||
}
|
||||
|
||||
@@ -324,7 +324,7 @@ class HeartbeatClient {
|
||||
this.client.disconnect();
|
||||
}
|
||||
|
||||
getClient(): LXDexClient {
|
||||
getClient(): Client {
|
||||
return this.client;
|
||||
}
|
||||
}
|
||||
@@ -333,7 +333,7 @@ class HeartbeatClient {
|
||||
async function useHeartbeatClient(): Promise<void> {
|
||||
const client = new HeartbeatClient(
|
||||
{
|
||||
jsonRpcUrl: 'http://localhost:8080/rpc',
|
||||
rpcUrl: 'http://localhost:8080/rpc',
|
||||
wsUrl: 'ws://localhost:8081'
|
||||
},
|
||||
() => {
|
||||
@@ -351,7 +351,7 @@ async function useHeartbeatClient(): Promise<void> {
|
||||
### Custom Message Handler
|
||||
|
||||
```typescript
|
||||
import { LXDexClient } from '@luxfi/dex-sdk';
|
||||
import { Client } from '@luxfi/trading';
|
||||
|
||||
interface WebSocketMessage {
|
||||
channel: string;
|
||||
@@ -404,14 +404,14 @@ class MessageHandler {
|
||||
### Browser WebSocket Client
|
||||
|
||||
```typescript
|
||||
import { LXDexClient, OrderBook, Trade } from '@luxfi/dex-sdk';
|
||||
import { Client, OrderBook, Trade } from '@luxfi/trading';
|
||||
|
||||
class BrowserDexClient {
|
||||
private client: LXDexClient;
|
||||
private client: Client;
|
||||
private visibilityHandler: (() => void) | null = null;
|
||||
|
||||
constructor(config: { jsonRpcUrl: string; wsUrl: string }) {
|
||||
this.client = new LXDexClient(config);
|
||||
constructor(config: { rpcUrl: string; wsUrl: string }) {
|
||||
this.client = new Client(config);
|
||||
this.setupVisibilityHandling();
|
||||
}
|
||||
|
||||
@@ -468,7 +468,7 @@ class BrowserDexClient {
|
||||
|
||||
```tsx
|
||||
import { useState, useEffect, useCallback, useRef } from 'react';
|
||||
import { LXDexClient, LXDexConfig } from '@luxfi/dex-sdk';
|
||||
import { Client, ClientConfig } from '@luxfi/trading';
|
||||
|
||||
interface UseWebSocketOptions {
|
||||
autoConnect?: boolean;
|
||||
@@ -483,11 +483,11 @@ interface UseWebSocketResult {
|
||||
error: Error | null;
|
||||
connect: () => Promise<void>;
|
||||
disconnect: () => void;
|
||||
client: LXDexClient | null;
|
||||
client: Client | null;
|
||||
}
|
||||
|
||||
export function useWebSocket(
|
||||
config: LXDexConfig,
|
||||
config: ClientConfig,
|
||||
options: UseWebSocketOptions = {}
|
||||
): UseWebSocketResult {
|
||||
const {
|
||||
@@ -500,7 +500,7 @@ export function useWebSocket(
|
||||
const [connected, setConnected] = useState(false);
|
||||
const [connecting, setConnecting] = useState(false);
|
||||
const [error, setError] = useState<Error | null>(null);
|
||||
const clientRef = useRef<LXDexClient | null>(null);
|
||||
const clientRef = useRef<Client | null>(null);
|
||||
const reconnectAttempts = useRef(0);
|
||||
|
||||
const connect = useCallback(async () => {
|
||||
@@ -511,7 +511,7 @@ export function useWebSocket(
|
||||
|
||||
try {
|
||||
if (!clientRef.current) {
|
||||
clientRef.current = new LXDexClient(config);
|
||||
clientRef.current = new Client(config);
|
||||
}
|
||||
|
||||
await clientRef.current.connect();
|
||||
@@ -563,11 +563,11 @@ export function useWebSocket(
|
||||
```tsx
|
||||
import React from 'react';
|
||||
import { useWebSocket } from './hooks/useWebSocket';
|
||||
import { OrderBook } from '@luxfi/dex-sdk';
|
||||
import { OrderBook } from '@luxfi/trading';
|
||||
|
||||
function TradingApp(): JSX.Element {
|
||||
const { connected, connecting, error, client } = useWebSocket({
|
||||
jsonRpcUrl: 'http://localhost:8080/rpc',
|
||||
rpcUrl: 'http://localhost:8080/rpc',
|
||||
wsUrl: 'ws://localhost:8081'
|
||||
});
|
||||
|
||||
@@ -616,11 +616,11 @@ function TradingApp(): JSX.Element {
|
||||
### Server-Side WebSocket Client
|
||||
|
||||
```typescript
|
||||
import { LXDexClient, OrderBook, Trade } from '@luxfi/dex-sdk';
|
||||
import { Client, OrderBook, Trade } from '@luxfi/trading';
|
||||
|
||||
async function runNodeClient(): Promise<void> {
|
||||
const client = new LXDexClient({
|
||||
jsonRpcUrl: 'http://localhost:8080/rpc',
|
||||
const client = new Client({
|
||||
rpcUrl: 'http://localhost:8080/rpc',
|
||||
wsUrl: 'ws://localhost:8081'
|
||||
});
|
||||
|
||||
@@ -664,7 +664,7 @@ runNodeClient();
|
||||
### Connection Status Monitor
|
||||
|
||||
```typescript
|
||||
import { LXDexClient } from '@luxfi/dex-sdk';
|
||||
import { Client } from '@luxfi/trading';
|
||||
|
||||
interface ConnectionStatus {
|
||||
connected: boolean;
|
||||
@@ -674,7 +674,7 @@ interface ConnectionStatus {
|
||||
}
|
||||
|
||||
class ConnectionMonitor {
|
||||
private client: LXDexClient;
|
||||
private client: Client;
|
||||
private status: ConnectionStatus = {
|
||||
connected: false,
|
||||
lastPing: null,
|
||||
@@ -684,7 +684,7 @@ class ConnectionMonitor {
|
||||
private pingInterval: NodeJS.Timeout | null = null;
|
||||
private statusCallbacks: ((status: ConnectionStatus) => void)[] = [];
|
||||
|
||||
constructor(client: LXDexClient) {
|
||||
constructor(client: Client) {
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
|
||||
@@ -581,7 +581,7 @@ function detectAnomaly(session: Session, request: Request): boolean {
|
||||
|
||||
```typescript
|
||||
// Enable request debugging (development only)
|
||||
const dex = new LxDex({
|
||||
const dex = await DEX({
|
||||
debug: true,
|
||||
onRequest: (req) => {
|
||||
console.log('Request:', {
|
||||
|
||||
@@ -190,14 +190,14 @@ See [Consensus](/docs/consensus) for details.
|
||||
|
||||
### How does settlement work?
|
||||
|
||||
1. Order matched in DEX sidecar (sub-millisecond)
|
||||
2. Settlement message sent via Warp
|
||||
1. Order matched on LX L2 chain (sub-millisecond)
|
||||
2. Settlement message sent via Warp to C-Chain
|
||||
3. On-chain confirmation (1ms finality)
|
||||
4. Balances updated atomically
|
||||
|
||||
### Is the order book really on-chain?
|
||||
|
||||
Yes. Every order, cancel, and trade is recorded on-chain with full transparency. The matching engine runs as a sidecar for performance but settlement is atomic and on-chain.
|
||||
Yes. Every order, cancel, and trade is recorded on-chain with full transparency. The matching engine runs on the LX L2 chain for performance, sharing consensus and finality with the main Lux network. Settlement is atomic and on-chain.
|
||||
|
||||
### What about MEV?
|
||||
|
||||
|
||||
@@ -72,9 +72,9 @@ curl -X POST https://faucet.testnet.lux.network/api/request \
|
||||
#### TypeScript
|
||||
|
||||
```typescript
|
||||
import { LXDexClient } from '@luxfi/dex-sdk';
|
||||
import { Client } from '@luxfi/trading';
|
||||
|
||||
const client = new LXDexClient({ network: 'testnet' });
|
||||
const client = new Client({ network: 'testnet' });
|
||||
|
||||
// Request all available tokens
|
||||
const result = await client.faucet.request({
|
||||
@@ -94,9 +94,9 @@ console.log('Remaining today:', allowance);
|
||||
#### Python
|
||||
|
||||
```python
|
||||
from luxfi_dex import LXDexClient
|
||||
from luxfi_dex import Client
|
||||
|
||||
client = LXDexClient(network='testnet')
|
||||
client = Client(network='testnet')
|
||||
|
||||
# Request all available tokens
|
||||
result = client.faucet.request(
|
||||
|
||||
@@ -65,12 +65,12 @@ curl -X POST https://faucet.testnet.lux.network/api/request \
|
||||
### 2. Connect to Testnet
|
||||
|
||||
```typescript
|
||||
import { LXDexClient } from '@luxfi/dex-sdk';
|
||||
import { Client } from '@luxfi/trading';
|
||||
|
||||
const client = new LXDexClient({
|
||||
const client = new Client({
|
||||
network: 'testnet',
|
||||
// Or explicitly:
|
||||
// jsonRpcUrl: 'https://testnet-api.lux.network/rpc',
|
||||
// rpcUrl: 'https://testnet-api.lux.network/rpc',
|
||||
// wsUrl: 'wss://testnet-api.lux.network/ws',
|
||||
});
|
||||
```
|
||||
@@ -131,9 +131,9 @@ ws.onmessage = (event) => {
|
||||
Test trading strategies with realistic market conditions:
|
||||
|
||||
```python
|
||||
from luxfi_dex import LXDexClient
|
||||
from luxfi_dex import Client
|
||||
|
||||
client = LXDexClient(network='testnet')
|
||||
client = Client(network='testnet')
|
||||
|
||||
# Execute paper trading strategy
|
||||
for signal in strategy.signals():
|
||||
|
||||
@@ -20,11 +20,11 @@ Choose your preferred language:
|
||||
#### TypeScript
|
||||
|
||||
```bash
|
||||
npm install @luxfi/dex-sdk
|
||||
npm install @luxfi/trading
|
||||
# or
|
||||
pnpm add @luxfi/dex-sdk
|
||||
pnpm add @luxfi/trading
|
||||
# or
|
||||
yarn add @luxfi/dex-sdk
|
||||
yarn add @luxfi/trading
|
||||
```
|
||||
#### Python
|
||||
|
||||
@@ -48,9 +48,9 @@ Request free test tokens from the faucet:
|
||||
#### TypeScript
|
||||
|
||||
```typescript
|
||||
import { LXDexClient } from '@luxfi/dex-sdk';
|
||||
import { Client } from '@luxfi/trading';
|
||||
|
||||
const client = new LXDexClient({ network: 'testnet' });
|
||||
const client = new Client({ network: 'testnet' });
|
||||
|
||||
// Request test tokens
|
||||
const result = await client.faucet.request({
|
||||
@@ -64,9 +64,9 @@ console.log('Tokens received:', result.amounts);
|
||||
#### Python
|
||||
|
||||
```python
|
||||
from luxfi_dex import LXDexClient
|
||||
from luxfi_dex import Client
|
||||
|
||||
client = LXDexClient(network='testnet')
|
||||
client = Client(network='testnet')
|
||||
|
||||
# Request test tokens
|
||||
result = client.faucet.request(
|
||||
@@ -364,11 +364,11 @@ curl -X POST https://testnet-api.lux.network/rpc \
|
||||
Here's a full working example that combines all steps:
|
||||
|
||||
```typescript
|
||||
import { LXDexClient } from '@luxfi/dex-sdk';
|
||||
import { Client } from '@luxfi/trading';
|
||||
|
||||
async function main() {
|
||||
// Initialize client
|
||||
const client = new LXDexClient({ network: 'testnet' });
|
||||
const client = new Client({ network: 'testnet' });
|
||||
|
||||
// Request test tokens
|
||||
console.log('Requesting test tokens...');
|
||||
|
||||
@@ -87,12 +87,12 @@ curl -X POST http://localhost:8080/rpc \
|
||||
### TypeScript
|
||||
|
||||
```typescript
|
||||
import { LXDexClient } from '@luxfi/dex-sdk';
|
||||
import { Client } from '@luxfi/trading';
|
||||
import crypto from 'crypto';
|
||||
|
||||
// Method 1: SDK handles authentication
|
||||
const client = new LXDexClient({
|
||||
jsonRpcUrl: 'http://localhost:8080/rpc',
|
||||
const client = new Client({
|
||||
rpcUrl: 'http://localhost:8080/rpc',
|
||||
apiKey: 'lx_pk_live_a1b2c3d4e5f6g7h8i9j0',
|
||||
apiSecret: 'lx_sk_live_z9y8x7w6v5u4t3s2r1q0'
|
||||
});
|
||||
@@ -160,10 +160,10 @@ import hashlib
|
||||
import time
|
||||
import json
|
||||
import requests
|
||||
from luxfi_dex import LXDexClient
|
||||
from luxfi_dex import Client
|
||||
|
||||
# Method 1: SDK handles authentication
|
||||
client = LXDexClient(
|
||||
client = Client(
|
||||
json_rpc_url='http://localhost:8080/rpc',
|
||||
api_key='lx_pk_live_a1b2c3d4e5f6g7h8i9j0',
|
||||
api_secret='lx_sk_live_z9y8x7w6v5u4t3s2r1q0'
|
||||
@@ -340,11 +340,11 @@ curl -X POST http://localhost:8080/rpc \
|
||||
#### TypeScript
|
||||
|
||||
```typescript
|
||||
import { LXDexClient } from '@luxfi/dex-sdk';
|
||||
import { Client } from '@luxfi/trading';
|
||||
|
||||
// Initialize with JWT
|
||||
const client = new LXDexClient({
|
||||
jsonRpcUrl: 'http://localhost:8080/rpc',
|
||||
const client = new Client({
|
||||
rpcUrl: 'http://localhost:8080/rpc',
|
||||
jwtToken: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...'
|
||||
});
|
||||
|
||||
@@ -375,12 +375,12 @@ async function refreshToken(refreshToken: string): Promise<string> {
|
||||
#### Python
|
||||
|
||||
```python
|
||||
from luxfi_dex import LXDexClient
|
||||
from luxfi_dex import Client
|
||||
import jwt
|
||||
from datetime import datetime
|
||||
|
||||
# Initialize with JWT
|
||||
client = LXDexClient(
|
||||
client = Client(
|
||||
json_rpc_url='http://localhost:8080/rpc',
|
||||
jwt_token='eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...'
|
||||
)
|
||||
@@ -457,9 +457,9 @@ WebSocket connections require authentication on connect.
|
||||
### TypeScript
|
||||
|
||||
```typescript
|
||||
import { LXDexClient } from '@luxfi/dex-sdk';
|
||||
import { Client } from '@luxfi/trading';
|
||||
|
||||
const client = new LXDexClient({
|
||||
const client = new Client({
|
||||
wsUrl: 'wss://localhost:8081',
|
||||
apiKey: 'lx_pk_live_a1b2c3d4e5f6g7h8i9j0',
|
||||
apiSecret: 'lx_sk_live_z9y8x7w6v5u4t3s2r1q0'
|
||||
@@ -502,11 +502,11 @@ import hmac
|
||||
import hashlib
|
||||
import time
|
||||
import websockets
|
||||
from luxfi_dex import AsyncLXDexClient
|
||||
from luxfi_dex import AsyncClient
|
||||
|
||||
async def main():
|
||||
# Method 1: SDK handles authentication
|
||||
client = AsyncLXDexClient(
|
||||
client = AsyncClient(
|
||||
ws_url='wss://localhost:8081',
|
||||
api_key='lx_pk_live_a1b2c3d4e5f6g7h8i9j0',
|
||||
api_secret='lx_sk_live_z9y8x7w6v5u4t3s2r1q0'
|
||||
@@ -709,7 +709,7 @@ import { config } from 'dotenv';
|
||||
config();
|
||||
|
||||
export const dexConfig = {
|
||||
jsonRpcUrl: process.env.LX_RPC_URL || 'http://localhost:8080/rpc',
|
||||
rpcUrl: process.env.LX_RPC_URL || 'http://localhost:8080/rpc',
|
||||
apiKey: process.env.LX_API_KEY,
|
||||
apiSecret: process.env.LX_API_SECRET
|
||||
};
|
||||
|
||||
@@ -75,10 +75,10 @@ testConnection()
|
||||
### Python
|
||||
|
||||
```python
|
||||
from luxfi_dex import LXDexClient
|
||||
from luxfi_dex import Client
|
||||
|
||||
# Create client instance
|
||||
client = LXDexClient(
|
||||
client = Client(
|
||||
json_rpc_url='http://localhost:8080/rpc',
|
||||
ws_url='ws://localhost:8081'
|
||||
)
|
||||
@@ -702,11 +702,11 @@ main().catch(console.error)
|
||||
### Python
|
||||
|
||||
```python
|
||||
from luxfi_dex import LXDexClient
|
||||
from luxfi_dex import Client
|
||||
|
||||
def main():
|
||||
# Initialize client
|
||||
client = LXDexClient(
|
||||
client = Client(
|
||||
json_rpc_url='http://localhost:8080/rpc'
|
||||
)
|
||||
|
||||
|
||||
@@ -75,12 +75,12 @@ LX supports comprehensive wallet integration for all user types:
|
||||
### TypeScript SDK
|
||||
|
||||
```typescript
|
||||
import { LXDexClient, WalletAdapter } from '@luxfi/dex-sdk';
|
||||
import { MetaMaskAdapter } from '@luxfi/dex-sdk/wallets';
|
||||
import { Client, WalletAdapter } from '@luxfi/trading';
|
||||
import { MetaMaskAdapter } from '@luxfi/trading/wallets';
|
||||
|
||||
// Create client with wallet adapter
|
||||
const wallet = new MetaMaskAdapter();
|
||||
const client = new LXDexClient({
|
||||
const client = new Client({
|
||||
endpoint: 'https://dex.lux.network',
|
||||
wallet: wallet
|
||||
});
|
||||
@@ -101,12 +101,12 @@ const order = await client.placeOrder({
|
||||
### Python SDK
|
||||
|
||||
```python
|
||||
from lx_dex import LXDexClient
|
||||
from lx_dex import Client
|
||||
from lx_dex.wallets import Web3Wallet
|
||||
|
||||
# Create client with wallet
|
||||
wallet = Web3Wallet(private_key=os.environ['PRIVATE_KEY'])
|
||||
client = LXDexClient(
|
||||
client = Client(
|
||||
endpoint='https://dex.lux.network',
|
||||
wallet=wallet
|
||||
)
|
||||
@@ -276,7 +276,7 @@ const LUX_TESTNET = {
|
||||
## Error Handling
|
||||
|
||||
```typescript
|
||||
import { WalletError, WalletErrorCode } from '@luxfi/dex-sdk/wallets';
|
||||
import { WalletError, WalletErrorCode } from '@luxfi/trading/wallets';
|
||||
|
||||
try {
|
||||
await wallet.connect();
|
||||
|
||||
@@ -62,7 +62,7 @@ MPC Wallet Architecture
|
||||
### Setup
|
||||
|
||||
```typescript
|
||||
import { FireblocksAdapter } from '@luxfi/dex-sdk/wallets/mpc';
|
||||
import { FireblocksAdapter } from '@luxfi/trading/wallets/mpc';
|
||||
|
||||
const fireblocks = new FireblocksAdapter({
|
||||
apiKey: process.env.FIREBLOCKS_API_KEY,
|
||||
@@ -71,7 +71,7 @@ const fireblocks = new FireblocksAdapter({
|
||||
vaultAccountId: 'YOUR_VAULT_ACCOUNT_ID'
|
||||
});
|
||||
|
||||
const client = new LXDexClient({
|
||||
const client = new Client({
|
||||
endpoint: 'https://dex.lux.network',
|
||||
wallet: fireblocks
|
||||
});
|
||||
@@ -191,7 +191,7 @@ app.post('/webhook/fireblocks', (req, res) => {
|
||||
### Setup
|
||||
|
||||
```typescript
|
||||
import { BitGoAdapter } from '@luxfi/dex-sdk/wallets/mpc';
|
||||
import { BitGoAdapter } from '@luxfi/trading/wallets/mpc';
|
||||
|
||||
const bitgo = new BitGoAdapter({
|
||||
accessToken: process.env.BITGO_ACCESS_TOKEN,
|
||||
@@ -199,7 +199,7 @@ const bitgo = new BitGoAdapter({
|
||||
coin: 'lux'
|
||||
});
|
||||
|
||||
const client = new LXDexClient({
|
||||
const client = new Client({
|
||||
endpoint: 'https://dex.lux.network',
|
||||
wallet: bitgo
|
||||
});
|
||||
@@ -249,7 +249,7 @@ async function signWithBitGo(order: Order): Promise<string> {
|
||||
### Setup
|
||||
|
||||
```typescript
|
||||
import { CopperAdapter } from '@luxfi/dex-sdk/wallets/mpc';
|
||||
import { CopperAdapter } from '@luxfi/trading/wallets/mpc';
|
||||
|
||||
const copper = new CopperAdapter({
|
||||
apiKey: process.env.COPPER_API_KEY,
|
||||
@@ -257,7 +257,7 @@ const copper = new CopperAdapter({
|
||||
portfolioId: process.env.COPPER_PORTFOLIO_ID
|
||||
});
|
||||
|
||||
const client = new LXDexClient({
|
||||
const client = new Client({
|
||||
endpoint: 'https://dex.lux.network',
|
||||
wallet: copper
|
||||
});
|
||||
@@ -288,7 +288,7 @@ For self-hosted MPC using Lux's native threshold signing:
|
||||
### Setup
|
||||
|
||||
```typescript
|
||||
import { ThresholdAdapter } from '@luxfi/dex-sdk/wallets/mpc';
|
||||
import { ThresholdAdapter } from '@luxfi/trading/wallets/mpc';
|
||||
|
||||
const threshold = new ThresholdAdapter({
|
||||
endpoint: 'https://t-chain.lux.network',
|
||||
|
||||
@@ -31,16 +31,16 @@ LX supports all major Web3 wallets through standard interfaces:
|
||||
### Installation
|
||||
|
||||
```bash
|
||||
npm install @luxfi/dex-sdk
|
||||
npm install @luxfi/trading
|
||||
```
|
||||
|
||||
### Basic Connection
|
||||
|
||||
```typescript
|
||||
import { LXDexClient, MetaMaskAdapter } from '@luxfi/dex-sdk';
|
||||
import { Client, MetaMaskAdapter } from '@luxfi/trading';
|
||||
|
||||
const adapter = new MetaMaskAdapter();
|
||||
const client = new LXDexClient({
|
||||
const client = new Client({
|
||||
endpoint: 'https://dex.lux.network',
|
||||
wallet: adapter
|
||||
});
|
||||
@@ -145,7 +145,7 @@ adapter.on('disconnect', () => {
|
||||
### Setup
|
||||
|
||||
```typescript
|
||||
import { WalletConnectAdapter } from '@luxfi/dex-sdk';
|
||||
import { WalletConnectAdapter } from '@luxfi/trading';
|
||||
|
||||
const adapter = new WalletConnectAdapter({
|
||||
projectId: 'YOUR_WALLETCONNECT_PROJECT_ID',
|
||||
@@ -218,7 +218,7 @@ async function disconnect() {
|
||||
## EIP-6963 Multi-Wallet Discovery
|
||||
|
||||
```typescript
|
||||
import { discoverWallets, WalletInfo } from '@luxfi/dex-sdk';
|
||||
import { discoverWallets, WalletInfo } from '@luxfi/trading';
|
||||
|
||||
// Discover all available wallets
|
||||
const wallets = await discoverWallets();
|
||||
@@ -255,7 +255,7 @@ async function connectWallet(wallet: WalletInfo) {
|
||||
|
||||
```typescript
|
||||
import { useState, useEffect, useCallback } from 'react';
|
||||
import { WalletAdapter, MetaMaskAdapter } from '@luxfi/dex-sdk';
|
||||
import { WalletAdapter, MetaMaskAdapter } from '@luxfi/trading';
|
||||
|
||||
export function useWallet() {
|
||||
const [adapter, setAdapter] = useState<WalletAdapter | null>(null);
|
||||
@@ -459,7 +459,7 @@ async function placeOrder(order: OrderParams) {
|
||||
## Error Handling
|
||||
|
||||
```typescript
|
||||
import { WalletErrorCode } from '@luxfi/dex-sdk';
|
||||
import { WalletErrorCode } from '@luxfi/trading';
|
||||
|
||||
const ERROR_MESSAGES: Record<number, string> = {
|
||||
4001: 'Transaction rejected by user',
|
||||
@@ -561,7 +561,7 @@ async function ensureAllowance(
|
||||
### Mock Wallet for Tests
|
||||
|
||||
```typescript
|
||||
import { MockWalletAdapter } from '@luxfi/dex-sdk/testing';
|
||||
import { MockWalletAdapter } from '@luxfi/trading/testing';
|
||||
|
||||
const mockWallet = new MockWalletAdapter({
|
||||
accounts: ['0x1234...'],
|
||||
@@ -570,7 +570,7 @@ const mockWallet = new MockWalletAdapter({
|
||||
});
|
||||
|
||||
// Use in tests
|
||||
const client = new LXDexClient({
|
||||
const client = new Client({
|
||||
endpoint: 'http://localhost:8080',
|
||||
wallet: mockWallet
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user