Auto cash-out closes a position at exactly the chosen target rather than the next tick's multiplier, and fires whenever the target is at or below the crash point. This is the feature that makes the game playable over a network, where manual timing is at the mercy of latency. House edge drops from 2% to 1% across crash and scratch. Scratch prize tables retuned so the published 99% RTP is exact. Adds docs/API.md: the client uses no private endpoints, so anyone can write a bot against the same API. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
147 lines
5.0 KiB
HTML
147 lines
5.0 KiB
HTML
<!doctype html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||
<title>QUANTUM ARCADE</title>
|
||
<link rel="stylesheet" href="/style.css">
|
||
</head>
|
||
<body>
|
||
|
||
<!-- Ornate background filigree, drawn once as an SVG pattern and tiled. -->
|
||
<svg class="filigree" aria-hidden="true">
|
||
<defs>
|
||
<pattern id="orn" width="60" height="52" patternUnits="userSpaceOnUse">
|
||
<g fill="none" stroke="currentColor" stroke-width="0.7">
|
||
<path d="M15 0 L45 0 L60 26 L45 52 L15 52 L0 26 Z"/>
|
||
<path d="M30 26 L60 26 M30 26 L15 0 M30 26 L15 52"/>
|
||
<circle cx="30" cy="26" r="1.6"/>
|
||
<circle cx="0" cy="26" r="1.2"/>
|
||
<circle cx="60" cy="26" r="1.2"/>
|
||
</g>
|
||
</pattern>
|
||
</defs>
|
||
<rect width="100%" height="100%" fill="url(#orn)"/>
|
||
</svg>
|
||
|
||
<header class="topbar">
|
||
<div class="brand">QUANTUM<span>ARCADE</span></div>
|
||
<div class="balance" id="balance-wrap" hidden>
|
||
<span class="label">balance</span>
|
||
<span class="value" id="balance">—</span>
|
||
</div>
|
||
<button class="sound" id="sound-toggle" title="Ambient sound">♪</button>
|
||
</header>
|
||
|
||
<!-- Sign-in: a nickname and nothing else. -->
|
||
<section class="panel center" id="signin">
|
||
<h1>ACCESS TERMINAL</h1>
|
||
<p class="muted small">
|
||
No account. No email. No password. This device generated a keypair that
|
||
<em>is</em> your identity. Keep the device, keep the balance.
|
||
</p>
|
||
<input id="nickname" maxlength="20" placeholder="handle" autocomplete="off">
|
||
<button class="primary" id="enter">Connect</button>
|
||
<p class="fineprint" id="keynote"></p>
|
||
</section>
|
||
|
||
<main id="app" hidden>
|
||
|
||
<nav class="tabs">
|
||
<button class="tab active" data-view="crash">Crash</button>
|
||
<button class="tab" data-view="scratch">Scratchers</button>
|
||
<button class="tab" data-view="wallet">Wallet</button>
|
||
<button class="tab" data-view="verify">Verify</button>
|
||
</nav>
|
||
|
||
<!-- ============ CRASH ============ -->
|
||
<section class="view" id="view-crash">
|
||
<div class="gamepick" id="gamepick"></div>
|
||
|
||
<div class="stage">
|
||
<canvas id="canvas"></canvas>
|
||
<div class="readout">
|
||
<div class="multiplier" id="multiplier">1.00×</div>
|
||
<div class="state" id="state">connecting…</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="controls">
|
||
<div class="stakerow">
|
||
<button class="chip" data-stake="1000">1</button>
|
||
<button class="chip" data-stake="5000">5</button>
|
||
<button class="chip" data-stake="25000">25</button>
|
||
<button class="chip" data-stake="100000">100</button>
|
||
<span class="unit">sats</span>
|
||
</div>
|
||
<div class="autorow" id="autorow">
|
||
<label for="auto-target">auto out</label>
|
||
<input id="auto-target" type="number" min="1.01" step="0.1"
|
||
inputmode="decimal" placeholder="off">
|
||
<span class="x">×</span>
|
||
</div>
|
||
|
||
<button class="primary big" id="action">Place bet</button>
|
||
<div class="hint" id="hint"></div>
|
||
</div>
|
||
|
||
<div class="players" id="players"></div>
|
||
|
||
<details class="proof">
|
||
<summary>Fairness for this round</summary>
|
||
<div class="kv"><span>commitment</span><code id="commitment">—</code></div>
|
||
<div class="kv"><span>revealed seed</span><code id="revealed">sealed until the round ends</code></div>
|
||
<p class="muted small">
|
||
The commitment is published before betting opens. The crash point is
|
||
derived from that seed combined with every player's key — so it cannot
|
||
be chosen after seeing who joined.
|
||
</p>
|
||
</details>
|
||
</section>
|
||
|
||
<!-- ============ SCRATCH ============ -->
|
||
<section class="view" id="view-scratch" hidden>
|
||
<div id="tickets"></div>
|
||
</section>
|
||
|
||
<!-- ============ WALLET ============ -->
|
||
<section class="view" id="view-wallet" hidden>
|
||
<div class="card">
|
||
<h2>Your key</h2>
|
||
<p class="muted small">Share this so friends can send you sats.</p>
|
||
<code class="pubkey" id="pubkey">—</code>
|
||
<button id="copykey">Copy</button>
|
||
</div>
|
||
<div class="card">
|
||
<h2>Send sats</h2>
|
||
<input id="to-key" placeholder="recipient key" autocomplete="off">
|
||
<input id="send-amt" type="number" min="1" placeholder="amount in sats">
|
||
<button class="primary" id="send">Send</button>
|
||
<div class="hint" id="send-hint"></div>
|
||
</div>
|
||
<div class="card">
|
||
<h2>Every change to your balance</h2>
|
||
<div id="history" class="history"></div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- ============ VERIFY ============ -->
|
||
<section class="view" id="view-verify" hidden>
|
||
<div class="card">
|
||
<h2>Check any round</h2>
|
||
<p class="muted small">
|
||
Enter a round number. Your phone recomputes the outcome from the
|
||
published seeds — it does not take the server's word for anything.
|
||
</p>
|
||
<input id="verify-id" type="number" min="1" placeholder="round number">
|
||
<button class="primary" id="do-verify">Verify</button>
|
||
<div id="verify-out" class="verify-out"></div>
|
||
</div>
|
||
</section>
|
||
|
||
</main>
|
||
|
||
<script src="/app.js"></script>
|
||
</body>
|
||
</html>
|