import React, { useState, useEffect } from 'react';
import { createPortal } from 'react-dom';
import {
ArrowLeft, X, ExternalLink,
Shield, Copy, Check,
TrendingUp
} from 'lucide-react';
import './TokenDetailModal.css';
const TokenDetailModal = ({ token, onClose }) => {
const [activeTab, setActiveTab] = useState('curve'); // 'curve' | 'audit'
const isOnCurve = Boolean(token?.launchpadProgress !== undefined && token.launchpadProgress < 1);
const [chartMode, setChartMode] = useState(isOnCurve ? 'curve' : 'dexscreener');
const [copied, setCopied] = useState(false);
// Close on Escape key press
useEffect(() => {
if (!token) return;
const handleKeyDown = (e) => {
if (e.key === 'Escape') onClose();
};
window.addEventListener('keydown', handleKeyDown);
return () => window.removeEventListener('keydown', handleKeyDown);
}, [token, onClose]);
// Lock background body scroll while modal is open
useEffect(() => {
if (!token) return;
const prevOverflow = document.body.style.overflow;
document.body.style.overflow = 'hidden';
return () => {
document.body.style.overflow = prevOverflow;
};
}, [token]);
if (!token) return null;
const copyAddress = () => {
if (token?.tokenAddress) {
navigator.clipboard.writeText(token.tokenAddress);
setCopied(true);
setTimeout(() => setCopied(false), 2000);
}
};
const curvePercent = token.launchpadProgress !== undefined
? Math.min(100, Math.max(0, Math.round(token.launchpadProgress * 100)))
: 0;
const dexscreenerUrl = `https://dexscreener.com/bsc/${token.tokenAddress}?embed=1&theme=dark&trades=0&info=0`;
const modalContent = (
{/* Floating Close Button for immediate exit regardless of scroll position */}
CLOSE [ESC]
e.stopPropagation()}>
{/* Top Navigation Bar: Guaranteed visible, dedicated Back button */}
← BACK TO SCANNER FEED
ESC
{/* Token Identity Banner */}
BACK
{ e.target.src = `https://api.dicebear.com/9.x/shapes/svg?seed=${token.tokenAddress}`; }}
/>
{token.tokenName}
{token.tokenSymbol && (
${token.tokenSymbol}
)}
{token.tokenAddress ? `${token.tokenAddress.slice(0, 8)}…${token.tokenAddress.slice(-6)}` : ''}
{copied ? : }
{isOnCurve ? (
🚀 ON FLAP CURVE ({curvePercent}%)
) : (
✅ MIGRATED TO DEX
)}
Trade on Flap.sh
{/* Navigation Tabs */}
setActiveTab('curve')}
>
📈 BONDING CURVE & CHART
setActiveTab('audit')}
>
🛡️ SECURITY AUDIT
{/* Modal Body */}
{activeTab === 'curve' && (
{/* Bonding Curve Telemetry Banner */}
FLAP.SH BONDING CURVE TELEMETRY
{isOnCurve
? 'Token is accumulating liquidity on Flap.sh bonding curve before DEX listing.'
: 'Bonding curve 100% completed. Liquidity has been seeded to PancakeSwap DEX.'}
{curvePercent}% TO DEX
{/* Key Metrics Grid */}
MARKET CAP
{token.marketCapUsd ? `$${Number(token.marketCapUsd).toLocaleString('en-US', { maximumFractionDigits: 0 })}` : 'N/A'}
CURVE LIQUIDITY
{token.liquidityUsd ? `$${Number(token.liquidityUsd).toLocaleString('en-US', { maximumFractionDigits: 0 })}` : 'N/A'}
TOP 10 HOLDERS
{token.top10HolderRate ? `${(Number(token.top10HolderRate) * 100).toFixed(1)}%` : 'N/A'}
DEV HOLDING
{token.creatorHoldRate !== undefined ? `${(Number(token.creatorHoldRate) * 100).toFixed(2)}%` : '0%'}
{/* Primary CTA Button */}
{/* Chart embed if user toggles or if migrated */}
{chartMode === 'dexscreener' && (
)}
{/* Quick Links Row */}
)}
{activeTab === 'audit' && (
AUTOMATED CONTRACT & DEV AUDIT REPORT
Real-time algorithmic checks analyzing smart contract bytecode, transaction clustering, dev funding origins, and anti-honeypot safeties.
{/* 1. Contract Bytecode Audit */}
1. BYTECODE & PROXY INTEGRITY
{token.taxInnovation?.includes('Custom') || token.taxInnovation?.includes('Suspicious') ? '⚠️ SUSPICIOUS' : '✅ VERIFIED'}
Architecture:
{token.taxInnovation || 'Standard Flap Proxy'}
Proxy Type:
{token.taxInnovation?.includes('Custom') ? 'Non-Standard Minimal Proxy' : 'Official ERC-1167 Flap Implementation'}
Honeypot Detected:
{token.isHoneypot ? '🚨 YES — High Honeypot Risk' : '✅ NO — Standard Transferability'}
{/* 2. Dev Wallet Clustering */}
2. DEV ON-CHAIN CLUSTERING
20) ? 'badge-danger' : 'badge-good'}`}>
{(token.pastScamsCount && token.pastScamsCount > 20) ? '🚨 HIGH RISK' : '✅ CLEAN'}
Deployer Cluster:
{token.devClusterHistory || 'Private Wallet'}
Funding Source:
{token.funderText || 'Exchange / Private'}
Serial Launches:
{token.creatorCreatedCount ? `${token.creatorCreatedCount} previous tokens` : '1st Launch'}
{/* 3. Tax & Safeties */}
3. TAX & HONEYPOT SAFEGUARD
8) || (token.sellTax && token.sellTax > 8)) ? 'badge-danger' : 'badge-good'}`}>
{((token.buyTax && token.buyTax > 8) || (token.sellTax && token.sellTax > 8)) ? '🚨 PREDATORY (>8%)' : '✅ SAFE (≤8%)'}
Buy Tax:
{token.buyTax !== null && token.buyTax !== undefined ? `${token.buyTax}%` : '0%'}
Sell Tax:
{token.sellTax !== null && token.sellTax !== undefined ? `${token.sellTax}%` : '0%'}
Dev Token Hold:
{token.creatorHoldRate ? `${(token.creatorHoldRate * 100).toFixed(2)}%` : '0%'}
{/* 4. Social & Phishing Checks */}
4. SOCIAL CLONE & PHISHING
{token.hasSocialClone ? '🚨 CLONE DETECTED' : '✅ ORIGINAL'}
Social Status:
{token.webStatus || 'No Public Socials'}
Telegram:
{token.tgUrl ? Joined ↗ : 'None'}
Twitter / X:
{token.xUrl ? Linked ↗ : 'None'}
)}
{/* Modal Bottom Return Bar for Easy Dismissal */}
← Return to Live Scanner Feed
Press ESC or click outside to dismiss
);
return typeof document !== 'undefined'
? createPortal(modalContent, document.body)
: modalContent;
};
export default TokenDetailModal;