Pull a graded card.
Keep it, or take
the buyback.
Every card in these packs is a real graded collectible, sealed and held in an on-chain pool. You draw with verifiable randomness, sign one transaction from your own wallet, and decide on the spot whether to take the card or the SOL behind it.

A hundred fake cards, backed in devnet SOL. Pull one, keep it or take the buyback, deposit one of your own. Nothing here costs real money.
Open this pack →- 01
The pool quotes itself
Price is read from the pool account: the harmonic mean of what its cards are backed by, plus the creator's surcharge. Never a number this site made up.
- 02
You sign one transaction
It requests the draw at a price cap of your quote plus the pool's slippage. Re-price past the cap and the program refuses rather than overcharge you.
- 03
The draw lands
Randomness is requested on chain in the same transaction and settled within seconds. The request account keeps the value your card was drawn from.
- 04
You decide what happens to it
Keep it and the card moves to your wallet. Take the buyback and the pool pays its bid rate. Where the pool allows it, relist it and earn from every pull until it is drawn again.
Verifiable, requested by the program
Nobody — not the creator, not this site — picks which card you draw or when.
Capped by the transaction you sign
The cap travels with the request. A pool that re-prices mid-flight loses the sale instead of taking more.
None, at any point
The buyer signs and pays from their own wallet. This site holds no keys, no cards and no funds.
- Clone and run it
git clone https://github.com/willmexi/opengacha.git cd opengacha && npm install && npm run dev
Then copy .env.example to .env.local, add your RPC, and npm run dev. SQLite writes itself on first run.
- List your pools
pools.json is the whole storefront: an address, a name, pack art. Make a pool at opengacha.io/create, copy its brief from Manage's API & SDK tab, and paste the address in.
- Read lib/gacha
Every call the site makes: read the pool, quote, request, wait for the draw, settle. No API key and no backend of ours.
- Make it yours
Your domain, your type, your art. Fees split on chain between the pool's creator and the protocol; nothing here can move them.
const pool = await readPool(addr) const req = await requestPull(w, addr, pool, cap) const done = await waitForDraw(req.request, addr) const [c] = await drawnCards(addr, done.requestId) await resolve(w, addr, pool, done, c, meta, "keep")