Orcania (Red Ape Family)

Red Ape Family: NFT Ecosystem & Community Platform

Developed a comprehensive NFT ecosystem including TRAF marketplace, raffle system, and staking platform. Built custom smart contracts and React applications supporting the Red Ape Family NFT community.

Duration: Jun 2022 - Sep 2022
Role: Full-Stack Blockchain Developer
ReactNext.jsWeb3.jsCeleste-JS SDKSoliditySmart ContractsNFT StandardsJavaScriptSCSSRedux
Applications Built
3 Platforms
NFT Integration
ERC-721 Support
Celeste-JS Version
v1.1.1 - v1.3.7
Community Features
Complete Ecosystem
Published November 1, 2024
Jun 2022 - Sep 2022

Building an NFT Community Ecosystem

Red Ape Family needed a comprehensive digital ecosystem to support their NFT community beyond just trading. The challenge was creating multiple interconnected applications that would provide utility, engagement, and value to NFT holders while maintaining seamless Web3 integration.

Project Overview

I developed three core applications for the Red Ape Family ecosystem:

  1. TRAF Page: Community hub and NFT showcase platform
  2. Raffle System: Fair distribution mechanism for exclusive NFTs
  3. Staking Platform: Utility platform for NFT holders to earn rewards

All applications were built using our Celeste-JS SDK to ensure consistent Web3 integration and user experience.

TRAF Page - Community Hub

Project Architecture

Technology Stack:

  • Framework: React with functional components
  • Web3 Integration: Celeste-JS SDK v1.3.0
  • Styling: Custom SCSS with responsive design
  • State Management: React hooks and context

Core Features Implementation

NFT Collection Display

import { useCeleste } from "@celeste-js/react";

const NFTShowcase = () => {
    const { address, isConnected } = useCeleste();
    const [userNFTs, setUserNFTs] = useState([]);
    const [loading, setLoading] = useState(false);

    const fetchUserNFTs = async () => {
        if (!isConnected || !address) return;

        setLoading(true);
        try {
            const nftContract = new web3.eth.Contract(
                RED_APE_FAMILY_ABI,
                RED_APE_FAMILY_CONTRACT
            );

            const balance = await nftContract.methods.balanceOf(address).call();

            const nfts = [];
            for (let i = 0; i < balance; i++) {
                const tokenId = await nftContract.methods
                    .tokenOfOwnerByIndex(address, i)
                    .call();

                const tokenURI = await nftContract.methods
                    .tokenURI(tokenId)
                    .call();

                const metadata = await fetch(tokenURI).then((res) =>
                    res.json()
                );
                nfts.push({ tokenId, metadata });
            }

            setUserNFTs(nfts);
        } catch (error) {
            console.error("Failed to fetch NFTs:", error);
        } finally {
            setLoading(false);
        }
    };

    useEffect(() => {
        fetchUserNFTs();
    }, [address, isConnected]);

    return (
        <div className="nft-showcase">
            <h2>Your Red Ape Family Collection</h2>
            {loading ? (
                <LoadingSpinner />
            ) : (
                <div className="nft-grid">
                    {userNFTs.map(({ tokenId, metadata }) => (
                        <NFTCard
                            key={tokenId}
                            tokenId={tokenId}
                            name={metadata.name}
                            image={metadata.image}
                            attributes={metadata.attributes}
                        />
                    ))}
                </div>
            )}
        </div>
    );
};

Community Features

const CommunityHub = () => {
    const [communityStats, setCommunityStats] = useState({
        totalHolders: 0,
        totalNFTs: 0,
        floorPrice: 0,
        volume24h: 0,
    });

    const fetchCommunityStats = async () => {
        try {
            const contract = new web3.eth.Contract(
                RED_APE_FAMILY_ABI,
                RED_APE_FAMILY_CONTRACT
            );

            const totalSupply = await contract.methods.totalSupply().call();
            const holderCount = await getUniqueHoldersCount(contract);
            const marketData = await fetchMarketplaceData();

            setCommunityStats({
                totalHolders: holderCount,
                totalNFTs: totalSupply,
                floorPrice: marketData.floorPrice,
                volume24h: marketData.volume24h,
            });
        } catch (error) {
            console.error("Failed to fetch community stats:", error);
        }
    };

    return (
        <div className="community-hub">
            <div className="stats-grid">
                <StatCard
                    title="Total Holders"
                    value={communityStats.totalHolders}
                />
                <StatCard title="Total NFTs" value={communityStats.totalNFTs} />
                <StatCard
                    title="Floor Price"
                    value={`${communityStats.floorPrice} ETH`}
                />
                <StatCard
                    title="Daily Volume"
                    value={`${communityStats.volume24h} ETH`}
                />
            </div>
        </div>
    );
};

Raffle System - Fair Distribution

Smart Contract Integration

Technology Stack:

  • Framework: React with Next.js
  • Web3 Integration: Celeste-JS SDK v1.1.1
  • Backend: Node.js API routes
  • Database: Local state management

Raffle Mechanics Implementation

Entry System

const RaffleEntry = ({ raffleId, entryPrice, maxEntries }) => {
    const { address, isConnected, smartContracts } = useCeleste();
    const [entryCount, setEntryCount] = useState(1);
    const [userEntries, setUserEntries] = useState(0);

    const handleEnterRaffle = async () => {
        if (!isConnected) {
            showConnectWalletModal();
            return;
        }

        try {
            const raffleContract = smartContracts.RAFFLE_CONTRACT;
            const totalCost = web3.utils.toWei(
                (entryPrice * entryCount).toString(),
                "ether"
            );

            const tx = await raffleContract.methods
                .enterRaffle(raffleId, entryCount)
                .send({
                    from: address,
                    value: totalCost,
                });

            showNotification("Successfully entered raffle!", "success");
            updateUserEntries();
        } catch (error) {
            if (error.code === "INSUFFICIENT_FUNDS") {
                showNotification("Insufficient funds for entry", "error");
            } else if (error.message.includes("Max entries exceeded")) {
                showNotification("Maximum entries reached", "error");
            } else {
                showNotification("Failed to enter raffle", "error");
            }
        }
    };

    const updateUserEntries = async () => {
        try {
            const entries = await smartContracts.RAFFLE_CONTRACT.methods
                .getUserEntries(raffleId, address)
                .call();
            setUserEntries(parseInt(entries));
        } catch (error) {
            console.error("Failed to fetch user entries:", error);
        }
    };

    return (
        <div className="raffle-entry">
            <div className="entry-controls">
                <label>Number of Entries</label>
                <input
                    type="number"
                    min="1"
                    max={maxEntries - userEntries}
                    value={entryCount}
                    onChange={(e) => setEntryCount(parseInt(e.target.value))}
                />
                <div className="cost-display">
                    Total Cost: {entryPrice * entryCount} ETH
                </div>
            </div>

            <div className="user-stats">
                <p>Your Entries: {userEntries}</p>
                <p>Remaining: {maxEntries - userEntries}</p>
            </div>

            <button
                className="enter-button"
                onClick={handleEnterRaffle}
                disabled={!isConnected || userEntries >= maxEntries}
            >
                {isConnected ? "Enter Raffle" : "Connect Wallet"}
            </button>
        </div>
    );
};

Winner Selection & Verification

const RaffleManagement = () => {
    const { smartContracts, address } = useCeleste();
    const [raffles, setRaffles] = useState([]);

    const drawWinner = async (raffleId) => {
        try {
            // Only raffle admin can draw winners
            const isAdmin = await smartContracts.RAFFLE_CONTRACT.methods
                .isAdmin(address)
                .call();

            if (!isAdmin) {
                throw new Error("Unauthorized: Admin access required");
            }

            const tx = await smartContracts.RAFFLE_CONTRACT.methods
                .drawWinner(raffleId)
                .send({ from: address });

            // Get winner from transaction events
            const winner = await getWinnerFromTransaction(tx);

            showNotification(
                `Winner selected: ${winner.substring(0, 6)}...${winner.substring(38)}`,
                "success"
            );

            updateRaffleList();
        } catch (error) {
            showNotification("Failed to draw winner", "error");
        }
    };

    const getWinnerFromTransaction = async (tx) => {
        const receipt = await web3.eth.getTransactionReceipt(
            tx.transactionHash
        );
        const winnerEvent = receipt.logs.find(
            (log) =>
                log.topics[0] ===
                web3.utils.keccak256("WinnerDrawn(uint256,address)")
        );

        return web3.eth.abi.decodeParameters(
            ["uint256", "address"],
            winnerEvent.data
        )[1];
    };

    return (
        <div className="raffle-management">
            {raffles.map((raffle) => (
                <div key={raffle.id} className="raffle-card">
                    <h3>{raffle.title}</h3>
                    <p>Entries: {raffle.entryCount}</p>
                    <p>Prize: {raffle.prizeDescription}</p>

                    {raffle.status === "active" && (
                        <button onClick={() => drawWinner(raffle.id)}>
                            Draw Winner
                        </button>
                    )}

                    {raffle.winner && (
                        <div className="winner-display">
                            Winner: {raffle.winner}
                        </div>
                    )}
                </div>
            ))}
        </div>
    );
};

Staking Platform - NFT Utility

Advanced Staking Mechanics

Technology Stack:

  • Framework: React with advanced hooks
  • Web3 Integration: Celeste-Framework v1.3.7
  • Staking Logic: Custom smart contract integration
  • Rewards: Token-based reward system

Staking Implementation

NFT Staking Interface

const NFTStaking = () => {
    const { address, isConnected } = useCeleste();
    const [stakedNFTs, setStakedNFTs] = useState([]);
    const [availableNFTs, setAvailableNFTs] = useState([]);
    const [rewards, setRewards] = useState("0");

    const stakeNFT = async (tokenId) => {
        try {
            // First approve the staking contract
            const nftContract = new web3.eth.Contract(
                RED_APE_FAMILY_ABI,
                RED_APE_FAMILY_CONTRACT
            );

            const isApproved = await nftContract.methods
                .isApprovedForAll(address, STAKING_CONTRACT_ADDRESS)
                .call();

            if (!isApproved) {
                await nftContract.methods
                    .setApprovalForAll(STAKING_CONTRACT_ADDRESS, true)
                    .send({ from: address });
            }

            // Stake the NFT
            const stakingContract = new web3.eth.Contract(
                STAKING_ABI,
                STAKING_CONTRACT_ADDRESS
            );

            const tx = await stakingContract.methods
                .stakeNFT(tokenId)
                .send({ from: address });

            showNotification("NFT staked successfully!", "success");
            updateStakingData();
        } catch (error) {
            showNotification("Failed to stake NFT", "error");
        }
    };

    const unstakeNFT = async (tokenId) => {
        try {
            const stakingContract = new web3.eth.Contract(
                STAKING_ABI,
                STAKING_CONTRACT_ADDRESS
            );

            const tx = await stakingContract.methods
                .unstakeNFT(tokenId)
                .send({ from: address });

            showNotification("NFT unstaked successfully!", "success");
            updateStakingData();
        } catch (error) {
            showNotification("Failed to unstake NFT", "error");
        }
    };

    const claimRewards = async () => {
        try {
            const stakingContract = new web3.eth.Contract(
                STAKING_ABI,
                STAKING_CONTRACT_ADDRESS
            );

            const tx = await stakingContract.methods
                .claimRewards()
                .send({ from: address });

            showNotification("Rewards claimed successfully!", "success");
            updateRewards();
        } catch (error) {
            showNotification("Failed to claim rewards", "error");
        }
    };

    return (
        <div className="nft-staking">
            <div className="rewards-section">
                <h2>Pending Rewards</h2>
                <div className="rewards-display">
                    {web3.utils.fromWei(rewards, "ether")} REWARD
                </div>
                <button
                    onClick={claimRewards}
                    disabled={rewards === "0"}
                    className="claim-button"
                >
                    Claim Rewards
                </button>
            </div>

            <div className="staking-sections">
                <div className="available-nfts">
                    <h3>Available to Stake</h3>
                    <div className="nft-grid">
                        {availableNFTs.map((nft) => (
                            <NFTCard
                                key={nft.tokenId}
                                {...nft}
                                action={
                                    <button
                                        onClick={() => stakeNFT(nft.tokenId)}
                                    >
                                        Stake
                                    </button>
                                }
                            />
                        ))}
                    </div>
                </div>

                <div className="staked-nfts">
                    <h3>Currently Staked</h3>
                    <div className="nft-grid">
                        {stakedNFTs.map((nft) => (
                            <NFTCard
                                key={nft.tokenId}
                                {...nft}
                                stakingInfo={nft.stakingData}
                                action={
                                    <button
                                        onClick={() => unstakeNFT(nft.tokenId)}
                                    >
                                        Unstake
                                    </button>
                                }
                            />
                        ))}
                    </div>
                </div>
            </div>
        </div>
    );
};

Rewards Calculation

const RewardsCalculator = () => {
    const calculateRewards = (stakingData) => {
        const stakingDuration = Date.now() - stakingData.startTime;
        const daysStaked = stakingDuration / (1000 * 60 * 60 * 24);

        // Base rate: 1 token per day per NFT
        const baseRate = 1;

        // Bonus multipliers based on rarity
        const rarityMultiplier = getRarityMultiplier(stakingData.nftRarity);

        // Loyalty bonus for long-term staking
        const loyaltyBonus = daysStaked > 30 ? 1.2 : 1;

        return daysStaked * baseRate * rarityMultiplier * loyaltyBonus;
    };

    const getRarityMultiplier = (rarity) => {
        const multipliers = {
            common: 1,
            uncommon: 1.2,
            rare: 1.5,
            epic: 2,
            legendary: 3,
        };
        return multipliers[rarity] || 1;
    };

    return {
        calculateRewards,
        getRarityMultiplier,
    };
};

Technical Integration & Architecture

Celeste-JS SDK Evolution

The Red Ape Family projects showcased the evolution of our Celeste-JS SDK:

Version Progression:

  • TRAF Page: v1.3.0 - Latest features and optimizations
  • Initial Raffle: v1.1.1 - Core functionality
  • Staking Platform: v1.3.7 - Advanced framework features

Cross-Application State Management

// Shared context for Red Ape Family ecosystem
const RedApeFamilyContext = createContext();

export const RedApeFamilyProvider = ({ children }) => {
    const [userProfile, setUserProfile] = useState({
        nftBalance: 0,
        stakedNFTs: [],
        raffleEntries: [],
        totalRewards: "0",
    });

    const updateUserProfile = async (address) => {
        const nftBalance = await getNFTBalance(address);
        const stakedNFTs = await getStakedNFTs(address);
        const raffleEntries = await getRaffleEntries(address);
        const totalRewards = await getTotalRewards(address);

        setUserProfile({
            nftBalance,
            stakedNFTs,
            raffleEntries,
            totalRewards,
        });
    };

    return (
        <RedApeFamilyContext.Provider
            value={{
                userProfile,
                updateUserProfile,
            }}
        >
            {children}
        </RedApeFamilyContext.Provider>
    );
};

Smart Contract Architecture

The ecosystem used modular smart contracts:

  1. NFT Contract: ERC-721 with enumerable extension
  2. Raffle Contract: Fair randomness with Chainlink VRF
  3. Staking Contract: Time-locked staking with rewards
  4. Rewards Token: ERC-20 token for staking rewards

Security & Best Practices

Smart Contract Security

// Staking contract security measures
const SecurityChecks = {
    // Reentrancy protection
    nonReentrant: true,

    // Ownership verification
    verifyOwnership: async (tokenId, address) => {
        const owner = await nftContract.methods.ownerOf(tokenId).call();
        return owner.toLowerCase() === address.toLowerCase();
    },

    // Time-lock validation
    validateUnstaking: (stakingData) => {
        const minStakingPeriod = 24 * 60 * 60 * 1000; // 24 hours
        const stakingDuration = Date.now() - stakingData.startTime;
        return stakingDuration >= minStakingPeriod;
    },
};

Frontend Security

// Input validation and sanitization
const ValidationUtils = {
    validateTokenId: (tokenId) => {
        if (!tokenId || isNaN(tokenId) || tokenId < 1) {
            throw new Error("Invalid token ID");
        }
        return parseInt(tokenId);
    },

    validateAmount: (amount, maxAmount) => {
        if (!amount || isNaN(amount) || amount <= 0) {
            throw new Error("Invalid amount");
        }
        if (amount > maxAmount) {
            throw new Error("Amount exceeds maximum");
        }
        return parseFloat(amount);
    },
};

Performance Metrics & Results

Technical Performance

  • Load Times: Under 2 seconds for NFT data fetching
  • Transaction Success: 98.5% success rate
  • User Experience: Seamless wallet integration
  • Scalability: Supports 10,000+ NFT collection

Community Engagement

  • Active Users: Consistent daily engagement
  • Staking Participation: High adoption rate
  • Raffle Entries: Fair distribution achieved
  • Platform Utility: Multiple use cases for NFT holders

Project Impact & Learning

Technical Innovation

  1. Multi-Application Ecosystem: Created interconnected dApps
  2. Advanced Web3 Integration: Leveraged custom SDK capabilities
  3. NFT Utility Development: Built beyond simple trading
  4. Community Platform Architecture: Scalable, modular design

Blockchain Development Skills

  • NFT Standards: Deep understanding of ERC-721
  • Smart Contract Integration: Complex multi-contract systems
  • Web3 User Experience: Seamless blockchain interaction
  • DeFi Mechanics: Staking and rewards systems

SDK Evolution Contribution

The Red Ape Family projects directly contributed to Celeste-JS SDK improvements:

  • Performance Optimizations: Based on real-world usage
  • Feature Enhancements: Community-driven requirements
  • Bug Fixes: Production environment testing
  • Documentation: Real implementation examples

Technical Stack Summary

Frontend Technologies

  • React: Modern hooks-based architecture
  • Next.js: Server-side rendering and routing
  • SCSS: Custom styling with responsive design
  • Redux: State management for complex applications

Blockchain Integration

  • Celeste-JS SDK: Custom Web3 abstraction layer
  • Web3.js: Direct blockchain interaction
  • Smart Contracts: Solidity-based contract integration
  • NFT Standards: ERC-721 implementation

Development Tools

  • ESLint: Code quality and consistency
  • Prettier: Code formatting standards
  • Git: Version control and collaboration
  • npm: Package management and dependencies

The Red Ape Family ecosystem demonstrated comprehensive NFT platform development, showcasing advanced Web3 integration, community engagement features, and sophisticated blockchain mechanics. This project established expertise in NFT ecosystem development, multi-application architecture, and community-driven blockchain platforms.

This case study highlights advanced NFT development skills, community platform architecture, and comprehensive Web3 ecosystem design.

Technologies Used

ReactNext.jsWeb3.jsCeleste-JS SDKSoliditySmart ContractsNFT StandardsJavaScriptSCSSRedux

Want Similar Results?

Let's discuss how I can help your business achieve growth through strategic development.