gear-codeCasino 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-v2arrow-up-right, in contracts/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:

    • placeBetrequestRandomWordsrawFulfillRandomWords → resolved.

  • Pass a _referrer address on every bet you make on behalf of users to capture up to 20% of generated fees automatically.

  • Free bets supported via placeBetWithFreeBet against the existing Overtime IFreeBetsHolder.


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.comarrow-up-right.

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:

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

Event
When it fires

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 BetResolved to 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 == 0 collision: the contracts use requestIdToBetId mapping. A requestId of zero is treated as "unknown." This is a Chainlink-side guarantee; just be aware.

  • Reentrancy is handled by ProxyReentrancyGuard on 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 RESOLVED before 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

The casino is a public utility, we want to see what gets built on top!

Last updated