/** * Deposit USDT Modal * Supports TON, Polkadot (recommended) and TRC20 (with fee warning) */ import { useState, useEffect } from 'react'; import { X, Copy, CheckCircle, ExternalLink, AlertCircle, Loader2, History, Plus, AlertTriangle, } from 'lucide-react'; import { useTelegram } from '@/hooks/useTelegram'; import { useWallet } from '@/contexts/WalletContext'; import { supabase } from '@/lib/supabase'; type Network = 'ton' | 'polkadot' | 'trc20'; interface NetworkInfo { id: Network; name: string; description: string; icon: string; recommended: boolean; fee: number; feeWarning?: string; explorer: string; minDeposit: number; } const NETWORKS: NetworkInfo[] = [ { id: 'ton', name: 'TON', description: 'Telegram Wallet', icon: '💎', recommended: true, fee: 0.05, explorer: 'https://tonviewer.com/transaction/', minDeposit: 10, }, { id: 'polkadot', name: 'Polkadot', description: 'Asset Hub', icon: '⚪', recommended: true, fee: 0.05, explorer: 'https://assethub-polkadot.subscan.io/extrinsic/', minDeposit: 10, }, { id: 'trc20', name: 'TRC20', description: 'TRON Network', icon: '🔴', recommended: false, fee: 3, feeWarning: 'TRC20 ağ masrafı yaklaşık $3 civarındadır. 1000 USDT altındaki gönderimlerde verimli değildir. TON veya Polkadot ağını öneriyoruz.', explorer: 'https://tronscan.org/#/transaction/', minDeposit: 10, }, ]; interface Deposit { id: string; network: Network; amount: number; status: string; tx_hash: string | null; created_at: string; } interface Props { isOpen: boolean; onClose: () => void; userId: string | null; } export function DepositUSDTModal({ isOpen, onClose }: Props) { const { hapticImpact, showAlert } = useTelegram(); const { address: localWalletAddress } = useWallet(); const [selectedNetwork, setSelectedNetwork] = useState('ton'); const [depositCode, setDepositCode] = useState(''); const [depositAddress, setDepositAddress] = useState(''); const [copied, setCopied] = useState<'address' | 'memo' | null>(null); const [deposits, setDeposits] = useState([]); const [showHistory, setShowHistory] = useState(false); const [isLoading, setIsLoading] = useState(false); const [trc20Accepted, setTrc20Accepted] = useState(false); const network = NETWORKS.find((n) => n.id === selectedNetwork) || NETWORKS[0]; // Get deposit address based on network const getNetworkAddress = (networkId: Network): string => { switch (networkId) { case 'ton': return import.meta.env.VITE_DEPOSIT_TON_ADDRESS || ''; case 'polkadot': return import.meta.env.VITE_DEPOSIT_POLKADOT_ADDRESS || ''; case 'trc20': // TRC20 uses HD wallet - address comes from backend return depositAddress; default: return ''; } }; // Fetch user's deposit code and TRC20 address useEffect(() => { const fetchDepositInfo = async () => { if (!isOpen) return; const initData = window.Telegram?.WebApp?.initData; if (!initData) { setDepositCode('---'); return; } setIsLoading(true); try { const { data, error } = await supabase.functions.invoke('get-deposit-info', { body: { initData }, }); if (error) { console.error('Error fetching deposit info:', error); setDepositCode('---'); } else { if (data?.code) setDepositCode(data.code); if (data?.trc20Address) setDepositAddress(data.trc20Address); // If database doesn't have wallet but we have local wallet, sync it if (!data?.walletAddress && localWalletAddress) { supabase.functions.invoke('save-wallet-address', { body: { initData, walletAddress: localWalletAddress }, }); } } } catch (err) { console.error('Error fetching deposit info:', err); setDepositCode('---'); } finally { setIsLoading(false); } }; fetchDepositInfo(); }, [isOpen, localWalletAddress]); // Fetch deposits history useEffect(() => { const fetchDeposits = async () => { if (!isOpen) return; const initData = window.Telegram?.WebApp?.initData; if (!initData) return; try { const { data, error } = await supabase.functions.invoke('get-deposits', { body: { initData }, }); if (!error && data?.deposits) { setDeposits(data.deposits as Deposit[]); } } catch { // Ignore - deposits history is optional } }; fetchDeposits(); }, [isOpen]); const copyToClipboard = async (text: string, type: 'address' | 'memo') => { try { await navigator.clipboard.writeText(text); setCopied(type); hapticImpact('light'); setTimeout(() => setCopied(null), 2000); } catch { showAlert('Kopî nekir'); } }; const getStatusColor = (status: string) => { switch (status) { case 'completed': return 'text-green-400'; case 'confirming': return 'text-yellow-400'; case 'failed': return 'text-red-400'; default: return 'text-muted-foreground'; } }; const getStatusText = (status: string) => { switch (status) { case 'pending': return 'Li benda'; case 'confirming': return 'Tê pejirandin'; case 'completed': return 'Qediya'; case 'failed': return 'Neserketî'; case 'expired': return 'Dema wê derbas bû'; default: return status; } }; const currentAddress = getNetworkAddress(selectedNetwork); const showTrc20Warning = selectedNetwork === 'trc20' && !trc20Accepted; if (!isOpen) return null; return (
{/* Header */}

USDT Depo Bike

Bo wUSDT li Asset Hub

{showHistory ? ( /* Deposit History */

Dîroka Depoyan

{deposits.length === 0 ? (

Hîn depo tune

) : ( deposits.map((deposit) => (
{deposit.network === 'ton' ? '💎' : deposit.network === 'polkadot' ? '⚪' : '🔴'} {deposit.amount} USDT

{new Date(deposit.created_at).toLocaleDateString('ku')}

{getStatusText(deposit.status)}
{deposit.tx_hash && ( n.id === deposit.network)?.explorer}${deposit.tx_hash}`} target="_blank" rel="noopener noreferrer" className="text-xs text-blue-400 flex items-center gap-1 mt-2" > TX bibîne )}
)) )}
) : (
{/* Network Selection */}
{NETWORKS.map((net) => ( ))}
{/* TRC20 Warning */} {showTrc20Warning && (

Dikkkat!

{network.feeWarning}

Mînak: 10 USDT bişîne → 7 wUSDT werbigire ($3 masraf)

)} {/* Deposit Info - Show only when TRC20 is accepted or other networks */} {(selectedNetwork !== 'trc20' || trc20Accepted) && ( <> {/* Important Notice */}

Girîng!

  • Kêmtirîn: {network.minDeposit} USDT
  • {selectedNetwork !== 'trc20' && (
  • Memo/Comment qada de koda xwe binivîse
  • )}
  • Tenê USDT bişîne, tokenên din winda dibin
  • {selectedNetwork === 'trc20' && (
  • $3 masraf dê ji mîqdara we bê kêmkirin
  • )}
{/* Deposit Address */}
{/* Address */}
{isLoading && selectedNetwork === 'trc20' ? (
) : ( {currentAddress || 'Amade nîne'} )}
{/* Memo/Reference - Not needed for TRC20 (unique address) */} {selectedNetwork !== 'trc20' && (
{isLoading ? (
) : ( {depositCode || '---'} )}

⚠️ Vê kodê di memo de binivîse, wekî din depoya te nayê nas kirin!

)} {selectedNetwork === 'trc20' && (

✅ Ev navnîşan tenê ya te ye. Memo ne pêwîst e.

)}
{/* Steps */}

Çawa Depo Bikim?

  1. 1. Navnîşan kopî bike
  2. {selectedNetwork !== 'trc20' && (
  3. 2. Memo kodê kopî bike
  4. )}
  5. {selectedNetwork === 'trc20' ? '2' : '3'}. {selectedNetwork === 'ton' ? 'Telegram Wallet an cîzdana xwe veke' : selectedNetwork === 'polkadot' ? 'Polkadot cîzdana xwe veke' : 'TronLink an cîzdana xwe veke'}
  6. {selectedNetwork === 'trc20' ? '3' : '4'}. USDT bişîne navnîşana jorîn
  7. {selectedNetwork === 'trc20' ? '4' : '5'}. wUSDT dê di nav çend hûrdeman de li hesabê te be
{/* Processing Time */}

Dema pêvajoyê: ~1-5 hûrdem

)}
)}
); }