Skip to content

Latest commit

Β 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

🎰 Solana Raffle

A comprehensive Solana raffle program built with the Anchor framework, featuring escrow functionality and pNFT (Programmable NFT) support.

✨ Features

  • 🎲 Raffle System: Create, join, and draw winners for raffles
  • 🏦 Escrow Integration: Secure prize management with automatic escrow
  • 🎨 pNFT Support: Create and use Programmable NFTs as prizes
  • πŸ’° Multiple Prize Types: SOL, SPL tokens, and pNFTs
  • πŸ”’ Security: Built with Anchor's security best practices
  • πŸ“± TypeScript SDK: Easy-to-use client library
  • πŸ§ͺ Comprehensive Tests: Full test coverage for all functionality

πŸ—οΈ Architecture

Core Components

  1. Raffle Program: Main Anchor program handling raffle logic
  2. Escrow System: Secure holding of prizes until winner is determined
  3. pNFT Integration: Support for Programmable NFTs as prizes
  4. Client SDK: TypeScript library for easy integration

Program Structure

programs/solana-raffle/src/
β”œβ”€β”€ lib.rs                 # Main program logic
β”œβ”€β”€ instructions/          # Individual instruction handlers
β”œβ”€β”€ state/                 # Account state definitions
└── errors.rs             # Custom error types

πŸš€ Quick Start

Prerequisites

Installation

  1. Clone the repository

    git clone <repository-url>
    cd solana-raffle
  2. Install dependencies

    yarn install
    # or
    npm install
  3. Build the program

    anchor build
  4. Run tests

    anchor test

Deployment

Option 1: Using the deployment script

./scripts/build-and-deploy.sh

Option 2: Manual deployment

# Build the program
anchor build

# Deploy to devnet
anchor deploy

# Verify deployment
ts-node scripts/deploy.ts deploy

πŸ“– Usage

Basic Raffle Creation

import { SolanaRaffleClient } from './client';
import { Connection, Keypair } from '@solana/web3.js';
import { AnchorProvider, Wallet } from '@coral-xyz/anchor';

// Setup
const connection = new Connection('https://api.devnet.solana.com');
const wallet = new Wallet(Keypair.generate());
const client = new SolanaRaffleClient(connection, wallet);

// Create a SOL raffle
const { rafflePda, escrowPda, tx } = await client.createRaffle({
  ticketPrice: 0.1,        // 0.1 SOL per ticket
  maxTickets: 100,         // Maximum 100 tickets
  endTime: Date.now() + 3600000, // Ends in 1 hour
  prizeType: 'sol'         // Prize is SOL
});

console.log(`Raffle created: ${rafflePda.toString()}`);

Joining a Raffle

// Join with 5 tickets
const joinTx = await client.joinRaffle(rafflePda, 5);
console.log(`Joined raffle: ${joinTx}`);

Drawing and Claiming

// Draw winner (only after raffle ends)
const drawTx = await client.drawWinner(rafflePda);

// Claim prize (only by winner)
const claimTx = await client.claimPrize(rafflePda);

pNFT Integration

// Create a pNFT
const { metadataPda } = await client.createPnftPrize(
  'Rare Digital Art',
  'RDA',
  'https://arweave.net/metadata-hash'
);

// Create a pNFT raffle
const { rafflePda } = await client.createRaffle({
  ticketPrice: 0.05,
  maxTickets: 50,
  endTime: Date.now() + 1800000,
  prizeType: 'pnft'
});

πŸ§ͺ Testing

The project includes comprehensive tests covering:

  • Basic Functionality: Create, join, draw, claim
  • Escrow System: Fund management and security
  • pNFT Operations: Creation and integration
  • Edge Cases: Error handling and validation
  • Integration Tests: End-to-end workflows

Running Tests

# Run all tests
anchor test

# Run specific test file
anchor test tests/solana-raffle.ts

# Run tests without local validator
anchor test --skip-local-validator

Test Structure

tests/
β”œβ”€β”€ solana-raffle.ts      # Main functionality tests
β”œβ”€β”€ escrow-tests.ts       # Escrow system tests
└── pnft-tests.ts         # pNFT integration tests

πŸ”§ Configuration

Anchor.toml

[programs.devnet]
solana_raffle = "Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS"

[programs.mainnet]
solana_raffle = "Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS"

[provider]
cluster = "Devnet"
wallet = "~/.config/solana/id.json"

Environment Variables

# Solana network
export SOLANA_NETWORK=devnet

# Wallet path
export SOLANA_WALLET=~/.config/solana/id.json

# RPC endpoint
export SOLANA_RPC_URL=https://api.devnet.solana.com

πŸ“š API Reference

SolanaRaffleClient

Methods

  • createRaffle(config: RaffleConfig): Create a new raffle
  • joinRaffle(rafflePda: PublicKey, ticketCount: number): Join a raffle
  • drawWinner(rafflePda: PublicKey): Draw the winner
  • claimPrize(rafflePda: PublicKey, ...): Claim the prize
  • createPnftPrize(name: string, symbol: string, uri: string): Create pNFT
  • getRaffleInfo(rafflePda: PublicKey): Get raffle information
  • getEscrowBalance(rafflePda: PublicKey): Get escrow balance

Types

interface RaffleConfig {
  ticketPrice: number;     // SOL amount per ticket
  maxTickets: number;      // Maximum tickets
  endTime: number;         // Unix timestamp
  prizeType: 'sol' | 'token' | 'pnft';
}

interface RaffleInfo {
  authority: PublicKey;
  ticketPrice: anchor.BN;
  maxTickets: number;
  ticketsSold: number;
  endTime: anchor.BN;
  prizeType: any;
  winner: number | null;
  claimed: boolean;
}

πŸ”’ Security Considerations

Program Security

  • PDA Usage: All accounts use Program Derived Addresses
  • Access Control: Proper authority checks on all operations
  • Escrow Protection: Funds are held securely until winner claims
  • Input Validation: All inputs are validated before processing

Best Practices

  1. Always verify program ID before interacting
  2. Check raffle state before joining or drawing
  3. Validate timestamps for raffle end times
  4. Use proper randomness for winner selection
  5. Handle errors gracefully in client applications

πŸ› οΈ Development

Project Structure

solana-raffle/
β”œβ”€β”€ programs/
β”‚   └── solana-raffle/
β”‚       β”œβ”€β”€ Cargo.toml
β”‚       └── src/
β”‚           └── lib.rs
β”œβ”€β”€ tests/
β”‚   β”œβ”€β”€ solana-raffle.ts
β”‚   β”œβ”€β”€ escrow-tests.ts
β”‚   └── pnft-tests.ts
β”œβ”€β”€ client/
β”‚   β”œβ”€β”€ index.ts
β”‚   β”œβ”€β”€ package.json
β”‚   └── tsconfig.json
β”œβ”€β”€ scripts/
β”‚   β”œβ”€β”€ deploy.ts
β”‚   └── build-and-deploy.sh
β”œβ”€β”€ examples/
β”‚   └── basic-usage.ts
β”œβ”€β”€ Anchor.toml
β”œβ”€β”€ Cargo.toml
└── package.json

Building

# Build the program
anchor build

# Build client SDK
cd client && npm run build

# Clean build artifacts
anchor clean

Linting

# Check Rust code
cargo clippy

# Check TypeScript code
cd client && npm run lint

🀝 Contributing

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

Development Guidelines

  • Follow Rust and TypeScript best practices
  • Add tests for new functionality
  • Update documentation for API changes
  • Ensure all tests pass before submitting

πŸ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.

πŸ†˜ Support

  • Documentation: Check this README and inline code comments
  • Issues: Open an issue on GitHub for bugs or feature requests
  • Discussions: Use GitHub Discussions for questions and ideas

πŸ™ Acknowledgments


⚠️ Disclaimer: This software is provided as-is for educational and development purposes. Use at your own risk in production environments.

About

A comprehensive Solana raffle program built with the Anchor framework, featuring escrow functionality and pNFT (Programmable NFT) support.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages