const { useState, useEffect, useRef, useMemo, useCallback } = React; /* Snipe.Run — views part 1: Overview, Copy Traders, Trader Detail */ /* ============ REAL COPY CONFIG ============ * On the live platform the user's copy list lives in the worker config * (GET/POST config → { traders:[wallets], ... }). This hook owns that list of * lowercased wallets and a toggle() that reads-modifies-writes the whole config * (push/pull the wallet, preserving every other field). No-ops on the demo. */ function _normWallet(w) { return (w || '').toString().trim().toLowerCase(); } // Compact duration ("14d 06h" / "3h 12m" / "8m") for engine uptime. function sniFmtDur(sec) { sec = Math.max(0, Math.floor(sec || 0)); const d = Math.floor(sec / 86400), h = Math.floor((sec % 86400) / 3600), m = Math.floor((sec % 3600) / 60); if (d > 0) return d + 'd ' + String(h).padStart(2, '0') + 'h'; if (h > 0) return h + 'h ' + String(m).padStart(2, '0') + 'm'; return m + 'm'; } // Real fill rate from engine stats (filled / submitted); '—' when not tracked. function _fillRate(stats) { const f = +stats.fills, o = +stats.orders; if (o > 0 && !isNaN(f)) return (f / o * 100).toFixed(1) + '%'; return '—'; } function useCopyConfig() { const [wallets, setWallets] = useState([]); const [loading, setLoading] = useState(sniIsReal()); const reload = useCallback(() => { if (!sniIsReal()) { setWallets([]); setLoading(false); return; } setLoading(true); sniApi('config') .then((d) => { setWallets(((d && d.traders) || []).map(_normWallet)); setLoading(false); }) .catch(() => { setLoading(false); }); }, []); useEffect(() => { reload(); }, [reload]); const isCopied = useCallback((w) => wallets.includes(_normWallet(w)), [wallets]); const toggle = useCallback((w, on) => { if (!sniIsReal() || !w) return Promise.resolve(); const target = _normWallet(w); return sniApi('config').then((cfg) => { const cur = ((cfg && cfg.traders) || []).map(_normWallet); const has = cur.includes(target); const want = (on === undefined) ? !has : !!on; let next = cur; if (want && !has) next = [...cur, target]; else if (!want && has) next = cur.filter((x) => x !== target); else { setWallets(cur); return; } const body = Object.assign({}, cfg || {}, { traders: next }); return sniApi('config', { method: 'POST', body: JSON.stringify(body) }) .then(() => setWallets(next)) .catch(() => setWallets(cur)); }); }, []); return { wallets, loading, isCopied, toggle, reload }; } /* ============ OVERVIEW ============ */ function Overview({ ctx }) { const { bot, setBot, balance, copied, positions, onNav, paper } = ctx; // Real engine telemetry (the user's own isolated worker) overlays the design's demo data. const live = useLiveData(); const real = sniIsReal(); const livePos = sniMapPositions(live); const showPos = real ? livePos : positions; const stats = sniStats(live); const w = sniWorker(live); const realizedReal = +stats.realized_pnl || 0; const unrealReal = livePos.reduce((a, p) => a + (+p.pnl || 0), 0); const winsR = +stats.wins || 0, lossR = +stats.losses || 0; const winRateReal = (winsR + lossR) ? (winsR / (winsR + lossR) * 100) : 0; // Paper bankroll = the running worker's bankroll, else the user's plan capital // (so a paused paper engine still shows e.g. Free $10k, not $0). const planCap = (live && live.plan && live.plan.paper_capital != null) ? +live.plan.paper_capital : 0; const bankrollReal = (w && typeof w.bankroll === 'number') ? w.bankroll : (paper ? planCap : 0); const portfolioReal = bankrollReal + realizedReal + unrealReal; const [tf, setTf] = useState('1W'); // Real equity line = cumulative realized PnL from actual closed trades (flat/empty // when none). Never the demo uptrend for a logged-in user. const series = useMemo(() => { if (!real) return genSeries('overview' + tf, 64, true); const cl = (live && live.closes) ? live.closes.slice().sort((a, b) => (+a.closed_ts || 0) - (+b.closed_ts || 0)) : []; if (!cl.length) return null; let cum = 0; const out = [0]; cl.forEach((c) => { cum += +c.realized || 0; out.push(cum); }); return out; }, [real, live, tf]); const totalPnl = showPos.reduce((a, p) => a + p.pnl, 0); const todayPnl = 18420.55; return (
{/* KPIs */}
{real ? {money(portfolioReal)} : } {real ? bankroll {moneyShort(bankrollReal)} : ▲ 8.2% 7d} {real ? = 0 ? 'up' : 'down')}>{(realizedReal + unrealReal) >= 0 ? '+' : ''}{money(realizedReal + unrealReal)} : } {real ? {money(realizedReal)} realized · {money(unrealReal)} open : ▲ 12.8% realized + open} {real ? ((winsR + lossR) ? winRateReal.toFixed(1) + '%' : '—') : '73.4%'}
{real ? showPos.length : (copied.length || 4)}{real ? 'positions' : 'traders'} {real ? (sniRunning(live) ? 'engine live' : 'engine paused') : 'mirroring live'}
{/* chart + side */}
Copied portfolio · realized PnL
= 0 ? 'up' : 'down') : 'up') + ' mono'}> {real ? ((realizedReal >= 0 ? '+' : '') + money(realizedReal)) : }
{['1D', '1W', '1M', 'ALL'].map((t) => ( ))}
{series ? :
No realized P/L yet — your closed trades will chart here.
}
Live activity
{/* open positions */}
Open positions {showPos.length}
{showPos.length ? :
No open positions yet — your engine fills this as it copies trades.
}
); } function KPI({ k, icon, children }) { const arr = React.Children.toArray(children); return (
{k}
{arr[0]}
{arr[1]}
); } function KPISub({ kind, children }) { return
{children}
; } function BotControl({ bot, setBot, paper }) { const live = useLiveData(); const real = sniIsReal(); const stats = sniStats(live); const trades = +stats.trades || 0; const running = sniRunning(live); // Real uptime from the worker's start time (epoch secs), else '—'. Demo keeps its mock. const w = sniWorker(live); const startTs = w && (+w.started_ts || +w.start_ts || 0); const upStr = (real && running && startTs > 0) ? sniFmtDur(Date.now() / 1000 - startTs) : '—'; return (
Snipe Engine {bot ? · Running : · Paused} {paper && PAPER}
{paper ? 'Paper mode · simulated fills against live prices — no real funds at risk' : (bot ? (real ? 'Live mode · mirroring your copied traders on-chain · priority lane' : 'Mirroring 4 traders across 2 wallets · priority lane') : 'Bot is paused — no trades will be copied')}
} accent /> } />
); } function MiniMetric({ k, v, accent }) { return (
{k}
{v}
); } function LiveMs() { const live = useLiveData(); const [v, setV] = useState(9); useInterval(() => setV((Math.random() * 6 + 7)), 1100); const real = sniLatency(live); if (sniIsReal()) { // Real users: latency is the engine's measured round-trip. A paused engine has // none — show '—', never an animated fake. return (sniRunning(live) && real > 0) ? <>{real}ms : <>—; } return <>{v.toFixed(0)}ms; } function LiveCount({ start }) { const [v, setV] = useState(start); useInterval(() => setV((p) => p + (Math.random() > 0.5 ? 1 : 0)), 1600); return <>{v}; } function ActivityFeed({ live, real }) { const [rows, setRows] = useState(() => Array.from({ length: 6 }, () => makeFeed())); useInterval(() => { if (!real) setRows((r) => [makeFeed(), ...r].slice(0, 7)); }, 2300); if (real) { const items = sniMapActivity(live).slice(0, 7); if (!items.length) return
Waiting for the first copy… your engine is watching the tape.
; return (
{items.map((r, i) => (
{r.type === 'fill' ? 'BUY' : (r.type === 'sl' ? 'LOSS' : 'WIN')} {r.trader || 'copy'} {r.market} {r.t}
))}
); } return (
{rows.map((r, i) => (
{r.buy ? 'BUY' : 'SELL'} {r.t} {r.m} {r.ms}ms
))}
); } let _fid = 0; function makeFeed() { const t = TRADERS[Math.floor(Math.random() * TRADERS.length)].name; const m = MARKETS[Math.floor(Math.random() * MARKETS.length)].q; return { id: _fid++, buy: Math.random() > 0.42, t, m: m.length > 26 ? m.slice(0, 26) + '…' : m, ms: (Math.random() * 50 + 7).toFixed(0) }; } function PositionsTable({ rows, onClose }) { const [sell, setSell] = useState(null); return ( <> {onClose && } {rows.map((p, i) => ( {onClose && } ))}
MarketSideCopied fromEntryNowSizePnL
{p.mkt} {p.side}
{p.via}
{(p.entry * 100).toFixed(0)}¢ {(p.cur * 100).toFixed(0)}¢ {moneyShort(p.size)} = 0 ? 'var(--green)' : 'var(--red)', fontWeight: 700, verticalAlign: 'middle' }}>{p.pnl >= 0 ? '+' : ''}{moneyShort(p.pnl)}
= 0 ? 'var(--green)' : 'var(--red)' }}>{pct(p.pnlPct)}
{sell && setSell(null)} onConfirm={() => { onClose(sell.i); setSell(null); }} />} ); } function SellPositionModal({ item: p, onClose, onConfirm }) { const shares = p.size / p.entry; const value = shares * p.cur; const fee = value * 0.001; const proceeds = value - fee; const [done, setDone] = useState(false); return ( {done ? (
Sold · {money(proceeds, 0)} returned
{p.mkt} · 7ms
) : (<>
{p.mkt}
{p.side} · {(p.cur * 100).toFixed(0)}¢via {p.via}
= 0 ? '+' : ''}${money(p.pnl, 0)} · ${pct(p.pnlPct)}`} />
Market sell at the current price — settles instantly to your wallet.
)}
); } /* ============ COPY TRADERS / LEADERBOARD ============ */ // Render a numeric metric, '—' when the real feed reports it null/undefined. function _orDash(v, render) { return (v === null || v === undefined) ? '—' : render(v); } // Map a real wallet kind ('external'|'snipe') onto the design's filter values. function _kindOf(t) { return t.kind === 'snipe' ? 'snipe' : (t.kind === 'external' ? 'wallet' : (t.kind || 'wallet')); } function CopyTraders({ ctx }) { const { onOpenTrader, copied, onUncopy } = ctx; const real = sniIsReal(); const [sort, setSort] = useState(real ? 'pnl' : 'roi'); const [cat, setCat] = useState('All'); const [kind, setKind] = useState('All'); const cats = ['All', 'Politics', 'Crypto', 'Sports', 'Macro']; // Real leaderboard from the platform; demo list otherwise (login backdrop). const { traders: realTraders } = useTraders('30d', 25); const cfg = useCopyConfig(); const src = real ? realTraders : TRADERS; const copyCount = real ? cfg.wallets.length : (copied.length || 4); // Copied-state predicate: config wallets when real, the demo id-list otherwise. const isCopiedT = useCallback((t) => real ? cfg.isCopied(t.wallet) : copied.includes(t.id), [real, cfg, copied]); const profiles = useMemo(() => src.filter((t) => _kindOf(t) === 'snipe'), [src]); const list = useMemo(() => { let l = src.filter((t) => kind === 'All' || _kindOf(t) === kind); if (cat !== 'All') l = l.filter((t) => (t.tags || []).includes(cat)); // Sort key per source: real exposes profit/volume always; roi/copiers only // when the feed provides them. Demo keeps its original roi/pnl/copiers keys. const keyFor = (k) => { if (!real) return k; // demo: roi|pnl|copiers if (k === 'volume') return 'volume'; // real: profit + volume are the live columns if (k === 'pnl') return 'profit'; if (k === 'copiers') return 'copiers'; if (k === 'roi') return 'roi'; return 'profit'; }; const k = keyFor(sort); l = l.slice().sort((a, b) => { let av = a[k], bv = b[k]; // ROI/copiers may be null on the real feed → push to bottom, keep order. if (av === null || av === undefined) av = -Infinity; if (bv === null || bv === undefined) bv = -Infinity; return bv - av; }); return l; }, [src, sort, cat, kind, real]); return (
{/* Who you're copying right now — the engine mirrors these wallets' trades. */} {real && cfg.wallets.length > 0 && (
Currently copying {cfg.wallets.length}
Your engine mirrors these wallets' trades to your balance. Stop any to remove it from your bot.
{cfg.wallets.map((w) => { const t = (realTraders || []).find((x) => _normWallet(x.wallet) === _normWallet(w)); const nm = (t && t.name) || short(w); return (
onOpenTrader(w)}>
{nm}
{short(w)}{t && t.profit != null ? ' · ' + moneyShort(t.profit) + ' 30d' : ''}
); })}
)} {/* Featured Snipe profiles — internal, followable, eToro-style */} {profiles.length > 0 &&
Popular Snipe profiles NEW
Registered Snipe traders & bots you can follow and copy — they earn a share when you copy them.
{profiles.map((p) => onOpenTrader(real ? p.wallet : p.id)} onToggle={() => real ? cfg.toggle(p.wallet) : (isCopiedT(p) ? onUncopy(p.id) : onOpenTrader(p.id))} />)}
}
Leaderboard
Snipe profiles & Polymarket wallets · ranked on-chain
{/* Category tags only exist for demo/internal profiles — external Polymarket wallets aren't categorized, so hide the filter in real mode (it would empty the list). */} {!real &&
{cats.map((c) => )}
}
{real ? (<> ) : (<> )}
{!real && } {!real && } {!real && } {list.map((t, i) => { const isCopied = isCopiedT(t); const snipe = _kindOf(t) === 'snipe'; const tid = real ? t.wallet : t.id; const sub = real ? (snipe ? '@' + (t.handle || (t.name || '').toLowerCase().replace(/\s+/g, '_')) : short(t.wallet)) + (((t.tags || []).length) ? ' · ' + t.tags.join(', ') : '') : (snipe ? '@' + t.handle : short(t.addr)) + ' · ' + t.tags.join(', '); return ( onOpenTrader(tid)}> {!real && } {!real && } {!real && } ); })}
#Trader30d ROIWin rate{real ? '30d Profit' : '30d PnL'}{real ? '30d Volume' : 'Sharpe'}Copiers
{i + 1}
{t.name} {snipe ? {t.verified && } Snipe : Wallet} {t.badge === 'top' && } {!real && t.streak >= 5 && {t.streak}}
{sub}
{pct(t.roi)}{t.win + '%'}{real ? moneyShort(t.profit) : moneyShort(t.pnl)} {real ? _orDash(t.volume, (v) => moneyShort(v)) : t.sharpe}{t.copiers.toLocaleString()} e.stopPropagation()} style={{ verticalAlign: 'middle' }}> {real ? : (isCopied ? : )}
); } function onNavToProfile(ctx) { ctx.onNav('settings'); try { localStorage.setItem('snipe_settings_tab', 'profile'); } catch (e) {} } function ProfileCard({ p, real, copiedNow, onOpen, onToggle }) { const isCopied = !!copiedNow; const handle = p.handle || (p.name || '').toLowerCase().replace(/\s+/g, '_'); return (
{p.name}{p.verified && }
@{handle}
{p.badge === 'top' && }
{p.bio}
{real ? (<>
30d ROI
{_orDash(p.roi, (v) => pct(v))}
Profit
{moneyShort(p.profit)}
Volume
{_orDash(p.volume, (v) => moneyShort(v))}
) : (<>
30d ROI
{pct(p.roi)}
Win
{p.win}%
Risk
= 7 ? 'var(--red)' : p.risk >= 5 ? 'var(--amber)' : 'var(--green)' }}>{p.risk}/10
)}
{real ? _orDash(p.copiers, (v) => v.toLocaleString() + ' copiers') : p.copiers.toLocaleString() + ' copiers'}
); } function StatMini({ k, v, icon, accent }) { return (
{k}
{v}
); } /* ============ TRADER DETAIL ============ */ function TraderDetail({ ctx }) { const real = sniIsReal(); if (real) return ; return ; } /* Real trader detail — traderId is a wallet. Detail endpoint gives positions, * recent trades & computed 30d metrics; leaderboard row supplies name/profit/ * roi/copiers/tags. Unknown metrics render '—' (never fabricated). */ function RealTraderDetail({ ctx }) { const { traderId, onBack } = ctx; const wallet = traderId; const { data, loading } = useTrader(wallet); const { traders } = useTraders('30d', 25); const cfg = useCopyConfig(); const [showCopy, setShowCopy] = useState(false); const lb = useMemo(() => (traders || []).find((x) => _normWallet(x.wallet) === _normWallet(wallet)) || null, [traders, wallet]); const isCopied = cfg.isCopied(wallet); const name = (lb && lb.name) || (data && data.short) || short(wallet); const tags = (lb && lb.tags) || []; const badge = lb && lb.badge; const m = (data && data.metrics) || {}; const positions = (data && data.positions) || []; const trades = (data && data.trades) || []; const roi = lb ? lb.roi : null; const profit = lb ? lb.profit : null; const copiers = lb ? lb.copiers : null; // Prefer the real 30d volume from the leaderboard (/volume endpoint) over the // recent-trades partial sum, which only covers the last ~50 activity rows. const volume = (lb && lb.volume != null) ? lb.volume : ((m.volume_30d !== undefined && m.volume_30d !== null) ? m.volume_30d : null); const win = (m.win !== undefined) ? m.win : null; const trader = { id: wallet, wallet, name, addr: wallet, roi: roi, profit: profit }; return (

{name}

{badge === 'top' && Top trader}
{short(wallet)} { try { navigator.clipboard.writeText(wallet); } catch (e) {} }} /> window.open('https://polygonscan.com/address/' + wallet, '_blank')} />
{tags.length > 0 &&
{tags.map((tag) => {tag})}
}
{isCopied && }
pct(v))} up /> v + '%')} /> moneyShort(v))} up /> moneyShort(v))} /> v.toLocaleString())} /> v.toLocaleString())} />
Equity curve
{roi !== null && roi !== undefined && ▲ {pct(roi)}}
Polymarket doesn't publish a historical equity curve for external wallets. The profit, volume and open positions on this page are live and real.
Open positions {positions.length}
{positions.length ?
{positions.slice(0, 6).map((p, i) => (
{p.market}
{p.side} {(p.entry * 100).toFixed(0)}¢ → {(p.cur * 100).toFixed(0)}¢
= 0) ? 'var(--green)' : 'var(--red)', fontWeight: 700, fontSize: 13 }}>{(+p.pnl >= 0 ? '+' : '') + moneyShort(p.pnl)}
{pct(+p.pnlPct || 0)}
))}
:
{loading ? 'Loading positions…' : 'No open positions.'}
}
Recent trades
{trades.length ? trades.slice(0, 12).map((r, i) => ( )) : ( )}
MarketSidePriceSizeValueWhen
{r.market}{r.outcome ? · {r.outcome} : null} {r.side} {(r.price !== null && r.price !== undefined) ? (r.price * 100).toFixed(0) + '¢' : '—'} {_orDash(r.size, (v) => moneyShort(v))} {_orDash(r.usdc, (v) => moneyShort(v))} {r.ts ? sniFmtAgo(r.ts) + ' ago' : '—'}
{loading ? 'Loading recent trades…' : 'No recent trades in this window.'}
{showCopy && setShowCopy(false)} onConfirm={() => { cfg.toggle(wallet, true); setShowCopy(false); }} alreadyCopied={isCopied} />}
); } function DemoTraderDetail({ ctx }) { const { traderId, onBack, copied, onCopyTrader, onUncopy } = ctx; const t = TRADERS.find((x) => x.id === traderId) || TRADERS[0]; const series = useMemo(() => genSeries('t' + t.id, 70, true), [t.id]); const isCopied = copied.includes(t.id); const [showCopy, setShowCopy] = useState(false); const recent = useMemo(() => MARKETS.slice(0, 5).map((m, i) => ({ m: m.q, side: i % 3 === 0 ? 'NO' : 'YES', price: m.yes, size: [8200, 12400, 4100, 6800, 9600][i], when: ['2m', '41m', '3h', '6h', '1d'][i], pnl: [820, 1240, -180, 540, 1960][i], })), [t.id]); return (
{/* hero */}

{t.name}

{t.badge === 'top' && Top trader}
{short(t.addr)}
{t.tags.map((tag) => {tag})}
{isCopied && }
Equity curve (90d)
▲ {pct(t.roi)}
If you'd copied $10k
Based on this trader's last 30 days of realized performance. Not a guarantee of future results.
Recent trades
{recent.map((r, i) => ( ))}
MarketSidePriceSizeResultWhen
{r.m} {r.side} {r.price}¢ {moneyShort(r.size)} = 0 ? 'var(--green)' : 'var(--red)', fontWeight: 700 }}>{r.pnl >= 0 ? '+' : ''}{moneyShort(r.pnl)} {r.when} ago
{showCopy && setShowCopy(false)} onConfirm={() => { onCopyTrader(t.id); setShowCopy(false); }} alreadyCopied={isCopied} />}
); } function DetailStat({ k, v, up }) { return (
{k}
{v}
); } /* ============ COPY MODAL ============ */ function CopyModal({ trader, onClose, onConfirm, alreadyCopied, initialAlloc }) { const [alloc, setAlloc] = useState(initialAlloc || 5000); const [maxTrade, setMaxTrade] = useState(15); const [sl, setSl] = useState(20); const [tp, setTp] = useState(50); const [proportional, setProportional] = useState(true); const [wallet, setWallet] = useState('w1'); return (
{trader.name}
{short(trader.addr)}
{(trader.roi === null || trader.roi === undefined) ? '—' : pct(trader.roi)}
30d ROI
{WALLETS.map((w) => )}
setAlloc(+e.target.value)} />
Total capital this trader can deploy on your behalf.
setMaxTrade(+e.target.value)} />
{proportional ? 'Proportional to trader' : 'Fixed per trade'}
setSl(+e.target.value)} />
setTp(+e.target.value)} />
Copy trading carries risk of total loss. The engine mirrors real positions at market and cannot guarantee fills or prices.
); } Object.assign(window, { Overview, CopyTraders, TraderDetail, PositionsTable });