feat: zap the winner button with lightning animation

Add ZAP WINNER button in FightViewer after fight ends. Server endpoint
POST /api/payments/zap increments zapsReceived on winner bot. Show zap
count on bot profile page. Add zaps_received column with migration.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Dorian
2026-03-08 20:10:46 +00:00
co-authored by Claude Opus 4.6
parent d1fe4d6e83
commit d22d739666
6 changed files with 92 additions and 1 deletions
+33
View File
@@ -271,3 +271,36 @@ paymentsRouter.delete('/disconnect-wallet', async (c) => {
return c.json({ success: true })
})
// POST /zap — zap sats to a fight winner
paymentsRouter.post('/zap', rateLimit(60_000, 10), async (c) => {
const { winnerId, fightId, amountSats } = await c.req.json<{
winnerId: string
fightId: string
amountSats: number
}>()
if (!winnerId || !fightId) return c.json({ error: 'Missing winnerId or fightId' }, 400)
const amount = amountSats || 21
// Verify the fight exists and this bot actually won
const fightRows = await db.select({
winnerId: schema.fights.winnerId,
status: schema.fights.status,
}).from(schema.fights).where(eq(schema.fights.id, fightId)).limit(1)
if (fightRows.length === 0) return c.json({ error: 'Fight not found' }, 404)
if (fightRows[0].status !== 'finished') return c.json({ error: 'Fight not finished' }, 400)
if (fightRows[0].winnerId !== winnerId) return c.json({ error: 'Bot did not win this fight' }, 400)
// Increment zaps on the winner
const botRows = await db.select({ zapsReceived: schema.bots.zapsReceived })
.from(schema.bots).where(eq(schema.bots.id, winnerId)).limit(1)
if (botRows.length === 0) return c.json({ error: 'Bot not found' }, 404)
await db.update(schema.bots).set({
zapsReceived: (botRows[0].zapsReceived || 0) + 1,
}).where(eq(schema.bots.id, winnerId))
return c.json({ ok: true, zapsReceived: (botRows[0].zapsReceived || 0) + 1 })
})