109 lines
4.2 KiB
JavaScript
109 lines
4.2 KiB
JavaScript
const DEXSCREENER_API_URL = "https://api.dexscreener.io/latest/dex/tokens/";
|
|
const fetchedTickers = new Set();
|
|
|
|
function isSmartContract(address) {
|
|
// Patterns for different blockchain addresses
|
|
const addressMatch = address.match(
|
|
/\b(0x[a-fA-F0-9]{40}|[1-9A-HJ-NP-Za-km-z]{33,34}|[A-HJ-NP-Za-km-z1-9]{58}|tz1[1-9A-HJ-NP-Za-km-z]{33}|erd1[a-z0-9]{58}|ckt1[a-z0-9]{42}|io[a-z0-9]{38}|terra1[a-z0-9]{38}|cosmos1[a-z0-9]{38}|osmo1[a-z0-9]{38}|cro1[a-z0-9]{38}|bc1[a-z0-9]{39}|nano_[13][a-z0-9]{59}|aave_[a-zA-Z0-9]{64}|erd1[a-z0-9]{38}|bsc1[a-z0-9]{38}|G[a-zA-Z0-9]{43})\b/
|
|
);
|
|
if(!addressMatch){
|
|
return "na";
|
|
}
|
|
return addressMatch[0];
|
|
}
|
|
function fetchTokenData(contractAddress, x, y) {
|
|
const url = `${DEXSCREENER_API_URL}${contractAddress}`;
|
|
console.log(url);
|
|
if (fetchedTickers.has(contractAddress)) {
|
|
return; // Ticker already fetched, do nothing
|
|
}
|
|
|
|
fetchedTickers.add(contractAddress); // Add the ticker to the set
|
|
|
|
|
|
try {
|
|
chrome.runtime.sendMessage({ action: "fetchData", url: url }, (response) => {
|
|
if (chrome.runtime.lastError) {
|
|
console.error("Error: ", chrome.runtime.lastError.message);
|
|
fetchedTickers.delete(contractAddress); // Cleanup in case of error
|
|
return;
|
|
}
|
|
|
|
const data = response.data.pairs[0]; // Assuming the first pair is what you want
|
|
if (data) {
|
|
const tooltip = createTooltip(contractAddress, data.baseToken.symbol, data.priceUsd || data.priceNative, data.url, x, y);
|
|
document.body.appendChild(tooltip);
|
|
monitorCursor(tooltip, contractAddress);
|
|
}
|
|
});
|
|
} catch (error) {
|
|
console.error("Failed to send message to background script: ", error);
|
|
fetchedTickers.delete(contractAddress); // Cleanup in case of error
|
|
}
|
|
}
|
|
|
|
|
|
function extractTicker(text) {
|
|
const index = text.indexOf('0x');
|
|
if (index !== -1 && text.length >= index + 42) { // 2 characters for '0x' + 40 characters for the address
|
|
return text.substring(index, index + 42); // Extract '0x' + 40 characters
|
|
}
|
|
return null;
|
|
}
|
|
|
|
function createTooltip(contractAddress, ticker, price, chartUrl, x, y) {
|
|
const tooltip = document.createElement('div');
|
|
tooltip.className = 'dex-tooltip';
|
|
tooltip.dataset.contractAddress = contractAddress;
|
|
tooltip.style.position = 'absolute';
|
|
tooltip.style.background = 'rgba(255, 255, 255, 0.05)'; // Semi-transparent white background
|
|
tooltip.style.backdropFilter = 'blur(10px)'; // Blur effect behind the tooltip
|
|
tooltip.style.color = '#fff'; // White text color
|
|
tooltip.style.padding = '10px'; // Increased padding for better look
|
|
tooltip.style.borderRadius = '10px'; // Rounded corners
|
|
tooltip.style.boxShadow = '0 4px 6px rgba(0, 0, 0, 0.1)'; // Subtle shadow for depth
|
|
tooltip.style.zIndex = '9999';
|
|
tooltip.style.left = `${x}px`;
|
|
tooltip.style.top = `${y}px`;
|
|
tooltip.innerHTML = `Ticker: ${ticker}<br>Price: ${price}`;
|
|
tooltip.addEventListener('click', () => window.open(chartUrl, '_blank'));
|
|
return tooltip;
|
|
}
|
|
|
|
function monitorCursor(tooltip, contractAddress) {
|
|
const distanceThreshold = 100; // Max distance in pixels before the tooltip disappears
|
|
|
|
function onMouseMove(event) {
|
|
const rect = tooltip.getBoundingClientRect();
|
|
const dx = Math.max(rect.left - event.clientX, event.clientX - rect.right);
|
|
const dy = Math.max(rect.top - event.clientY, event.clientY - rect.bottom);
|
|
const distance = Math.sqrt(dx * dx + dy * dy);
|
|
|
|
if (distance > distanceThreshold) {
|
|
document.body.removeChild(tooltip);
|
|
fetchedTickers.delete(contractAddress);
|
|
document.removeEventListener('mousemove', onMouseMove);
|
|
}
|
|
}
|
|
|
|
document.addEventListener('mousemove', onMouseMove);
|
|
}
|
|
|
|
function handleMouseOver(event) {
|
|
const target = event.target;
|
|
|
|
if (target.nodeType === Node.TEXT_NODE || target.nodeType === Node.ELEMENT_NODE) {
|
|
const text = target.textContent.trim();
|
|
const extractedTicker = isSmartContract(text);
|
|
if(extractedTicker == "na"){
|
|
return;
|
|
}
|
|
const rect = target.getBoundingClientRect(); // Get the target's position relative to the viewport
|
|
const x = rect.left + window.scrollX; // X-coordinate
|
|
const y = rect.top + window.scrollY;
|
|
fetchTokenData(extractedTicker, x, y);
|
|
}
|
|
}
|
|
|
|
document.addEventListener('mouseover', handleMouseOver);
|