'use client' import React, { useState } from 'react' import { useRouter } from 'next/navigation' import { Wallet, Shield, Code, AlertCircle, CheckCircle } from 'lucide-react' declare global { interface Window { ethereum?: any } } export default function JoinExamWallet() { const [examCode, setExamCode] = useState('') const [studentName, setStudentName] = useState('') const [walletAddress, setWalletAddress] = useState('') const [isConnecting, setIsConnecting] = useState(false) const [isJoining, setIsJoining] = useState(false) const [error, setError] = useState('') const [step, setStep] = useState<'connect' | 'auth' | 'join'>('connect') const [authMessage, setAuthMessage] = useState('') const router = useRouter() const connectWallet = async () => { if (!window.ethereum) { setError('MetaMask is not installed. Please install MetaMask to continue.') return } setIsConnecting(true) setError('') try { const accounts = await window.ethereum.request({ method: 'eth_requestAccounts' }) if (accounts.length > 0) { setWalletAddress(accounts[0]) setStep('auth') } } catch (error: any) { setError('Failed to connect wallet: ' + error.message) } finally { setIsConnecting(false) } } const getAuthMessage = async () => { if (!examCode.trim()) { setError('Please enter exam code') return } try { const response = await fetch('http://127.0.0.1:5000/api/exam/wallet-auth-message', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ wallet_address: walletAddress, exam_code: examCode.toUpperCase() }) }) const data = await response.json() if (data.success) { setAuthMessage(data.message) setStep('join') } else { setError(data.error || 'Failed to get authentication message') } } catch (error) { setError('Connection failed. Please check if the backend is running.') } } const signAndJoinExam = async () => { if (!studentName.trim()) { setError('Please enter your name') return } setIsJoining(true) setError('') try { // Sign the message const signature = await window.ethereum.request({ method: 'personal_sign', params: [authMessage, walletAddress] }) // Join exam with signature const response = await fetch('http://127.0.0.1:5000/api/exam/join-exam-wallet', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ wallet_address: walletAddress, exam_code: examCode.toUpperCase(), signature: signature, student_name: studentName }) }) const data = await response.json() if (data.success) { // Store session data localStorage.setItem('exam_session', JSON.stringify({ exam_code: examCode.toUpperCase(), student_name: studentName, wallet_address: walletAddress, blockchain_verified: true, exam_info: data.exam_info })) // Redirect to exam interface router.push('/coding/exam') } else { setError(data.error || 'Failed to join exam') } } catch (error: any) { if (error.code === 4001) { setError('Transaction was cancelled by user') } else { setError('Failed to sign message or join exam') } } finally { setIsJoining(false) } } return (
Connect your wallet to join the blockchain-verified coding exam
Connect MetaMask to verify your identity on the blockchain
{walletAddress.slice(0, 6)}...{walletAddress.slice(-4)}
Enter the exam code provided by your instructor
Enter your name and sign the message to join
You will sign this message:
Permanent participation records