The Problem

Researchers and traders need a quick, local way to evaluate Solana memecoins—identifying bundle or linked‑wallet patterns, developer ownership, and historical launch performance—without trusting a remote service or manually parsing on‑chain data.

What This Does

gem-search is a local, end‑to‑end tool that scans a Solana contract address, produces a ranked score, and visualizes linked wallets and launch cohorts. The web UI (static/index.html + static/app.js) shows the scan results and the spider’s provenance graph. The background worker (launch/worker.mjs) performs the heavy on‑chain queries and writes the findings to a local SQLite database. The Chrome extension (extension/background.js, extension/content.js) injects the spider UI into social‑media feeds, turning any post into an interactive research card.

How It Is Wired

Entry Point – app.py

  • app.py starts a Flask server (app = Flask(__name__)).
  • On /scan, it calls scan_contract(address) defined in app.py which orchestrates the scan workflow.
  • scan_contract imports launch/worker.mjs via subprocess.run(['node', 'launch/worker.mjs', address]).
  • The worker emits JSON to stdout; app.py parses it, stores it in db.sqlite, and returns the score and links.

Launch Layer – launch/*.mjs

  • worker.mjs loads the Solana RPC client (via @solana/web3.js), pulls transaction history, and calls helper functions in launch/transport.mjs.
  • transport.mjs formats the raw data into the DATA_FORMAT.md schema.
  • guard.mjs validates addresses and checks against a whitelist; check-provider.mjs resolves the RPC provider.

Extension Layer – extension/*.js

  • background.js listens for chrome.runtime.onMessage from content.js.
  • content.js scans the DOM for Solana addresses, sends them to background.js, which forwards them to the local Flask API.
  • The response is rendered into the popup UI (popup.html + popup.js).

Database & Persistence All scan results are stored in db.sqlite via SQLAlchemy models defined in app.py. The tests/ folder contains unit tests for app.py, launch/*.mjs, and the extension.

How To Use It

# Clone
git clone https://github.com/moses-y/gem-search
cd gem-search

# Install dependencies
pip install -r requirements.txt          # Python back‑end
npm install                                # JavaScript front‑end & extension

# Start the local server
python app.py

# Load the Chrome extension
  1. Open chrome://extensions
  2. Enable Developer mode
  3. Load unpacked → ./extension

Environment variables are defined in .env.example; copy it to .env and fill SOLANA_RPC_URL and optional GROK_KEY. Run a scan from the UI or via curl http://localhost:5000/scan?address=....

Real‑World Use

# Inside a notebook
import requests
resp = requests.get('http://localhost:5000/scan', params={'address': 'A1B2C3...'})
print(resp.json()['score'])

The result instantly shows the bundle status and historical launch context.

Code Health & Issues

  • Tests – 12 test files covering Flask routes, launch worker, and extension messages.
  • CI – GitHub Actions workflow ci.yml runs lint, tests, and static analysis.
  • Licensing – MIT license present.
  • No structural red flags – dependency files (requirements.txt, package.json) are in sync; no secrets committed.

The Bottom Line

gem-search delivers a complete, locally hosted memecoin analysis stack with a modern web UI and browser integration. It is well‑tested, CI‑backed, and requires minimal configuration. Teams needing instant, private on‑chain insights can deploy it with the provided commands; developers can modify the worker logic or extension UI without touching unrelated modules.