PolyLite — prediction market demo
PolyLite

Minimal prediction market

Демо-платформа событий с расчётами в USDT

Популярные события, проценты перевеса исходов, объём рынка, графики за день/неделю/месяц и фиксация результата.

Демо-баланс после регистрации 1 000 USDT Без блокчейна и реальных платежей. Код можно доработать под кошельки и смарт-контракты.

Войти или создать аккаунт

Авторизация нужна для ставок. Все операции хранятся локально в JSON-файле проекта.

Вход

Регистрация

Trending

Самые популярные события

const $ = (s) => document.querySelector(s); const toastEl = $('#toast'); let currentUser = null; function toast(message) { toastEl.textContent = message; toastEl.classList.add('show'); setTimeout(() => toastEl.classList.remove('show'), 3200); } async function api(path, options = {}) { const res = await fetch(path, { headers: { 'Content-Type': 'application/json', ...(options.headers || {}) }, credentials: 'same-origin', ...options }); const data = await res.json().catch(() => ({})); if (!res.ok) throw new Error(data.error || 'Ошибка запроса'); return data; } function money(n) { return `${Number(n || 0).toLocaleString('ru-RU', { maximumFractionDigits: 2 })} USDT`; } function fmtDate(ts) { return new Date(ts).toLocaleDateString('ru-RU', { day: '2-digit', month: 'short', year: 'numeric' }); } function renderAuth() { const authbar = $('#authbar'); const panel = $('#authPanel'); if (currentUser) { authbar.innerHTML = `${currentUser.name} · ${money(currentUser.balance)}`; panel.style.display = 'none'; $('#logoutBtn').onclick = async () => { await api('/api/logout', { method: 'POST', body: '{}' }); currentUser = null; renderAuth(); toast('Вы вышли из аккаунта'); }; } else { authbar.innerHTML = `Гость`; panel.style.display = ''; } } function marketCard(m) { return `
${m.category} ${m.status === 'open' ? 'Открыто' : 'Закрыто'}

${m.title}

${m.description}

YES${m.percentages.YES}%
NO${m.percentages.NO}%
Объём${money(m.totals.volume)}
До ${fmtDate(m.closesAt)}
`; } async function loadMarkets() { const grid = $('#marketsGrid'); grid.innerHTML = '
Загрузка событий...
'; try { const { markets } = await api('/api/markets'); grid.innerHTML = markets.length ? markets.map(marketCard).join('') : '
Событий пока нет
'; } catch (e) { grid.innerHTML = `
${e.message}
`; } } async function init() { try { const me = await api('/api/me'); currentUser = me.user; } catch {} renderAuth(); loadMarkets(); $('#refreshBtn').onclick = loadMarkets; $('#loginForm').onsubmit = async (e) => { e.preventDefault(); const fd = new FormData(e.currentTarget); try { const data = await api('/api/login', { method: 'POST', body: JSON.stringify(Object.fromEntries(fd)) }); currentUser = data.user; renderAuth(); toast('Вход выполнен'); } catch (err) { toast(err.message); } }; $('#registerForm').onsubmit = async (e) => { e.preventDefault(); const fd = new FormData(e.currentTarget); try { const data = await api('/api/register', { method: 'POST', body: JSON.stringify(Object.fromEntries(fd)) }); currentUser = data.user; renderAuth(); toast('Аккаунт создан, начислено 1000 USDT'); } catch (err) { toast(err.message); } }; } init();
Made on
Tilda