import { useState, useEffect } from 'react'; import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; import { Button } from '@/components/ui/button'; import { Badge } from '@/components/ui/badge'; import { Input } from '@/components/ui/input'; import { useToast } from '@/hooks/use-toast'; import { usePolkadot } from '@/contexts/PolkadotContext'; import { Loader2, Plus, CheckCircle, AlertTriangle, Shield } from 'lucide-react'; import { COMMISSIONS } from '@/config/commissions'; import { Alert, AlertDescription } from '@/components/ui/alert'; export function CommissionSetupTab() { const { api, isApiReady, selectedAccount } = usePolkadot(); const { toast } = useToast(); const [loading, setLoading] = useState(true); const [commissionMembers, setCommissionMembers] = useState([]); const [proxyMembers, setProxyMembers] = useState([]); const [setupComplete, setSetupComplete] = useState(false); const [processing, setProcessing] = useState(false); const [newMemberAddress, setNewMemberAddress] = useState(''); useEffect(() => { if (!api || !isApiReady) return; checkSetup(); }, [api, isApiReady]); const checkSetup = async () => { if (!api) return; setLoading(true); try { // Check DynamicCommissionCollective members const members = await api.query.dynamicCommissionCollective.members(); const memberList = members.toJSON() as string[]; setCommissionMembers(memberList); // Commission is initialized if there's at least one member setSetupComplete(memberList.length > 0); console.log('Commission members:', memberList); console.log('Setup complete:', memberList.length > 0); } catch (error) { console.error('Error checking setup:', error); } finally { setLoading(false); } }; const handleAddMember = async () => { if (!api || !selectedAccount) { toast({ title: 'Wallet Not Connected', description: 'Please connect your admin wallet', variant: 'destructive', }); return; } if (!newMemberAddress) { toast({ title: 'No Addresses', description: 'Please enter at least one address', variant: 'destructive', }); return; } setProcessing(true); try { const { web3FromAddress } = await import('@polkadot/extension-dapp'); const injector = await web3FromAddress(selectedAccount.address); // Parse addresses (one per line, trim whitespace) const newAddresses = newMemberAddress .split('\n') .map(addr => addr.trim()) .filter(addr => addr.length > 0); if (newAddresses.length === 0) { toast({ title: 'No Valid Addresses', description: 'Please enter at least one valid address', variant: 'destructive', }); setProcessing(false); return; } // Get current members const currentMembers = await api.query.dynamicCommissionCollective.members(); const memberList = (currentMembers.toJSON() as string[]) || []; // Filter out already existing members const newMembers = newAddresses.filter(addr => !memberList.includes(addr)); if (newMembers.length === 0) { toast({ title: 'Already Members', description: 'All addresses are already commission members', variant: 'destructive', }); setProcessing(false); return; } // Add new members const updatedList = [...memberList, ...newMembers]; console.log('Adding new members:', newMembers); console.log('Updated member list:', updatedList); const tx = api.tx.sudo.sudo( api.tx.dynamicCommissionCollective.setMembers( updatedList, null, updatedList.length ) ); await new Promise((resolve, reject) => { tx.signAndSend( selectedAccount.address, { signer: injector.signer }, ({ status, dispatchError }) => { if (status.isInBlock || status.isFinalized) { if (dispatchError) { let errorMessage = 'Failed to add member'; if (dispatchError.isModule) { const decoded = api.registry.findMetaError(dispatchError.asModule); errorMessage = `${decoded.section}.${decoded.name}`; } toast({ title: 'Error', description: errorMessage, variant: 'destructive', }); reject(new Error(errorMessage)); } else { toast({ title: 'Success', description: `${newMembers.length} member(s) added successfully!`, }); setNewMemberAddress(''); setTimeout(() => checkSetup(), 2000); resolve(); } } } ); }); } catch (error: any) { console.error('Error adding member:', error); toast({ title: 'Error', description: error.message || 'Failed to add member', variant: 'destructive', }); } finally { setProcessing(false); } }; const handleInitializeCommission = async () => { if (!api || !selectedAccount) { toast({ title: 'Wallet Not Connected', description: 'Please connect your admin wallet', variant: 'destructive', }); return; } setProcessing(true); try { const { web3FromAddress } = await import('@polkadot/extension-dapp'); const injector = await web3FromAddress(selectedAccount.address); console.log('Initializing KYC Commission...'); console.log('Proxy account:', COMMISSIONS.KYC.proxyAccount); // Initialize DynamicCommissionCollective with Alice as first member // Other members can be added later const tx = api.tx.sudo.sudo( api.tx.dynamicCommissionCollective.setMembers( [selectedAccount.address], // Add caller as first member null, 1 ) ); await new Promise((resolve, reject) => { tx.signAndSend( selectedAccount.address, { signer: injector.signer }, ({ status, dispatchError, events }) => { console.log('Transaction status:', status.type); if (status.isInBlock || status.isFinalized) { if (dispatchError) { let errorMessage = 'Transaction failed'; if (dispatchError.isModule) { const decoded = api.registry.findMetaError(dispatchError.asModule); errorMessage = `${decoded.section}.${decoded.name}: ${decoded.docs.join(' ')}`; } else { errorMessage = dispatchError.toString(); } console.error('Setup error:', errorMessage); toast({ title: 'Setup Failed', description: errorMessage, variant: 'destructive', }); reject(new Error(errorMessage)); return; } // Check for Sudid event const sudidEvent = events.find(({ event }) => event.section === 'sudo' && event.method === 'Sudid' ); if (sudidEvent) { console.log('✅ KYC Commission initialized'); toast({ title: 'Success', description: 'KYC Commission initialized successfully!', }); resolve(); } else { console.warn('Transaction included but no Sudid event'); resolve(); } } } ).catch((error) => { console.error('Failed to sign and send:', error); toast({ title: 'Transaction Error', description: error.message || 'Failed to submit transaction', variant: 'destructive', }); reject(error); }); }); // Reload setup status setTimeout(() => checkSetup(), 2000); } catch (error: any) { console.error('Error initializing commission:', error); toast({ title: 'Error', description: error.message || 'Failed to initialize commission', variant: 'destructive', }); } finally { setProcessing(false); } }; if (!isApiReady) { return (
Connecting to blockchain...
); } if (!selectedAccount) { return ( Please connect your admin wallet to manage commission setup. ); } return (
{/* Setup Status */} KYC Commission Setup {loading ? (
) : ( <>

Commission Status

{setupComplete ? 'Commission is initialized and ready' : 'Commission needs to be initialized'}

{setupComplete ? ( Ready ) : ( Not Initialized )}

Proxy Account

{COMMISSIONS.KYC.proxyAccount}

Commission Members ({commissionMembers.length})

{commissionMembers.length === 0 ? (
No members yet
) : (
{commissionMembers.map((member, index) => (

{member}

{member === COMMISSIONS.KYC.proxyAccount && ( KYC Proxy )}
))}
)}
{!setupComplete && ( Required: Initialize the commission before members can join. This requires sudo privileges. )} {setupComplete && (

Add Members