8dbaf3a0e4
- exchanges/hyperliquid/{client,leverage_cap,tools}.py
- routers/hyperliquid.py con 16 endpoint /mcp-hyperliquid/tools/*
- builder hyperliquid in exchanges/__init__.py
- test migrati: test_client, test_leverage_cap (skip V1: server_acl, environment_info)
- test builder hyperliquid (testnet vs mainnet base_url)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
170 lines
5.5 KiB
Python
170 lines
5.5 KiB
Python
"""Router /mcp-hyperliquid/* — DI per env, client e (write) creds.
|
|
|
|
Mappa 1:1 i tool di `cerbero_mcp.exchanges.hyperliquid.tools` a endpoint
|
|
`POST /mcp-hyperliquid/tools/{tool_name}`. L'autenticazione bearer è gestita
|
|
dal middleware in `cerbero_mcp.auth`; qui leggiamo solo `request.state.environment`.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
from typing import Literal
|
|
|
|
from fastapi import APIRouter, Depends, Request
|
|
|
|
from cerbero_mcp.client_registry import ClientRegistry
|
|
from cerbero_mcp.exchanges.hyperliquid import tools as t
|
|
from cerbero_mcp.exchanges.hyperliquid.client import HyperliquidClient
|
|
|
|
Environment = Literal["testnet", "mainnet"]
|
|
|
|
|
|
def get_environment(request: Request) -> Environment:
|
|
return request.state.environment
|
|
|
|
|
|
async def get_hyperliquid_client(
|
|
request: Request, env: Environment = Depends(get_environment)
|
|
) -> HyperliquidClient:
|
|
registry: ClientRegistry = request.app.state.registry
|
|
return await registry.get("hyperliquid", env)
|
|
|
|
|
|
def _build_creds(request: Request) -> dict:
|
|
"""Costruisce dict `creds` minimale per leverage cap / metadata."""
|
|
settings = request.app.state.settings
|
|
return {
|
|
"max_leverage": settings.hyperliquid.max_leverage,
|
|
"wallet_address": settings.hyperliquid.wallet_address,
|
|
}
|
|
|
|
|
|
def make_router() -> APIRouter:
|
|
r = APIRouter(prefix="/mcp-hyperliquid", tags=["hyperliquid"])
|
|
|
|
# === READ tools ===
|
|
|
|
@r.post("/tools/environment_info")
|
|
async def _environment_info(
|
|
request: Request,
|
|
client: HyperliquidClient = Depends(get_hyperliquid_client),
|
|
):
|
|
creds = _build_creds(request)
|
|
return await t.environment_info(client, creds=creds)
|
|
|
|
@r.post("/tools/get_markets")
|
|
async def _get_markets(
|
|
params: t.GetMarketsReq,
|
|
client: HyperliquidClient = Depends(get_hyperliquid_client),
|
|
):
|
|
return await t.get_markets(client, params)
|
|
|
|
@r.post("/tools/get_ticker")
|
|
async def _get_ticker(
|
|
params: t.GetTickerReq,
|
|
client: HyperliquidClient = Depends(get_hyperliquid_client),
|
|
):
|
|
return await t.get_ticker(client, params)
|
|
|
|
@r.post("/tools/get_orderbook")
|
|
async def _get_orderbook(
|
|
params: t.GetOrderbookReq,
|
|
client: HyperliquidClient = Depends(get_hyperliquid_client),
|
|
):
|
|
return await t.get_orderbook(client, params)
|
|
|
|
@r.post("/tools/get_positions")
|
|
async def _get_positions(
|
|
params: t.GetPositionsReq,
|
|
client: HyperliquidClient = Depends(get_hyperliquid_client),
|
|
):
|
|
return await t.get_positions(client, params)
|
|
|
|
@r.post("/tools/get_account_summary")
|
|
async def _get_account_summary(
|
|
params: t.GetAccountSummaryReq,
|
|
client: HyperliquidClient = Depends(get_hyperliquid_client),
|
|
):
|
|
return await t.get_account_summary(client, params)
|
|
|
|
@r.post("/tools/get_trade_history")
|
|
async def _get_trade_history(
|
|
params: t.GetTradeHistoryReq,
|
|
client: HyperliquidClient = Depends(get_hyperliquid_client),
|
|
):
|
|
return await t.get_trade_history(client, params)
|
|
|
|
@r.post("/tools/get_historical")
|
|
async def _get_historical(
|
|
params: t.GetHistoricalReq,
|
|
client: HyperliquidClient = Depends(get_hyperliquid_client),
|
|
):
|
|
return await t.get_historical(client, params)
|
|
|
|
@r.post("/tools/get_open_orders")
|
|
async def _get_open_orders(
|
|
params: t.GetOpenOrdersReq,
|
|
client: HyperliquidClient = Depends(get_hyperliquid_client),
|
|
):
|
|
return await t.get_open_orders(client, params)
|
|
|
|
@r.post("/tools/get_funding_rate")
|
|
async def _get_funding_rate(
|
|
params: t.GetFundingRateReq,
|
|
client: HyperliquidClient = Depends(get_hyperliquid_client),
|
|
):
|
|
return await t.get_funding_rate(client, params)
|
|
|
|
@r.post("/tools/basis_spot_perp")
|
|
async def _basis_spot_perp(
|
|
params: t.BasisSpotPerpReq,
|
|
client: HyperliquidClient = Depends(get_hyperliquid_client),
|
|
):
|
|
return await t.basis_spot_perp(client, params)
|
|
|
|
@r.post("/tools/get_indicators")
|
|
async def _get_indicators(
|
|
params: t.GetIndicatorsReq,
|
|
client: HyperliquidClient = Depends(get_hyperliquid_client),
|
|
):
|
|
return await t.get_indicators(client, params)
|
|
|
|
# === WRITE tools (richiedono creds per leverage cap / audit) ===
|
|
|
|
@r.post("/tools/place_order")
|
|
async def _place_order(
|
|
params: t.PlaceOrderReq,
|
|
request: Request,
|
|
client: HyperliquidClient = Depends(get_hyperliquid_client),
|
|
):
|
|
creds = _build_creds(request)
|
|
return await t.place_order(client, params, creds=creds)
|
|
|
|
@r.post("/tools/cancel_order")
|
|
async def _cancel_order(
|
|
params: t.CancelOrderReq,
|
|
client: HyperliquidClient = Depends(get_hyperliquid_client),
|
|
):
|
|
return await t.cancel_order(client, params)
|
|
|
|
@r.post("/tools/set_stop_loss")
|
|
async def _set_stop_loss(
|
|
params: t.SetStopLossReq,
|
|
client: HyperliquidClient = Depends(get_hyperliquid_client),
|
|
):
|
|
return await t.set_stop_loss(client, params)
|
|
|
|
@r.post("/tools/set_take_profit")
|
|
async def _set_take_profit(
|
|
params: t.SetTakeProfitReq,
|
|
client: HyperliquidClient = Depends(get_hyperliquid_client),
|
|
):
|
|
return await t.set_take_profit(client, params)
|
|
|
|
@r.post("/tools/close_position")
|
|
async def _close_position(
|
|
params: t.ClosePositionReq,
|
|
client: HyperliquidClient = Depends(get_hyperliquid_client),
|
|
):
|
|
return await t.close_position(client, params)
|
|
|
|
return r
|