SpinDrop Documentation

Everything you need to deploy, customize, and manage your SpinDrop prize wheel.

01 Overview

SpinDrop is a complete on-chain spin-the-wheel giveaway tool. Deploy your own branded token, configure prizes, and let users spin to win — all fully on-chain with no backend required.

Tech Stack

What You Get

02 Requirements

Before you begin, make sure you have the following ready:

Tip: Use a dedicated deployer wallet. Never use your main wallet's private key.

03 Quick Start

Get up and running in under 10 minutes. Follow these steps in order:

  1. cd contracts && npm install — install contract dependencies
  2. Create contracts/.env and add your PRIVATE_KEY
  3. npx hardhat compile — compile the smart contracts
  4. npx hardhat run scripts/deploy.js --network bscTestnet — deploy to BSC Testnet
  5. cd frontend && npm install — install frontend dependencies
  6. Create frontend/.env from .env.example and set your VITE_REOWN_PROJECT_ID, VITE_TOKEN_ADDRESS, and VITE_WHEEL_ADDRESS
  7. npm run build — build the production frontend
  8. Upload the dist/ folder to your hosting provider

Note: The deploy script prints both contract addresses to your terminal. Copy them immediately.

04 Environment Variables

contracts/.env

contracts/.env
PRIVATE_KEY=your_wallet_private_key_here
ALCHEMY_KEY=your_alchemy_api_key_here

frontend/.env

frontend/.env
VITE_REOWN_PROJECT_ID=your_reown_project_id_here
VITE_TOKEN_ADDRESS=0xYourSpinTokenAddress
VITE_WHEEL_ADDRESS=0xYourSpinWheelAddress
VITE_EXPLORER_URL=https://testnet.bscscan.com
VITE_RPC_URL=https://data-seed-prebsc-1-s1.binance.org:8545
VITE_FREE_SPINS_ENABLED=true

05 Reown Project ID

Reown (formerly WalletConnect) provides the wallet connection infrastructure. You need a free Project ID:

  1. Go to cloud.reown.com
  2. Create a free account (email or social login)
  3. Click "Create a new project" from the dashboard
  4. Copy the Project ID shown on the project settings page
  5. Paste it into frontend/.env as VITE_REOWN_PROJECT_ID

Free tier is more than sufficient for most projects. No credit card required.

06 Deploy Contracts

Make sure you have compiled the contracts first (npx hardhat compile) and that your contracts/.env is configured. Then run the deploy command for your target network:

Network Command
BSC Testnet npx hardhat run scripts/deploy.js --network bscTestnet
BSC Mainnet npx hardhat run scripts/deploy.js --network bscMainnet
Ethereum npx hardhat run scripts/deploy.js --network ethereum
Polygon npx hardhat run scripts/deploy.js --network polygon
Arbitrum npx hardhat run scripts/deploy.js --network arbitrum
Base npx hardhat run scripts/deploy.js --network base

After deployment, the script will print two contract addresses to the terminal:

SpinToken deployed to: 0x1234...abcd
SpinWheel deployed to: 0x5678...efgh

Copy both addresses — you will need them in the next step.

Important: Ensure the deployer wallet has enough native gas tokens on the target network before running the deploy script.

07 Update Frontend

After deploying the contracts, update frontend/.env with your deployed addresses and network settings:

frontend/.env
VITE_TOKEN_ADDRESS=0xYOUR_DEPLOYED_TOKEN_ADDRESS
VITE_WHEEL_ADDRESS=0xYOUR_DEPLOYED_WHEEL_ADDRESS
VITE_EXPLORER_URL=https://bscscan.com
VITE_RPC_URL=https://bsc-dataseed1.binance.org

Replace the placeholder addresses with the actual addresses printed by the deploy script.

Change Network

If you are targeting a different chain (not BSC), update the networks import in frontend/src/lib/contracts.ts:

frontend/src/lib/contracts.ts
import { bsc } from "@reown/appkit/networks";  // or polygon, arbitrum, base, mainnet
export const networks = [bsc];

Then set the matching VITE_EXPLORER_URL and VITE_RPC_URL in your .env file.

08 Customize Wheel Segments

To customize the prizes and their probabilities, edit the segment configuration in contracts/scripts/deploy.js.

Segment Types

Weights

Each segment has a weight that controls its probability relative to other segments. A higher weight means that segment is more likely to be selected.

For example, if you have three segments with weights [2, 5, 10], their probabilities are approximately 12%, 29%, and 59% respectively.

Constraints

Tip: After changing segments, you must redeploy or call setSegments on the deployed contract to apply changes.

09 Token Branding

To change the name, symbol, or initial supply of the token, edit contracts/contracts/SpinToken.sol:

SpinToken.sol
// Change the token name
"SpinDrop Token"  →  "Your Token Name"

// Change the token symbol
"SPIN"  →  "YOUR"

// Change the initial supply (default: 1,000,000 tokens)
1_000_000  →  5_000_000

The token has a max supply cap of 1 billion tokens to prevent infinite minting.

After making changes, recompile and redeploy:

npx hardhat compile
npx hardhat run scripts/deploy.js --network yourNetwork

10 Free Spins

By default, SpinDrop gives every connected wallet one free spin per day. After using their free spin, users must wait for the cooldown to expire or pay SPIN tokens. This feature is fully optional and can be disabled.

How It Works

Disabling Free Spins

To disable free spins entirely so users must always pay SPIN tokens:

Option 1: Frontend only (hides the free spin UI, but the contract still allows them)

frontend/.env
VITE_FREE_SPINS_ENABLED=false

This removes the free spin badge and countdown timer from the interface. Users will only see the paid spin option. Rebuild with npm run build after changing.

Option 2: On-chain (fully disables free spins at the contract level)

Set the free spin cooldown to an extremely high value so canSpinFree always returns false:

npx hardhat console --network yourNetwork

const wheel = await ethers.getContractAt("SpinWheel", "0xYOUR_WHEEL_ADDRESS");
// Set cooldown to ~100 years (effectively disabling free spins)
await wheel.setFreeCooldown(3153600000);

Option 3: Both (recommended for production)

Use both options together: disable on the frontend for a clean UI, and disable on-chain so even direct contract calls cannot get free spins.

Re-enabling Free Spins

To re-enable free spins:

  1. Set VITE_FREE_SPINS_ENABLED=true in frontend/.env and rebuild
  2. Set a normal cooldown on-chain: await wheel.setFreeCooldown(86400) (24 hours)

Demo mode: The default configuration gives one free spin per 24 hours. This is a good setting for demos and live previews, as it lets visitors try the wheel without needing tokens.

11 Spin Cost & Cooldown

Configure the cost of paid spins and the cooldown between free spins by editing contracts/scripts/deploy.js:

contracts/scripts/deploy.js
const SPIN_COST = hre.ethers.parseEther("10");  // 10 SPIN tokens per paid spin
const FREE_COOLDOWN = 86400;                     // 24 hours in seconds

Common Cooldown Values

Value (seconds) Duration
3600 1 hour
21600 6 hours
43200 12 hours
86400 24 hours (default)
604800 7 days

Note: You can also change the spin cost and cooldown via the admin panel after deployment.

12 UI Colors & Theming

Customize the look and feel of the frontend by editing CSS custom properties in frontend/src/index.css:

frontend/src/index.css
:root {
  --bg-base: #0b0a14;       /* Page background */
  --gold: #ffd700;           /* Primary accent */
  --cyan: #00f0ff;           /* Secondary accent */
  --purple: #a855f7;         /* Tertiary accent */
  --text-1: #f0ead8;         /* Primary text */
  --text-2: #8a7d6a;         /* Secondary text */
  --font-display: "Orbitron"; /* Display font */
  --font-body: "Exo 2";      /* Body font */
}

Wallet Modal Accent

Update the wallet modal accent color in frontend/src/main.tsx:

frontend/src/main.tsx
themeVariables: { "--w3m-accent": "#a855f7" }

Background Image

Replace frontend/public/images/casino-bg.jpg with your own image. Recommended resolution is 2752x1536 or similar 16:9 aspect ratio.

After changing theme values, rebuild the frontend with npm run build and re-upload the dist/ folder.

13 Deploy Frontend

The frontend builds to a static dist/ folder that can be hosted anywhere. Below are instructions for the most popular options.

Vercel

  1. Install the Vercel CLI: npm i -g vercel
  2. Build the frontend: cd frontend && npm run build
  3. Deploy: vercel deploy --prod

Netlify

  1. Build the frontend: cd frontend && npm run build
  2. Go to netlify.com/drop and drag the dist/ folder onto the page

cPanel

  1. Build the frontend: cd frontend && npm run build
  2. Open File Manager in cPanel and navigate to public_html
  3. Upload the contents of the dist/ folder (not the folder itself) into public_html

Important: Make sure index.html ends up in the root of your hosting directory, not inside a subfolder.

SPA Routing

For single-page application routing, add a redirect rule so all paths serve index.html:

Vercel — vercel.json
{
  "rewrites": [{ "source": "/(.*)", "destination": "/index.html" }]
}
Netlify — _redirects
/*  /index.html  200

14 Admin Guide

The deployer wallet is automatically set as the contract admin. The Admin panel is visible in the app when connected with the admin wallet — look for the gear icon in the top bar.

Admin Panel Features

Update Segments After Deployment

To change the wheel segments after deployment, use the Hardhat console or a custom script:

npx hardhat console --network yourNetwork

const wheel = await ethers.getContractAt("SpinWheel", "0xYOUR_WHEEL_ADDRESS");
await wheel.setSegments([...newSegments]);

15 Smart Contract Security

SpinDrop contracts are built with multiple layers of security using battle-tested OpenZeppelin libraries:

Events

The contracts emit events for all key operations, making on-chain activity fully transparent:

Tests

The contracts include 43 passing tests covering all functionality including edge cases, access control, and error conditions.

Note on randomness: SpinDrop supports both block.prevrandao for instant on-chain randomness and optional Chainlink VRF v2.5 for provably fair, verifiable randomness. See Section 15 for VRF setup instructions.

17 Troubleshooting

"Wallet not connecting"

Verify that VITE_REOWN_PROJECT_ID is set correctly in frontend/.env. After updating the env file, rebuild with npm run build and redeploy.

"Transaction failed"

Ensure the connected wallet has enough native gas tokens (BNB, ETH, MATIC, etc.) and that you are on the correct network matching where the contracts are deployed.

"Wheel not configured"

The deploy script must call setSegments to configure the wheel. If segments are missing, run the deploy script again or manually call setSegments on the contract.

"Insufficient prize pool"

The wheel contract does not have enough tokens to pay out prizes. Deposit more tokens via the Admin panel or by calling depositTokens on the contract.

"Free spin on cooldown"

The free spin cooldown has not expired yet. The default is 24 hours. Wait for the cooldown period to pass, or adjust the FREE_COOLDOWN value and redeploy.

"Admin panel not visible"

The admin panel is only visible when connected with the deployer/owner wallet. Make sure you are connecting with the same wallet that deployed the contracts.

"Prize not awarded"

Check the prize pool balance. The contract emits a PrizeNotAwarded event when the balance is insufficient to cover the prize amount. Deposit more tokens to resolve this.

"Contract paused"

The admin has paused the contract. Connect with the admin wallet and unpause the contract via the Admin panel.

Build errors

Make sure you are running Node.js 18 or later. Try deleting node_modules and package-lock.json, then run npm install again from scratch.

Back to Top