// DEVNET · this is a test deployment. tokens have no value. SOL is fake. get test SOL →
// LIVE — one coin. one curve. one bag to hold.

another launchpad.
only 1 coin.

a thousand new tokens a day. just one. trade it, hold it, earn from every trade. 2% of every trade goes back to holders.

$ONLY 7CBjK9wH3xZpMeRdQk2vL8nT5ftYhU3aXbV4mNsKtkT9j
$ONLY price
◎ 0.00214
+ 18.2%
Market cap
◎ 8,521
+ 12.4%
Paid to holders
◎ 168.4
+ 22.1% / 24h
Bought back
◎ 84.2
+ 22.1% / 24h
$ONLY / SOL
24h volume
◎ 921
24h high
◎ 0.00231
24h low
◎ 0.00181
Holders
2,841
$
$ONLY 7CB...kT9j
◎ 0.00214
+18.2%
You paybalance: 12.84 SOL
SOL
You receive1 SOL ≈ 467 ONLY
$ONLY
hold $ONLY → earn 2% of every trade
// HOLD AND EARN

Every trade pays the bag.
2% goes straight to holders.

Drag the slider. See what your bag earns based on real 24-hour trading volume. Distributions land in your wallet automatically — no claim, no gas fees.

Earnings calculator

// based on last 24h volume of ◎ 921
10,000 $ONLY
◎ 921
Your share of supply 0.0008%
Daily rewards (2% of vol) ◎ 18.42
Your daily payout ◎ 0.00015
Estimated annual ◎ 0.0540
live distributions
live ●
02s
9Df...8mQp earned ◎ 0.0142
reward
14s
3Kx...7pLn bought ◎ 0.50 of $ONLY
buy
28s
buyback executed: burned 142.8 $ONLY
buyback
41s
7Hf...2nKt earned ◎ 0.0089
reward
56s
5Aq...9bRm bought ◎ 1.20 of $ONLY
buy
1m
2Vw...4kTs earned ◎ 0.0312
reward
2m
buyback executed: burned 68.4 $ONLY
buyback
2m
8Lp...1cYj bought ◎ 0.30 of $ONLY
buy
// LAUNCHPAD

Launch your own coin.

Pick a name. Upload a logo. Add your socials. Hit launch. Your token gets a bonding curve, 2% holder rewards, and automated buybacks — same mechanics as $ONLY.

create_token() — launch your coin
awaiting launch
media
+
socials
// connect your wallet to launch.
// your coin gets a bonding curve, holder rewards, and auto-buybacks.
a new coin every 30 seconds.
racing to be first out.
rugs disguised as launches.
just one coin. hold it. earn from it.
// HOW IT WORKS

Three things, then you're done reading.

One coin, forever

$ONLY is the only token this platform will ever launch. No new coin tomorrow. No followup project. Just one bag, one curve, one focus.

Hold, earn 2%

Every buy and every sell sends 2% to holders. Distributed pro-rata to your bag, no claims, no gas. The longer you hold, the more you stack.

1% buybacks, burned

Another 1% builds in a buyback vault. A bot triggers buybacks on a schedule and burns the tokens — supply only goes down.

one coin.
one bag. hold it.

Buy $ONLY in two clicks. Every trade after yours adds to your wallet automatically.

// and importing the IDL. async function callBuy(solAmount) { if (!wallet.connected) { toast({ type: 'warn', title: 'Connect wallet first' }); return; } if (!isConfigured()) { toast({ type: 'error', title: 'Frontend not configured', sub: 'Deploy the program first, then update CONFIG in the HTML' }); return; } if (CONFIG.mintAddress === 'REPLACE_AFTER_LAUNCH') { toast({ type: 'warn', title: 'Token not launched yet', sub: 'Admin must call create_token before trading is enabled' }); return; } if (wallet.balance < solAmount + 0.01) { toast({ type: 'error', title: 'Insufficient SOL', sub: `Need ◎ ${(solAmount + 0.01).toFixed(4)}, have ◎ ${wallet.balance.toFixed(4)}` }); return; } // Real call requires loading @coral-xyz/anchor + the IDL. // Easiest path: bundle anchor + IDL into a separate JS file and import here. // The structure of that call is documented in README.md under "Wire up the frontend". toast({ type: 'info', title: 'Buy ready to wire up', sub: 'See README step 5 — load anchor IDL and call program.methods.buy(...)' }); } async function callSell(tokenAmount) { if (!wallet.connected) { toast({ type: 'warn', title: 'Connect wallet first' }); return; } if (!isConfigured() || CONFIG.mintAddress === 'REPLACE_AFTER_LAUNCH') { toast({ type: 'warn', title: 'Not configured', sub: 'Deploy program and launch token first' }); return; } toast({ type: 'info', title: 'Sell ready to wire up', sub: 'See README step 5 — call program.methods.sell(...)' }); } async function callCreateToken(metadata) { if (!wallet.connected) { toast({ type: 'warn', title: 'Connect wallet first' }); return false; } if (!isConfigured()) { toast({ type: 'error', title: 'Frontend not configured', sub: 'Set CONFIG.programId and CONFIG.adminPubkey first' }); return false; } if (!wallet.isAdmin) { // This is the meme. Admin check matches the program's constraint. return { success: false, notAdmin: true }; } // Admin path: build the create_token transaction. // This is deliberately left for you to wire up after deploy, since it // requires the IDL + a generated mint keypair + ATA derivation. toast({ type: 'info', title: 'create_token ready to wire up', sub: 'See README — needs IDL and mint keypair generation' }); return { success: false, notAdmin: false }; } // ============================================================ // BIND CONNECT BUTTON ON LOAD // ============================================================ document.getElementById('connectBtn')?.addEventListener('click', (e) => { e.preventDefault(); connectWallet(); }); // Auto-connect if Phantom was previously trusted window.addEventListener('load', async () => { const provider = getPhantomProvider(); if (provider) { try { const resp = await provider.connect({ onlyIfTrusted: true }); wallet.publicKey = resp.publicKey; wallet.connected = true; wallet.provider = provider; wallet.isAdmin = resp.publicKey.toString() === CONFIG.adminPubkey; const lamports = await connection.getBalance(resp.publicKey); wallet.balance = lamports / LAMPORTS_PER_SOL; updateWalletUI(); provider.on('accountChanged', handleAccountChanged); provider.on('disconnect', handleDisconnect); } catch (e) { /* not trusted, user will click connect */ } } }); // Expose for console testing window.__only = { wallet, CONFIG, callBuy, callSell, callCreateToken, refreshBalance }; // ============================================================ // ORIGINAL TRADE PANEL LOGIC // ============================================================ // === TRADE PANEL MATH === const PRICE = 0.00214; const FEE_PCT = 0.04; const payInput = document.getElementById('payInput'); const receiveInput = document.getElementById('receiveInput'); const buyBtn = document.getElementById('buyBtn'); const sellBtn = document.getElementById('sellBtn'); const confirmBtn = document.getElementById('confirmBtn'); const fmtTokens = (n) => Math.floor(n).toLocaleString(); function recalcTrade() { const sol = parseFloat(payInput.value.replace(/,/g, '')) || 0; const net = sol * (1 - FEE_PCT); const tokens = net / PRICE; receiveInput.value = fmtTokens(tokens); } payInput.addEventListener('input', recalcTrade); document.querySelectorAll('.quick-amounts button').forEach(btn => { btn.addEventListener('click', () => { payInput.value = btn.dataset.amt; recalcTrade(); }); }); buyBtn.addEventListener('click', () => { buyBtn.classList.add('active'); sellBtn.classList.remove('active'); confirmBtn.textContent = 'buy $ONLY →'; confirmBtn.style.background = 'var(--green)'; }); sellBtn.addEventListener('click', () => { sellBtn.classList.add('active'); buyBtn.classList.remove('active'); confirmBtn.textContent = 'sell $ONLY →'; confirmBtn.style.background = 'var(--red)'; }); // === COPY CONTRACT === const copyBtn = document.getElementById('copyBtn'); copyBtn.addEventListener('click', () => { navigator.clipboard.writeText('7CBjK9wH3xZpMeRdQk2vL8nT5ftYhU3aXbV4mNsKtkT9j'); copyBtn.textContent = 'copied'; setTimeout(() => copyBtn.textContent = 'copy', 1500); }); // === EARNINGS CALCULATOR === const TOTAL_SUPPLY = 1_000_000_000; const bagSlider = document.getElementById('bagSlider'); const volSlider = document.getElementById('volSlider'); const bagValue = document.getElementById('bagValue'); const volValue = document.getElementById('volValue'); const shareValue = document.getElementById('shareValue'); const dailyValue = document.getElementById('dailyValue'); const payoutValue = document.getElementById('payoutValue'); const annualValue = document.getElementById('annualValue'); function recalcEarnings() { const bag = parseFloat(bagSlider.value); const vol = parseFloat(volSlider.value); const share = bag / TOTAL_SUPPLY; const dailyPool = vol * 0.02; const payout = dailyPool * share; const annual = payout * 365; bagValue.textContent = bag.toLocaleString() + ' $ONLY'; volValue.textContent = '◎ ' + vol.toLocaleString(); shareValue.textContent = (share * 100).toFixed(4) + '%'; dailyValue.textContent = '◎ ' + dailyPool.toFixed(2); payoutValue.textContent = '◎ ' + payout.toFixed(5); annualValue.textContent = '◎ ' + annual.toFixed(4); } bagSlider.addEventListener('input', recalcEarnings); volSlider.addEventListener('input', recalcEarnings); recalcEarnings(); // === LIVE FEED === const feedList = document.getElementById('feedList'); const wallets = ['9Df...8mQp', '3Kx...7pLn', '7Hf...2nKt', '5Aq...9bRm', '2Vw...4kTs', '8Lp...1cYj', '4Mn...6rDp', '1Zb...3xKw', '6Rt...0vQs', '0Yh...5jBn']; const eventTypes = ['reward', 'reward', 'reward', 'buy', 'buy', 'buyback']; function makeEvent() { const type = eventTypes[Math.floor(Math.random() * eventTypes.length)]; const wallet = wallets[Math.floor(Math.random() * wallets.length)]; const item = document.createElement('div'); item.className = 'feed-item'; if (type === 'reward') { const amt = (Math.random() * 0.04 + 0.005).toFixed(4); item.innerHTML = `now
${wallet} earned ◎ ${amt}
reward`; } else if (type === 'buy') { const amt = (Math.random() * 2 + 0.1).toFixed(2); item.innerHTML = `now
${wallet} bought ◎ ${amt} of $ONLY
buy`; } else { const amt = (Math.random() * 200 + 30).toFixed(1); item.innerHTML = `now
buyback executed: burned ${amt} $ONLY
buyback`; } feedList.insertBefore(item, feedList.firstChild); // Bump timestamps on existing items const items = feedList.querySelectorAll('.feed-item'); items.forEach((el, i) => { if (i === 0) return; const t = el.querySelector('.feed-time'); if (t.textContent === 'now') t.textContent = '01s'; else if (t.textContent.endsWith('s')) { const n = parseInt(t.textContent) + 4; t.textContent = n < 60 ? n.toString().padStart(2, '0') + 's' : Math.floor(n / 60) + 'm'; } }); // Cap list length if (items.length > 12) { feedList.removeChild(items[items.length - 1]); } } setInterval(makeEvent, 4000); // === CHART PRICE TICK === setInterval(() => { const valEl = document.querySelector('.stat-card .value'); if (!valEl) return; const cur = 0.00214 * (1 + (Math.random() - 0.45) * 0.005); valEl.textContent = '◎ ' + cur.toFixed(5); }, 3000); // === IMAGE UPLOAD PREVIEW === function setupUpload(zoneId, inputId) { const zone = document.getElementById(zoneId); const input = document.getElementById(inputId); if (!zone || !input) return; input.addEventListener('change', (e) => { const file = e.target.files[0]; if (!file) return; const reader = new FileReader(); reader.onload = (ev) => { zone.innerHTML = ``; zone.classList.add('has-image'); // re-bind the new input const newInput = zone.querySelector('input[type="file"]'); newInput.addEventListener('change', (e2) => { const f = e2.target.files[0]; if (!f) return; const r = new FileReader(); r.onload = (ev2) => { zone.querySelector('img').src = ev2.target.result; }; r.readAsDataURL(f); }); }; reader.readAsDataURL(file); }); } setupUpload('avatarZone', 'avatarInput'); setupUpload('bannerZone', 'bannerInput'); // === LAUNCH BUTTON — fakes the launch, then reveals the joke === const launchBtn = document.getElementById('launchBtn'); const stopModal = document.getElementById('stopModal'); const modalClose = document.getElementById('modalClose'); const modalDismiss = document.getElementById('modalDismiss'); const modalBuy = document.getElementById('modalBuy'); function showStopModal() { stopModal.classList.add('show'); document.body.style.overflow = 'hidden'; } function hideStopModal() { stopModal.classList.remove('show'); document.body.style.overflow = ''; // Reset the launch button so they can try again if they want if (launchBtn) { launchBtn.disabled = false; launchBtn.textContent = 'launch coin →'; launchBtn.style.background = ''; } } if (launchBtn) { launchBtn.addEventListener('click', async () => { // Step 1: Must be connected if (!wallet.connected) { toast({ type: 'warn', title: 'Connect Phantom first' }); return; } launchBtn.disabled = true; launchBtn.textContent = 'awaiting wallet signature...'; // Brief UX delay so the state changes register await new Promise(r => setTimeout(r, 800)); launchBtn.textContent = 'broadcasting transaction...'; // Collect form data const metadata = { name: document.getElementById('formName')?.value || '', symbol: document.getElementById('formSymbol')?.value || '', website: document.getElementById('formWebsite')?.value || '', twitter: document.getElementById('formX')?.value || '', telegram: document.getElementById('formTelegram')?.value || '', }; const result = await callCreateToken(metadata); await new Promise(r => setTimeout(r, 600)); // The result will be {success: false, notAdmin: true} for non-admin wallets, // OR the program will revert TokenAlreadyCreated for the admin's second attempt. // Either way, we show the stop-launching meme modal. launchBtn.textContent = 'transaction reverted ✕'; launchBtn.style.background = 'var(--red)'; launchBtn.style.color = 'var(--bg)'; await new Promise(r => setTimeout(r, 500)); showStopModal(); }); } modalClose?.addEventListener('click', hideStopModal); modalDismiss?.addEventListener('click', hideStopModal); modalBuy?.addEventListener('click', hideStopModal); stopModal?.addEventListener('click', (e) => { if (e.target === stopModal) hideStopModal(); }); document.addEventListener('keydown', (e) => { if (e.key === 'Escape' && stopModal.classList.contains('show')) hideStopModal(); }); // Tab toggling document.querySelectorAll('.panel-tabs .tab').forEach(t => { t.addEventListener('click', () => { t.parentElement.querySelectorAll('.tab').forEach(x => x.classList.remove('active')); t.classList.add('active'); }); });