Card Protocol

A deck nobody
can stack.

Card Protocol hands out shuffles and draws through a two-party commit-reveal exchange, so no dealer and no player can steer a hand alone. Publish the seed and anyone can redeal it to check the result.
Running on Robinhood Chain

0.000025
ETH
Cost per draw
~1-3
seconds
Time to reveal
52
cards
Full deck
Robinhood Chain
network
Where it's live

Why Card Protocol

Four things you get for free

Plug into CardEntropy instead of building your own randomness stack from scratch.

No single party controls the deck

A dealer's hash-chain reveal gets mixed with your own client-side randomness before any card is drawn. Neither side can steer a hand by itself.

Check the math yourself

A reveal is just a value anyone can hash and compare against what was committed. Recompute a shuffle from its seed and you get the same hand, every time.

A real SDK, not just a spec

A typed TypeScript client, a one-function Solidity interface (ICardConsumer), and a working reference contract to copy from.

Not locked to one chain

The contracts, the keeper, and this site all take their target chain as configuration, not as something baked into the code.

How it works

Request, reveal, deal

Usually settles in a few seconds. Miss the window entirely and your fee comes back automatically.

01

Place the request

Your contract calls requestDraw() with a fresh random value and pays the dealer's posted fee. Nothing shows up within 90 seconds? Call refundRequest() and get the fee back.

02

The dealer turns their card

Whoever gets there first - usually the Dealer keeper, but reveal submission is open to anyone - posts the next link in the dealer's hash chain.

03

Your contract gets dealt in

CardEntropy checks the reveal, mixes it with your random value, shuffles a 52-card deck from the result, and calls cardCallback() with the cards.

Get dealt in

One callback. That's the integration.

MyCardGame.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

import {ICardConsumer} from "card-protocol/ICardConsumer.sol";

contract MyCardGame is ICardConsumer {
    ICardEntropy public immutable cardEntropy;

    constructor(address entropy) {
        cardEntropy = ICardEntropy(entropy);
    }

    function dealHand(address dealer, bytes32 userRandom) external payable {
        cardEntropy.requestDraw{value: msg.value}(
            dealer, userRandom, 200_000, 5
        );
    }

    function cardCallback(uint64 seq, address, uint8[] calldata cards)
        external override
    {
        // cards[i] is 0-51: rank = id % 13, suit = id / 13
    }
}

Ready to deal your first hand?

Read the integration guide or drop into the SDK reference.