Real-time detection and risk analysis for new Pump.fun token launches on Solana.
- Real-time Detection: Webhook-based ingestion of Solana transactions
- Pump.fun Focus: Identifies token
createinstructions via program ID and discriminator matching - Risk Scoring: Heuristic-based analysis (0-100 score, LOW/MED/HIGH labels)
- Mint authority presence
- Freeze authority presence
- Holder concentration (top holder %, top 5%)
- Metadata existence check
- REST API: Query launches and token risk reports
- Production-Ready: Idempotency, async processing, structured logging, CI/CD
┌─────────────┐
│ Webhook │ POST /webhooks/helius
│ Provider │ (e.g., Helius)
│ (Solana) │
└──────┬──────┘
│
▼
┌─────────────────────────────────────┐
│ Fastify Server │
│ ┌──────────────────────────────┐ │
│ │ Webhook Handler │ │
│ │ - Auth check │ │
│ │ - Payload validation (Zod) │ │
│ │ - Pump.fun detection │ │
│ │ - Upsert LaunchEvent │ │
│ │ - Enqueue for risk scoring │ │
│ │ - Return 200 (async) │ │
│ └──────────────────────────────┘ │
│ │
│ ┌──────────────────────────────┐ │
│ │ Processing Queue (p-queue) │ │
│ │ - Concurrency: 3 (default) │ │
│ │ - Deduplication │ │
│ │ - Async risk computation │ │
│ └──────────────────────────────┘ │
│ │
│ ┌──────────────────────────────┐ │
│ │ Risk Scorer │ │
│ │ - Fetch mint info (RPC) │ │
│ │ - Check authorities │ │
│ │ - Holder concentration │ │
│ │ - Metadata check │ │
│ │ - Compute score + label │ │
│ │ - Store TokenRiskReport │ │
│ └──────────────────────────────┘ │
└─────────────────────────────────────┘
│
▼
┌─────────────┐
│ SQLite DB │
│ (Prisma) │
│ │
│ - LaunchEvent
│ - TokenRiskReport
└─────────────┘
- Node.js 20+
- npm
# Clone repo and navigate to this folder
cd solana-pump-radar
# Install dependencies
npm install
# Set up environment
cp .env.example .env
# Edit .env with your values
# Set up database
npm run db:generate
npm run db:migratenpm run devServer starts on http://localhost:3000
# In another terminal
npm run replaySends fixtures/pumpfun-create.sample.json to your local webhook.
| Variable | Description | Required | Default |
|---|---|---|---|
PORT |
Server port | No | 3000 |
NODE_ENV |
Environment (development/production/test) | No | development |
DATABASE_URL |
Database connection string | No | file:./dev.db |
SOLANA_RPC_URL |
Solana RPC endpoint | Yes | - |
WEBHOOK_SECRET |
Shared secret for webhook auth | Yes | - |
QUEUE_CONCURRENCY |
Max concurrent risk computations | No | 3 |
MAX_LAUNCHES_RESPONSE |
Max launches returned by API | No | 100 |
openssl rand -hex 32Accepts raw Solana transaction webhooks.
Headers:
Authorization: Bearer <WEBHOOK_SECRET>Content-Type: application/json
Body: Array of raw transactions (see fixtures/pumpfun-create.sample.json)
Response:
{
"success": true,
"received": 10,
"detected": 2,
"processed": 2
}List recent token launches.
Query Parameters:
limit(optional): Max results (default 50, max 100)
Response:
{
"launches": [
{
"signature": "5Q9p...",
"slot": "250000000",
"blockTime": "2024-01-01T00:00:00.000Z",
"mint": "MintAbc123...",
"creator": "7NpF...",
"source": "pumpfun",
"createdAt": "2024-01-01T00:00:10.000Z"
}
],
"count": 1
}Get token details and risk report.
Response (with risk report):
{
"launch": {
"signature": "5Q9p...",
"slot": "250000000",
"blockTime": "2024-01-01T00:00:00.000Z",
"mint": "MintAbc123...",
"creator": "7NpF...",
"source": "pumpfun"
},
"risk": {
"mint": "MintAbc123...",
"score": 65,
"label": "HIGH",
"reasons": [
"Mint authority is active - creator can mint unlimited tokens",
"Freeze authority is active - creator can freeze accounts",
"High holder concentration: top holder owns 45.2%"
],
"authorities": {
"mintAuthority": "7NpF...",
"freezeAuthority": "7NpF..."
},
"topHolders": [
{ "address": "Holder1...", "percentage": 45.2 },
{ "address": "Holder2...", "percentage": 12.3 }
],
"computedAt": "2024-01-01T00:00:15.000Z"
}
}Response (risk pending):
{
"launch": { ... },
"risk": {
"status": "pending",
"message": "Risk analysis in progress"
}
}Health check.
Response:
{
"status": "healthy",
"timestamp": "2024-01-01T00:00:00.000Z",
"database": "connected"
}- Go to Helius Dashboard → Webhooks
- Create new webhook:
- Type: Raw Transaction
- URL:
https://your-domain.com/webhooks/helius - Auth Header:
Bearer <your-WEBHOOK_SECRET> - Account Addresses:
6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P - Transaction Types: All
- Test webhook delivery
- Save and activate
Any provider that supports raw Solana transaction webhooks will work. Ensure they can send an Authorization header.
npm test # Watch mode
npm run test:ci # CI mode (run once)npm run lint # Check
npm run lint:fix # Fix auto-fixable issuesnpm run typechecknpm run db:studio # Open Prisma Studio (GUI)
npm run db:migrate # Create/apply migrationsSee RUNBOOK.md for detailed deployment instructions.
Quick Deploy:
npm ci --only=production
npm run db:generate
npm run db:migrate
npm run build
npm startUse a process manager like PM2 or systemd for production.
- PRD.md - Product requirements and scope
- DECISION_LOG.md - Technical decisions with rationale
- RISK_REGISTER.md - Identified risks and mitigations
- RUNBOOK.md - Operational procedures
- CODEX_SAFE.md - AI-assisted development guidelines
- HELLFIRE_MODE.md - Quality gates and enforcement
- Webhook receives Solana transactions
- For each instruction in each transaction:
- Check if
programIdIndexpoints to Pump.fun program:6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P - Decode instruction data from base58
- Check if first 8 bytes match create discriminator:
[24, 30, 200, 40, 5, 28, 7, 119] - If match, extract mint address from
accounts[0]
- Check if
- Store as
LaunchEvent(dedupe by signature)
Heuristic-based, explainable scoring:
| Factor | Weight | Description |
|---|---|---|
| Mint Authority | +35 | Can print unlimited tokens |
| Freeze Authority | +25 | Can freeze holder accounts |
| Top Holder >50% | +30 | Extreme concentration risk |
| Top Holder 30-50% | +20 | High concentration |
| Top Holder 15-30% | +10 | Moderate concentration |
| Top 5 >80% | +10 | Few holders control supply |
| No Metadata | +5 | Missing Metaplex metadata (unusual) |
Labels:
- HIGH: Score ≥60
- MED: Score 30-59
- LOW: Score <30
Disclaimer: Risk scores are heuristics, not guarantees. Not financial advice. Always DYOR.
Webhook returns 401:
- Check
WEBHOOK_SECRETmatches provider config - Verify Authorization header format:
Bearer <secret>
Risk scores not computing:
- Check
SOLANA_RPC_URLis valid and not rate limited - Review logs for RPC errors
- Try different RPC provider (Helius, QuickNode, Alchemy)
No launches detected:
- Verify webhook is sending to correct URL
- Check webhook account filter includes Pump.fun program ID
- Test with
npm run replay
See RUNBOOK.md for more troubleshooting.
- Fork the repository
- Create a feature branch
- Make changes with tests
- Run quality checks:
npm run lint && npm run typecheck && npm test - Submit PR
All PRs must pass CI (see HELLFIRE_MODE.md).
See repository root LICENSE file.