# Setup (/docs/cookbook/reaction-time-game/setup)

import { Tabs, Tab } from 'fumadocs-ui/components/tabs';
import { Callout } from 'fumadocs-ui/components/callout';

## Project Setup

### Create a New Next.js Project

First, create a new Next.js application with TypeScript:

<Tabs items={['npm', 'yarn', 'pnpm', 'bun']} groupId="package-manager">
  <Tab value="npm">
    ```bash
    npx create-next-app@latest reaction-time-game
    ```
  </Tab>

  <Tab value="yarn">
    ```bash
    yarn create next-app reaction-time-game
    ```
  </Tab>

  <Tab value="pnpm">
    ```bash
    pnpm create next-app reaction-time-game
    ```
  </Tab>

  <Tab value="bun">
    ```bash
    bun create next-app reaction-time-game
    ```
  </Tab>
</Tabs>

When prompted, select these options:

* Use recommended Next.js defaults: **No, customize settings**
* TypeScript: **Yes**
* Linter: **None**
* React Compiler: **Yes**
* Tailwind CSS: **Yes**
* `src/` directory: **Yes**
* App Router: **Yes**
* Customize import alias: **No**

<Callout type="info">
  If you've completed another tutorial, you can select **No, reuse previous settings** to skip configuration.
</Callout>

Navigate into your project:

```bash
cd reaction-time-game
```

### Install Dependencies

Install the required packages for blockchain integration:

<Tabs items={['npm', 'yarn', 'pnpm', 'bun']} groupId="package-manager">
  <Tab value="npm">
    ```bash
    npm install viem shreds lucide-react
    ```
  </Tab>

  <Tab value="yarn">
    ```bash
    yarn add viem shreds lucide-react
    ```
  </Tab>

  <Tab value="pnpm">
    ```bash
    pnpm add viem shreds lucide-react
    ```
  </Tab>

  <Tab value="bun">
    ```bash
    bun add viem shreds lucide-react
    ```
  </Tab>
</Tabs>

**Package breakdown:**

* `viem` - Lightweight Ethereum client library for transactions
* `shreds` - RISE Shreds SDK for 3ms confirmations
* `lucide-react` - Icon library for UI elements

### Generate a Burner Wallet

Create a burner wallet for testnet transactions. Run this in your terminal:

```bash
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
```

This generates a random private key. Copy the output.

<Callout type="warn" title="Security Warning">
  This is a **burner wallet** for demo purposes. Never use this pattern with real funds or mainnet!
</Callout>

### Set Up Environment Variables

Create a `.env.local` file in your project root:

```bash title=".env.local"
NEXT_PUBLIC_BURNER_KEY=0xYOUR_GENERATED_KEY_HERE
```

Replace `YOUR_GENERATED_KEY_HERE` with the key you just generated (add `0x` prefix).

<Callout type="info">
  The `NEXT_PUBLIC_` prefix makes this variable accessible in the browser. This is acceptable for burner wallets but never use this for production keys!
</Callout>

***

## Configuration

### Configure Fonts

Update your root layout to include arcade-style fonts:

```typescript title="src/app/layout.tsx"
import type { Metadata } from "next";
import { Geist, Geist_Mono, Press_Start_2P, Rajdhani } from "next/font/google";
import "./globals.css";
import { Navbar } from "@/components/Navbar";

const geistSans = Geist({
  variable: "--font-geist-sans",
  subsets: ["latin"],
});

const geistMono = Geist_Mono({
  variable: "--font-geist-mono",
  subsets: ["latin"],
});

const pressStart = Press_Start_2P({
  weight: "400",
  subsets: ["latin"],
  variable: "--font-doom",
});

const rajdhani = Rajdhani({
  weight: ["400", "500", "600", "700"],
  subsets: ["latin"],
  variable: "--font-rajdhani",
});

export const metadata: Metadata = {
  title: "Reaction Time Game - RISE",
  description: "Test your reflexes with blockchain-backed precision",
};

export default function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {
  return (
    <html lang="en">
      <body
        className={`${geistSans.variable} ${geistMono.variable} ${pressStart.variable} ${rajdhani.variable} antialiased`}
      >
        <Navbar />
        {children}
      </body>
    </html>
  );
}
```

**Fonts included:**

* `Press Start 2P` - Retro arcade font for titles
* `Rajdhani` - Modern gaming font for UI
* `Geist` - Clean sans-serif for body text

### Update Global Styles

Replace your `globals.css` with Tailwind imports:

```css title="src/app/globals.css"
@import "tailwindcss";
```

That's it! Tailwind CSS 4 uses a simplified import system.

***

## Building the Navbar

Create a navbar to display wallet information and balance:

```typescript title="src/components/Navbar.tsx"
"use client";

import { useEffect, useState } from "react";
import { createPublicClient, http, formatEther } from "viem";
import { riseTestnet } from "viem/chains";
import { privateKeyToAccount } from "viem/accounts";
import { Copy, Check } from "lucide-react";

const account = privateKeyToAccount(
  process.env.NEXT_PUBLIC_BURNER_KEY as `0x${string}`
);

const publicClient = createPublicClient({
  chain: riseTestnet,
  transport: http(),
});

export function Navbar() {
  const [balance, setBalance] = useState<string>("0");
  const [copied, setCopied] = useState(false);

  useEffect(() => {
    const fetchBalance = async () => {
      const bal = await publicClient.getBalance({
        address: account.address,
      });
      setBalance(formatEther(bal));
    };

    fetchBalance();
    const interval = setInterval(fetchBalance, 10000); // Update every 10s

    return () => clearInterval(interval);
  }, []);

  const copyAddress = async () => {
    await navigator.clipboard.writeText(account.address);
    setCopied(true);
    setTimeout(() => setCopied(false), 2000);
  };

  return (
    <nav className="fixed top-0 left-0 right-0 z-50 bg-black/50 backdrop-blur-md border-b border-purple-500/20">
      <div className="max-w-7xl mx-auto px-6 py-4">
        <div className="flex items-center justify-between">
          <h1 className="text-2xl font-bold text-purple-400 font-[var(--font-doom)]">
            REACTION TIME
          </h1>

          <div className="flex items-center gap-6">
            <div className="text-right">
              <p className="text-xs text-gray-400">Balance</p>
              <p className="text-lg font-semibold text-white">
                {parseFloat(balance).toFixed(4)} ETH
              </p>
            </div>

            <div className="flex items-center gap-2">
              <div className="text-right">
                <p className="text-xs text-gray-400">Burner Wallet</p>
                <p className="text-sm font-mono text-white">
                  {account.address.slice(0, 6)}...{account.address.slice(-4)}
                </p>
              </div>
              <button
                onClick={copyAddress}
                className="p-2 rounded-lg bg-purple-500/20 hover:bg-purple-500/30 transition-colors"
              >
                {copied ? (
                  <Check className="w-4 h-4 text-green-400" />
                ) : (
                  <Copy className="w-4 h-4 text-purple-400" />
                )}
              </button>
            </div>
          </div>
        </div>
      </div>
    </nav>
  );
}
```

**Key features:**

* Displays ETH balance (refreshes every 10 seconds)
* Shows truncated burner wallet address
* Copy address to clipboard with visual feedback
* Arcade-themed styling with purple accents

Now you're ready to implement the game logic in the [next section](/docs/cookbook/reaction-time-game/implementation).
