OhMyGame
OhMyGame is the open-source studio for making games with AI. Design, build, playtest, and publish games in one app, with your own model keys.
45-second typing races in English and Spanish. Compete for the highest score and daily USDT rewards.
GamesTypeScript · JavaScriptGitHub @JuanFCastOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
The maker's introduction consists of the line above. Read the repository README for more details. Repository README ↗
Loading the full README.
Read the full README ↗A daily typing competition living inside MiniPay (Opera's wallet) on Celo — race a 45-second passage, get ranked by speed and accuracy, and the daily #1 wins the USDT prize pool, paid on-chain.
Live: typerush.fun
Built in Colombia
TypeRush is a casual mobile typing game with real stablecoin prizes, running inside MiniPay
on Celo mainnet. From a home lobby the player picks a mode (es/en) and a daily challenge,
then types a passage against a 45-second timer. The app measures WPM, accuracy, errors,
corrections and a final score, and ranks every player against everyone else who raced the same
mode that day.
The whole interface is bilingual (Spanish/English) and independent from the typing mode: you can read the app in English while typing a Spanish passage, or vice versa.
window.ethereum, alongside external wallets
(RainbowKit/wagmi) and an optional embedded wallet via Privy.Each mode (es/en) has a set of challenges built from curated passages. A race lasts 45 seconds;
per-character feedback marks correct/incorrect input live. Score is computed as:
mistakePenalty = Math.max(0.7, 1 - mistakeCount * 0.03) // soft penalty, up to −30%
score = Math.round(wpm * accuracy * progress * mistakePenalty * 100) // wpm = (correctChars / 5) / minute
The player's best score per challenge is kept in localStorage; every ranked race is also
persisted to Supabase for the leaderboard and profile history.
The entry fee, the pool and the payout are handled entirely on-chain by TypeRushGameV3,
deployed and verified on Celo mainnet (chainId 42220).
| Contract | TypeRushGameV3 |
| Address | 0xD8287809e0D68E7e50D0D962f11Eb72150F48d39 |
| Network | Celo mainnet · chainId 42220 |
| Entry token | USDT (0.10 per paid play) |
| Protocol fee | 20% of each entry (the rest funds the pool) |
| Payout model | Push — the operator calls settle(day, mode, winner, tokens) and the prize leaves for the winner's wallet in that same transaction. There is no separate claim step. |
settle only pays a wallet that actually has a recorded play for that day/mode on-chain
(played[day][mode][winner]), and rollover moves an unplayed pool forward untouched so a quiet
day never drains the prize. A seeding job tops each mode's pool up to a floor of 0.30 USDT so
the lobby never shows an empty pot.
Contract source lives in contracts/src/TypeRushGameV3.sol; see contracts/README.md for the
Foundry build/test/deploy workflow.
The live ranking for the open round is read from the same table the settlement robot uses
(v3_results, filtered by the contract's own currentDay()), so what the UI shows and what the
contract will actually pay always agree. Each player is ranked by their best race of the day; no
wallet address is ever sent to the browser — only an opaque per-round identifier, since who played
is already public on-chain. Historial and Perfil also show past rounds and a wallet's own results
history.
NEXT_PUBLIC_PRIVY_APP_ID is configured; without
it the app simply runs on MiniPay + external wallets.Every race, free or paid, is backed by a signed on-chain transaction, and scoring is fully server-authoritative:
play(mode, token) on the contract./api/plays reads the transaction receipt and only accepts a PlayRecorded log emitted by the
game contract itself — player, day, mode and free/paid all come from that log, never from the
client. Only after that check does the server hand back the passage to type./api/results recomputes WPM/accuracy/score from the stored passage, with plausibility clamps
(WPM ceiling, typed length can't exceed the passage, elapsed time is clamped to the race length,
plays expire).lib/settleV3.ts, invoked by /api/cron/settle-v3 on a Vercel cron
(00:10 / 00:25 / 00:45 UTC — 7:10 / 7:25 / 7:45 p.m. Colombia) and mirrored by a GitHub Actions
backup (settle-v3.yml, scripts/settle-v3.mjs). It picks the day's #1 per mode from
v3_results, calls settle() (or rollover() if nobody played), and tracks each attempt's state
(pending/processing/broadcast/paid/failed/rollover) so a transaction that was sent but not yet
confirmed is never retried as if it failed.scripts/seed-v3.mjs (GitHub Actions workflow seed-v3.yml, hourly) tops up
each mode's USDT pool to the floor once the previous day is settled. It only ever tops up — running
it more than once cannot add money twice.contracts/)next/fontnpm install # first time only
npm run dev # http://localhost:3000
By default the app is fail-closed like production: it expects a real wallet signature and a
configured Supabase project. To try a race locally without either, copy .env.example to
.env.local and set NEXT_PUBLIC_APP_ENV=development — races then run with no charge, no
ranking and no signing (lib/devPractice.ts). Never set this in a deployed environment: it would
let anyone play for free.
Build / type-check:
npm run build
Lint:
npm run lint
Unit tests (no external dependencies) and end-to-end checks:
npm test
npm run test:e2e
MiniPay requires HTTPS and a real device (emulators don't work). Expose your local server:
npx ngrok http 3000
Open the HTTPS ngrok URL on a phone with MiniPay installed, in Developer Mode → Use Testnet/Load
Test Page — the wallet injects window.ethereum automatically.
app/
layout.tsx — fonts, metadata, viewport
page.tsx — lobby + game states (idle → countdown → racing → finished)
historial/ — past rounds + winners history
perfil/ — wallet, alias, preferences, personal results
api/ — plays, results, ranking, history, settlement cron, welcome gas
components/
lobby/ — daily challenge card, leaderboard preview, how-to-play
profile/ — profile card, wallet balances, prizes, activity
CountdownScreen · RaceScreen · TypeField · Track · StatBlock · ResultScreen
RoundRanking · FullRanking · PlayV3Button · ClaimBanner · AppShell · BottomNav
hooks/
useTypeRush.ts — game state machine
useModeRanking.ts — live ranking of the open round
usePrizePools.ts — on-chain pool amounts + countdown to the daily close
lib/
i18n/ — UI language (independent from the typing mode)
game.ts — pure scoring logic + local best-score storage
passages.ts — modes, challenges and passage text
contractsV3.ts · playV3.ts · poolsV3.ts · settleV3.ts — GameV3 wiring
gamePeriod.ts — the daily reset window
winners.ts · leaderboard.ts · history.ts · roundRanking.ts
wallet.ts · walletSession.ts · operator.ts · supabase.ts
scripts/
settle-v3.mjs · seed-v3.mjs — the settlement and seeding robots
contracts/ — Foundry project: TypeRushGameV3 (active contract)
supabase/ — SQL schema, applied by hand in the Supabase SQL editor
Made with 💚 for the Celo / MiniPay ecosystem.