feat: Rust workspace — 13 crates, game engines, covenant compiler, oracle daemon#3
feat: Rust workspace — 13 crates, game engines, covenant compiler, oracle daemon#3THTProtocol wants to merge 143 commits into
Conversation
…ime/mode/stake/visibility)
…+create, covenant escrow+autopayout wired
…er polish - Add Texas Hold'em + Blackjack cards to the main #v-skill grid (now 6 cards) alongside Chess/Connect4/Checkers/Tic-Tac-Toe. Each card pipes through the shared sgGamePicker -> createMatchWithLobby covenant-escrow flow so the same 2% protocol fee, cancel-before-join, and forfeit-on-leave rules apply. - Disable patch-games.js's duplicate skill section injection now that the primary panel hosts all 6 games. - Wallet (htp-wallet-v3.js): enable Mainnet network selector (was hard-disabled), validate manual Kaspa addresses against kaspa:/kaspatest: bech32 envelope, give actionable feedback when a chosen extension is not detected and point the user at the install URL plus the existing Mnemonic/Hex import paths. - Maximizer: have calc() route through HTPFee.maximizerWinSettle/loseSettle so the trade card payout preview matches the same 50/50 split + 2% on winnings + 30% on hedge claim used at settlement. Add an in-form caption explaining that the maximizer cap is max(expected, actual) x cap%, with the 100K->200K example, and noting cap=0 disables maximizers entirely. Treasury addresses (mainnet kaspa:qza6...ka4fel and TN12 kaspatest:qpyfz...68354m) are unchanged. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…se, board UI - index.html: declare safe global net (defaults to 'both' or activeNet) so renderM no longer crashes; replace em-dashes in visible UI strings; restyle LIVE KASPA dot (solid, no pulse, no clipping); make all sgv2-card skill game cards fully keyboard accessible and route through a shared __htpPickGame helper that scrolls picker into view; add per-game extras panel (chess color, checkers forced capture, c4 first mover/board width, ttt quick mode, poker seats/blinds, blackjack decks/rounds); richer checkers board palette with gradient squares, glowing select/legal-target rings, and 3D rim-lit discs. - kaspa-wasm-sdk-inline.js: probe /kaspa_bg.wasm and verify wasm magic bytes before instantiating; fall back cleanly to lite mode when the binary is missing or served as HTML. - htp-init.js: replace blocking WASM error modal with a quiet Lite Mode banner + retry; add Toccata forward-compat network entry and HTP_TOCCATA_LIVE feature flag; carry direct TN12 wRPC fallbacks in NETWORK_MAP. - htp-blockdag-viz.js: catch permission_denied on /kaspa/stats writes and disable further writes after the first failure to stop the 5s spam loop. - firebase-config.js: skip the gstatic compat loaders if firebase-app-compat is already on the page so the duplicate-global warning goes away. - chess-sync, games-sync, board-engine: gate the install banner behind a one-shot flag so re-runs after WASM recovery do not re-log the same lines. - server.js: serve .wasm with application/wasm and refuse to fall through to the SPA for asset paths so missing assets return 404 rather than HTML. - firebase.json: add .wasm content-type header and exclude assets from SPA rewrite.
Adds public/kaspa_bg.wasm (10.6 MB) from the official Rusty Kaspa v1.1.0 release web build (kaspa-wasm32-sdk-v1.1.0.zip -> web/kaspa/kaspa_bg.wasm). The existing inline JS glue is wbindgen output with the identical ABI (verified: 254/254 imports match, 849 exports satisfy all 843 references; full WebAssembly.instantiate succeeds). The app now exits lite mode and the SDK initialises with the correct binary, eliminating the "expected magic word ... <!DO" console error. Banner/log lines updated to identify the binary as official v1.1.0. No loader path changes needed; firebase.json + server.js already serve .wasm with application/wasm and refuse SPA fallback for asset-typed paths. Source: https://github.com/kaspanet/rusty-kaspa/releases/tag/v1.1.0 SHA-256 of binary: 036af491c05e8d23806470fa135947355e1f8516766f54bb26259637c9f10394 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Fixes from production console: - net is not defined: early-init window.net/HTP_NETWORK shim, defensive resolver inside renderM, single-source htpResolveNet helper - WASM loader: probe always reads bytes and verifies magic; one-shot auto-init guard; never instantiate HTML; loader watchdog max 15s with single state transition - Firebase: safeSet skips writes when disabled (default for anon clients); _fbWriteFailures backs off after 2 errors; opt-in via window.HTP_FB_STATS_WRITES - Firebase config: idempotent install + init guards; loadScript matches by ending segment to prevent double compat load - Patch idempotency: chess-sync, games-sync, board-engine, autopayout-engine, patch-games guarded with window.__htp*Installed UI: - LIVE KASPA BLOCKDAG dot: no pulse, fixed clipping with !important min-size and overflow visible - Em dashes replaced with commas across UI strings, comments, log strings; placeholder dashes restored to hyphens/zero defaults - Big skill game cards already clickable; updGameOpts now triggers htpRenderGameExtras for per-game settings - Checkers: classic high-contrast walnut + cream squares, glossy radial-gradient pieces, mandatory-capture gold ring - Connect4 + chess board polish with subtle shadows and legal-move dots KGI heightDifference NaN errors originate inside the kgi.kaspad.net iframe and cannot be patched from parent. Mainnet/TN12 protocol fee addresses unchanged.
… attestor node - New htp-skill-v3 module renders a per-game lobby panel when a skill card is pressed. Filters open matches by game; shows attractive empty state with Create flow when none exist for that game. - Per-game settings: chess time controls, ranked/draw policy; checkers forced capture, multi-jump, king mode; connect4 first mover and width; tictactoe pace and series; poker action clock plus blinds and blind interval (cash vs tournament); blackjack decks, rounds, soft 17. - Payout preview shown for create and per-match-card: equal stake X each, pot 2X, 2% protocol fee, winner 1.96X. - Cypherpunk polish: neon teal panels, scanlines, sharper hover/active/ focus on cards. Cards keyboard accessible. - LIVE KASPA dot: pulse removed, ancestor overflow fixed so dot is never clipped at the left edge. - Em dashes scrubbed from visible copy at runtime; package.json description rewritten without em dash. - New scripts/run-attestor-node.mjs plus docs/attestor-node.md. Reads env, pulls events, hashes evidence, signs, submits off-chain to Firebase if configured. On-chain leg explicit about pending state. Mainnet treated as dry-run until activation flag set. - npm run attestor and attestor:once.
UI: removed decorative emojis across the app (rockets, sparkles, trophies, warnings, money bags, wallet plug, KasWare modal, leaderboard medals, settlement icons, market feed icons, etc.). Preserved functional glyphs: chess pieces, checker stones, card suits, and the X used for tic-tac-toe and modal close buttons. Buttons: added public/htp-buttons-v2.css and linked it after style.css and htp-skill-v3.css. Provides a uniform cypherpunk button shell across .btn, .btn-primary, .btn-secondary, .btn-outline, .btn-ghost, .btn-danger, .btn-gold, .cta1, .cta2, .chess-btn, .chess-btn-danger, .risk-btn, .sgv3-btn, .sgv3-tab, .sgv3-close, .nav-btn, .chip, .market-chip, plus modal/wallet/market/join/create button hooks. Features: - crisp 1px gradient scanline highlight on the top edge - consistent height (sm/md/lg) and padding - accessible focus-visible ring (double outline) - intentional disabled state with crosshatch hint - hover lift, active press - danger and gold variants for destructive and settlement actions No new emojis introduced. Preserves Skill Games v3, attestor script, public/kaspa_bg.wasm, fee addresses, and Toccata caveats.
Adds scripts/stress-skill-games.mjs and `npm run stress:games`. The harness exercises: - Payout formula: pot=2X, 2% protocol fee, winner=1.96X (matches lib/fees.js calculateGamePayout for both win and draw paths). - Game lifecycle: create → cancel-before-join (creator recovers stake), create → join → forfeit (opponent wins), draw path. All in-memory; no real on-chain calls, no data/ pollution. - Chess: FEN parse + e4 turn flip + castling rights. - Checkers: init layout (12+12), diagonal advance, jump capture, king promotion on far row. - Connect 4: vertical / horizontal / diagonal wins, full-board draw layout. - Tic-Tac-Toe: row-win and draw detection. - Poker (lib/games/poker.js): heads-up hand with PokerEngine, fold ends hand, public-state hides opponent hole cards, hand evaluator rank ordering (royal flush > four of a kind > one pair). - Blackjack (lib/games/blackjack.js): start dealer + player hands, stand action, hand totals (21 / soft A+9+5 / bust 24), naturals. Random sources are seeded with xorshift32 inside try/finally so Math.random is not perturbed for the rest of the process. Run: `npm run stress:games` — 61 passing, exit 0.
…rame arrow
Two low-severity browser-QA items.
(1) Wallet extension clicks now show actionable feedback when no provider
is injected. Both selWallet (index.html v-wallet view) and
htpWalletV3.connectWallet (v-wallet-v3 grid) previously logged-or-set a
red status string, but selWallet did not also surface a toast and
connectWallet used a non-handled toast type ('warn') which rendered as a
default-dark toast. Now:
- selWallet renders an inline red panel inside #walletStatus listing the
install URL plus a hint to use mnemonic/hex private key import, and
also fires showToast(...,'error') so users scrolled past the panel
still see it.
- connectWallet calls showToast(...,'error') with the concise spec copy
("<Wallet> extension not detected. Install the wallet or use
mnemonic/key import.") and falls back to alert() only when no toast
is available.
No emojis added, no extension provider APIs assumed, mnemonic and hex
private-key import flows untouched.
(2) The kgi.kaspad.net visualizer renders a circular pan/zoom control
near its right edge that lands on the rounded card border and reads as
clipped. Add one CSS rule in htp-skill-v3.css to extend the iframe by
44px to the right (right:-44px; width:calc(100% + 44px); !important).
The parent card's overflow:hidden cleanly hides that control. The DAG
canvas continues to render across the full visible width — the right
44px is mostly the control plus empty viewport. Applies to both
in-page locations of the visualizer (hero panel + Kaspa overview).
LIVE KASPA dot CSS untouched and remains static and unclipped per the
existing rules in htp-skill-v3.css.
…ger renderM+buildF
…e KSPR, event delegation instead of inline onclick
…click not delegation, remove pointer-events:none
…mainnet, server hardening - Delete conflicting chess-ui.js renderer (V4 in htp-chess-ui.js is canonical) - Move htp-chess-ischeck-fix.js to load right after chess.min.js - htp-chess-sync.js: deterministic color from matchId hash, applyOrientation defers to V4 renderer (no CSS rotate hijack), clock tick is timeout-only (display derived from stored_ms minus elapsed) - htp-board-engine.js: clock state moved to derived display (lastMoveTs), switchClock snapshots remainder plus increment, applyClockSync resets lastMoveTs - htp-wallet-v3.js: Kastle, Kaspa-NG, Kaspium use provider.connect() with all return shapes; Kaspium canConnect=true; mainnet button enabled; setNetwork toggles RPC URL and HTP_PREFIX - htp-covenant-escrow-v2.js: AES-256-GCM encrypt private key in sessionStorage only; localStorage holds only public metadata; getEscrow now async and decrypts; getFeeDest selects mainnet vs testnet treasury; settleMatchPayout uses network-specific fee dest - htp-autopayout-engine.js, htp-settlement-preview.js: await getEscrow - htp-events-v3.js: log Firebase top-level keys for debug, add fallback listener at /events alongside /markets - database.rules.json plus firebase.json: full security rules covering relay, settlement, markets, events, oracle, stats - Remove redundant patch files: htp-wallet-fix.js, htp-wallet-patch.js, patch-games.js, htp-gamefix-sync.js (and stop dynamic injection from htp-demo-match.js)
Co-authored-by: HTP Agent <agent@hightable.local>
… handling, mobile tap targets, network status indicator, overlay dismissal, turn pulse animation, mobile nav sizing
…prediction markets, DAA counter, REST migration
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: eaf8050a77
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| - uses: dtolnay/rust-toolchain@stable | ||
| - uses: Swatinem/rust-cache@v2 | ||
| - name: Build | ||
| run: cargo build --workspace |
There was a problem hiding this comment.
Run cargo commands from Rust workspace root
These CI commands execute from the repository root, but this repo has no top-level Cargo.toml (the workspace manifest is under crates/Cargo.toml), so cargo build --workspace fails immediately with “could not find Cargo.toml” on every triggered run. This makes the new Rust CI workflow red by default unless you set working-directory: crates (or pass --manifest-path crates/Cargo.toml) for both build and test steps.
Useful? React with 👍 / 👎.
Rust workspace with 13 crates including all 6 game engines (chess, connect4, checkers, poker, blackjack, tictactoe), covenant compiler, oracle daemon, settlement engine, P2P networking, WASM bridge, CLI, and MiroFish bridge. Ready for CI build verification.