From 44d1ef42adc4528a758f4d987a0b89bf7c762b5b Mon Sep 17 00:00:00 2001 From: shinchan-zhai Date: Mon, 23 Mar 2026 11:40:34 +0800 Subject: [PATCH] fix: Lighter CancelStopOrders now filters by TriggerPrice, proxyBinance checks upstream status MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - CancelStopOrders: only cancel orders with non-empty TriggerPrice (was canceling ALL orders including regular limit orders — safety bug) - proxyBinance: return 502 when upstream returns non-200 instead of silently proxying error pages - Remove redundant CORS headers in agent/web.go (already handled by gin middleware) --- agent/web.go | 11 +++++++++-- trader/lighter/orders.go | 13 +++++++++---- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/agent/web.go b/agent/web.go index bf079571..7542c9a3 100644 --- a/agent/web.go +++ b/agent/web.go @@ -122,15 +122,22 @@ func proxyBinance(rw http.ResponseWriter, url string) { return } defer resp.Body.Close() + + // Forward upstream error status codes instead of silently proxying bad data + if resp.StatusCode != http.StatusOK { + writeJSON(rw, 502, map[string]string{"error": fmt.Sprintf("upstream returned status %d", resp.StatusCode)}) + return + } + rw.Header().Set("Content-Type", "application/json") - rw.Header().Set("Access-Control-Allow-Origin", "*") + // CORS is handled by the gin middleware — no need to set it here // Limit response body to 2MB to prevent memory exhaustion io.Copy(rw, io.LimitReader(resp.Body, 2*1024*1024)) } func writeJSON(w http.ResponseWriter, status int, v interface{}) { w.Header().Set("Content-Type", "application/json") - w.Header().Set("Access-Control-Allow-Origin", "*") + // CORS is handled by the gin middleware — no need to set it here w.WriteHeader(status) json.NewEncoder(w).Encode(v) } diff --git a/trader/lighter/orders.go b/trader/lighter/orders.go index 16edb832..8fe5de47 100644 --- a/trader/lighter/orders.go +++ b/trader/lighter/orders.go @@ -186,17 +186,22 @@ func (t *LighterTraderV2) CancelStopOrders(symbol string) error { } canceledCount := 0 + skippedCount := 0 for _, order := range orders { - // TODO: Check order type, only cancel stop orders - // For now, cancel all orders + // Only cancel orders with a trigger price (stop-loss / take-profit) + // Regular limit orders have empty or "0" trigger price + if order.TriggerPrice == "" || order.TriggerPrice == "0" || order.TriggerPrice == "0.0" { + skippedCount++ + continue + } if err := t.CancelOrder(symbol, order.OrderID); err != nil { - logger.Infof("⚠️ Failed to cancel order (ID: %s): %v", order.OrderID, err) + logger.Infof("⚠️ Failed to cancel stop order (ID: %s): %v", order.OrderID, err) } else { canceledCount++ } } - logger.Infof("✓ LIGHTER - Canceled %d stop orders", canceledCount) + logger.Infof("✓ LIGHTER - Canceled %d stop orders (skipped %d regular orders)", canceledCount, skippedCount) return nil }