import http from "node:http"; const PORT = Number(process.env.NEURAMESH_API_PORT || 8787); const state = { health: "prototype" }; const STOCK_SYMBOLS = new Set(["NVDA", "AMD", "MSFT", "AMZN", "GOOGL"]); const STOCK_RANGES = new Set(["1mo", "3mo", "6mo", "1y"]); const stockCache = new Map(); function json(response, status, body) { response.writeHead(status, { "Content-Type": "application/json", "Access-Control-Allow-Origin": "*" }); response.end(JSON.stringify(body)); } const server = http.createServer(async (request, response) => { if (request.method === "OPTIONS") return json(response, 204, {}); const url = new URL(request.url, `http://${request.headers.host}`); try { if (request.method === "GET" && url.pathname === "/api/gpu-prices") { const upstream = await fetch("https://console-api.akash.network/v1/gpu-prices", { signal: AbortSignal.timeout(10000) }); if (!upstream.ok) return json(response, 503, { error: "Live GPU pricing is temporarily unavailable." }); const data = await upstream.json(); if (!Array.isArray(data.models)) return json(response, 503, { error: "Live GPU pricing is temporarily unavailable." }); return json(response, 200, { source: "Akash Network", sourceUrl: "https://console-api.akash.network/v1/gpu-prices", retrievedAt: new Date().toISOString(), models: data.models }); } if (request.method === "GET" && url.pathname === "/api/stock-history") { // Mirrors api/stock-history.js so local dev matches the deployed route. const symbol = String(url.searchParams.get("symbol") || "").toUpperCase(); const range = String(url.searchParams.get("range") || "6mo"); if (!STOCK_SYMBOLS.has(symbol) || !STOCK_RANGES.has(range)) return json(response, 400, { error: "Unsupported symbol or range." }); const cached = stockCache.get(`${symbol}:${range}`); if (cached && Date.now() - cached.at < 900000) return json(response, 200, cached.body); const upstream = await fetch(`https://query1.finance.yahoo.com/v8/finance/chart/${symbol}?range=${range}&interval=1d`, { headers: { "User-Agent": "Mozilla/5.0 (compatible; NeuraMesh/1.0)" }, signal: AbortSignal.timeout(10000) }); if (!upstream.ok) return json(response, 503, { error: "Share price history is temporarily unavailable." }); const payload = await upstream.json(); const result = payload?.chart?.result?.[0]; const closes = result?.indicators?.quote?.[0]?.close; if (!result?.timestamp?.length || !Array.isArray(closes)) return json(response, 503, { error: "Share price history is temporarily unavailable." }); const points = result.timestamp.map((seconds, index) => ({ t: seconds * 1000, v: closes[index] })).filter(point => Number.isFinite(point.v)); if (points.length < 2) return json(response, 503, { error: "Share price history is temporarily unavailable." }); const body = { symbol, range, name: result.meta?.shortName || symbol, currency: result.meta?.currency || "USD", source: "Yahoo Finance", retrievedAt: new Date().toISOString(), points }; stockCache.set(`${symbol}:${range}`, { at: Date.now(), body }); return json(response, 200, body); } if (request.method === "GET" && url.pathname === "/api/health") return json(response, 200, { status: state.health, settlement: "sui-walrus-testnet", liveTrading: false }); if (request.method === "GET" && url.pathname === "/api/markets") return json(response, 200, { status: "unavailable", markets: [], reason: "NeuraMesh Trade has no verified markets yet. Browse external GPU pricing in the Marketplace." }); if (request.method === "GET" && url.pathname === "/api/portfolio") return json(response, 200, { status: "unavailable", account: null, balances: null, positions: null, reason: "Account access is not available in this prototype." }); if (request.method === "POST" && ["/api/orders", "/api/swap/quote", "/api/settlements"].includes(url.pathname)) return json(response, 503, { status: "unavailable", error: "Live trading, swaps, and settlement are not available yet." }); return json(response, 404, { error: "Not found" }); } catch (error) { return json(response, 400, { error: error.message }); } }); server.listen(PORT, () => console.log(`NeuraMesh API prototype listening on http://localhost:${PORT}`));