| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182 |
- from fastapi import FastAPI
- from fastapi.middleware.cors import CORSMiddleware
- from dotenv import load_dotenv
- import os
- load_dotenv() # 加载 .env
- app = FastAPI(title="Hyperliquid DEX Backend")
- # 添加 CORS(允许前端访问)
- app.add_middleware(
- CORSMiddleware,
- allow_origins=["http://localhost:5173", "http://101.32.51.95:5173"], # 前端 URL
- allow_credentials=True,
- allow_methods=["*"],
- allow_headers=["*"],
- )
- @app.get("/")
- def read_root():
- return {"message": "Hyperliquid DEX Backend 就绪!"}
- @app.get("/health")
- def health_check():
- return {"status": "OK", "builder_address": os.getenv("BUILDER_ADDRESS")}
- from hyperliquid.exchange import Exchange
- from hyperliquid.utils import constants
- from hyperliquid.utils.signing import get_timestamp_ms
- from eth_account import Account
- import json
- TESTNET_API_URL = constants.TESTNET_API_URL
- info = None # 全局 Info
- exchange = None # 全局 Exchange
- @app.on_event("startup")
- async def startup_event():
- global info, exchange
- info = Info(TESTNET_API_URL, skip_ws=False)
- # 初始化 Exchange,用你的私钥(代理钱包)
- private_key = os.getenv("PRIVATE_KEY")
- account = Account.from_key(private_key)
- wallet_address = account.address
- exchange = Exchange(TESTNET_API_URL, account=account, skip_ws=True)
- @app.post("/approve-builder")
- async def approve_builder(user_address: str, max_fee_rate: int = 50):
- """
- 用户批准 Builder Fee:签名批准你的地址的最大费率。
- 前端调用:POST { "user_address": "0xUserAddress" }
- """
- try:
- # 构建批准消息(Hyperliquid Builder Fee 批准格式)
- timestamp = get_timestamp_ms()
- action = {
- "type": "BuilderApprove",
- "builder": os.getenv("BUILDER_ADDRESS"),
- "maxBuilderFeeBps": max_fee_rate * 10, # 0.05% = 50 * 10 = 500 bps
- "nonce": timestamp,
- }
- # 用户签名消息(前端提供签名,此处模拟代理)
- # 实际:前端用 Wagmi 签名,传签名到后端验证
- signed_action = exchange.sign_action(action, user_address) # 需调整为用户签名
- # 调用 SDK 提交批准
- result = exchange.builder_approve(signed_action)
- return {"status": "批准成功", "result": result, "fee_rate": max_fee_rate}
- except Exception as e:
- return {"error": str(e)}
- # 测试查询价格(从阶段 1 复用)
- @app.get("/prices")
- def get_prices():
- global info
- mids = info.all_mids()
- return {"prices": mids}
- if __name__ == "__main__":
- import uvicorn
- uvicorn.run(app, host="0.0.0.0", port=8000)
|