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

# Frontend Integration

> Set up the ParentProvider and use hooks to access player authentication, balance, and UI controls in your game frontend.

## ParentProvider

The `ParentProvider` component connects your game frontend to the Upside platform and provides authentication.

```javascript theme={null}
import { ParentProvider, useParent, useBalance, useToken, useAuthenticatedFetch } from "@b3dotfun/upside-sdk";

export default function CoinFlipGame() {
  return (
    <ParentProvider>
      <GameContent />
    </ParentProvider>
  );
}

function GameContent() {
  const { token, balance, showWinModal, showLossModal, refetchBalance } = useParent();

  // Or use individual hooks:
  const balance = useBalance(); // number | null
  const token = useToken(); // string | null
  const authFetch = useAuthenticatedFetch(); // fetch with Authorization header

  return (
    <div>
      <h1>Coin Flip</h1>
      <p>Balance: {(balance / 1e18).toFixed(2)} WIN</p>
      <button onClick={() => playGame(token)}>Play</button>
    </div>
  );
}
```

## Available Hooks

### useParent()

Access full context (token, balance, showWinModal, showLossModal, etc.)

**Return Values:**

* `token` (string | null): JWT authentication token for backend calls
* `balance` (number | null): Current WIN token balance in wei
* `showWinModal(wins: string)`: Show win modal
* `showLossModal(loss: string)`: Show loss modal
* `showToast(options)`: Show toast notification
* `showCustomModal(content)`: Show custom modal
* `refetchBalance()`: Request balance refresh from platform

### useBalance()

Get player balance (number | null)

```javascript theme={null}
const balance = useBalance();
```

### useToken()

Get authentication token (string | null)

```javascript theme={null}
const token = useToken();
```

### useRefetchBalance()

Function to request balance refresh

```javascript theme={null}
const refetchBalance = useRefetchBalance();
```

### useCustomModal()

Function to show custom modals

```javascript theme={null}
const showCustomModal = useCustomModal();
```

### useAuthenticatedFetch()

Fetch function with automatic Bearer token header

```javascript theme={null}
const authFetch = useAuthenticatedFetch();
```

## Making API Calls

Use the `useAuthenticatedFetch()` hook to make authenticated requests:

```javascript theme={null}
import { useAuthenticatedFetch, useBalance, useToken } from "@b3dotfun/upside-sdk";

function GameComponent() {
  const authFetch = useAuthenticatedFetch();
  const balance = useBalance();
  const token = useToken();

  const playGame = async prediction => {
    // Authorization header is automatically added
    const response = await authFetch("/api/game/coin-flip", {
      method: "POST",
      body: JSON.stringify({
        playerId: "player-id",
        prediction,
        betAmount: "1000000000000000000", // 1 WIN in wei
      }),
    });

    const data = await response.json();
    return data;
  };

  return (
    <div>
      <p>Balance: {(balance / 1e18).toFixed(2)} WIN</p>
      <button onClick={() => playGame("heads")}>Predict Heads</button>
    </div>
  );
}
```

**How useAuthenticatedFetch() Works:**

* Automatically includes `Authorization: Bearer {token}` header
* Sets `Content-Type: application/json` by default
* Merges additional headers you provide
* Handles token from `useToken()` automatically

## Frontend Example

```javascript theme={null}
import { ParentProvider, useParentContext } from "@b3dotfun/upside-sdk";

export default function CoinFlipGame() {
  return (
    <ParentProvider>
      <CoinFlipContent />
    </ParentProvider>
  );
}

function CoinFlipContent() {
  const { token, balance, playerId } = useParentContext();
  const [gameState, setGameState] = useState("ready"); // ready, playing, won, lost
  const [prediction, setPrediction] = useState(null);
  const [result, setResult] = useState(null);
  const [earnings, setEarnings] = useState(0);

  const playGame = async playerPrediction => {
    setPrediction(playerPrediction);
    setGameState("playing");

    try {
      // Call your backend
      const response = await fetch("/api/game/coin-flip", {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          Authorization: `Bearer ${token}`,
        },
        body: JSON.stringify({
          playerId,
          prediction: playerPrediction,
          betAmount: "100000000000000000", // 1 token in wei
        }),
      });

      const data = await response.json();

      if (data.outcome === "win") {
        setGameState("won");
        setEarnings(data.payout);
      } else {
        setGameState("lost");
        setEarnings(0);
      }

      setResult(data.result);
    } catch (error) {
      console.error("Game error:", error);
      setGameState("error");
    }
  };

  return (
    <div style={{ textAlign: "center", padding: "40px" }}>
      <h1>Coin Flip</h1>
      <p>Balance: {(balance / 1e18).toFixed(2)} WIN</p>

      {gameState === "ready" && (
        <div>
          <button onClick={() => playGame("heads")}>Predict Heads</button>
          <button onClick={() => playGame("tails")}>Predict Tails</button>
        </div>
      )}

      {gameState === "playing" && <p>Flipping...</p>}

      {gameState === "won" && (
        <div>
          <p>🎉 You won! Coin landed on {result}</p>
          <p>+{(earnings / 1e18).toFixed(2)} WIN</p>
        </div>
      )}

      {gameState === "lost" && (
        <div>
          <p>❌ You lost! Coin landed on {result}</p>
          <p>Better luck next time</p>
        </div>
      )}

      {gameState !== "ready" && <button onClick={() => setGameState("ready")}>Play Again</button>}
    </div>
  );
}
```
