from __future__ import annotations from fastapi import FastAPI from fastapi.responses import HTMLResponse from .ledger import Ledger from .models import EventIn, WindsurfPacketRequest from .loop import LiquidityLoop from .windsurf_bridge import WindsurfBridge def create_app(db_path: str = "membra_liquidity_agg.db") -> FastAPI: ledger = Ledger(db_path) ledger.init() loop = LiquidityLoop(ledger) bridge = WindsurfBridge(ledger) app = FastAPI(title="Membra Liquidity Automation Aggregator", version="0.1.0") @app.get("/", response_class=HTMLResponse) def root(): return """
Local-first automation/control plane for 24/7 liquidity loop with Windsurf bridge.
GET /health - Health checkPOST /events - Ingest eventsGET /events - List eventsPOST /loop/step - Execute loop stepGET /loop/state - Get loop statePOST /windsurf/packet - Build Windsurf packetGET /receipts - Get receiptsPOST /halt - Emergency haltPOST /resume - Resume operationStatus: Control plane only (no live trading)
""" @app.get("/health") def health(): return {"ok": True, "product": "Membra Liquidity Automation Aggregator", "mode": "control_plane_only"} @app.post("/events") def add_event(event: EventIn): return ledger.add_event(event) @app.get("/events") def events(limit: int = 100): return ledger.list_events(limit=limit) @app.post("/loop/step") def loop_step(): return loop.step() @app.get("/loop/state") def loop_state(): return ledger.get_loop_state() @app.post("/windsurf/packet") def windsurf_packet(req: WindsurfPacketRequest): return bridge.build_packet( goal=req.goal, repo_path=req.repo_path, include_recent_events=req.include_recent_events, strict_dry_run=req.strict_dry_run, liquidity_loop=req.liquidity_loop, ) @app.get("/receipts") def receipts(limit: int = 100): return ledger.receipts(limit=limit) @app.post("/halt") def halt(reason: str = "manual halt"): from .models import LoopState ledger.set_loop_state(LoopState.HALTED, halted=True, reason=reason) return ledger.get_loop_state() @app.post("/resume") def resume(): from .models import LoopState ledger.set_loop_state(LoopState.OBSERVE, halted=False, reason=None) return ledger.get_loop_state() return app app = create_app()