您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Dexscreener MEV 地址标注 & GMGN 链接替换
// ==UserScript== // @name Dexscreener MEV 地址标注 // @namespace https://www.tampermonkey.net/ // @version 0.2.0 // @description Dexscreener MEV 地址标注 & GMGN 链接替换 // @author https://x.com/0xshimmer // @match https://dexscreener.com/* // @icon https://www.google.com/s2/favicons?sz=64&domain=dexscreener.com // @grant none // @license MIT // ==/UserScript== (function() { 'use strict'; function addIconsToRow(row) { const addressCell = row.firstChild.children[6]; const addressLink = addressCell.querySelector('a'); if (!addressLink || addressCell.querySelector('.custom-icon')) return; const address = addressLink.href.split('/account/')[1]; // const gmgnLink = document.createElement('a'); // gmgnLink.href = `https://gmgn.ai/sol/address/${address}`; // gmgnLink.target = '_blank'; // gmgnLink.innerHTML = '🔍'; // gmgnLink.className = 'custom-icon'; // gmgnLink.style.marginRight = '5px'; // gmgnLink.style.textDecoration = 'none'; addressLink.href = `https://gmgn.ai/sol/address/${address}`; const copyButton = document.createElement('span'); copyButton.innerHTML = '📋'; copyButton.className = 'custom-icon'; copyButton.style.cursor = 'pointer'; copyButton.style.marginRight = '5px'; copyButton.onclick = () => { navigator.clipboard.writeText(address); copyButton.innerHTML = '✅'; setTimeout(() => { copyButton.innerHTML = '📋'; }, 1000); }; // addressCell.insertBefore(gmgnLink, addressCell.firstChild); addressCell.insertBefore(copyButton, addressCell.firstChild); } function highlightAdjacentDuplicateRows() { const rows = document.querySelectorAll('tr[data-index]'); if (!rows.length) return; for (let i = 0; i < rows.length - 1; i++) { const currentRow = rows[i]; const nextRow = rows[i + 1]; addIconsToRow(currentRow); addIconsToRow(nextRow); const type1 = currentRow.firstChild.children[1].textContent; const type2 = nextRow.firstChild.children[1].textContent; const address1 = currentRow.firstChild.children[6].textContent.slice(0, 6); const address2 = nextRow.firstChild.children[6].textContent.slice(0, 6); const time1 = currentRow.firstChild.children[0].textContent; const time2 = nextRow.firstChild.children[0].textContent; if (time1 === time2 && address1 === address2 && type1 != type2) { currentRow.style.backgroundColor = 'grey'; nextRow.style.backgroundColor = 'grey'; // currentRow.hidden = true; // nextRow.hidden = true; i++; } } } function setupTableObserver() { const firstRow = document.querySelector('tr[data-index]'); if (!firstRow) { setTimeout(setupTableObserver, 1000); return; } let timeout; const observer = new MutationObserver((mutations) => { if (mutations.some(mutation => mutation.addedNodes.length && Array.from(mutation.addedNodes).some(node => node.classList && node.classList.contains('custom-icon') ))) { return; } clearTimeout(timeout); timeout = setTimeout(() => { console.log('Rows updated'); highlightAdjacentDuplicateRows(); }, 200); }); observer.observe(document.body, { childList: true, subtree: true }); highlightAdjacentDuplicateRows(); } const documentObserver = new MutationObserver(() => { const table = document.querySelector('table'); if (table && !table._hasObserver) { console.log('Table found, initializing...'); table._hasObserver = true; setupTableObserver(); } }); documentObserver.observe(document.body, { childList: true, subtree: true }); })();