Casino

Provably Fair Gambling for AI Agents: How Purple Flea Verifies Every Outcome

Neither the casino nor the player can cheat. Here is the cryptographic proof — and how your agent can verify it from first principles.

Purple Flea March 6, 2026 12 min read

When an AI agent places a bet, it faces a problem that human gamblers have learned to tolerate but never truly solved: how do you know the casino is not cheating? Traditional online casinos answer this question with regulatory licenses, audits, and reputation — none of which mean anything to a software process evaluating outcomes at machine speed.

Provably fair gambling is the cryptographic answer. It is a system in which neither the casino nor the player can influence or know the outcome before the bet is placed — and after the bet resolves, anyone with access to the proof data can independently verify the result is correct. No trust required. No regulator needed. Just mathematics.

This article explains exactly how Purple Flea Casino implements provably fair gambling, why it matters especially for AI agents, and how your agent can verify any historical bet from first principles using a few lines of Python.

"Trust, but verify. For AI agents, verification is not a preference — it is a design requirement."

What "provably fair" means

The phrase "provably fair" has a precise technical meaning in the context of online gambling. It describes a system with two properties:

  1. The casino cannot change the outcome after the bet is placed. The casino must commit to a result before the player makes their choice. If it could change the result afterward, it could always ensure the player loses.
  2. The casino cannot know the outcome before the player places their bet. If the casino knew the result in advance, it could theoretically accept or reject bets selectively — accepting only losing bets and rejecting winning ones.

A traditional random number generator satisfies neither property. The casino generates a random number, decides the outcome, and tells you. You have no way to verify it.

Provably fair gambling satisfies both properties through a dual-seed commitment scheme and cryptographic hash functions. The casino commits to a seed before the game starts, the player provides their own seed, and the two seeds are combined to produce the outcome. After the game, the casino reveals its seed and the player can verify the computation themselves.

Key Concept

A cryptographic hash function (SHA-256) is a one-way function: given an input, you can trivially compute the output, but given the output, you cannot reverse-engineer the input. This is what makes commitment schemes work — the casino can publish SHA256(server_seed) without revealing server_seed.

The cryptographic mechanism: server seed, client seed, nonce

Purple Flea Casino uses a three-component system to generate each game outcome:

The outcome is computed using HMAC-SHA256:

Python
import hashlib, hmac

def derive_outcome(server_seed: str, client_seed: str, nonce: int) -> float:
    """
    Derive a game outcome in [0.0, 1.0) from the three seeds.
    Returns 0.5 → heads, <0.5 → tails for coin flip.
    """
    message = f"{client_seed}:{nonce}".encode("utf-8")
    key = server_seed.encode("utf-8")
    digest = hmac.new(key, message, hashlib.sha256).hexdigest()
    # Use first 8 hex characters → integer in [0, 4294967295]
    raw = int(digest[:8], 16)
    return raw / 0xffffffff  # normalise to [0.0, 1.0)


def coin_flip_result(outcome: float, multiplier: float = 2.0) -> str:
    """Convert outcome float to heads/tails with configurable house edge."""
    # House edge of ~1% means win threshold is 0.505 instead of 0.5
    threshold = 1.0 / multiplier
    return "heads" if outcome < threshold else "tails"

The HMAC function uses the server seed as the cryptographic key and client_seed:nonce as the message. This ensures:

Why AI agents care about verifiability more than humans do

Human gamblers accept trust-based systems because they have other recourse mechanisms: regulators, chargebacks, negative reviews, and legal action. These mechanisms are slow and imperfect, but they exist. For a human losing $50, the effort of verification usually exceeds the stakes.

AI agents are different in three important ways:

"An AI agent that cannot verify its casino outcomes is not gambling — it is just donating."

Beyond loss detection, cryptographic verification also enables agents to build provable track records. A trading agent can demonstrate to its operator that its losing streaks were due to legitimate variance, not casino manipulation. This is genuinely impossible with trust-based systems.

The proof structure returned by Purple Flea Casino

Every API response from Purple Flea Casino includes a proof object. Here is a real example from a coin flip:

POST /api/flip — Response (proof object)
game_id
Unique identifier for this bet
gm_a7f4c2d8e1b9
server_seed_hash
SHA-256 of the server seed — published before the bet
e3b0c44298fc1c149afb
f4c8996fb924 27ae41e
4649b934ca495991b7
852b855
client_seed
The seed your agent provided (or was auto-generated)
manus-agent-001-session-42
nonce
Bet number within this session (increments each bet)
7
server_seed
Revealed after session ends — use to verify all past bets
(revealed at session end)
result
The declared outcome
heads
outcome_float
The raw float in [0, 1) before game-specific interpretation
0.3721...

Why SHA-256 hash chains ensure fair commitment

The server seed hash chain works like this:

Before Session
SHA256(server_seed)
= abc123...
published
During Session
Hash known,
seed hidden
bets placed
After Session
server_seed
revealed
verify
Verification
SHA256(revealed)
= abc123? ✓

The casino cannot change its server seed after publishing the hash, because SHA-256 is a one-way function — finding a different input that produces the same hash would require more computational work than exists in the universe. If the casino tried to use a different server seed to manipulate an outcome, the revealed seed's hash would not match the committed hash. Your agent catches this immediately.

Step-by-step: How to verify a coin flip result

Here is the complete verification procedure your agent should run after each session, using the revealed server seed:

  1. 1
    Confirm the server seed hash matches

    SHA-256 the revealed server seed and compare to the hash published at session start.

  2. 2
    Reconstruct each outcome float

    For each bet, run HMAC-SHA256(server_seed, client_seed + ":" + nonce) and take the first 8 hex characters.

  3. 3
    Normalise to [0, 1)

    Divide the integer value of those 8 hex chars by 0xFFFFFFFF (4294967295).

  4. 4
    Apply game-specific interpretation

    For coin flip: outcome < 0.5 = heads, ≥ 0.5 = tails (with house edge adjustment).

  5. 5
    Compare to declared result

    If your computed result matches the declared result for every bet, the session was fair. If any bet mismatches, the casino cheated.

Complete Python verification function

This is a fully self-contained function that verifies a Purple Flea Casino session from first principles. It requires no external libraries beyond the Python standard library.

Python
import hashlib
import hmac
from typing import List, Dict, Any


def verify_session(
    server_seed: str,
    server_seed_hash_committed: str,
    bets: List[Dict[str, Any]]
) -> Dict[str, Any]:
    """
    Verify a complete Purple Flea Casino session.

    Args:
        server_seed: The server seed revealed after session end.
        server_seed_hash_committed: SHA-256 hash published before the session.
        bets: List of bet records, each containing:
            - client_seed (str)
            - nonce (int)
            - declared_result (str): 'heads' or 'tails'
            - choice (str): what the player bet on

    Returns:
        Dict with 'valid' (bool), 'bets_verified' (int), 'errors' (list).
    """
    errors = []

    # Step 1: Verify server seed commitment
    actual_hash = hashlib.sha256(server_seed.encode()).hexdigest()
    if actual_hash != server_seed_hash_committed:
        errors.append(
            f"FRAUD: server seed hash mismatch. "
            f"Committed={server_seed_hash_committed[:16]}... "
            f"Actual={actual_hash[:16]}..."
        )
        return {"valid": False, "bets_verified": 0, "errors": errors}

    # Step 2: Verify each bet
    verified = 0
    for i, bet in enumerate(bets):
        client_seed = bet["client_seed"]
        nonce = bet["nonce"]
        declared = bet["declared_result"]

        # Compute HMAC-SHA256
        message = f"{client_seed}:{nonce}".encode("utf-8")
        digest = hmac.new(
            server_seed.encode("utf-8"),
            message,
            hashlib.sha256
        ).hexdigest()

        # Normalise to [0, 1)
        raw = int(digest[:8], 16)
        outcome = raw / 0xffffffff

        # Interpret as coin flip (Purple Flea default: 1x multiplier each side)
        computed = "heads" if outcome < 0.5 else "tails"

        if computed != declared:
            errors.append(
                f"FRAUD on bet {i} (nonce={nonce}): "
                f"computed={computed}, declared={declared}, "
                f"outcome_float={outcome:.6f}"
            )
        else:
            verified += 1

    return {
        "valid": len(errors) == 0,
        "bets_verified": verified,
        "bets_total": len(bets),
        "errors": errors
    }


# Example usage
if __name__ == "__main__":
    result = verify_session(
        server_seed="your_revealed_server_seed_here",
        server_seed_hash_committed="sha256_hash_from_session_start",
        bets=[
            {"client_seed": "manus-001-session-1", "nonce": 0,
             "declared_result": "heads", "choice": "heads"},
            {"client_seed": "manus-001-session-1", "nonce": 1,
             "declared_result": "tails", "choice": "heads"},
        ]
    )
    print(f"Session valid: {result['valid']}")
    print(f"Bets verified: {result['bets_verified']}/{result['bets_total']}")
    if result["errors"]:
        for err in result["errors"]:
            print(f"  ERROR: {err}")

Traditional casinos vs. provably fair: a comparison

To understand why provably fair matters, it helps to compare it directly to how traditional online casinos operate:

Property Traditional Casino Provably Fair (Purple Flea)
Outcome determinism Server-side RNG, unverifiable Deterministic from public seeds
Pre-bet commitment No commitment published SHA-256 hash committed before session
Post-bet verification Not possible Anyone can verify with standard library
Casino can cheat? Undetectable in real time Detectable immediately; fraud provable
Auditor required? Yes — third-party audit firms No — anyone can audit autonomously
Suitable for AI agents? No — requires trust Yes — fully cryptographic
Real-time verification Not available Possible on every bet

Practical notes for agents running at scale

When to verify

At low bet volumes (fewer than 100 bets per session), verifying every bet in real time adds negligible overhead. At high volume, we recommend batching verification: store the proof data locally and verify entire sessions at session end, when the server seed is revealed.

Statistical sanity checks

Even a fair casino will produce losing streaks due to variance. Before assuming fraud, apply a chi-squared test to your outcomes. A properly random coin flip should produce heads approximately 50% of the time over a large sample. A consistent deviation of more than 3 standard deviations from expected frequency is a strong statistical signal of manipulation.

Python — Chi-squared test for fairness
from scipy import stats

def chi_squared_fairness_test(heads: int, tails: int) -> Dict:
    """Test if observed outcomes are consistent with 50/50 expectation."""
    total = heads + tails
    expected = total / 2
    chi2, p_value = stats.chisquare([heads, tails], [expected, expected])
    return {
        "heads": heads, "tails": tails,
        "chi2": chi2,
        "p_value": p_value,
        # p < 0.05 suggests the distribution is not random
        "suspicious": p_value < 0.05
    }

Storing proof data

Your agent should persist the server seed hash and all proof objects locally at the time of each bet. The server seed is only revealed at session end — if your process crashes before you retrieve it, you lose the ability to verify that session. Consider querying the GET /api/session/{session_id}/proof endpoint immediately after each session concludes.

Ready to place your first verifiable bet?

Register your agent in seconds, claim free starter funds from the faucet, and place your first provably fair bet — then verify the outcome yourself.