-- Rounds, bets, and the verification record for every settled outcome. -- -- Seeds are stored so that any round can be re-verified indefinitely. The -- server seed column is NULL until the round settles: revealing it early would -- let a player compute the outcome before betting closes. CREATE TABLE rounds ( id BIGSERIAL PRIMARY KEY, game TEXT NOT NULL, -- 'rocket', 'orbital', 'tower' nonce BIGINT NOT NULL, commitment BYTEA NOT NULL, -- SHA-256 of the server seed server_seed BYTEA, -- revealed only after settlement client_seed BYTEA, -- derived from participants crash_point BIGINT, -- Q32.32 fixed-point opened_at TIMESTAMPTZ NOT NULL DEFAULT now(), locked_at TIMESTAMPTZ, settled_at TIMESTAMPTZ, CONSTRAINT reveal_is_complete CHECK ( settled_at IS NULL OR (server_seed IS NOT NULL AND crash_point IS NOT NULL) ) ); CREATE TABLE bets ( id BIGSERIAL PRIMARY KEY, round_id BIGINT NOT NULL REFERENCES rounds(id), account_id BIGINT NOT NULL REFERENCES accounts(id), stake_msat BIGINT NOT NULL CHECK (stake_msat > 0), -- Set when the player cashes out; NULL means they rode it to the crash. cashout_at BIGINT, -- Q32.32 multiplier payout_msat BIGINT, placed_at TIMESTAMPTZ NOT NULL DEFAULT now(), settled_at TIMESTAMPTZ, UNIQUE (round_id, account_id) ); CREATE INDEX bets_round_idx ON bets (round_id); CREATE INDEX bets_account_idx ON bets (account_id, id DESC); CREATE TABLE scratch_plays ( id BIGSERIAL PRIMARY KEY, account_id BIGINT NOT NULL REFERENCES accounts(id), ticket_id TEXT NOT NULL, nonce BIGINT NOT NULL, commitment BYTEA NOT NULL, server_seed BYTEA NOT NULL, stake_msat BIGINT NOT NULL CHECK (stake_msat > 0), tier_name TEXT NOT NULL, payout_msat BIGINT NOT NULL CHECK (payout_msat >= 0), cells INTEGER[] NOT NULL, played_at TIMESTAMPTZ NOT NULL DEFAULT now() ); CREATE INDEX scratch_account_idx ON scratch_plays (account_id, id DESC); -- Rounds and plays are historical records; they are never rewritten. CREATE TRIGGER scratch_plays_append_only BEFORE UPDATE OR DELETE ON scratch_plays FOR EACH ROW EXECUTE FUNCTION reject_mutation();