OhMyGame
OhMyGame은 AI로 게임을 만들 수 있는 오픈소스 스튜디오로, 디자인·구축·플레이테스트·출판을 하나의 앱에서 모델 키와 함께 수행합니다
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기메이커가 쓴 소개는 위의 한 줄이 전부입니다. 더 자세한 내용은 저장소 README에서 읽을 수 있습니다. 저장소 README ↗
README 전체를 불러오는 중입니다.
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.