RISE Logo-Light

Setup

Initialize the project, install dependencies, and configure your development environment

Project Setup

We'll build this as a monorepo with two main parts: a Foundry smart contract project and a Next.js frontend/backend.

Create Project Structure

mkdir vrf-rps && cd vrf-rps

Initialize Foundry Project

forge init foundry-project
cd foundry-project

This creates a Foundry project with the standard layout:

  • src/ for contracts
  • test/ for tests
  • script/ for deployment scripts
  • foundry.toml for configuration

Initialize Next.js Project

Return to the root directory and create the Next.js app:

cd ..
bunx create-next-app@latest . --typescript --tailwind --app --no-src-dir

Select the following options:

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

If you've completed another tutorial, you can select No, reuse previous settings to skip configuration.

Install Dependencies

Install the required packages for blockchain interaction and wallet integration:

bun add viem wagmi rise-wallet @tanstack/react-query

Package breakdown:

  • viem: Ethereum library for contract interaction
  • wagmi: React hooks for Ethereum
  • rise-wallet: RISE Wallet connector for gasless transactions
  • @tanstack/react-query: Async state management (required by wagmi)

Install shadcn/ui

Initialize shadcn/ui in your project:

npx shadcn@latest init
yarn dlx shadcn@latest init
pnpm dlx shadcn@latest init
bun x shadcn@latest init

When prompted, select these options:

  • Style: New York
  • Base color: Neutral
  • CSS variables: Yes

Then add the required components:

npx shadcn@latest add button dropdown-menu
yarn dlx shadcn@latest add button dropdown-menu
pnpm dlx shadcn@latest add button dropdown-menu
bun x shadcn@latest add button dropdown-menu

This installs the Button and Dropdown Menu components with all necessary dependencies.

Environment Configuration

Create a .env.local file in the root directory:

touch .env.local

Add your sponsor wallet private key (this account pays for VRF requests):

DEV_PRIVATE_KEY=0x...your_private_key_here

Security: Never commit .env.local to git. Make sure it's in your .gitignore. This should be a burner wallet with only testnet funds.

Update .gitignore

Ensure your .gitignore includes:

# Environment
.env.local

# Foundry
foundry-project/out
foundry-project/cache
foundry-project/broadcast

Project Structure

Your project should now look like this:

vrf-rps/
├── foundry-project/
│   ├── src/
│   ├── test/
│   ├── script/
│   └── foundry.toml
├── src/
│   └── app/
│       ├── page.tsx
│       ├── layout.tsx
│       └── api/
│           └── route.ts (we'll create this)
├── .env.local
├── package.json
└── next.config.ts

Configuration Files

Wagmi Configuration

Create src/config/wagmi.ts:

import { http, createConfig } from 'wagmi'
import { Chains, RiseWallet } from "rise-wallet"
import { riseWallet } from "rise-wallet/wagmi"

// RISE Wallet connector with default config
export const rwConnector = riseWallet(RiseWallet.defaultConfig)

// Wagmi configuration for RISE Testnet
export const config = createConfig({
  chains: [Chains.riseTestnet],
  connectors: [rwConnector],
  transports: {
    [Chains.riseTestnet.id]: http("https://testnet.riselabs.xyz")
  }
})

Provider Setup

Create src/context/index.tsx:

"use client"

import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { WagmiProvider } from 'wagmi'
import { config } from '@/config/wagmi'
import { ReactNode, useState } from 'react'

export function Providers({ children }: { children: ReactNode }) {
  const [queryClient] = useState(() => new QueryClient())

  return (
    <WagmiProvider config={config}>
      <QueryClientProvider client={queryClient}>
        {children}
      </QueryClientProvider>
    </WagmiProvider>
  )
}

Update Root Layout

Modify src/app/layout.tsx:

import type { Metadata } from "next"
import { Providers } from "@/context"
import "./globals.css"

export const metadata: Metadata = {
  title: "VRF Rock Paper Scissors",
  description: "Onchain RPS with RISE VRF",
}

export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html lang="en">
      <body>
        <Providers>
          {children}
        </Providers>
      </body>
    </html>
  )
}

Constants Setup

Create src/constants/index.ts (we'll populate this after deploying the contract):

// Contract address (update after deployment)
export const RPS_ADDRESS = "0x..." as const

// Contract ABI (update after compilation)
export const ABI = [] as const

Next Steps

Your development environment is ready! Next, we'll write and deploy the smart contract with VRF integration.

Make sure you have some testnet ETH in your sponsor wallet address. Get free testnet ETH from RISE Faucet.