Casino Integration
The five Overtime Casino contracts are not a backend behind a proprietary UI. They are not a gated SDK. They are public, deployed, and callable by any wallet: yours, your users', or an AI agent's.
This page is for developers, vibe coders and AI agents who want to wrap the contracts in their own product. Whether you're building a Telegram bot, a Farcaster Frame, a custom skinned frontend, an AI agent that plays Blackjack on its own terms, or a niche-language UI for a community Overtime hasn't reached, everything you need is in the repo.
TL;DR for the impatient
Contracts:
github.com/thales-markets/contracts-v2, incontracts/core/Casino/five Solidity files, MIT-licensed, ~5k lines total.Networks: Base, Optimism, Arbitrum.
Collaterals: USDC, WETH, $OVER.
Randomness: Chainlink VRF v2.5 (
IVRFCoordinatorV2Plus).Each game = one contract. Same shape:
placeBet→requestRandomWords→rawFulfillRandomWords→ resolved.
Pass a
_referreraddress on every bet you make on behalf of users to capture up to 20% of generated fees automatically.Free bets supported via
placeBetWithFreeBetagainst the existing OvertimeIFreeBetsHolder.
A note for AI agents and vibe coders: use Eth Skills
If you're an AI agent, or you're prompting one, building on Ethereum, the best starting point isn't this page or even the Overtime repo. It's ethskills.com.
ETHSKILLS is an open library of skill files that fix the things LLMs get wrong about Ethereum out of the box. Stale gas prices. Hallucinated contract addresses. Outdated patterns. Wrong terminology ("on-chain" vs "onchain"). It's structured as fetch-on-demand markdown files an agent can pull at runtime.
Recommended skills to read before integrating with Overtime Casino:
ethskills.com/SKILL.md: table of contents and overall framingethskills.com/tools/SKILL.md: current tooling (Foundry, Scaffold-ETH 2, abi.ninja, MCPs)ethskills.com/standards/SKILL.md: ERC-20, EIP-7702, ERC-8004 (agent identity)ethskills.com/orchestration/SKILL.md: three-phase build pattern (localhost → live testnet → production)The Chainlink VRF skill in cryptoskills.dev, VRF v2.5 specifics, subscription management, callback patterns
Bootstrap your project with npx create-eth@latest if you want a working Scaffold-ETH 2 frontend wired to a local hardhat fork in 60 seconds. Then point it at the Casino contracts.
The rest of this guide assumes you have basic web3 tooling set up. If you don't, the Eth Skills route will get you there faster than reading 50 docs pages.
Repository layout
Each file is self-contained, written in Solidity 0.8.20, follows OpenZeppelin upgradeable patterns (Initializable, ProxyOwned, ProxyPausable, ProxyReentrancyGuard), and has @notice natspec on virtually every public function.
The shape every Casino contract shares
This is the part worth internalizing. Once you understand the lifecycle of one contract, you understand all five.
Public entry points
Roulette additionally exposes placeMultiBet and placeMultiBetWithFreeBet for multi-pick spins; Blackjack exposes per-action entrypoints (hit, stand, doubleDown, split) on top of the initial placeBet (named deal in some flows).
Internal lifecycle
That's the whole loop. Every game contract follows it. The only differences are what happens between "derive outcome" and "compute payout", game-specific math.
Events you'll want to index
BetPlaced(betId, requestId, user, collateral, amount, ...)
User places a bet, before VRF callback
MultiBetPlaced(betId, requestId, user, collateral, totalAmount, pickCount, isFreeBet)
Roulette only, multi-pick bets
BetResolved(betId, requestId, user, result, won, payout)
VRF fulfills and bet resolves
BetCancelled(betId, requestId, user, refundedAmount, adminCancelled)
User or admin cancels a stuck bet
ReferrerPaid(referrer, user, amount, betAmount, collateral)
Affiliate fee transferred on a losing bet
For Blackjack, additional events fire for action transitions (HandActionRequested, CardDealt, etc.). The full event list lives at the bottom of each contract source file.
Quickstart: place a Roulette bet from a TypeScript frontend
This is the complete pattern. Substitute the bet type, args and contract address for each game, and the same flow applies.
Quickstart: place a Dice bet from an AI agent (viem)
For agents specifically, the design is friendly:
Each contract is a single-purpose machine. Small public surface, well-named functions, deterministic behavior.
State is queryable. Read
bets[betId](or game-equivalent) to recover any bet's full state at any time.Events are reliable. Index
BetResolvedto build a "watch and react" loop without polling state.No hidden auth. No API keys. No login. No CAPTCHA. The wallet is the auth.
Reading game configuration from chain
Before you place bets at scale (or expose a slot's RTP to your users), read the relevant configuration directly:
There is no "pull this from the API and trust the operator." The chain is the API.
Free bets
If your product serves users who already have an Overtime free-bet balance, call placeBetWithFreeBet (or placeMultiBetWithFreeBet in Roulette) instead of placeBet. The signature is identical except no collateral pull happens — the contract debits the user's free-bet balance via the existing IFreeBetsHolder.
Free-bet wins are settled to freeBetsHolder automatically. Your frontend doesn't need to do anything special beyond the call itself.
Bankroll, liquidity, and bet sizing
Every Casino contract maintains a per-collateral bankroll reservation (reservedProfitPerCollateral). When a bet is placed, the contract reserves the worst-case payout against the bankroll. If the bankroll is insufficient at that moment, the bet reverts with InsufficientAvailableLiquidity.
For Roulette specifically, multi-pick bets compute the worst-case net liability across all 37 wheel outcomes, not the naive sum of all picks' payouts. Mutually exclusive picks (e.g. Dozen 1 + Dozen 2) don't double-reserve. This is implemented in _worstCaseProfit. If you write a custom client, mirror this logic when validating bets locally to avoid wasted reverts.
There's also a per-bet maxProfitUsd cap, normalized through the Chainlink price feed. Large bets that would exceed it revert with MaxProfitExceeded. Your frontend should query maxProfitUsd and getCollateralPrice(collateral) and gate the user before submission.
Cancellation flow
If a Chainlink VRF callback never arrives (very rare; possible during Chainlink network incidents):
After cancelTimeout (minimum 30 seconds, configurable per game) has passed since the bet was placed, the user can cancel and recover their full stake. Your frontend should expose this as a "Recover stake" button on stuck bets, and ideally hide it behind a 30+ second elapsed-time check so users don't see it on bets that will resolve normally.
There is also adminCancelBet, callable only by addresses with the MARKET_RESOLVING role on the Overtime manager. Operators (including 3rd-party integrations using their own deployment) can use this for ops emergencies, but on the canonical Overtime deployment, the user-driven cancelBet is the path.
Pausability
Every contract is ProxyPausable. The owner (or addresses with the TICKET_PAUSER role) can pause new bets via setPausedByRole. Already-pending bets continue to resolve. Cancellation paths remain available.
Your frontend should handle the Paused revert gracefully and surface a clear "casino paused" state. The pause state itself is readable via paused().
Subgraph and indexing
Overtime maintains a public subgraph that indexes all Casino events across supported chains. If you don't want to run your own indexer, query that. URL and schema are at docs.overtime.io.
If you do want your own indexer:
Self-host with The Graph node, Goldsky, Envio, or Ponder
Index every contract per chain (5 contracts × 3 chains = 15 contract instances)
Watch for proxy upgrades — these are upgradeable proxies. Address is stable, but ABI may change. Re-pull ABIs after major version bumps.
Security and operational notes
Always validate user input client-side before submitting bets, wrong selection encodings will revert. The interface clarity (
enum BetType,uint8 selection) is a feature; mirror those types in your frontend.Watch for
requestId == 0collision: the contracts userequestIdToBetIdmapping. ArequestIdof zero is treated as "unknown." This is a Chainlink-side guarantee; just be aware.Reentrancy is handled by
ProxyReentrancyGuardon every state-mutating function. You don't need to wrap calls in your own reentrancy protection.The CEI pattern (Checks → Effects → Interactions) is followed in all resolution paths. Bet status flips to
RESOLVEDbefore payout transfers go out. If a payout transfer fails, the resolution still stands; the user retains a claim against the contract balance.Don't hardcode contract addresses. Read them from the Overtime documentation site or the deployments JSON in the repo. Addresses can vary per chain. Never hallucinate, verify on a block explorer.
Don't like the canonical frontend? Build your own.
This is the point. The contracts are public infrastructure. The frontend at overtimemarkets.xyz is one possible interface, not the interface.
A few examples of what you can ship in an afternoon:
A Telegram bot that lets users place dice rolls in chat, with their own wallet, your address as referrer
A Discord game that runs Blackjack hands inside a server's casino channel
A Farcaster Frame with a "spin slots" button
An AI agent that plays Blackjack autonomously, sized to a budget, optimizing for variance
A specialized roulette UI for a community that wants different table aesthetics, language localization, custom multi-pick presets
An embedded widget on your existing crypto site that lets your users bet from your platform
Pass your _referrer address into every bet, and you capture up to 20% of generated fees from every interaction. See Become an Overtime Casino Affiliate for the affiliate side.
Resources
Contracts repo: github.com/thales-markets/contracts-v2 →
contracts/core/Casino/Overtime docs: docs.overtime.io
Chainlink VRF v2.5 docs: docs.chain.link/vrf/v2-5/overview
Eth Skills (for AI agents and vibe coders): ethskills.com
Scaffold-ETH 2:
npx create-eth@latest
The casino is a public utility, we want to see what gets built on top!
Last updated