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

# Gacha

> Prepare a pull, validate payment, reveal cards and recover interrupted purchases.

Use `createGachaClient` with your app's EOA signer. Public browsing needs no credentials; purchases and wallet-specific history go through your builder-authorized backend. A wallet access token is not required for these gacha operations.

## Browse packs

Call `listGachaMachines().firstPage()` for the catalog and `fetchGachaMachine({ slug })` for the selected pack and its tiers. Display the price and quantity before preparing a purchase. `listGachaMachineContents` provides the published contents.

The API calls a pack a **machine** in SDK method names. The returned `id` identifies the catalog record; `onChainPackId` is the contract's pack ID. Preserve both when validating a purchase.

## Pull a card

<Steps>
  <Step title="Prepare the selected pack">
    Call `prepareGachaPull` with `machineSlug`, `buyerWalletAddress`, `quantity` and the reviewed per-card `expectedPriceInUsdt` as a bigint. Keep the pack IDs, price and quantity from the user's selection for signing validation.

    Preparation checks the selected network, contracts and price before any approval. If the price changed, refresh the selection and ask the user to review it.
  </Step>

  <Step title="Check payment and approval">
    Check the connected wallet and chain, USDT balance, and the token's allowance to Permit2. If an approval is needed, use your wallet library to approve the reviewed amount and wait for its receipt. The wallet needs BNB for this on-chain transaction.
  </Step>

  <Step title="Sign and submit once">
    Call `signGachaPull({ prepared, expected })`, then `submitGachaPull({ pull, onEvent })`. The SDK rechecks the signing context, amount and expiry before prompting.

    Save a pending record before submission. Save `permitFundTxHash` as soon as the stream emits `payment_confirmed`.
  </Step>

  <Step title="Show the result">
    Use stream events to show payment and draw progress. A resolved draw can still be waiting for its buyback window to end before the token reaches the user's wallet.
  </Step>
</Steps>

Keep signing expectations tied to what the user reviewed. Do not replace a mismatched expected price or contract with values from a preparation response just to make signing succeed.

## Recover an interrupted pull

A disconnected stream does not mean payment failed. With the funding hash, read the existing pull:

```ts theme={null}
import {
  getError, getValue, isFailed, type GachaClient,
} from '@renaiss-protocol/client';

export async function recoverPull(
  gacha: GachaClient,
  buyerWalletAddress: string,
  permitFundTxHash: string,
) {
  const result = await gacha.fetchGachaDrawStatus({
    buyerWalletAddress,
    permitFundTxHash,
  });
  if (isFailed(result)) throw new Error(getError(result).detail);
  return getValue(result);
}
```

Persist the wallet, chain, pack, quantity, submission time and funding hash. Refresh `listWalletPulls` and buyback offers after reconciliation. If no hash was received, inspect wallet activity and the pending request before allowing another purchase. An empty history may reflect indexing delay; a new nonce can charge for another pull.

## Buybacks and delivery

`fetchGachaBuybackOffers` returns the wallet's current offers for your builder. Use `createGachaBuyback` and `submitGachaBuyback` to settle selected offers. A batch accepts 1–10 unique, unexpired offers from the same pack and contract. No NFT approval is required for this buyback flow.

Buyback windows vary by pack. Use the returned deadline and status rather than a fixed countdown. After the window closes, token delivery is asynchronous. An expiring offer may race with delivery; refresh offers after a failed settlement.

## Two kinds of history

| Read | Purpose |
| - | - |
| `listWalletPulls` | The wallet's resolved pulls attributed to your builder |
| `listGachaPullHistory` | A pack's public activity feed; draws appear only after their buyback windows close |

Use wallet history and draw status for recovery. Public history deliberately lags active pulls and is not a payment-status check.
