Docs · Architecture

Trust and technology

Architecture

Program, orchestrator, sim, stream and web.

On this page

The big picture

FlySports has five moving parts. The Solana program holds the money and the rules. The orchestrator drives each race through its lifecycle. The simulation works out what happens in a race. The stream broadcasts it. The web app is what you use. A moderated chat runs as a small separate service next to them.

Solana program

An Anchor program (Rust) called fly_racing. On devnet its address is CDV7VxAXMHfVQ3rD9VEviJZgjqkWu9GxM8EmmHE2ho6D. It stores each race in a Race account with a separate token vault, and each bettor's stakes in a Bet account.

Program instructions
InstructionWhat it does
create_raceOpens a race: commit hash, race card, sport, lock slot, number of breeds.
place_betMoves your USDC into the race vault, only before the lock slot.
seed_raceAdds the rollover bonus to the pool, only before lock.
lock_racePermissionless. Stores the lock slot's hash once the slot has passed.
settle_raceOracle reveals the salt. The program verifies it, derives the seed and records the winner and result hash.
cancel_race / expire_raceCancel is admin-only and only before lock. Expire is permissionless and only after a settle timeout.
claim_payoutYou claim your winnings or refund. Closes your bet account and returns its rent.
sweep_rakeSplits the rake between treasury and rollover vault, and returns any bonus not paid out.
close_raceReclaims the rent of a finished race once its vault is empty.

The admin key can create races, rotate keys, pause new races and sweep rake, but cannot move bettor funds. Funds only leave a vault to a bettor's own claim or to the configured treasury and rollover accounts. See what is not guaranteed.

Orchestrator

A standalone Node and TypeScript worker. It runs the race loop: create a race, wait for the betting window, lock, ask the simulation for the result, settle, then sweep the rake and close the race about ten minutes later. It also publishes the public API the web app reads (current race, traces, stats, leaderboard, bet history), and, during the beta, runs the house bettor bots. It is built to fail safe: calls are time-bounded, it takes a single-instance lock, and a race it cannot settle in time expires into refunds rather than sitting stuck.

Simulation

A Python package with a small web service. Given a seed and a race card it generates the course, runs every fly's spiking brain tick by tick, applies physics, hazards and conditions, and returns a trace (every position, event and spike) plus a result hash. It is deterministic and is tested against golden hashes so it reproduces identically across machines. It also offers the endpoints for race results, verification and win-chance tables.

Stream

The /broadcast page is a chrome-free view of the live race, shared on a schedule so everyone sees the same race at the same moment. A streamer process opens it in headless Chromium, captures frames, and uses ffmpeg to make an HLS stream and optionally push to Twitch. The stream shows no odds, pools or betting language, so it is safe to put on Twitch. Betting happens only on the website. A result is never shown to a bettor before it has aired.

Web app

A Next.js app. It reads race state from the orchestrator and sends bets and claims straight to the program from your wallet. It never runs the simulation itself. It replays the recorded trace in 3D, including the brain panel, and calls the simulation's verify endpoint for the Verify button. A built-in devnet faucet mints test USDC and a little SOL.

  • The web app is hosted on Vercel; the backend (orchestrator, simulation, chat) runs in Docker containers on a server.
  • Everything is on Solana devnet during the beta.

Life of a race

  1. The orchestrator picks a race card and commits a salt, then calls create_race.
  2. The betting window opens (about a minute). Bettors call place_bet; the rollover bonus is seeded.
  3. The lock slot passes. lock_race stores the slot hash.
  4. The orchestrator asks the simulation to run the race for the chain-derived seed.
  5. settle_race reveals the salt, the program records the seed, winner and result hash.
  6. The race airs on the broadcast. The bet panel then shows the result.
  7. Winners press Claim (claim_payout). The rake is swept, and the finished race is closed.