import './index.css'; import { StrictMode, useEffect, useState } from 'react'; import { createRoot } from 'react-dom/client'; import { bootTelegram, telegramWebApp, tgHeaders } from './telegram'; type Status = { seeds: number; receipts: number; routes: number; }; type PassStatus = { required: boolean; active: boolean; priceStars: number; username: string; freeBreeds?: { limit: number; used: number; left: number }; }; async function getJson(path: string): Promise { try { const response = await fetch(path, { headers: tgHeaders() }); return response.ok ? ((await response.json()) as T) : null; } catch { return null; } } function Splash() { const [status, setStatus] = useState(null); const [pass, setPass] = useState(null); const [checked, setChecked] = useState(false); const [message, setMessage] = useState(''); const [busy, setBusy] = useState(false); async function refresh() { const [nextStatus, nextPass] = await Promise.all([getJson('/api/status'), getJson('/api/pass/status')]); setStatus(nextStatus); setPass(nextPass); setChecked(true); } useEffect(() => { bootTelegram(); void Promise.all([getJson('/api/status'), getJson('/api/pass/status')]).then(([nextStatus, nextPass]) => { setStatus(nextStatus); setPass(nextPass); setChecked(true); }); }, []); const insideTelegram = Boolean(telegramWebApp()?.initData); async function buyPass() { setBusy(true); setMessage(''); try { const response = await fetch('/api/pass/invoice', { method: 'POST', headers: tgHeaders() }); const body = (await response.json()) as { ok: boolean; alreadyActive?: boolean; link?: string | null; message?: string }; if (!body.ok) { setMessage(body.message ?? 'Could not start the purchase.'); return; } if (body.alreadyActive) { await refresh(); return; } const webApp = telegramWebApp(); if (!body.link || !webApp) { setMessage('Purchases only work inside Telegram.'); return; } webApp.openInvoice(body.link, (invoiceStatus) => { if (invoiceStatus === 'paid') { setMessage('Payment received. Activating your pass...'); let attempts = 0; const poll = window.setInterval(() => { attempts += 1; void getJson('/api/pass/status').then((next) => { if (next?.active) { window.clearInterval(poll); window.location.href = 'game.html'; } else if (attempts > 20) { window.clearInterval(poll); setMessage('Payment received but activation is lagging. Reopen the app in a moment.'); } }); }, 1500); } else if (invoiceStatus === 'failed') { setMessage('Payment failed. No Stars were charged.'); } }); } finally { setBusy(false); } } return (

Maryjane Genetics Sim

{status ? `${status.seeds} specimens, ${status.receipts} receipts, ${status.routes} mapped routes` : checked && !insideTelegram ? 'WEED-SIM is a fictional cannabis genetics breeding sim that lives inside Telegram. Grow, crossbreed, trade with a haggling broker, and hand your garden to an AI agent. Free to try - first 25 crosses included.' : 'Breeding sandbox loading'}

{checked && !insideTelegram ? ( Open in Telegram ) : null} {pass || !checked ? ( ) : null} {pass && pass.required && !pass.active ? ( <>

{pass.freeBreeds ? `Free to play: ${pass.freeBreeds.left} of ${pass.freeBreeds.limit} free crosses left.` : 'Free to play.'}

) : null} {message ?

{message}

: null}
); } createRoot(document.getElementById('root')!).render( );