repositories
loading repo index
repositories
loading repo index
repository
loading code, commits, and activity
public Clawd ADK gateway launch mirror
stars
latest
clone command
git clone gitlawb://did:key:z6Mkq5mY...iFZ5/my-project-publ...git clone gitlawb://did:key:z6Mkq5mY.../my-project-publ...2fa351d6docs: add automaton and perps launch sources16d ago| #1 | { |
| #2 | "skillId": "dex-screener-scanner", |
| #3 | "name": "dex-screener-scanner", |
| #4 | "description": "Automate DexScreener Solana token discovery and screening via browser automation. Navigate dexscreener.com/solana, scrape real-time token listings, filter by volume/liquidity/age/holders, and identify the best opportunities. Triggers: scan dexscreener, find new tokens, find trending tokens, screen Solana tokens, best tokens on Solana, dexscreener scanner.", |
| #5 | "category": "pump-protocol", |
| #6 | "path": "dex-screener-scanner/SKILL.md", |
| #7 | "url": "https://x402.wtf/api/skills/dex-screener-scanner", |
| #8 | "tags": [ |
| #9 | "dex", |
| #10 | "solana", |
| #11 | "screener", |
| #12 | "scanner" |
| #13 | ], |
| #14 | "requiredEnv": [], |
| #15 | "homepage": null, |
| #16 | "attestation": { |
| #17 | "status": "pending", |
| #18 | "isFormallyVerified": false, |
| #19 | "attestationPda": null, |
| #20 | "verificationTimestamp": null |
| #21 | }, |
| #22 | "markdown": "---\nname: dex-screener-scanner\ndescription: \"Automate DexScreener Solana token discovery and screening via browser automation. Navigate dexscreener.com/solana, scrape real-time token listings, filter by volume/liquidity/age/holders, and identify the best opportunities. Triggers: scan dexscreener, find new tokens, find trending tokens, screen Solana tokens, best tokens on Solana, dexscreener scanner.\"\n---\n\n# DexScreener Solana Scanner\n\nAutonomous agent skill for scanning and screening Solana tokens on DexScreener using browser automation (Playwright/Puppeteer). The goal is to navigate `dexscreener.com/solana`, extract token data from live listings, apply screening filters, and identify the best trading opportunities.\n\n## Overview\n\nThis skill uses browser automation to:\n\n1. Navigate to DexScreener's Solana board\n2. Scrape live token listings (new, trending, gainers, etc.)\n3. Extract key metrics for each token\n4. Apply configurable screening filters to find the best opportunities\n5. Return ranked results with rationale\n\n## Workflow\n\n### Step 1: Launch Browser & Navigate\n\nUse a browser automation tool (Playwright or Puppeteer) to open `https://dexscreener.com/solana`.\n\n```python\n# Example with Playwright\npage = await browser.new_page()\nawait page.goto(\"https://dexscreener.com/solana\", wait_until=\"domcontentloaded\")\n```\n\n**Important:** DexScreener is a heavy React SPA. Wait for the token table rows to render before scraping. The table typically appears within 3-8 seconds.\n\n### Step 2: Wait for Token Table to Load\n\nThe token listing is a dynamic table. Watch for:\n\n- CSS selector for table rows: `div[data-group=\"token-row\"]` or `.ds-table-row` or `tr[data-id]`\n- The table has multiple tabs: **New**, **Trending**, **Gainers**, **Recently Copied**, etc.\n- Wait for at least one row to be visible before scraping\n\nRecommended wait strategy:\n\n```python\n# Wait for first token row to appear\nawait page.wait_for_selector('[data-group=\"token-row\"]', timeout=15000)\n# Or wait for the table body\nawait page.wait_for_selector('table tbody tr', timeout=15000)\n```\n\nIf the wait times out, the page may be loading slowly — retry once with a longer timeout.\n\n### Step 3: Parse Token Listing Data\n\nEach token row typically contains these fields (column order may vary slightly):\n\n| Field | Description | Example |\n|-------|-------------|---------|\n| **#** | Rank/position | 1, 2, 3 |\n| **Name/Symbol** | Token name + ticker | \"dogwifhat / WIF\" |\n| **Price** | Current SOL or USD price | \"$0.0042\" |\n| **Price Change** | 5m/1h/6h/24h change % | \"+15.3%\" |\n| **Volume** | 24h trading volume | \"$1.2M\" |\n| **Liquidity** | Pool liquidity | \"$45K\" |\n| **Market Cap** | Fully diluted market cap | \"$2.1M\" |\n| **Age** | How long since creation | \"3m\" (3 minutes), \"1h\" |\n| **Txns** | Transaction count (buys/sells) | \"1.2K / 800\" |\n| **Holders** | Unique holder count | \"450\" |\n| **FDV / Liq** | FDV-to-Liquidity ratio | \"12.5x\" |\n\n**Parsing approach:**\n\n```python\nrows = await page.query_selector_all('[data-group=\"token-row\"]')\ntokens = []\nfor row in rows:\n cells = await row.query_selector_all('td')\n # Extract based on cell index\n tokens.append({\n \"rank\": await cells[0].inner_text(),\n \"name\": await cells[1].inner_text(),\n \"price\": await cells[2].inner_text(),\n \"change_5m\": await cells[3].inner_text(),\n \"volume\": await cells[4].inner_text(),\n \"liquidity\": await cells[5].inner_text(),\n \"market_cap\": await cells[6].inner_text(),\n \"age\": await cells[7].inner_text(),\n \"txns\": await cells[8].inner_text(),\n \"holders\": await cells[9].inner_text(),\n # ... etc\n })\n```\n\n**Note:** Cell indices may shift if DexScreener updates their layout. Always inspect the actual DOM first. Use `page.evaluate()` for more robust scraping if query selectors are unreliable.\n\n### Step 4: Switch Between Listing Tabs\n\nDexScreener has multiple tabs that reveal different token sets. Click these to scan more broadly:\n\n```python\n# Available tabs (selectors may vary):\n# New: Most recently created pairs\nawait page.click('button:has-text(\"New\")')\n# Trending: Hottest tokens right now\nawait page.click('button:has-text(\"Trending\")')\n# Gainers: Top gainers\nawait page.click('button:has-text(\"Gainers\")')\n# Recently Copied: Tokens being copied from other chains\nawait page.click('button:has-text(\"Recently Copied\")')\n```\n\nWait 2-3 seconds after clicking a tab for the table to re-render.\n\n### Step 5: Scroll to Load More Tokens\n\nDexScreener loads tokens in batches (about 25 per page). Scroll down to trigger lazy loading:\n\n```python\n# Scroll to bottom of table to load more\nfor _ in range(3):\n await page.evaluate('window.scrollBy(0, 800)')\n await page.wait_for_timeout(1500)\n```\n\n**Be respectful:** Don't hammer the page. 2-3 scrolls is enough to get a meaningful sample (~75-100 tokens per tab).\n\n### Step 6: Apply Screening Filters\n\nAfter collecting raw token data, apply filters to find the \"best\" tokens. These are the recommended default thresholds:\n\n| Criterion | Recommended Threshold | Why |\n|-----------|----------------------|-----|\n| **Min Liquidity** | ≥ $10,000 | Below this = high slippage, rug risk |\n| **Min Volume** | ≥ $50,000 (24h) | Shows organic interest |\n| **Max Age** | ≤ 48 hours | Catches new launches |\n| **Min Holders** | ≥ 50 unique | Indicates distribution, not a single dev wallet |\n| **Max Holder Concentration** | Top 10 holders < 20% | Prevents whale manipulation |\n| **Min Price Change (5m)** | ≥ 5% (for momentum) | Shows buying pressure |\n| **FDV / Liquidity Ratio** | < 50x | Lower = less overvalued relative to available liquidity |\n| **Min Txns** | ≥ 100 transactions | Shows real activity |\n\n**Screening function example:**\n\n```python\ndef screen_tokens(tokens, config=None):\n defaults = {\n \"min_liquidity\": 10_000,\n \"min_volume\": 50_000,\n \"max_age_hours\": 48,\n \"min_holders\": 50,\n \"min_txns\": 100,\n }\n config = {**defaults, **(config or {})}\n \n passed = []\n for t in tokens:\n reasons = []\n if t.get(\"liquidity_usd\", 0) >= config[\"min_liquidity\"]:\n reasons.append(f\"liquidity={t['liquidity_usd']}\")\n if t.get(\"volume_24h\", 0) >= config[\"min_volume\"]:\n reasons.append(f\"volume={t['volume_24h']}\")\n if t.get(\"age_hours\", 999) <= config[\"max_age_hours\"]:\n reasons.append(f\"age={t['age_hours']}h\")\n if t.get(\"holders\", 0) >= config[\"min_holders\"]:\n reasons.append(f\"holders={t['holders']}\")\n if t.get(\"txns\", 0) >= config[\"min_txns\"]:\n reasons.append(f\"txns={t['txns']}\")\n if reasons:\n passed.append((t, reasons))\n \n # Sort by volume (descending) - highest volume = most liquid interest\n passed.sort(key=lambda x: x[0].get(\"volume_24h\", 0), reverse=True)\n return passed\n```\n\n### Step 7: Click Through for Token Details\n\nFor tokens that pass screening, click through to the pair page for deeper analysis:\n\n```python\n# Click on a token row to navigate to its pair page\npair_link = await row.query_selector('a[href*=\"/solana/\"]')\npair_url = await pair_link.get_attribute('href')\nawait page.goto(f\"https://dexscreener.com{pair_url}\")\n```\n\nOn the pair page you can extract:\n- **Full holder distribution** (top holders %)\n- **Price chart context** (support/resistance levels)\n- **Social links** (Twitter, Telegram, website)\n- **Token contract address** (for further analysis)\n- **Creator wallet** (check if it's a known rug deployer)\n\n**Safety check on pair page:**\n\n```python\n# Check if the token CA has been rug-checked\n# Look for \"Rug Pull\" or scam warnings in the UI\nrisk_warning = await page.query_selector('[class*=\"risk\"], [class*=\"warning\"], [class*=\"scam\"]')\nif risk_warning:\n warning_text = await risk_warning.inner_text()\n # Flag this token as potentially dangerous\n```\n\n## Token Ranking System\n\nRank screened tokens using a scoring system:\n\n```python\ndef score_token(t):\n score = 0\n score += min(t.get(\"volume_24h\", 0) / 100_000, 10) # up to 10 pts for volume\n score += min(t.get(\"liquidity_usd\", 0) / 50_000, 10) # up to 10 pts for liquidity\n score += 5 if t.get(\"age_hours\", 999) < 1 else 0 # bonus for brand new\n score += 3 if t.get(\"change_5m\", 0) > 10 else 0 # bonus for strong momentum\n score += 2 if t.get(\"holders\", 0) > 200 else 0 # bonus for wide distribution\n score -= 5 if t.get(\"fdv_liquidity_ratio\", 0) > 100 else 0 # penalty for high FDV/liq\n return score\n```\n\nReturn results sorted by score descending, with a brief rationale for each pick.\n\n## Tab Strategy\n\nScan tabs in this priority order for best results:\n\n1. **Trending** — Hottest tokens, highest chance of continuation\n2. **New** — Recently created, potential early entries\n3. **Gainers** — Strong momentum plays\n4. **Recently Copied** — Arbitrage opportunities from other chains\n\nFor a comprehensive scan, scrape all 4 tabs and deduplicate by contract address.\n\n## Edge Cases & Handling\n\n| Situation | Handling |\n|-----------|----------|\n| **Cloudflare/rate limiting** | Add random delays (1-3s) between actions. If blocked, rotate user-agent |\n| **No tokens pass filters** | Report honestly: \"No tokens meet the criteria. Consider loosening thresholds\" |\n| **Table fails to load** | Retry with page refresh. If persistent, report error and suggest checking if dexscreener.com is accessible |\n| **Dynamic class names** | Use stable data attributes (`[data-group]`) or text matchers instead of CSS classes |\n| **Very new tokens (< 1 min)** | May not have full data. These are high-risk; flag them as \"extremely early\" |\n| **Duplicate tokens across tabs** | Deduplicate by contract address to avoid double-counting |\n\n## Output Format\n\nPresent findings in a structured format:\n\n```\n## DexScreener Scan Results\n\n### Top Picks (Passed Screening)\n1. **$TOKEN** — Score: 18/20\n - Price: $0.0042 | Vol: $1.2M | Liq: $45K | Age: 3m | Holders: 150\n - Rationale: Brand new, strong volume, good liquidity, wide holder distribution\n - CA: [contract_address]\n\n2. **$TOKEN2** — Score: 14/20\n - ...\n\n### Tokens Scanned\n- Trending tab: 25 tokens\n- New tab: 25 tokens\n- Total unique: 48 tokens\n- Passed screening: 2 tokens\n\n### Market Notes\n- Average liquidity across scanned tokens: $12K\n- Heaviest volume: $TOKEN ($1.2M)\n- Oldest token in top 25: 6h ago\n```\n\n## Scripts\n\n### `scripts/scan_dexscreener.py`\nMain scanning script that orchestrates: open browser → navigate → scrape → filter → rank → output.\n\n### `scripts/screen_tokens.py`\nStandalone screening/filtering logic that can be used independently on cached data. Accepts configurable thresholds via stdin or arguments.\n\n## References\n\n### `references/dexscreener_layout.md`\nCurrent DOM structure and selectors for dexscreener.com/solana. Update this when DexScreener changes their layout. Always inspect the page before scraping to verify selectors are still valid.\n" |
| #23 | } |
| #24 |