> ## Documentation Index
> Fetch the complete documentation index at: https://docs.grapl.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Gacha and token bags

> Local paid entries, reserved inventory and three-prize delivery.

The local game accepts GEM or LocalUSD and delivers **three ERC-20 prizes** from pre-funded inventory. It is separate from the app's animated gacha and sample balances.

<Warning>
  The game and randomness adapter only deploy on chain 31337. The operator
  chooses entropy; this is not VRF or fair production randomness. The local game
  is not ready to accept real paid entries.
</Warning>

## Two entry methods

<Tabs>
  <Tab title="Pay with GEM" icon="gem">
    Grant a limited benefit allowance to the game through the reserve.
    `spinWithGems(minimumDebit, deadline)` burns the configured GEM amount and
    sends the reference debit to the game. GEM itself never transfers.
  </Tab>

  <Tab title="Pay with LocalUSD" icon="coins">
    Approve the game's LocalUSD spending, then call `spinWithCash()`. It
    receives the configured cash price. LocalUSD is an 18-decimal fixture, not
    USDC or guaranteed dollars.
  </Tab>
</Tabs>

The fixture costs **1 GEM or 1 LocalUSD**, independent of frontend simulation prices. Combining a GEM discount with cash is not implemented. Payment, inventory reservation and request creation succeed or revert together.

## From entry to delivery

```mermaid theme={null}
flowchart TD
  Entry[Pay LocalUSD or consent to GEM burn] --> Lock[Lock worst-case inventory]
  Lock --> Request[Create pending spin and entropy request]
  Request --> Operator[Local operator supplies entropy]
  Operator --> Select[Select three prizes]
  Select --> Deliver[Transfer tokens and emit bag events]
```

<Steps>
  <Step title="Fund inventory first">
    An immutable table identifies each token, amount and GRAPL reference value.
    The fixture holds ORBIT and SORBIT. A pending spin locks three times each
    prize amount, covering any possible three-slot outcome.
  </Step>

  <Step title="Accept the request atomically">
    Insufficient unlocked inventory reverts the entry, including payment or
    burn. Reserved inventory cannot fund another spin. Entry does not
    automatically buy winning tokens from a market.
  </Step>

  <Step title="Fulfill once">
    The configured adapter returns operator-selected entropy. Each slot hashes
    entropy, request ID and slot, then selects by modulo prize count. Repeated
    and unauthorized callbacks revert; a prize token can repeat in one bag.
  </Step>

  <Step title="Deliver tokens">
    The game marks fulfillment, releases worst-case locks and transfers prizes
    to the recorded player. `PrizeDelivered` records quantities and reference
    values; `BagDelivered` records their sum. Transfer failure rolls back
    fulfillment.
  </Step>
</Steps>

## Reference value is not a market quote

Configured GRAPL prize values are not live USD prices or guaranteed liquidation values. Odds, inventory funding and promotional value need an approved economic model. No automatic launch contribution percentage has been finalized.

## Pending requests and production gaps

Fulfillment works during a game pause, but accepted local requests have no timeout, cancellation or refund if the operator never responds. Production needs secure randomness, recovery handling, budgets, approved odds and independent review.

The app's animation changes fixture state only. It neither chooses an onchain outcome nor confirms delivery. Compare environments under [availability](/reference/availability).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.