您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Monitor new div elements on the gmgn.ai/meme page and log unseen data-row-keys
// ==UserScript== // @name GMGN Tools // @namespace https://github.com/Xuthics/GMGN-Tools // @version 0.2 // @license MIT // @description Monitor new div elements on the gmgn.ai/meme page and log unseen data-row-keys // @author Xuthics // @match https://gmgn.ai/* // @icon https://www.google.com/s2/favicons?sz=64&domain=gmgn.ai // @grant none // ==/UserScript== (function() { 'use strict'; // Load seenKeys and excludedKeys from local storage const seenKeys = JSON.parse(localStorage.getItem('seenKeys')) || {}; const excludedKeys = JSON.parse(localStorage.getItem('excludedKeys')) || {}; // Function to check and log new elements function checkNewElements() { const elements = document.querySelectorAll('div.g-table-tbody-virtual-holder-inner div.g-table-row'); const currentTime = Date.now(); elements.forEach(element => { const rowKey = element.getAttribute('data-row-key'); if (rowKey && !excludedKeys[rowKey]) { const lastSeenTime = seenKeys[rowKey] || 0; // Check if the key is new or 10 minutes have passed since last seen if (!lastSeenTime || (currentTime - lastSeenTime) > 30 * 1000) { check_token(rowKey, element).then(() => { console.log(`New or reappeared element found with data-row-key: ${rowKey}`); seenKeys[rowKey] = currentTime; // Save updated seenKeys to local storage localStorage.setItem('seenKeys', JSON.stringify(seenKeys)); }).catch(error => { console.error(`Failed to fetch data for ${rowKey}:`, error); }); } } else if (excludedKeys[rowKey]) { element.style.display = 'none'; } }); } // Function to fetch token data and analyze it async function check_token(token, element) { // Check if the token contains an underscore const underscoreIndex = token.indexOf('_'); // If an underscore is present, use the part after it if (underscoreIndex !== -1) { token = token.substring(underscoreIndex + 1); } const url = `https://gmgn.ai/defi/quotation/v1/tokens/top_holders/sol/${token}?limit=50&cost=20&orderby=amount_percentage&direction=desc`; const response = await fetch(url); if (!response.ok) { throw new Error(`HTTP error! Status: ${response.status}`); } const data = await response.json(); // Data analysis let dev_team_count = 0; let is_suspicious_count = 0; let self_transfer_count = 0; const addresses = data.data.map(item => item.address); data.data.forEach(item => { if (item.maker_token_tags.includes('dev_team')) { dev_team_count++; } if (item.is_suspicious) { is_suspicious_count++; } if (addresses.includes(item.native_transfer.from_address)) { self_transfer_count++; } }); // Display results in HTML const stats = { 'Dev': dev_team_count, 'SUS': is_suspicious_count, 'SeT': self_transfer_count }; const targetElement = element.querySelector('.css-1c1kq07'); if (targetElement) { Object.entries(stats).forEach(([key, value]) => { let existingStat = targetElement.querySelector(`div[data-key="${key}"]`); if (!existingStat) { existingStat = document.createElement('div'); existingStat.setAttribute('data-key', key); targetElement.appendChild(existingStat); } existingStat.textContent = `${key}: ${value}`; existingStat.className = value > 20 ? 'css-1x9rvdf' : 'css-8l1uvm'; }); // Add a hide button inside the css-1c1kq07 element let existingStat = targetElement.querySelector(`button[data-key="hide_btn"]`); if (!existingStat) { const hideButton = document.createElement('button'); hideButton.textContent = 'Hide'; hideButton.style.marginLeft = '5px'; hideButton.style.backgroundColor = 'blue'; hideButton.style.color = 'white'; hideButton.setAttribute('data-key', "hide_btn"); hideButton.onclick = (e) => { e.stopPropagation(); // Prevent link click e.preventDefault(); // Prevent default action element.style.display = 'none'; excludedKeys[token] = true; localStorage.setItem('excludedKeys', JSON.stringify(excludedKeys)); }; targetElement.appendChild(hideButton); } } } // Set an interval to check for new elements every second setInterval(checkNewElements, 1000); })();