from fastapi import FastAPI, Request import os import json from hyperliquid.exchange import Exchange from eth_account import Account app = FastAPI() @app.get("/") def home(): return { "status": "online", "message": "Sentinel V1 est opérationnel", "version": "1.2.2-stable" } @app.post("/webhook") async def handle_webhook(request: Request): try: # 1. Récupération des données du signal TradingView body = await request.body() data = json.loads(body) # 2. Vérification de la clé privée (Secret Hugging Face) pk = os.getenv("HL_PRIVATE_KEY") if not pk: return {"error": "Secret HL_PRIVATE_KEY introuvable dans la configuration"} # 3. Initialisation de la connexion à Hyperliquid account = Account.from_key(pk) exchange = Exchange(account, "https://api.hyperliquid.xyz") # 4. Lecture des paramètres du signal # Par défaut : ETH et une taille de 0.01 si non précisé action = data.get("action", "").lower() symbol = data.get("symbol", "ETH") size = float(data.get("size", 0.01)) # 5. Exécution de l'ordre sur le marché (Market Order) # Paramètres : symbol, is_buy, size, price (None pour Market), slippage (0.01 = 1%) if "buy" in action: # Ouvre ou renforce un LONG result = exchange.market_open(symbol, True, size, None, 0.01) return {"status": "success", "action": "buy", "response": result} elif "sell" in action: # Ouvre ou renforce un SHORT result = exchange.market_open(symbol, False, size, None, 0.01) return {"status": "success", "action": "sell", "response": result} elif "close" in action: # Ferme la position existante sur ce symbole result = exchange.market_close(symbol) return {"status": "success", "action": "close", "response": result} return {"error": "Action non reconnue (doit contenir buy, sell ou close)"} except Exception as e: # Retourne l'erreur précise en cas de problème technique return {"error": str(e)}