import { Hono } from 'hono' import { db, schema } from '../db/index.js' import { eq } from 'drizzle-orm' import { joinQueue, leaveQueue, getQueueSize, getQueueSnapshot } from '../engine/queue.js' import { joinRankedQueue, getRankedQueueStatus } from '../engine/ranked-queue.js' import { rateLimit } from '../middleware/rate-limit.js' export const queueRouter = new Hono() // Get queue status queueRouter.get('/status', (c) => { return c.json({ waiting: getQueueSize(), queue: getQueueSnapshot(), }) }) // Join the queue — blocks until matched, then returns fightId queueRouter.post('/join/:botId', async (c) => { const botId = c.req.param('botId') const botRows = await db.select({ id: schema.bots.id, name: schema.bots.name }) .from(schema.bots) .where(eq(schema.bots.id, botId)) .limit(1) if (botRows.length === 0) { return c.json({ error: 'Bot not found.' }, 404) } try { const fightId = await joinQueue(botId) return c.json({ fightId, message: 'Matched! Fight starting.' }) } catch (err) { const message = err instanceof Error ? err.message : 'Queue error' return c.json({ error: message }, 500) } }) // Leave the queue queueRouter.post('/leave/:botId', (c) => { const botId = c.req.param('botId') const left = leaveQueue(botId) return c.json({ left }) }) // Get ranked queue status queueRouter.get('/ranked-status', (c) => { return c.json(getRankedQueueStatus()) }) // Join ranked queue — requires confirmed payment + bot ownership queueRouter.post('/join-ranked/:botId', async (c) => { const botId = c.req.param('botId') const { paymentId, pubkey } = await c.req.json<{ paymentId: string; pubkey?: string }>() if (!paymentId) { return c.json({ error: 'Missing paymentId' }, 400) } // Verify bot ownership in production if (process.env.NODE_ENV === 'production') { if (!pubkey || typeof pubkey !== 'string' || pubkey.length !== 64) { return c.json({ error: 'Missing pubkey' }, 400) } const botRows = await db.select({ publicKey: schema.bots.publicKey }) .from(schema.bots).where(eq(schema.bots.id, botId)).limit(1) if (botRows.length === 0 || botRows[0].publicKey !== pubkey) { return c.json({ error: 'Unauthorized' }, 403) } } try { const fightId = await joinRankedQueue(botId, paymentId) return c.json({ fightId, message: 'Ranked match found! Fight starting.' }) } catch (err) { const message = err instanceof Error ? err.message : 'Ranked queue error' return c.json({ error: message }, 500) } })