Flip.is Docs
  • What is Flip.is?
  • Smart Contract Architecture
  • Backend Architecture
  • Frontend Architecture
  • $FLIP Tokenomics
Powered by GitBook
On this page
  • Technology Stack
  • Application Structure
  • Core Components
  • Game Management
  • UI Components
  • User Experience Features
  • Performance Optimization
  • Error Handling
  • Security Considerations
  • Development Guidelines
  • Deployment
  • Conclusion

Frontend Architecture

Technology Stack

Core Technologies

  • React 18

  • TypeScript

  • TailwindCSS

  • WebSocket

  • Solana Web3.js

  • Anchor Framework

Key Libraries

{
  "dependencies": {
    "@solana/wallet-adapter-react": "^0.15.35",
    "@solana/wallet-adapter-react-ui": "^0.9.34",
    "@solana/web3.js": "^1.87.6",
    "react-infinite-scroll": "^0.1.5",
    "react-toastify": "^9.1.3",
    "tailwindcss": "^3.3.5"
  }
}

Application Structure

Directory Organization

src/
├── Components/
│   ├── Header/
│   ├── Body/
│   ├── GameModal/
│   ├── JoinModal/
│   └── Pattern/
├── Context/
│   └── WebSocketProvider/
├── Config/
│   ├── constant.ts
│   └── menu.ts
├── Assets/
│   └── images/
└── Utils/
    └── helpers.ts

Core Components

App Component

The root component that sets up wallet providers and routing:

function App() {
  const wallets = [new PhantomWalletAdapter()];

  return ( 
    <ConnectionProvider endpoint={RPC}> 
      <WalletProvider wallets={wallets} autoConnect>
        <WalletModalProvider>
          <WebSocketProvider>
            <ToastContainer/> 
              <BrowserRouter>
                <div className="App Inter h-full md:h-screen hide_scrollbar">
                  <Header/>
                  <Routes>
                    <Route path='/' element = {<Body/>} />
                    <Route path='/jackpot' element = {<JackPot/>} />
                    <Route path='/jackpotcomingsoon' element = {<JackPotComingSoon/>} />
                    <Route path='/historycomingsoon' element = {<HistoryComingSoon/>} />
                  </Routes>
                </div>
              </BrowserRouter>
          </WebSocketProvider>
        </WalletModalProvider>
      </WalletProvider>
    </ConnectionProvider>
  );
}

WebSocket Provider

Manages real-time game state and communication:

interface WebSocketContextProps {
    rooms: Room[];
    creating: boolean;
    joining: boolean;
    porfolioInfo: {
        totalGame: number;
        wins: number;
        losses: number;
    };
    createRoom: (params: CreateRoomParams) => void;
    joinRoom: (params: JoinRoomParams) => void;
    getRooms: () => void;
}

const WebSocketProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
    const [socket, setSocket] = useState<WebSocket | null>(null);
    const [rooms, setRooms] = useState<Room[]>([]);
    const [creating, setCreating] = useState(false);
    const [joining, setJoining] = useState(false);

    // WebSocket implementation...
};

Game Modal

Handles game creation interface:

export const GameModal = (props: { open: boolean; handleModal: any }) => {
    const { createRoom, creating, setCreatingState } = useWebSocket();
    const [step, setStep] = useState(0);
    const [currentCoin, setCurrentCoin] = useState({
        name: 'Solana',
        unit: 'SOL',
        selected: true,
        mint: "So11111111111111111111111111111111111111112",
        decimal: 9
    });
    const [amount, setAmount] = useState(0);
    const [selection, setSelection] = useState(true);

    // Modal implementation...
};

Game Management

Token Selection

Available tokens for game creation:

const token_list = [
    {
        name: 'Solana',
        unit: 'SOL',
        selected: true,
        mint: "So11111111111111111111111111111111111111112",
        decimal: 9
    },
    {
        name: 'Solana USDT',
        unit: 'USDT',
        selected: false,
        mint: "Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB",
        decimal: 6
    },
    // Additional tokens...
];

Game Creation Process

const handleGameCreation = async () => {
    try {
        const decodedBufferTx = Buffer.from(message.room, 'base64');
        const vtx = VersionedTransaction.deserialize(decodedBufferTx);
        
        if (!wallet) {
            errorAlert("Wallet not initialized!");
            return;
        }
        
        const signedVtx = await wallet?.signTransaction(vtx);
        const signature = await connection.sendTransaction(signedVtx);
        await connection.confirmTransaction(signature);
    } catch (error) {
        setCreating(false);
        errorAlert("Error creating game!");
    }
};

UI Components

Header Navigation

export const Header = () => {
    const { publicKey } = useWallet();
    
    return (
        <div className="fixed top-0 left-0 w-full bg-bg-strong px-3 md:px-4 xl:px-9 py-3">
            <div className="flex justify-between items-center">
                <Logo />
                <WalletConnection />
            </div>
        </div>
    );
};

User Interface States

Loading State

const LoadingOverlay = () => (
    <div className="absolute inset-0 backdrop-blur-sm flex items-center justify-center">
        <ClipLoader
            color="#fff"
            loading={true}
            size={100}
            aria-label="Loading Spinner"
        />
    </div>
);

Notifications

const notifications = {
    success: (message: string) => toast.success(message),
    error: (message: string) => toast.error(message),
    info: (message: string) => toast.info(message),
    warning: (message: string) => toast.warning(message)
};

User Experience Features

Responsive Design

The application is built with a mobile-first approach using Tailwind CSS classes:

<div className="w-full md:w-[370px] flex flex-col gap-[14px] rounded-2xl h-full">
    <div className="w-full border border-white/10 rounded-2xl relative">
        {/* Component content */}
    </div>
</div>

Input Validation

const validateAmount = (amount: number): boolean => {
    return amount > 0 && amount <= MAX_BET_AMOUNT;
};

Performance Optimization

Data Management

const [rooms, setRooms] = useState<Room[]>([]);
useEffect(() => {
    const fiveMinutesAgo = Math.floor(Date.now()/1000) - 5 * 60;
    // Clean up expired rooms
    setRooms(prev => prev.filter(room => room.createdAt > fiveMinutesAgo));
}, []);

WebSocket Connection

useEffect(() => {
    const ws = new WebSocket(WS_HOST);
    setSocket(ws);

    ws.onopen = () => {
        console.log('WebSocket connection established');
        ws.send(JSON.stringify({ type: 'GET_ROOMS' }));
    };

    return () => ws.close();
}, []);

Error Handling

Toast Notifications

export const errorAlert = (text: string) => {
    toast.error(text, {
        position: "top-right",
        autoClose: 2000,
        hideProgressBar: false,
        closeOnClick: true,
        pauseOnHover: true,
        draggable: true,
        theme: "colored",
    });
};

Security Considerations

Transaction Validation

  • All transactions are validated before submission

  • Balance checks are performed before game creation

  • Wallet connection state is verified

  • Input validation for all user inputs

Error Recovery

  • Automatic reconnection for WebSocket

  • Transaction retry logic

  • State recovery after errors

Development Guidelines

Code Style

  • Use TypeScript for type safety

  • Follow React best practices

  • Implement responsive design

  • Use Tailwind CSS for styling

Testing

  • Component testing

  • State management testing

  • WebSocket integration testing

  • Transaction flow testing

Deployment

Environment Configuration

export const WS_HOST = process.env.REACT_APP_WS_HOST;
export const RPC = process.env.REACT_APP_RPC_ENDPOINT;

Conclusion

The Flip.is frontend provides a secure, responsive, and user-friendly interface for the gaming platform. It leverages modern web technologies and best practices to ensure a smooth user experience while maintaining high security standards.

PreviousBackend ArchitectureNext$FLIP Tokenomics

Last updated 4 months ago