@0xprotovox/deficlaw 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +230 -0
- package/dist/analysis/formatOutput.d.ts +4 -0
- package/dist/analysis/formatOutput.js +209 -0
- package/dist/analysis/formatOutput.js.map +1 -0
- package/dist/analysis/riskScorer.d.ts +6 -0
- package/dist/analysis/riskScorer.js +104 -0
- package/dist/analysis/riskScorer.js.map +1 -0
- package/dist/analysis/summaryGenerator.d.ts +68 -0
- package/dist/analysis/summaryGenerator.js +171 -0
- package/dist/analysis/summaryGenerator.js.map +1 -0
- package/dist/cache/memoryCache.d.ts +13 -0
- package/dist/cache/memoryCache.js +31 -0
- package/dist/cache/memoryCache.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -0
- package/dist/server.d.ts +7 -0
- package/dist/server.js +76 -0
- package/dist/server.js.map +1 -0
- package/dist/sources/dexscreener.d.ts +20 -0
- package/dist/sources/dexscreener.js +117 -0
- package/dist/sources/dexscreener.js.map +1 -0
- package/dist/sources/gmgn.d.ts +8 -0
- package/dist/sources/gmgn.js +210 -0
- package/dist/sources/gmgn.js.map +1 -0
- package/dist/sources/solanaRpc.d.ts +14 -0
- package/dist/sources/solanaRpc.js +60 -0
- package/dist/sources/solanaRpc.js.map +1 -0
- package/dist/tools/analyzeToken.d.ts +8 -0
- package/dist/tools/analyzeToken.js +253 -0
- package/dist/tools/analyzeToken.js.map +1 -0
- package/dist/tools/getPrice.d.ts +17 -0
- package/dist/tools/getPrice.js +13 -0
- package/dist/tools/getPrice.js.map +1 -0
- package/dist/tools/getTopTraders.d.ts +45 -0
- package/dist/tools/getTopTraders.js +44 -0
- package/dist/tools/getTopTraders.js.map +1 -0
- package/dist/tools/getTrending.d.ts +9 -0
- package/dist/tools/getTrending.js +16 -0
- package/dist/tools/getTrending.js.map +1 -0
- package/dist/types/index.d.ts +127 -0
- package/dist/types/index.js +2 -0
- package/dist/types/index.js.map +1 -0
- package/package.json +46 -0
package/README.md
ADDED
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
# DefiClaw
|
|
2
|
+
|
|
3
|
+
**The first open-source DeFi MCP server for Claude Code.**
|
|
4
|
+
|
|
5
|
+
Analyze any Solana token in seconds. Holder intelligence, risk scoring, smart money tracking, KOL detection. Zero API keys required.
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
> "analyze token 3oQwNvAfZMuPWjVPC12ukY7RPA9JiGwLod6Pr4Lkpump"
|
|
9
|
+
|
|
10
|
+
═══ SUMMARY ═══
|
|
11
|
+
POKE6900 is a 9mo old PumpSwap token with $25.9K liquidity and $34.5K market cap.
|
|
12
|
+
53 diamond hands (53.0%), strong holder conviction.
|
|
13
|
+
Only 18.0% of holders are in profit, most are underwater with avg loss of $844 per wallet.
|
|
14
|
+
Buy pressure is strong at 3.3:1 ratio (1093 buys vs 395 sells), accumulation phase.
|
|
15
|
+
Contract looks safe: mint and freeze authorities revoked.
|
|
16
|
+
🟢 Lower risk profile based on available data.
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Why deficlaw?
|
|
20
|
+
|
|
21
|
+
Claude Code can write code, fix bugs, deploy apps. But ask it "what's the price of BONK?" and it says *"I don't have real-time data."*
|
|
22
|
+
|
|
23
|
+
**deficlaw fixes that.** It gives Claude Code real-time access to DeFi data across Solana and 10+ chains.
|
|
24
|
+
|
|
25
|
+
- **Token Analysis** with holder intelligence, risk scoring, KOL tracking
|
|
26
|
+
- **Real-time Prices** from DexScreener across all major chains
|
|
27
|
+
- **Trending Tokens** with volume, liquidity, and boost data
|
|
28
|
+
- **Top Traders** showing who made and lost money on any token
|
|
29
|
+
- **Contract Security** checking mint/freeze authority on Solana
|
|
30
|
+
- **1.5 second** full analysis (not 11 seconds like browser-based scrapers)
|
|
31
|
+
- **Zero config** - no API keys, no wallets, no accounts needed
|
|
32
|
+
|
|
33
|
+
## Quick Start
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
# Clone and build
|
|
37
|
+
git clone https://github.com/0xprotovox/deficlaw.git
|
|
38
|
+
cd deficlaw
|
|
39
|
+
npm install && npm run build
|
|
40
|
+
|
|
41
|
+
# Add to Claude Code
|
|
42
|
+
claude mcp add defi -- node /path/to/deficlaw/dist/index.js
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Then just ask Claude naturally:
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
> "analyze this token: 3oQw...pump"
|
|
49
|
+
> "what's the price of BONK?"
|
|
50
|
+
> "show me trending tokens on solana"
|
|
51
|
+
> "who made money on JUP token?"
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Tools
|
|
55
|
+
|
|
56
|
+
### `analyze_token`
|
|
57
|
+
|
|
58
|
+
Full token analysis with holder intelligence, risk scoring, and human-readable summary.
|
|
59
|
+
|
|
60
|
+
**Input:**
|
|
61
|
+
| Parameter | Type | Default | Description |
|
|
62
|
+
|-----------|------|---------|-------------|
|
|
63
|
+
| `address` | string | required | Token contract address |
|
|
64
|
+
| `chain` | string | `"solana"` | Blockchain (solana, ethereum, bsc, base, arbitrum) |
|
|
65
|
+
| `include_holders` | boolean | `true` | Include GMGN holder analysis |
|
|
66
|
+
|
|
67
|
+
**Output includes:**
|
|
68
|
+
- Token info (name, symbol, age, socials)
|
|
69
|
+
- Price with 5m/1h/6h/24h changes
|
|
70
|
+
- Market data (mcap, fdv, volume, liquidity, vol/liq ratio)
|
|
71
|
+
- Contract security (mint authority, freeze authority, supply)
|
|
72
|
+
- Risk score (0-100) with detailed flags
|
|
73
|
+
- Holder concentration (top 5/10/20)
|
|
74
|
+
- Holder categories (diamond hands, snipers, KOLs, fresh wallets, insiders)
|
|
75
|
+
- Buy/sell pressure ratio
|
|
76
|
+
- Sentiment (profitable vs underwater holders, avg PnL)
|
|
77
|
+
- Dev wallet detection and status
|
|
78
|
+
- Top 20 holders table with PnL and tags
|
|
79
|
+
- KOL list with Twitter handles
|
|
80
|
+
- Human-readable summary with actionable insights
|
|
81
|
+
|
|
82
|
+
### `get_price`
|
|
83
|
+
|
|
84
|
+
Quick price lookup. Sub-second response.
|
|
85
|
+
|
|
86
|
+
```
|
|
87
|
+
> "price of So11111112222..."
|
|
88
|
+
|
|
89
|
+
BONK — $0.000024 (+5.2% 24h)
|
|
90
|
+
Volume: $142M | Liquidity: $12M | MCap: $1.8B
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### `get_trending`
|
|
94
|
+
|
|
95
|
+
Trending and boosted tokens on any chain.
|
|
96
|
+
|
|
97
|
+
```
|
|
98
|
+
> "trending tokens on solana"
|
|
99
|
+
|
|
100
|
+
1. BONK — $0.000024 (+12%) — $142M volume
|
|
101
|
+
2. WIF — $0.89 (-2.1%) — $89M volume
|
|
102
|
+
3. JUP — $0.94 (+3.5%) — $45M volume
|
|
103
|
+
...
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### `get_top_traders`
|
|
107
|
+
|
|
108
|
+
Who made and lost money on a token. Winners, losers, PnL, tags.
|
|
109
|
+
|
|
110
|
+
```
|
|
111
|
+
> "who profited on this token?"
|
|
112
|
+
|
|
113
|
+
🏆 Top Winners:
|
|
114
|
+
1. CR5N... — +$680 (+124%) 🟢 still holding
|
|
115
|
+
2. EsRB... — +$166 (+16%) 💎 diamond hands
|
|
116
|
+
|
|
117
|
+
💀 Top Losers:
|
|
118
|
+
1. BgeeV... — -$7,548 (-65%) 💎 diamond hands (!)
|
|
119
|
+
2. 5vqid... — -$5,420 (-50%) gmgn user
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## Data Sources
|
|
123
|
+
|
|
124
|
+
All free, no API keys required:
|
|
125
|
+
|
|
126
|
+
| Source | Data | Speed |
|
|
127
|
+
|--------|------|-------|
|
|
128
|
+
| **DexScreener** | Prices, volume, liquidity, pairs, trending | <0.5s |
|
|
129
|
+
| **GMGN** | Holders, tags, KOLs, PnL, dev wallet, snipers | ~1s |
|
|
130
|
+
| **Solana RPC** | Mint authority, freeze authority, supply | <0.5s |
|
|
131
|
+
|
|
132
|
+
**Total analysis time: ~1.5 seconds**
|
|
133
|
+
|
|
134
|
+
## Supported Chains
|
|
135
|
+
|
|
136
|
+
Prices and trending work on all DexScreener chains:
|
|
137
|
+
|
|
138
|
+
Solana, Ethereum, Base, BSC, Arbitrum, Polygon, Avalanche, Optimism, Fantom, and more.
|
|
139
|
+
|
|
140
|
+
Holder analysis (GMGN) currently supports **Solana** tokens.
|
|
141
|
+
|
|
142
|
+
## Risk Scoring
|
|
143
|
+
|
|
144
|
+
The risk scorer analyzes 6 dimensions to produce a 0-100 score:
|
|
145
|
+
|
|
146
|
+
| Dimension | Weight | What it checks |
|
|
147
|
+
|-----------|--------|----------------|
|
|
148
|
+
| Liquidity | 25% | Pool depth in USD |
|
|
149
|
+
| Token Age | 10% | Time since creation |
|
|
150
|
+
| Holder Concentration | 20% | Top 10 holder % |
|
|
151
|
+
| Dev Wallet | 20% | Dev holdings and selling behavior |
|
|
152
|
+
| Fresh Wallets | 15% | New wallet % (possible wash/bundle) |
|
|
153
|
+
| Sniper Activity | 10% | Bot/sniper wallets in top holders |
|
|
154
|
+
|
|
155
|
+
**Levels:** 🟢 LOW (0-19) | 🟡 MEDIUM (20-44) | 🟠 HIGH (45-69) | 🔴 CRITICAL (70-100)
|
|
156
|
+
|
|
157
|
+
## Architecture
|
|
158
|
+
|
|
159
|
+
```
|
|
160
|
+
Claude Code ←→ MCP stdio ←→ deficlaw server
|
|
161
|
+
│
|
|
162
|
+
┌────────────┼────────────┐
|
|
163
|
+
│ │ │
|
|
164
|
+
DexScreener GMGN API Solana RPC
|
|
165
|
+
(prices) (holders) (security)
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
- **MCP SDK** for Claude Code integration
|
|
169
|
+
- **curl-based GMGN fetcher** bypasses Cloudflare (Playwright fallback if needed)
|
|
170
|
+
- **In-memory TTL cache** prevents rate limiting
|
|
171
|
+
- **Rate limiter** for DexScreener (150 req/min)
|
|
172
|
+
- **TypeScript** with full type safety
|
|
173
|
+
|
|
174
|
+
## Configuration
|
|
175
|
+
|
|
176
|
+
### Environment Variables (all optional)
|
|
177
|
+
|
|
178
|
+
| Variable | Default | Description |
|
|
179
|
+
|----------|---------|-------------|
|
|
180
|
+
| `SOLANA_RPC_URL` | `https://api.mainnet-beta.solana.com` | Custom Solana RPC endpoint |
|
|
181
|
+
|
|
182
|
+
### Claude Code Config
|
|
183
|
+
|
|
184
|
+
Add to your project's `.mcp.json`:
|
|
185
|
+
|
|
186
|
+
```json
|
|
187
|
+
{
|
|
188
|
+
"mcpServers": {
|
|
189
|
+
"defi": {
|
|
190
|
+
"command": "node",
|
|
191
|
+
"args": ["/path/to/deficlaw/dist/index.js"],
|
|
192
|
+
"env": {
|
|
193
|
+
"SOLANA_RPC_URL": "https://your-rpc.com"
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
## Roadmap
|
|
201
|
+
|
|
202
|
+
- [x] Token analysis with holder intelligence
|
|
203
|
+
- [x] Risk scoring (6 dimensions)
|
|
204
|
+
- [x] Contract security checks
|
|
205
|
+
- [x] KOL detection with Twitter handles
|
|
206
|
+
- [x] Human-readable AI summary
|
|
207
|
+
- [x] Top traders (winners/losers)
|
|
208
|
+
- [ ] Token search by name/symbol
|
|
209
|
+
- [ ] Slippage estimation (Jupiter quotes)
|
|
210
|
+
- [ ] Token comparison (side by side)
|
|
211
|
+
- [ ] Multi-chain holder analysis
|
|
212
|
+
- [ ] npm package (`npm install -g deficlaw`)
|
|
213
|
+
- [ ] Price alerts via MCP resources
|
|
214
|
+
|
|
215
|
+
## Built With
|
|
216
|
+
|
|
217
|
+
- [Model Context Protocol SDK](https://github.com/modelcontextprotocol/typescript-sdk) - MCP server framework
|
|
218
|
+
- [DexScreener API](https://docs.dexscreener.com) - Price and market data
|
|
219
|
+
- [GMGN](https://gmgn.ai) - Holder intelligence
|
|
220
|
+
- TypeScript, Zod, Node.js 18+
|
|
221
|
+
|
|
222
|
+
## License
|
|
223
|
+
|
|
224
|
+
MIT
|
|
225
|
+
|
|
226
|
+
## Author
|
|
227
|
+
|
|
228
|
+
**@0xprotovox** - [Twitter](https://x.com/0xprotovox) | [GitHub](https://github.com/0xprotovox)
|
|
229
|
+
|
|
230
|
+
20 years building software. Now building AI trading agents and DeFi tools.
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Format analysis output — clean, readable, both summary + detailed numbers
|
|
3
|
+
*/
|
|
4
|
+
function fmt(n) {
|
|
5
|
+
if (n === 0)
|
|
6
|
+
return '$0';
|
|
7
|
+
if (Math.abs(n) >= 1_000_000)
|
|
8
|
+
return `$${(n / 1_000_000).toFixed(2)}M`;
|
|
9
|
+
if (Math.abs(n) >= 1_000)
|
|
10
|
+
return `$${(n / 1_000).toFixed(1)}K`;
|
|
11
|
+
if (Math.abs(n) >= 1)
|
|
12
|
+
return `$${n.toFixed(2)}`;
|
|
13
|
+
if (Math.abs(n) >= 0.001)
|
|
14
|
+
return `$${n.toFixed(4)}`;
|
|
15
|
+
return `$${n.toFixed(8)}`;
|
|
16
|
+
}
|
|
17
|
+
function pct(n, digits = 1) {
|
|
18
|
+
return `${(n * 100).toFixed(digits)}%`;
|
|
19
|
+
}
|
|
20
|
+
function arrow(n) {
|
|
21
|
+
if (n > 0)
|
|
22
|
+
return `+${n.toFixed(2)}% 📈`;
|
|
23
|
+
if (n < 0)
|
|
24
|
+
return `${n.toFixed(2)}% 📉`;
|
|
25
|
+
return '0% ➖';
|
|
26
|
+
}
|
|
27
|
+
function shortenAddr(addr) {
|
|
28
|
+
if (addr.length <= 12)
|
|
29
|
+
return addr;
|
|
30
|
+
return `${addr.slice(0, 6)}...${addr.slice(-4)}`;
|
|
31
|
+
}
|
|
32
|
+
export function formatAnalysis(data) {
|
|
33
|
+
const lines = [];
|
|
34
|
+
// ═══════ SUMMARY ═══════
|
|
35
|
+
if (data.summary) {
|
|
36
|
+
lines.push('═══ SUMMARY ═══');
|
|
37
|
+
lines.push(data.summary);
|
|
38
|
+
lines.push('');
|
|
39
|
+
}
|
|
40
|
+
// ═══════ TOKEN INFO ═══════
|
|
41
|
+
lines.push('═══ TOKEN ═══');
|
|
42
|
+
lines.push(`Name: ${data.token.name} (${data.token.symbol})`);
|
|
43
|
+
lines.push(`Chain: ${data.token.chain}`);
|
|
44
|
+
lines.push(`Address: ${data.token.address}`);
|
|
45
|
+
lines.push(`Age: ${data.token.age}`);
|
|
46
|
+
if (data.token.createdAt)
|
|
47
|
+
lines.push(`Created: ${data.token.createdAt}`);
|
|
48
|
+
lines.push('');
|
|
49
|
+
// ═══════ PRICE ═══════
|
|
50
|
+
lines.push('═══ PRICE ═══');
|
|
51
|
+
lines.push(`Price: ${fmt(data.price.usd)}`);
|
|
52
|
+
lines.push(`5min: ${arrow(data.price.change5m)}`);
|
|
53
|
+
lines.push(`1h: ${arrow(data.price.change1h)}`);
|
|
54
|
+
lines.push(`6h: ${arrow(data.price.change6h)}`);
|
|
55
|
+
lines.push(`24h: ${arrow(data.price.change24h)}`);
|
|
56
|
+
lines.push('');
|
|
57
|
+
// ═══════ MARKET ═══════
|
|
58
|
+
lines.push('═══ MARKET ═══');
|
|
59
|
+
lines.push(`Market Cap: ${fmt(data.market.marketCap)}`);
|
|
60
|
+
lines.push(`FDV: ${fmt(data.market.fdv)}`);
|
|
61
|
+
lines.push(`Liquidity: ${fmt(data.market.liquidity)}`);
|
|
62
|
+
lines.push(`Volume 24h: ${fmt(data.market.volume24h)}`);
|
|
63
|
+
lines.push(`Volume 6h: ${fmt(data.market.volume6h)}`);
|
|
64
|
+
lines.push(`Volume 1h: ${fmt(data.market.volume1h)}`);
|
|
65
|
+
lines.push(`Volume 5m: ${fmt(data.market.volume5m)}`);
|
|
66
|
+
lines.push(`Vol/Liq Ratio: ${data.market.volumeLiquidityRatio}x`);
|
|
67
|
+
lines.push(`DEX: ${data.market.dex}`);
|
|
68
|
+
lines.push(`Pair: ${data.market.pairAddress}`);
|
|
69
|
+
lines.push('');
|
|
70
|
+
// ═══════ SECURITY ═══════
|
|
71
|
+
if (data.security) {
|
|
72
|
+
lines.push('═══ SECURITY ═══');
|
|
73
|
+
const mintOk = data.security.mintAuthority === 'revoked';
|
|
74
|
+
const freezeOk = data.security.freezeAuthority === 'revoked';
|
|
75
|
+
lines.push(`Mint Authority: ${mintOk ? '✅ Revoked (safe)' : '⚠️ ACTIVE (can print tokens!)'}`);
|
|
76
|
+
lines.push(`Freeze Authority: ${freezeOk ? '✅ Revoked (safe)' : '⚠️ ACTIVE (can freeze wallets!)'}`);
|
|
77
|
+
lines.push(`Total Supply: ${Math.round(data.security.supply).toLocaleString()}`);
|
|
78
|
+
lines.push(`Decimals: ${data.security.decimals}`);
|
|
79
|
+
lines.push('');
|
|
80
|
+
}
|
|
81
|
+
// ═══════ RISK ═══════
|
|
82
|
+
lines.push('═══ RISK ═══');
|
|
83
|
+
const riskMap = { LOW: '🟢', MEDIUM: '🟡', HIGH: '🟠', CRITICAL: '🔴' };
|
|
84
|
+
const riskEmoji = riskMap[data.risk.level] || '⚪';
|
|
85
|
+
lines.push(`Score: ${data.risk.score}/100 ${riskEmoji} ${data.risk.level}`);
|
|
86
|
+
if (data.risk.flags?.length > 0) {
|
|
87
|
+
data.risk.flags.forEach((f) => {
|
|
88
|
+
const sevMap = { critical: '🔴', high: '🟠', medium: '🟡', low: '🟢' };
|
|
89
|
+
const fEmoji = sevMap[f.severity] || '⚪';
|
|
90
|
+
lines.push(` ${fEmoji} ${f.message}`);
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
lines.push('');
|
|
94
|
+
// ═══════ HOLDERS ═══════
|
|
95
|
+
if (data.holders) {
|
|
96
|
+
const h = data.holders;
|
|
97
|
+
lines.push('═══ HOLDERS ═══');
|
|
98
|
+
lines.push(`Total Analyzed: ${h.total}`);
|
|
99
|
+
lines.push('');
|
|
100
|
+
// Concentration
|
|
101
|
+
lines.push('Concentration:');
|
|
102
|
+
lines.push(` Top 5: ${pct(h.concentration.top5Pct)}`);
|
|
103
|
+
lines.push(` Top 10: ${pct(h.concentration.top10Pct)}`);
|
|
104
|
+
lines.push(` Top 20: ${pct(h.concentration.top20Pct)}`);
|
|
105
|
+
lines.push('');
|
|
106
|
+
// Categories
|
|
107
|
+
lines.push('Categories:');
|
|
108
|
+
const cats = h.categories;
|
|
109
|
+
if (cats.diamondHands > 0)
|
|
110
|
+
lines.push(` 💎 Diamond Hands: ${cats.diamondHands}`);
|
|
111
|
+
if (cats.snipers > 0)
|
|
112
|
+
lines.push(` 🎯 Snipers: ${cats.snipers}`);
|
|
113
|
+
if (cats.freshWallets > 0)
|
|
114
|
+
lines.push(` 🆕 Fresh Wallets: ${cats.freshWallets}`);
|
|
115
|
+
if (cats.kols > 0)
|
|
116
|
+
lines.push(` 👑 KOLs: ${cats.kols}`);
|
|
117
|
+
if (cats.smartMoney > 0)
|
|
118
|
+
lines.push(` 🧠 Smart Money: ${cats.smartMoney}`);
|
|
119
|
+
if (cats.insiders > 0)
|
|
120
|
+
lines.push(` 🔑 Insiders: ${cats.insiders}`);
|
|
121
|
+
if (cats.devWallets > 0)
|
|
122
|
+
lines.push(` 🛠️ Dev Wallets: ${cats.devWallets}`);
|
|
123
|
+
if (cats.photonUsers > 0)
|
|
124
|
+
lines.push(` 📸 Photon: ${cats.photonUsers}`);
|
|
125
|
+
if (cats.gmgnUsers > 0)
|
|
126
|
+
lines.push(` 📲 GMGN: ${cats.gmgnUsers}`);
|
|
127
|
+
if (cats.transferIn > 0)
|
|
128
|
+
lines.push(` ↗️ Transfer In: ${cats.transferIn}`);
|
|
129
|
+
lines.push('');
|
|
130
|
+
// Sentiment
|
|
131
|
+
lines.push('Sentiment:');
|
|
132
|
+
lines.push(` Profitable: ${h.sentiment.profitableHolders} (${pct(h.sentiment.profitRatio)})`);
|
|
133
|
+
lines.push(` Losing: ${h.sentiment.losingHolders}`);
|
|
134
|
+
lines.push(` Total PnL: ${fmt(h.sentiment.totalPnlUsd)}`);
|
|
135
|
+
lines.push(` Total Cost: ${fmt(h.sentiment.totalCostUsd)}`);
|
|
136
|
+
lines.push(` Avg PnL/holder: ${fmt(h.sentiment.avgPnlPerHolder)}`);
|
|
137
|
+
lines.push('');
|
|
138
|
+
// Buy/Sell Pressure
|
|
139
|
+
lines.push('Buy/Sell Pressure:');
|
|
140
|
+
lines.push(` Buy TX: ${h.pressure.totalBuyTx}`);
|
|
141
|
+
lines.push(` Sell TX: ${h.pressure.totalSellTx}`);
|
|
142
|
+
lines.push(` Ratio: ${h.pressure.buySellRatio.toFixed(2)}:1 ${h.pressure.buySellRatio > 1.5 ? '🟢' : h.pressure.buySellRatio < 0.7 ? '🔴' : '🟡'}`);
|
|
143
|
+
lines.push('');
|
|
144
|
+
// Dev Wallet
|
|
145
|
+
if (h.devWallet) {
|
|
146
|
+
lines.push('Dev Wallet:');
|
|
147
|
+
lines.push(` Address: ${shortenAddr(h.devWallet.address)}`);
|
|
148
|
+
lines.push(` Holding: ${pct(h.devWallet.holdingPercent)}`);
|
|
149
|
+
lines.push(` PnL: ${fmt(h.devWallet.pnl)}`);
|
|
150
|
+
lines.push(` Status: ${h.devWallet.status}`);
|
|
151
|
+
lines.push('');
|
|
152
|
+
}
|
|
153
|
+
// Top 20 Holders Table
|
|
154
|
+
lines.push('Top 20 Holders:');
|
|
155
|
+
lines.push(' # | Address | Supply | Value | PnL | Tags');
|
|
156
|
+
lines.push(' ---|-------------|---------|-----------|------------|------');
|
|
157
|
+
h.topHolders.slice(0, 20).forEach((holder, i) => {
|
|
158
|
+
const num = String(i + 1).padStart(2);
|
|
159
|
+
const addr = shortenAddr(holder.address).padEnd(12);
|
|
160
|
+
const supply = pct(holder.supplyPercent).padStart(6);
|
|
161
|
+
const value = fmt(holder.valueUsd).padStart(9);
|
|
162
|
+
const pnl = (holder.pnl >= 0 ? '+' : '') + fmt(holder.pnl);
|
|
163
|
+
const tags = holder.tags.filter((t) => !/^TOP\d+$/.test(t)).join(', ') || '-';
|
|
164
|
+
const twitter = holder.twitterHandle ? ` @${holder.twitterHandle}` : '';
|
|
165
|
+
lines.push(` ${num} | ${addr} | ${supply} | ${value} | ${pnl.padStart(10)} | ${tags}${twitter}`);
|
|
166
|
+
});
|
|
167
|
+
lines.push('');
|
|
168
|
+
}
|
|
169
|
+
// ═══════ LP DETECTION ═══════
|
|
170
|
+
if (data.lpDetection) {
|
|
171
|
+
lines.push('═══ LP POOL ═══');
|
|
172
|
+
lines.push(`Top holder is LP pool: ✅`);
|
|
173
|
+
lines.push(`LP Address: ${shortenAddr(data.lpDetection.lpAddress)}`);
|
|
174
|
+
lines.push(`LP holds: ${pct(data.lpDetection.lpPercent)}`);
|
|
175
|
+
if (data.lpDetection.realTopHolder) {
|
|
176
|
+
lines.push(`Real top holder: ${shortenAddr(data.lpDetection.realTopHolder.address)} (${pct(data.lpDetection.realTopHolder.percent)})`);
|
|
177
|
+
}
|
|
178
|
+
lines.push('');
|
|
179
|
+
}
|
|
180
|
+
// ═══════ KOLs ═══════
|
|
181
|
+
if (data.kols && data.kols.length > 0) {
|
|
182
|
+
lines.push('═══ KOLs ═══');
|
|
183
|
+
data.kols.forEach((k, i) => {
|
|
184
|
+
const handle = k.twitterHandle ? `@${k.twitterHandle}` : shortenAddr(k.address);
|
|
185
|
+
const pnlStr = k.pnl !== 0 ? ` | PnL: ${fmt(k.pnl)}` : '';
|
|
186
|
+
const status = k.status === 'selling' ? '🔴 selling' : '🟢 holding';
|
|
187
|
+
const tags = k.tags.filter((t) => !/^TOP\d+$/.test(t) && t !== 'kol').join(', ');
|
|
188
|
+
lines.push(` ${i + 1}. ${handle} | ${status}${pnlStr}${tags ? ` | ${tags}` : ''}`);
|
|
189
|
+
});
|
|
190
|
+
lines.push('');
|
|
191
|
+
}
|
|
192
|
+
// ═══════ SOCIALS ═══════
|
|
193
|
+
if (data.socials) {
|
|
194
|
+
lines.push('═══ SOCIALS ═══');
|
|
195
|
+
if (data.socials.websites?.length > 0)
|
|
196
|
+
lines.push(`Website: ${data.socials.websites.join(', ')}`);
|
|
197
|
+
if (data.socials.twitter)
|
|
198
|
+
lines.push(`Twitter: ${data.socials.twitter}`);
|
|
199
|
+
if (data.socials.telegram)
|
|
200
|
+
lines.push(`Telegram: ${data.socials.telegram}`);
|
|
201
|
+
lines.push('');
|
|
202
|
+
}
|
|
203
|
+
// ═══════ META ═══════
|
|
204
|
+
lines.push('═══ META ═══');
|
|
205
|
+
lines.push(`Sources: ${data.meta.sources.join(' + ')}`);
|
|
206
|
+
lines.push(`Fetch time: ${(data.meta.fetchTimeMs / 1000).toFixed(1)}s`);
|
|
207
|
+
return lines.join('\n');
|
|
208
|
+
}
|
|
209
|
+
//# sourceMappingURL=formatOutput.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formatOutput.js","sourceRoot":"","sources":["../../src/analysis/formatOutput.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
export function scoreRisk(pair, holders) {
|
|
2
|
+
const flags = [];
|
|
3
|
+
let totalScore = 0;
|
|
4
|
+
// 1. Liquidity risk (25% weight)
|
|
5
|
+
const liquidity = pair?.liquidity?.usd || 0;
|
|
6
|
+
if (liquidity < 5000) {
|
|
7
|
+
flags.push({ type: 'liquidity', severity: 'critical', message: `Extremely low liquidity: $${liquidity.toFixed(0)}` });
|
|
8
|
+
totalScore += 25;
|
|
9
|
+
}
|
|
10
|
+
else if (liquidity < 25000) {
|
|
11
|
+
flags.push({ type: 'liquidity', severity: 'high', message: `Low liquidity: $${liquidity.toFixed(0)}` });
|
|
12
|
+
totalScore += 18;
|
|
13
|
+
}
|
|
14
|
+
else if (liquidity < 100000) {
|
|
15
|
+
flags.push({ type: 'liquidity', severity: 'medium', message: `Moderate liquidity: $${liquidity.toFixed(0)}` });
|
|
16
|
+
totalScore += 8;
|
|
17
|
+
}
|
|
18
|
+
// 2. Token age (10% weight)
|
|
19
|
+
if (pair?.pairCreatedAt) {
|
|
20
|
+
const ageMs = Date.now() - pair.pairCreatedAt;
|
|
21
|
+
const ageHours = ageMs / (1000 * 60 * 60);
|
|
22
|
+
if (ageHours < 1) {
|
|
23
|
+
flags.push({ type: 'age', severity: 'critical', message: `Token launched ${Math.round(ageHours * 60)}m ago` });
|
|
24
|
+
totalScore += 10;
|
|
25
|
+
}
|
|
26
|
+
else if (ageHours < 24) {
|
|
27
|
+
flags.push({ type: 'age', severity: 'high', message: `Token is ${Math.round(ageHours)}h old` });
|
|
28
|
+
totalScore += 6;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
// Holder-based risks (only if we have GMGN data)
|
|
32
|
+
if (holders && holders.length > 0) {
|
|
33
|
+
// 3. Top holder concentration (20% weight)
|
|
34
|
+
const sorted = [...holders].sort((a, b) => b.supplyPercent - a.supplyPercent);
|
|
35
|
+
const top10Pct = sorted.slice(0, 10).reduce((s, h) => s + h.supplyPercent, 0);
|
|
36
|
+
if (top10Pct > 60) {
|
|
37
|
+
flags.push({ type: 'concentration', severity: 'critical', message: `Top 10 holders own ${(top10Pct * 100).toFixed(1)}%` });
|
|
38
|
+
totalScore += 20;
|
|
39
|
+
}
|
|
40
|
+
else if (top10Pct > 40) {
|
|
41
|
+
flags.push({ type: 'concentration', severity: 'high', message: `Top 10 holders own ${(top10Pct * 100).toFixed(1)}%` });
|
|
42
|
+
totalScore += 12;
|
|
43
|
+
}
|
|
44
|
+
else if (top10Pct > 25) {
|
|
45
|
+
flags.push({ type: 'concentration', severity: 'medium', message: `Top 10 holders own ${(top10Pct * 100).toFixed(1)}%` });
|
|
46
|
+
totalScore += 5;
|
|
47
|
+
}
|
|
48
|
+
// 4. Dev wallet (20% weight)
|
|
49
|
+
const dev = holders.find(h => h.isDeployer);
|
|
50
|
+
if (dev) {
|
|
51
|
+
if (dev.supplyPercent > 0.10) {
|
|
52
|
+
flags.push({ type: 'dev_wallet', severity: 'high', message: `Dev holds ${(dev.supplyPercent * 100).toFixed(1)}%` });
|
|
53
|
+
totalScore += 15;
|
|
54
|
+
}
|
|
55
|
+
else if (dev.sellAmount > dev.buyAmount * 0.5) {
|
|
56
|
+
flags.push({ type: 'dev_selling', severity: 'medium', message: 'Dev has been selling' });
|
|
57
|
+
totalScore += 8;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
// 5. Fresh wallets (15% weight)
|
|
61
|
+
const freshCount = holders.filter(h => h.isFreshWallet).length;
|
|
62
|
+
const freshPct = freshCount / holders.length;
|
|
63
|
+
if (freshPct > 0.30) {
|
|
64
|
+
flags.push({ type: 'fresh_wallets', severity: 'high', message: `${(freshPct * 100).toFixed(0)}% fresh wallets (possible bundle/wash)` });
|
|
65
|
+
totalScore += 15;
|
|
66
|
+
}
|
|
67
|
+
else if (freshPct > 0.15) {
|
|
68
|
+
flags.push({ type: 'fresh_wallets', severity: 'medium', message: `${(freshPct * 100).toFixed(0)}% fresh wallets` });
|
|
69
|
+
totalScore += 7;
|
|
70
|
+
}
|
|
71
|
+
// 6. Sniper activity (10% weight)
|
|
72
|
+
const sniperCount = holders.filter(h => h.tags.some(t => t.toLowerCase().includes('sniper') || t.toLowerCase().includes('bot'))).length;
|
|
73
|
+
if (sniperCount > 5) {
|
|
74
|
+
flags.push({ type: 'snipers', severity: 'high', message: `${sniperCount} sniper/bot wallets detected` });
|
|
75
|
+
totalScore += 10;
|
|
76
|
+
}
|
|
77
|
+
else if (sniperCount > 2) {
|
|
78
|
+
flags.push({ type: 'snipers', severity: 'medium', message: `${sniperCount} sniper wallets detected` });
|
|
79
|
+
totalScore += 4;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
// No holder data — add uncertainty
|
|
84
|
+
totalScore += 15;
|
|
85
|
+
flags.push({ type: 'no_holder_data', severity: 'medium', message: 'Holder analysis unavailable (install Playwright for full analysis)' });
|
|
86
|
+
}
|
|
87
|
+
// Clamp to 0-100
|
|
88
|
+
totalScore = Math.min(100, Math.max(0, totalScore));
|
|
89
|
+
const level = totalScore >= 70 ? 'CRITICAL' : totalScore >= 45 ? 'HIGH' : totalScore >= 20 ? 'MEDIUM' : 'LOW';
|
|
90
|
+
const summaryParts = [];
|
|
91
|
+
if (level === 'CRITICAL')
|
|
92
|
+
summaryParts.push('Extreme risk');
|
|
93
|
+
else if (level === 'HIGH')
|
|
94
|
+
summaryParts.push('High risk');
|
|
95
|
+
else if (level === 'MEDIUM')
|
|
96
|
+
summaryParts.push('Moderate risk');
|
|
97
|
+
else
|
|
98
|
+
summaryParts.push('Lower risk');
|
|
99
|
+
if (flags.length > 0) {
|
|
100
|
+
summaryParts.push(flags.slice(0, 3).map(f => f.message).join('; '));
|
|
101
|
+
}
|
|
102
|
+
return { score: totalScore, level, flags, summary: summaryParts.join('. ') + '.' };
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=riskScorer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"riskScorer.js","sourceRoot":"","sources":["../../src/analysis/riskScorer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AI-like Summary Generator — code-generated, no API calls
|
|
3
|
+
* Produces human-readable analysis from raw data
|
|
4
|
+
*/
|
|
5
|
+
interface SummaryInput {
|
|
6
|
+
token: {
|
|
7
|
+
symbol: string;
|
|
8
|
+
name: string;
|
|
9
|
+
age: string;
|
|
10
|
+
};
|
|
11
|
+
price: {
|
|
12
|
+
usd: number;
|
|
13
|
+
change1h: number;
|
|
14
|
+
change6h: number;
|
|
15
|
+
change24h: number;
|
|
16
|
+
change5m: number;
|
|
17
|
+
};
|
|
18
|
+
market: {
|
|
19
|
+
marketCap: number;
|
|
20
|
+
volume24h: number;
|
|
21
|
+
volume1h: number;
|
|
22
|
+
liquidity: number;
|
|
23
|
+
volumeLiquidityRatio: number;
|
|
24
|
+
dex: string;
|
|
25
|
+
};
|
|
26
|
+
risk: {
|
|
27
|
+
score: number;
|
|
28
|
+
level: string;
|
|
29
|
+
};
|
|
30
|
+
holders?: {
|
|
31
|
+
total: number;
|
|
32
|
+
concentration: {
|
|
33
|
+
top5Pct: number;
|
|
34
|
+
top10Pct: number;
|
|
35
|
+
top20Pct: number;
|
|
36
|
+
};
|
|
37
|
+
categories: Record<string, number>;
|
|
38
|
+
sentiment: {
|
|
39
|
+
profitableHolders: number;
|
|
40
|
+
losingHolders: number;
|
|
41
|
+
profitRatio: number;
|
|
42
|
+
totalPnlUsd: number;
|
|
43
|
+
avgPnlPerHolder: number;
|
|
44
|
+
};
|
|
45
|
+
pressure: {
|
|
46
|
+
buySellRatio: number;
|
|
47
|
+
totalBuyTx: number;
|
|
48
|
+
totalSellTx: number;
|
|
49
|
+
};
|
|
50
|
+
devWallet: {
|
|
51
|
+
status: string;
|
|
52
|
+
holdingPercent: number;
|
|
53
|
+
} | null;
|
|
54
|
+
};
|
|
55
|
+
kols?: {
|
|
56
|
+
twitterHandle: string | null;
|
|
57
|
+
status: string;
|
|
58
|
+
pnl: number;
|
|
59
|
+
}[];
|
|
60
|
+
security?: {
|
|
61
|
+
mintAuthority: string;
|
|
62
|
+
freezeAuthority: string;
|
|
63
|
+
isLpTopHolder: boolean;
|
|
64
|
+
realTopHolderPct: number;
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
export declare function generateSummary(data: SummaryInput): string;
|
|
68
|
+
export {};
|