> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cosmos.network/llms.txt
> Use this file to discover all available pages before exploring further.

# EIP Reference

> A complete list of Ethereum Mainnet "Final" EIPs and details on their implementation with Cosmos-EVM

export default function EIPCompatibilityTable({sheetTab} = {}) {
  const [searchTerm, setSearchTerm] = useState('');
  const [sortConfig, setSortConfig] = useState({
    key: null,
    direction: 'asc'
  });
  const [eipData, setEipData] = useState([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);
  const SHEET_ID = '1OGscheUSh-g15p7mNYjSaxI05E8O_3R3tDK0IwXaczk';
  const SHEET_GIDS = {
    'v0.4.x': '422015233',
    'eip_compatibility_data': '3257530'
  };
  const detectVersionFromPath = () => {
    if (typeof window !== 'undefined') {
      const path = window.location.pathname;
      const versionMatch = path.match(/\/docs\/([vV]\d+\.\d+\.[\dx]+)\//);
      if (versionMatch) {
        return versionMatch[1];
      }
    }
    return null;
  };
  const effectiveSheetTab = sheetTab || detectVersionFromPath();
  useEffect(() => {
    loadGoogleSheetData();
  }, [effectiveSheetTab]);
  const loadGoogleSheetData = async () => {
    try {
      console.log('EIP Table - sheetTab prop:', sheetTab);
      console.log('EIP Table - Detected from URL:', detectVersionFromPath());
      console.log('EIP Table - Effective sheet tab:', effectiveSheetTab);
      console.log('EIP Table - Available GIDs:', SHEET_GIDS);
      let url;
      let debugInfo = '';
      if (effectiveSheetTab && SHEET_GIDS[effectiveSheetTab]) {
        const gid = SHEET_GIDS[effectiveSheetTab];
        url = `https://docs.google.com/spreadsheets/d/${SHEET_ID}/gviz/tq?gid=${gid}&headers=1&tqx=out:json`;
        debugInfo = `Using GID ${gid} for sheet "${effectiveSheetTab}"`;
      } else if (effectiveSheetTab) {
        const range = `${effectiveSheetTab}!A:Z`;
        url = `https://docs.google.com/spreadsheets/d/${SHEET_ID}/gviz/tq?range=${encodeURIComponent(range)}&headers=1&tqx=out:json`;
        debugInfo = `Using range fallback for unmapped sheet "${effectiveSheetTab}"`;
      } else {
        url = `https://docs.google.com/spreadsheets/d/${SHEET_ID}/gviz/tq?gid=3257530&tqx=out:json`;
        debugInfo = 'Using default main sheet (GID 3257530)';
      }
      console.log('EIP Table - ' + debugInfo);
      console.log('EIP Table - Fetching URL:', url);
      const response = await fetch(url);
      const text = await response.text();
      console.log('EIP Table - Response status:', response.status);
      console.log('EIP Table - Response text preview:', text.substring(0, 200));
      const jsonMatch = text.match(/google\.visualization\.Query\.setResponse\((.*)\);?$/);
      if (!jsonMatch) {
        console.error('EIP Table - Failed to parse response. Full text:', text);
        throw new Error('Invalid response format');
      }
      const data = JSON.parse(jsonMatch[1]);
      if (data.status === 'error') {
        console.error('EIP Table - Google Sheets API error:', data.errors);
        throw new Error(`Google Sheets error: ${data.errors?.[0]?.message || 'Unknown error'}`);
      }
      const rows = data.table?.rows || [];
      const cols = data.table?.cols || [];
      console.log('EIP Table - Rows found:', rows.length);
      console.log('EIP Table - Columns found:', cols.length);
      if (cols.length > 0) {
        console.log('EIP Table - Column labels:', cols.map(c => c.label || c.id));
      }
      const parsed = rows.map((row, rowIndex) => {
        const obj = {};
        cols.forEach((col, index) => {
          const value = row.c[index] ? row.c[index].v : null;
          const label = col.label || col.id;
          if (rowIndex === 0) {
            console.log(`EIP Table - Row 0, Col ${label}:`, value);
          }
          if (label === 'eip') {
            obj[label] = parseInt(value) || 0;
          } else if (label === 'critical') {
            obj[label] = value === true || value === 'TRUE';
          } else if (label === 'issue' || label === 'pr') {
            obj[label] = value ? String(value) : '';
          } else if (label === 'geth' || label === 'priority' || label === 'triage') {
            return;
          } else {
            obj[label] = value || '';
          }
        });
        return obj;
      });
      setEipData(parsed);
      setLoading(false);
      console.log('EIP Table - Data loaded, first 3 EIPs:', parsed.slice(0, 3).map(e => ({
        eip: e.eip,
        title: e.title,
        status: e.status
      })));
      console.log('EIP Table - Total EIPs loaded:', parsed.length);
    } catch (err) {
      console.error('Error loading sheet data:', err);
      setError('Failed to load data from Google Sheets');
      setLoading(false);
    }
  };
  const handleSort = key => {
    let direction = 'asc';
    if (sortConfig.key === key && sortConfig.direction === 'asc') {
      direction = 'desc';
    }
    setSortConfig({
      key,
      direction
    });
  };
  const sortedData = useMemo(() => {
    let sortableItems = [...eipData];
    const statusPriority = {
      'supported': 5,
      'in_development': 4,
      'partial': 3,
      'not_applicable': 2,
      'unknown': 1,
      'not_supported': 0
    };
    sortableItems.sort((a, b) => {
      const aPriority = statusPriority[a.status] || 0;
      const bPriority = statusPriority[b.status] || 0;
      if (sortConfig.key !== 'status' && aPriority !== bPriority) {
        return bPriority - aPriority;
      }
      const key = sortConfig.key || 'eip';
      let aVal = a[key];
      let bVal = b[key];
      if (key === 'status') {
        if (aPriority !== bPriority) {
          return sortConfig.direction === 'asc' ? bPriority - aPriority : aPriority - bPriority;
        }
        return 0;
      }
      if (aVal == null) return 1;
      if (bVal == null) return -1;
      if (typeof aVal === 'boolean') {
        aVal = aVal ? 1 : 0;
        bVal = bVal ? 1 : 0;
      } else if (typeof aVal === 'string') {
        aVal = aVal.toLowerCase();
        bVal = bVal.toLowerCase();
      }
      if (aVal < bVal) return sortConfig.direction === 'asc' ? -1 : 1;
      if (aVal > bVal) return sortConfig.direction === 'asc' ? 1 : -1;
      return 0;
    });
    return sortableItems;
  }, [eipData, sortConfig]);
  const filteredData = sortedData.filter(eip => {
    if (!eip || !eip.eip) return false;
    const matchesSearch = searchTerm === '' || String(eip.eip).includes(searchTerm) || eip.title && eip.title.toLowerCase().includes(searchTerm.toLowerCase()) || eip.note && eip.note.toLowerCase().includes(searchTerm.toLowerCase());
    return matchesSearch;
  });
  const uniqueStatuses = [...new Set(eipData.map(eip => eip.status))];
  const statusColors = {
    'supported': 'text-green-600 dark:text-green-400',
    'partial': 'text-yellow-600 dark:text-yellow-400',
    'not_supported': 'text-red-600 dark:text-red-400',
    'not_applicable': 'text-gray-500 dark:text-gray-400',
    'in_development': 'text-cyan-600 dark:text-cyan-400',
    'unknown': 'text-gray-400 dark:text-gray-500'
  };
  const renderTextWithLinks = text => {
    if (!text || typeof text !== 'string') {
      return <span>{text || ''}</span>;
    }
    if (text.includes('7702') || text.includes('EOA') || text.includes('[')) {
      console.log('EIP Table - Parsing text for links:', JSON.stringify(text));
    }
    const linkRegex = /\[([^\]]+)\]\(([^)]+)\)/g;
    const parts = [];
    let lastIndex = 0;
    let match;
    let keyIndex = 0;
    while ((match = linkRegex.exec(text)) !== null) {
      console.log('EIP Table - Found link match:', {
        full: match[0],
        text: match[1],
        url: match[2],
        index: match.index
      });
      if (match.index > lastIndex) {
        const beforeText = text.slice(lastIndex, match.index);
        if (beforeText) {
          parts.push(<span key={`text-${keyIndex++}`}>
              {beforeText}
            </span>);
        }
      }
      parts.push(<a key={`link-${keyIndex++}`} href={match[2]} target="_blank" rel="noopener noreferrer" className="text-blue-600 dark:text-blue-400 hover:text-blue-700 dark:hover:text-blue-300 hover:underline transition-colors">
          {match[1]}
        </a>);
      lastIndex = match.index + match[0].length;
    }
    if (lastIndex < text.length) {
      const remainingText = text.slice(lastIndex);
      if (remainingText) {
        parts.push(<span key={`text-${keyIndex++}`}>
            {remainingText}
          </span>);
      }
    }
    if (parts.length === 0) {
      return <span>{text}</span>;
    } else if (parts.length === 1) {
      return parts[0];
    } else {
      return <>{parts}</>;
    }
  };
  const SortIcon = ({column}) => {
    if (sortConfig.key !== column) {
      return <span className="text-gray-400 ml-1">↕</span>;
    }
    return sortConfig.direction === 'asc' ? <span className="text-blue-600 ml-1">↑</span> : <span className="text-blue-600 ml-1">↓</span>;
  };
  if (loading) {
    return <div className="text-center py-8">
        Loading EIP data from Google Sheets{effectiveSheetTab ? ` (${effectiveSheetTab} snapshot)` : ''}...
      </div>;
  }
  if (error) {
    return <div className="text-center py-8">
        <p className="text-red-600 dark:text-red-400">{error}</p>
        <p className="text-sm text-gray-600 dark:text-gray-400 mt-2">Using fallback data</p>
      </div>;
  }
  return <div className="w-full bg-white dark:bg-black relative p-6 border border-gray-200 dark:border-gray-800 rounded-lg">
      {}
      <div className="sticky top-0 z-20 bg-white dark:bg-black pb-4 border-b border-gray-200 dark:border-gray-800">
        <div className="space-y-4">
        <div className="flex gap-4 flex-wrap">
          <div className="flex-1">
            <input type="text" placeholder="Search by EIP number, title, or notes..." value={searchTerm} onChange={e => setSearchTerm(e.target.value)} className="w-full px-4 py-2 border border-gray-300 dark:border-gray-700 rounded-lg bg-gray-50 dark:bg-gray-900 text-gray-900 dark:text-white placeholder-gray-500 focus:ring-2 focus:ring-black dark:focus:ring-white" />
          </div>
        </div>

          <div className="text-sm text-gray-600 dark:text-gray-400">
            Showing {filteredData.length} of {eipData.length} EIPs
            {effectiveSheetTab && <span className="ml-2 text-blue-600 dark:text-blue-400">Version {effectiveSheetTab} snapshot</span>}
            {error && <span className="ml-2 text-yellow-600">Warning: Using cached data</span>}
          </div>
        </div>
      </div>

      {}
      <div className="overflow-auto shadow-[0_0_0_1px_rgba(156,163,175,0.3)] dark:shadow-[0_0_0_1px_rgba(75,85,99,0.5)] rounded-lg mt-4" style={{
    maxHeight: 'calc(100vh - 240px)'
  }}>
        <table className="min-w-full divide-y divide-gray-200 dark:divide-gray-800 relative">
          <thead className="bg-gray-50 dark:bg-gray-900 sticky top-0 z-10">
            <tr>
              <th className="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider cursor-pointer hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors" onClick={() => handleSort('eip')}>
                EIP <SortIcon column="eip" />
              </th>
              <th className="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider cursor-pointer hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors" onClick={() => handleSort('title')}>
                Title <SortIcon column="title" />
              </th>
              <th className="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider cursor-pointer hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors" onClick={() => handleSort('status')}>
                Status <SortIcon column="status" />
              </th>
              <th className="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider cursor-pointer hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors" onClick={() => handleSort('critical')}>
                Critical <SortIcon column="critical" />
              </th>
              <th className="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider cursor-pointer hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors" onClick={() => handleSort('cosmos')}>
                Implementation <SortIcon column="cosmos" />
              </th>
              <th className="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">
                Notes
              </th>
            </tr>
          </thead>
          <tbody className="bg-white dark:bg-black divide-y divide-gray-200 dark:divide-gray-800">
            {filteredData.map((eip, index) => <tr key={eip.eip} className={`${index % 2 === 0 ? 'bg-white dark:bg-black' : 'bg-gray-50 dark:bg-gray-900'} hover:bg-gray-50 dark:hover:bg-gray-800 transition-colors`}>
                <td className="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900 dark:text-white">
                  <a href={`https://eips.ethereum.org/EIPS/eip-${eip.eip}`} target="_blank" rel="noopener noreferrer" className="text-blue-600 dark:text-blue-400 hover:text-blue-700 dark:hover:text-blue-300 hover:underline transition-colors">
                    {eip.eip}
                  </a>
                </td>
                <td className="px-6 py-4 text-sm text-gray-900 dark:text-gray-300">
                  {eip.title}
                </td>
                <td className="px-6 py-4 whitespace-nowrap text-sm">
                  <span className={`font-medium ${statusColors[eip.status]}`}>
                    {eip.status ? eip.status.replace(/_/g, ' ') : ''}
                  </span>
                </td>
                <td className="px-7 py-4 whitespace-nowrap text-sm text-gray-900 dark:text-gray-300">
                  {eip.critical ? 'Yes' : '-'}
                </td>
                <td className="px-6 py-4 text-sm text-gray-900 dark:text-gray-300">
                  <div>
                    {renderTextWithLinks(eip.cosmos)}
                    {eip.pr && <a href={`https://github.com/cosmos/evm/pull/${eip.pr}`} target="_blank" rel="noopener noreferrer" className="ml-2 text-blue-600 dark:text-blue-400 hover:underline">
                        #{eip.pr}
                      </a>}
                  </div>
                </td>
                <td className="px-6 py-4 text-sm text-gray-500 dark:text-gray-400">
                  <div>
                    {renderTextWithLinks(eip.note)}
                    {eip.issue && <a href={`https://github.com/cosmos/evm/issues/${eip.issue}`} target="_blank" rel="noopener noreferrer" className="ml-2 text-blue-600 dark:text-blue-400 hover:underline">
                        #{eip.issue}
                      </a>}
                  </div>
                </td>
              </tr>)}
          </tbody>
        </table>
      </div>
    </div>;
}

<EIPCompatibilityTable sheetTab="v0.5.0" />

***

*This page displays a frozen snapshot of EIP compatibility data for version v0.5.0.*
