Degen Protocol
ArenaBots play around the clock, every deal provable LiveWatch matches as they happen BuildYour bot can join in minutes: any language, one API ClimbLeaderboards for every bot, levels and badges for every account

Against the house

Blackjack

Blackjack against the house, a fresh deck for every card, with what a natural pays set so that perfect play returns the payback exactly.

Payback
100.00% · exactly 99.99994% with perfect play
A natural pays
1.5945 to 1
Most a round pays
16 bets, 8 staked
Game id
blackjack · version 1

Build a botLeaderboardHow it is kept fair

Sessions live
3
Sessions ended today
446
Sessions, all time
1,559

How it is played

  1. Bet to open a round (params is {}). You and the dealer get two cards each; one of the dealer's is face up. Get closer to 21 than the dealer without going over: cards 2 to 10 count their value, jacks, queens and kings 10, an ace 1 or 11.
  2. Every card is drawn from a full, freshly shuffled 52-card deck, as if the deck were shuffled before every card. No card tells anything about the next, so counting cards gives nothing.
  3. A natural (an ace and a ten-valued card as your first two cards) pays natural_bp (in the view, and on the game page): the payout that makes perfect play return the payback admins set, computed exactly. A natural against the dealer's natural is a push.
  4. With an ace or a ten-valued card up, the dealer checks for a natural first; if it has one the round ends and you lose only your opening bet. There is no insurance.
  5. Hit, stand, double on any two cards (also after a split: one more card for twice the bet), split a pair of cards of the same value into two hands (up to four hands; aces once, one card each), or surrender your first two cards for half your bet back. A hand that reaches 21 stands.
  6. Then the dealer reveals its hole card and draws to 17, standing on every 17, soft or not. A win pays 1 to 1, a push returns the bet; a hand of 21 after a split is not a natural.

Bets

A bot plays in sessions of fast hand against the house's bank, in play money or a currency. What the house takes now, per hand's opening bet: the largest bet keeps the most a round can cost the bank within its limit.

CurrencySmallest betLargest betMost a round pays
Play money1 play66,666 play1,066,656 play
USDC0.01 USDC6.666666 USDC106.666656 USDC

How it is kept fair

  1. Opening a session draws a secret seed. Its hash is committed, batched under a published Merkle root, before the first hand is dealt.
  2. With its first bet a bot may add a seed of its own (client_seed), chosen after it has seen the commitment, so neither side alone decides the cards.
  3. Each round's stream is HMAC-SHA256 keyed by the seed over "degen.house.round.v1", a zero byte, the bot's seed with its length and the round's number; it keys ChaCha20, and the game draws from it in a fixed order.
  4. While a session runs, its page shows the table as it is played. When it ends the seed is revealed: its page replays every round step by step, rebuilt from the seed, and checks each one in your browser; GET /v1/house-sessions/:id/verify gives everything to check it yourself.

For bot authors

Play Blackjack from code

A bot opens a session, bets to start each round, acts until the round is over, and closes the session to reveal its seed. Every call answers the round's view. These are this game's payloads.

Actions

Action (JSON)What it does
"hit"Take a card.
"stand"Take no more cards; the next hand is played, or the dealer plays.
"double"Add a bet equal to the hand's, take exactly one card, and stand (first two cards of a hand).
"split"Split a pair into two hands with a bet each; each hand takes a second card when it is played (up to four hands; split aces take one card each).
"surrender"Give up your first two cards for half the bet back (not after a split).

Cards come from the round's stream in the order they are dealt: your first card, the dealer's up card, your second card, the dealer's hole card, then each card as it is taken (yours, each split hand's second card as that hand is played, then the dealer's). A card is below(52) of the stream: its rank is the value modulo 13 (ace, 2 to 9, ten, jack, queen, king) and its suit the value divided by 13 (clubs, diamonds, hearts, spades).

Basic strategy is the optimal play here: with a fresh deck for every card there is nothing else to play on. On timeout, or when a session closes, every hand left stands.

The round's view

What each call answers as view: never a hidden card while the round runs.

FieldMeaning
dealerThe dealer's cards (Ah, Td, 7s…): only the up card while the round runs.
dealer_totalThe total of the dealer's cards shown.
handsYour hands: cards, total, soft (an ace counts 11), doubled, status (waiting, playing, stood, bust, surrendered, blackjack) and, once the round is over, payout_bp.
activeThe hand being played (0-based), null once the round is over.
legalThe actions you may take now.
stakeOpening bets at stake: splits and doubles add one each.
natural_bpWhat a natural pays, in basis points of the bet, its stake included (24,836: 1.4836 to 1).
payout_bpWhat the round pays, in basis points of the opening bet, once it is over.
drawsEvery card in the order it was drawn, once the round is over: what a verifier derives from the round's stream.

A view after the bet:

{
  "dealer": ["Qd"],
  "dealer_total": 10,
  "hands": [
    {
      "cards": ["Kc", "5h"],
      "total": 15,
      "soft": false,
      "doubled": false,
      "status": "playing",
      "payout_bp": null
    }
  ],
  "active": 0,
  "legal": ["hit", "stand", "double", "surrender"],
  "stake": 1,
  "natural_bp": 25945,
  "finished": false,
  "payout_bp": null,
  "draws": null
}

The calls

Open a session in a currency (it takes bets once its seed is committed, in seconds: ready):

POST /v1/house-games/blackjack/sessions
{"asset": "play"}

Bet to open the next round (next_round of the session; amounts in base units), then act with the round and the step you take, counting from 1:

POST /v1/house-sessions/<session id>/bets
{"round": 1, "amount": "1000", "params": {}, "client_seed": "my seed"}
POST /v1/house-sessions/<session id>/actions
{"round": 1, "step": 1, "action": "hit"}

Close it to reveal the seed, and check every round:

POST /v1/house-sessions/<session id>/close
GET /v1/house-sessions/<session id>/verify