@0xprotovox/deficlaw 0.1.1 → 0.2.0
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 +60 -39
- package/dist/analysis/formatOutput.d.ts +113 -2
- package/dist/analysis/formatOutput.js +135 -100
- package/dist/analysis/formatOutput.js.map +1 -1
- package/dist/analysis/riskScorer.d.ts +24 -2
- package/dist/analysis/riskScorer.js +146 -48
- package/dist/analysis/riskScorer.js.map +1 -1
- package/dist/analysis/summaryGenerator.d.ts +3 -2
- package/dist/analysis/summaryGenerator.js +125 -42
- package/dist/analysis/summaryGenerator.js.map +1 -1
- package/dist/cache/memoryCache.d.ts +12 -3
- package/dist/cache/memoryCache.js +43 -2
- package/dist/cache/memoryCache.js.map +1 -1
- package/dist/server.d.ts +3 -2
- package/dist/server.js +28 -16
- package/dist/server.js.map +1 -1
- package/dist/sources/dexscreener.d.ts +6 -17
- package/dist/sources/dexscreener.js +72 -26
- package/dist/sources/dexscreener.js.map +1 -1
- package/dist/sources/gmgn.d.ts +11 -4
- package/dist/sources/gmgn.js +179 -105
- package/dist/sources/gmgn.js.map +1 -1
- package/dist/sources/solanaRpc.d.ts +4 -4
- package/dist/sources/solanaRpc.js +60 -29
- package/dist/sources/solanaRpc.js.map +1 -1
- package/dist/tools/analyzeToken.d.ts +1 -2
- package/dist/tools/analyzeToken.js +114 -100
- package/dist/tools/analyzeToken.js.map +1 -1
- package/dist/tools/getPrice.d.ts +2 -12
- package/dist/tools/getPrice.js +23 -4
- package/dist/tools/getPrice.js.map +1 -1
- package/dist/tools/getTopTraders.d.ts +30 -24
- package/dist/tools/getTopTraders.js +36 -21
- package/dist/tools/getTopTraders.js.map +1 -1
- package/dist/tools/getTrending.d.ts +8 -1
- package/dist/tools/getTrending.js +12 -2
- package/dist/tools/getTrending.js.map +1 -1
- package/dist/types/index.d.ts +34 -0
- package/package.json +18 -2
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
2
|
+
* Summary Generator — produces human-readable token analysis from raw data.
|
|
3
|
+
* No API calls needed; all logic is rule-based.
|
|
4
4
|
*/
|
|
5
5
|
function fmt(n) {
|
|
6
6
|
if (Math.abs(n) >= 1_000_000)
|
|
@@ -15,12 +15,28 @@ function pct(n) {
|
|
|
15
15
|
export function generateSummary(data) {
|
|
16
16
|
const lines = [];
|
|
17
17
|
const { token, price, market, risk, holders, kols, security } = data;
|
|
18
|
-
// Opening line
|
|
19
|
-
const dexName = market.dex === 'pumpswap' ? 'PumpSwap'
|
|
18
|
+
// ── Opening line: what is this token? ──
|
|
19
|
+
const dexName = market.dex === 'pumpswap' ? 'PumpSwap'
|
|
20
|
+
: market.dex === 'raydium' ? 'Raydium'
|
|
21
|
+
: market.dex === 'orca' ? 'Orca'
|
|
22
|
+
: market.dex === 'meteora' ? 'Meteora'
|
|
23
|
+
: market.dex;
|
|
20
24
|
lines.push(`${token.symbol} is a ${token.age} old ${dexName} token with ${fmt(market.liquidity)} liquidity and ${fmt(market.marketCap)} market cap.`);
|
|
21
|
-
// Price action
|
|
25
|
+
// ── Price action ──
|
|
22
26
|
const priceSignals = [];
|
|
23
|
-
|
|
27
|
+
// Short-term momentum (5m/1h)
|
|
28
|
+
if (Math.abs(price.change5m) > 10) {
|
|
29
|
+
priceSignals.push(price.change5m > 0
|
|
30
|
+
? `pumping ${price.change5m.toFixed(0)}% in the last 5 minutes`
|
|
31
|
+
: `dumping ${Math.abs(price.change5m).toFixed(0)}% in the last 5 minutes`);
|
|
32
|
+
}
|
|
33
|
+
// 24h trend
|
|
34
|
+
if (Math.abs(price.change24h) > 50) {
|
|
35
|
+
priceSignals.push(price.change24h > 0
|
|
36
|
+
? `up ${price.change24h.toFixed(0)}% in 24h, explosive move`
|
|
37
|
+
: `crashed ${Math.abs(price.change24h).toFixed(0)}% in 24h`);
|
|
38
|
+
}
|
|
39
|
+
else if (Math.abs(price.change24h) > 20) {
|
|
24
40
|
priceSignals.push(price.change24h > 0
|
|
25
41
|
? `up ${price.change24h.toFixed(0)}% in 24h, strong momentum`
|
|
26
42
|
: `down ${Math.abs(price.change24h).toFixed(0)}% in 24h, heavy selling`);
|
|
@@ -33,66 +49,112 @@ export function generateSummary(data) {
|
|
|
33
49
|
else {
|
|
34
50
|
priceSignals.push('price is flat today');
|
|
35
51
|
}
|
|
52
|
+
// Divergence between timeframes
|
|
53
|
+
if (price.change1h > 10 && price.change24h < -10) {
|
|
54
|
+
priceSignals.push('bouncing after a sell-off');
|
|
55
|
+
}
|
|
56
|
+
else if (price.change1h < -10 && price.change24h > 10) {
|
|
57
|
+
priceSignals.push('selling off after earlier gains');
|
|
58
|
+
}
|
|
59
|
+
// Volume signals
|
|
36
60
|
if (market.volume1h === 0 && market.volume24h < 1000) {
|
|
37
61
|
priceSignals.push('volume is dead right now');
|
|
38
62
|
}
|
|
39
|
-
else if (market.volume1h > market.volume24h * 0.2) {
|
|
63
|
+
else if (market.volume1h > market.volume24h * 0.2 && market.volume1h > 0) {
|
|
40
64
|
priceSignals.push('volume spiking in the last hour');
|
|
41
65
|
}
|
|
42
|
-
if (market.volumeLiquidityRatio < 0.1) {
|
|
66
|
+
if (market.volumeLiquidityRatio < 0.1 && market.volume24h > 0) {
|
|
43
67
|
priceSignals.push('very low trading activity relative to liquidity');
|
|
44
68
|
}
|
|
69
|
+
else if (market.volumeLiquidityRatio > 5) {
|
|
70
|
+
priceSignals.push('extreme turnover, massive volume relative to pool size');
|
|
71
|
+
}
|
|
45
72
|
else if (market.volumeLiquidityRatio > 2) {
|
|
46
73
|
priceSignals.push('high turnover, lots of trading relative to pool size');
|
|
47
74
|
}
|
|
48
|
-
|
|
49
|
-
|
|
75
|
+
if (priceSignals.length > 0) {
|
|
76
|
+
const first = priceSignals[0];
|
|
77
|
+
const rest = priceSignals.slice(1);
|
|
78
|
+
lines.push(first[0].toUpperCase() + first.slice(1) + (rest.length > 0 ? ', ' + rest.join(', ') : '') + '.');
|
|
79
|
+
}
|
|
80
|
+
// ── Holder analysis ──
|
|
50
81
|
if (holders) {
|
|
51
82
|
const { concentration, categories, sentiment, pressure, devWallet } = holders;
|
|
52
|
-
// Concentration
|
|
53
|
-
if (concentration.top5Pct > 0.
|
|
83
|
+
// Concentration insight
|
|
84
|
+
if (concentration.top5Pct > 0.50) {
|
|
54
85
|
lines.push(`Top 5 wallets control ${pct(concentration.top5Pct)} of supply, very concentrated.`);
|
|
55
86
|
}
|
|
56
|
-
else if (concentration.top10Pct > 0.
|
|
87
|
+
else if (concentration.top10Pct > 0.50) {
|
|
57
88
|
lines.push(`Top 10 hold ${pct(concentration.top10Pct)}, moderately concentrated.`);
|
|
58
89
|
}
|
|
90
|
+
else if (concentration.top10Pct < 0.20) {
|
|
91
|
+
lines.push(`Supply is broadly distributed, top 10 hold only ${pct(concentration.top10Pct)}.`);
|
|
92
|
+
}
|
|
59
93
|
else {
|
|
60
94
|
lines.push(`Supply is well distributed, top 10 hold ${pct(concentration.top10Pct)}.`);
|
|
61
95
|
}
|
|
62
|
-
// Diamond hands
|
|
63
|
-
if (categories.diamondHands > holders.total * 0.4) {
|
|
96
|
+
// Diamond hands
|
|
97
|
+
if (categories.diamondHands > 0 && categories.diamondHands > holders.total * 0.4) {
|
|
64
98
|
lines.push(`${categories.diamondHands} diamond hands (${pct(categories.diamondHands / holders.total)}), strong holder conviction.`);
|
|
65
99
|
}
|
|
100
|
+
else if (categories.diamondHands > 0 && categories.diamondHands > holders.total * 0.2) {
|
|
101
|
+
lines.push(`${categories.diamondHands} diamond hands among holders, decent conviction.`);
|
|
102
|
+
}
|
|
66
103
|
// Profit/loss sentiment
|
|
67
|
-
if (sentiment.profitRatio < 0.
|
|
104
|
+
if (sentiment.profitRatio < 0.10 && holders.total > 5) {
|
|
105
|
+
lines.push(`Almost nobody is in profit (${pct(sentiment.profitRatio)}), most holders are deep underwater with avg loss of ${fmt(Math.abs(sentiment.avgPnlPerHolder))} per wallet.`);
|
|
106
|
+
}
|
|
107
|
+
else if (sentiment.profitRatio < 0.20) {
|
|
68
108
|
lines.push(`Only ${pct(sentiment.profitRatio)} of holders are in profit, most are underwater with avg loss of ${fmt(Math.abs(sentiment.avgPnlPerHolder))} per wallet.`);
|
|
69
109
|
}
|
|
70
|
-
else if (sentiment.profitRatio > 0.
|
|
110
|
+
else if (sentiment.profitRatio > 0.70) {
|
|
111
|
+
lines.push(`${pct(sentiment.profitRatio)} of holders are profitable, very healthy sentiment.`);
|
|
112
|
+
}
|
|
113
|
+
else if (sentiment.profitRatio > 0.50) {
|
|
71
114
|
lines.push(`${pct(sentiment.profitRatio)} of holders are profitable, healthy sentiment.`);
|
|
72
115
|
}
|
|
73
116
|
else {
|
|
74
117
|
lines.push(`${pct(sentiment.profitRatio)} in profit, ${pct(1 - sentiment.profitRatio)} underwater.`);
|
|
75
118
|
}
|
|
76
119
|
// Buy/sell pressure
|
|
77
|
-
if (pressure.buySellRatio >
|
|
120
|
+
if (pressure.buySellRatio > 5) {
|
|
121
|
+
lines.push(`Extreme buy pressure at ${pressure.buySellRatio.toFixed(1)}:1 ratio (${pressure.totalBuyTx} buys vs ${pressure.totalSellTx} sells), heavy accumulation.`);
|
|
122
|
+
}
|
|
123
|
+
else if (pressure.buySellRatio > 3) {
|
|
78
124
|
lines.push(`Buy pressure is strong at ${pressure.buySellRatio.toFixed(1)}:1 ratio (${pressure.totalBuyTx} buys vs ${pressure.totalSellTx} sells), accumulation phase.`);
|
|
79
125
|
}
|
|
80
126
|
else if (pressure.buySellRatio > 1.5) {
|
|
81
127
|
lines.push(`More buying than selling (${pressure.buySellRatio.toFixed(1)}:1), slight accumulation.`);
|
|
82
128
|
}
|
|
83
|
-
else if (pressure.buySellRatio < 0.
|
|
129
|
+
else if (pressure.buySellRatio < 0.3 && pressure.totalSellTx > 0) {
|
|
130
|
+
lines.push(`Massive sell pressure (${pressure.buySellRatio.toFixed(2)}:1), panic selling.`);
|
|
131
|
+
}
|
|
132
|
+
else if (pressure.buySellRatio < 0.5 && pressure.totalSellTx > 0) {
|
|
84
133
|
lines.push(`Heavy sell pressure (${pressure.buySellRatio.toFixed(2)}:1), distribution phase.`);
|
|
85
134
|
}
|
|
135
|
+
else if (pressure.totalBuyTx === 0 && pressure.totalSellTx === 0) {
|
|
136
|
+
lines.push(`No recent buy/sell activity detected.`);
|
|
137
|
+
}
|
|
86
138
|
else {
|
|
87
139
|
lines.push(`Buy/sell pressure is balanced.`);
|
|
88
140
|
}
|
|
89
141
|
// Snipers & fresh wallets
|
|
90
|
-
if (categories.snipers >
|
|
142
|
+
if (categories.snipers > 5) {
|
|
143
|
+
lines.push(`${categories.snipers} sniper/bot wallets detected, high dump risk.`);
|
|
144
|
+
}
|
|
145
|
+
else if (categories.snipers > 3) {
|
|
91
146
|
lines.push(`${categories.snipers} sniper wallets detected, watch for dumps.`);
|
|
92
147
|
}
|
|
93
|
-
if (categories.freshWallets > holders.total * 0.
|
|
148
|
+
if (categories.freshWallets > holders.total * 0.30) {
|
|
149
|
+
lines.push(`${pct(categories.freshWallets / holders.total)} fresh wallets, highly likely bundled or wash traded.`);
|
|
150
|
+
}
|
|
151
|
+
else if (categories.freshWallets > holders.total * 0.20) {
|
|
94
152
|
lines.push(`${pct(categories.freshWallets / holders.total)} fresh wallets, possible wash trading or bundle.`);
|
|
95
153
|
}
|
|
154
|
+
// Smart money presence
|
|
155
|
+
if (categories.smartMoney > 0) {
|
|
156
|
+
lines.push(`${categories.smartMoney} smart money wallet${categories.smartMoney > 1 ? 's' : ''} detected.`);
|
|
157
|
+
}
|
|
96
158
|
// Dev wallet
|
|
97
159
|
if (devWallet) {
|
|
98
160
|
if (devWallet.status === 'sold_most') {
|
|
@@ -101,32 +163,40 @@ export function generateSummary(data) {
|
|
|
101
163
|
else if (devWallet.status === 'selling') {
|
|
102
164
|
lines.push(`Dev is actively selling, holding ${pct(devWallet.holdingPercent)}.`);
|
|
103
165
|
}
|
|
166
|
+
else if (devWallet.holdingPercent > 0.10) {
|
|
167
|
+
lines.push(`Dev still holding ${pct(devWallet.holdingPercent)}, large position.`);
|
|
168
|
+
}
|
|
104
169
|
else {
|
|
105
170
|
lines.push(`Dev still holding ${pct(devWallet.holdingPercent)}, aligned with project.`);
|
|
106
171
|
}
|
|
107
172
|
}
|
|
108
|
-
else {
|
|
173
|
+
else if (holders.total > 0) {
|
|
109
174
|
lines.push(`No dev wallet detected in top holders.`);
|
|
110
175
|
}
|
|
111
176
|
}
|
|
112
|
-
// KOL analysis
|
|
177
|
+
// ── KOL analysis ──
|
|
113
178
|
if (kols && kols.length > 0) {
|
|
114
|
-
const kolsWithTwitter = kols.filter(k => k.twitterHandle);
|
|
115
179
|
const kolsSelling = kols.filter(k => k.status === 'selling');
|
|
116
180
|
const kolsHolding = kols.filter(k => k.status === 'holding');
|
|
117
181
|
const kolsProfitable = kols.filter(k => k.pnl > 0);
|
|
118
|
-
lines.push(`${kols.length}
|
|
119
|
-
if (kolsSelling.length > kolsHolding.length) {
|
|
182
|
+
lines.push(`${kols.length} KOL${kols.length > 1 ? 's' : ''} tracked: ${kolsHolding.length} holding, ${kolsSelling.length} selling.`);
|
|
183
|
+
if (kolsSelling.length > kolsHolding.length && kols.length >= 3) {
|
|
120
184
|
lines.push(`Most KOLs are exiting, bearish signal.`);
|
|
121
185
|
}
|
|
122
|
-
else if (kolsHolding.length > kols.length * 0.
|
|
123
|
-
lines.push(`
|
|
186
|
+
else if (kolsHolding.length > kols.length * 0.7) {
|
|
187
|
+
lines.push(`Strong KOL conviction, most still holding.`);
|
|
188
|
+
}
|
|
189
|
+
else if (kolsHolding.length > kols.length * 0.5) {
|
|
190
|
+
lines.push(`Majority of KOLs still holding.`);
|
|
124
191
|
}
|
|
125
192
|
if (kolsProfitable.length === 0 && kols.length > 3) {
|
|
126
193
|
lines.push(`None of the KOLs are profitable on this token.`);
|
|
127
194
|
}
|
|
195
|
+
else if (kolsProfitable.length === kols.length && kols.length > 1) {
|
|
196
|
+
lines.push(`All tracked KOLs are in profit.`);
|
|
197
|
+
}
|
|
128
198
|
}
|
|
129
|
-
// Security
|
|
199
|
+
// ── Security ──
|
|
130
200
|
if (security) {
|
|
131
201
|
const securityIssues = [];
|
|
132
202
|
if (security.mintAuthority === 'active')
|
|
@@ -134,7 +204,7 @@ export function generateSummary(data) {
|
|
|
134
204
|
if (security.freezeAuthority === 'active')
|
|
135
205
|
securityIssues.push('freeze authority active (tokens can be frozen)');
|
|
136
206
|
if (securityIssues.length > 0) {
|
|
137
|
-
lines.push(
|
|
207
|
+
lines.push(`Security concerns: ${securityIssues.join(', ')}.`);
|
|
138
208
|
}
|
|
139
209
|
else {
|
|
140
210
|
lines.push(`Contract looks safe: mint and freeze authorities revoked.`);
|
|
@@ -143,28 +213,41 @@ export function generateSummary(data) {
|
|
|
143
213
|
lines.push(`Top holder is the LP pool, real top holder owns ${pct(security.realTopHolderPct)}.`);
|
|
144
214
|
}
|
|
145
215
|
}
|
|
146
|
-
// Risk verdict
|
|
216
|
+
// ── Risk verdict ──
|
|
147
217
|
if (risk.level === 'CRITICAL') {
|
|
148
|
-
lines.push(
|
|
218
|
+
lines.push(`HIGH RISK: multiple red flags, extreme caution advised.`);
|
|
149
219
|
}
|
|
150
220
|
else if (risk.level === 'HIGH') {
|
|
151
|
-
lines.push(
|
|
221
|
+
lines.push(`Elevated risk, do thorough research before entering.`);
|
|
152
222
|
}
|
|
153
223
|
else if (risk.level === 'MEDIUM') {
|
|
154
|
-
lines.push(
|
|
224
|
+
lines.push(`Moderate risk, some concerns but nothing critical.`);
|
|
155
225
|
}
|
|
156
226
|
else {
|
|
157
|
-
lines.push(
|
|
227
|
+
lines.push(`Lower risk profile based on available data.`);
|
|
158
228
|
}
|
|
159
|
-
// Final actionable insight
|
|
229
|
+
// ── Final actionable insight (pattern-matching) ──
|
|
160
230
|
if (market.volume1h === 0 && market.volume24h < 500) {
|
|
161
|
-
lines.push(
|
|
231
|
+
lines.push(`Token appears dormant. Check if community and socials are still active before entering.`);
|
|
162
232
|
}
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
233
|
+
if (holders) {
|
|
234
|
+
// Accumulation despite underwater holders
|
|
235
|
+
if (holders.pressure.buySellRatio > 3 && holders.sentiment.profitRatio < 0.25) {
|
|
236
|
+
lines.push(`Interesting setup: strong buy pressure despite most holders being underwater. Could mean accumulation before a move, or dead cat buying.`);
|
|
237
|
+
}
|
|
238
|
+
// Diamond hands conviction despite losses
|
|
239
|
+
if (holders.categories.diamondHands > holders.total * 0.5 && holders.sentiment.profitRatio < 0.2) {
|
|
240
|
+
lines.push(`Holders refuse to sell despite being down. Either strong conviction or stuck with illiquid bags.`);
|
|
241
|
+
}
|
|
242
|
+
// Insider/smart money accumulating while others sell
|
|
243
|
+
if (holders.categories.smartMoney > 0 && holders.pressure.buySellRatio < 0.8 && price.change24h < -15) {
|
|
244
|
+
lines.push(`Smart money present while others are selling. Watch for reversal signals.`);
|
|
245
|
+
}
|
|
246
|
+
// Warning: all KOLs selling + high concentration
|
|
247
|
+
if (kols && kols.length > 2 && kols.every(k => k.status === 'selling') &&
|
|
248
|
+
holders.concentration.top10Pct > 0.40) {
|
|
249
|
+
lines.push(`All KOLs exiting combined with high concentration. Significant dump risk.`);
|
|
250
|
+
}
|
|
168
251
|
}
|
|
169
252
|
return lines.join('\n');
|
|
170
253
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"summaryGenerator.js","sourceRoot":"","sources":["../../src/analysis/summaryGenerator.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"summaryGenerator.js","sourceRoot":"","sources":["../../src/analysis/summaryGenerator.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,13 +1,22 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* TTL-based in-memory cache
|
|
3
|
-
*
|
|
2
|
+
* TTL-based in-memory cache with automatic cleanup.
|
|
3
|
+
* Expired entries are purged periodically to prevent unbounded memory growth.
|
|
4
4
|
*/
|
|
5
5
|
export declare class MemoryCache<T> {
|
|
6
6
|
private cache;
|
|
7
|
-
private ttlMs;
|
|
7
|
+
private readonly ttlMs;
|
|
8
|
+
private cleanupTimer;
|
|
9
|
+
/** Maximum entries before forced cleanup (safety valve) */
|
|
10
|
+
private static readonly MAX_ENTRIES;
|
|
8
11
|
constructor(ttlMs: number);
|
|
9
12
|
get(key: string): T | null;
|
|
10
13
|
set(key: string, data: T): void;
|
|
11
14
|
has(key: string): boolean;
|
|
15
|
+
/** Number of entries (including possibly expired ones) */
|
|
16
|
+
get size(): number;
|
|
12
17
|
clear(): void;
|
|
18
|
+
/** Stop the background cleanup timer */
|
|
19
|
+
destroy(): void;
|
|
20
|
+
/** Remove all expired entries */
|
|
21
|
+
private evictExpired;
|
|
13
22
|
}
|
|
@@ -1,12 +1,21 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* TTL-based in-memory cache
|
|
3
|
-
*
|
|
2
|
+
* TTL-based in-memory cache with automatic cleanup.
|
|
3
|
+
* Expired entries are purged periodically to prevent unbounded memory growth.
|
|
4
4
|
*/
|
|
5
5
|
export class MemoryCache {
|
|
6
6
|
cache = new Map();
|
|
7
7
|
ttlMs;
|
|
8
|
+
cleanupTimer = null;
|
|
9
|
+
/** Maximum entries before forced cleanup (safety valve) */
|
|
10
|
+
static MAX_ENTRIES = 10_000;
|
|
8
11
|
constructor(ttlMs) {
|
|
9
12
|
this.ttlMs = ttlMs;
|
|
13
|
+
// Run cleanup every 5 minutes (or 10x TTL, whichever is larger)
|
|
14
|
+
const cleanupInterval = Math.max(ttlMs * 10, 5 * 60 * 1000);
|
|
15
|
+
this.cleanupTimer = setInterval(() => this.evictExpired(), cleanupInterval);
|
|
16
|
+
// Allow the process to exit even if the timer is running
|
|
17
|
+
if (this.cleanupTimer.unref)
|
|
18
|
+
this.cleanupTimer.unref();
|
|
10
19
|
}
|
|
11
20
|
get(key) {
|
|
12
21
|
const entry = this.cache.get(key);
|
|
@@ -19,13 +28,45 @@ export class MemoryCache {
|
|
|
19
28
|
return entry.data;
|
|
20
29
|
}
|
|
21
30
|
set(key, data) {
|
|
31
|
+
// Safety valve: if cache is way too large, evict oldest entries
|
|
32
|
+
if (this.cache.size >= MemoryCache.MAX_ENTRIES) {
|
|
33
|
+
this.evictExpired();
|
|
34
|
+
// If still over limit after eviction, drop oldest half
|
|
35
|
+
if (this.cache.size >= MemoryCache.MAX_ENTRIES) {
|
|
36
|
+
const keys = [...this.cache.keys()];
|
|
37
|
+
for (let i = 0; i < keys.length / 2; i++) {
|
|
38
|
+
this.cache.delete(keys[i]);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
22
42
|
this.cache.set(key, { data, ts: Date.now() });
|
|
23
43
|
}
|
|
24
44
|
has(key) {
|
|
25
45
|
return this.get(key) !== null;
|
|
26
46
|
}
|
|
47
|
+
/** Number of entries (including possibly expired ones) */
|
|
48
|
+
get size() {
|
|
49
|
+
return this.cache.size;
|
|
50
|
+
}
|
|
27
51
|
clear() {
|
|
28
52
|
this.cache.clear();
|
|
29
53
|
}
|
|
54
|
+
/** Stop the background cleanup timer */
|
|
55
|
+
destroy() {
|
|
56
|
+
if (this.cleanupTimer) {
|
|
57
|
+
clearInterval(this.cleanupTimer);
|
|
58
|
+
this.cleanupTimer = null;
|
|
59
|
+
}
|
|
60
|
+
this.cache.clear();
|
|
61
|
+
}
|
|
62
|
+
/** Remove all expired entries */
|
|
63
|
+
evictExpired() {
|
|
64
|
+
const now = Date.now();
|
|
65
|
+
for (const [key, entry] of this.cache) {
|
|
66
|
+
if (now - entry.ts > this.ttlMs) {
|
|
67
|
+
this.cache.delete(key);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
30
71
|
}
|
|
31
72
|
//# sourceMappingURL=memoryCache.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memoryCache.js","sourceRoot":"","sources":["../../src/cache/memoryCache.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,OAAO,WAAW;IACd,KAAK,GAAG,IAAI,GAAG,EAAmC,CAAC;
|
|
1
|
+
{"version":3,"file":"memoryCache.js","sourceRoot":"","sources":["../../src/cache/memoryCache.ts"],"names":[],"mappings":"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"}
|
package/dist/server.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* DeFi MCP Server
|
|
3
|
-
* First open-source DeFi MCP for Claude Code
|
|
2
|
+
* DeFi MCP Server — deficlaw
|
|
3
|
+
* First open-source DeFi MCP for Claude Code.
|
|
4
|
+
* Token analysis, prices, trending, top traders.
|
|
4
5
|
* by @0xprotovox
|
|
5
6
|
*/
|
|
6
7
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
package/dist/server.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* DeFi MCP Server
|
|
3
|
-
* First open-source DeFi MCP for Claude Code
|
|
2
|
+
* DeFi MCP Server — deficlaw
|
|
3
|
+
* First open-source DeFi MCP for Claude Code.
|
|
4
|
+
* Token analysis, prices, trending, top traders.
|
|
4
5
|
* by @0xprotovox
|
|
5
6
|
*/
|
|
6
7
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
@@ -13,62 +14,73 @@ import { formatAnalysis } from './analysis/formatOutput.js';
|
|
|
13
14
|
export function createServer() {
|
|
14
15
|
const server = new McpServer({
|
|
15
16
|
name: 'deficlaw',
|
|
16
|
-
version: '0.
|
|
17
|
+
version: '0.2.0',
|
|
17
18
|
});
|
|
18
19
|
// ── analyze_token ──
|
|
19
20
|
server.tool('analyze_token', 'Full token analysis: price, volume, liquidity, holder intelligence, risk scoring. Supports Solana tokens with GMGN holder data.', {
|
|
20
|
-
address: z.string().describe('Token contract address (e.g. Solana mint address)'),
|
|
21
|
+
address: z.string().min(1).describe('Token contract address (e.g. Solana mint address)'),
|
|
21
22
|
chain: z.string().default('solana').describe('Blockchain: solana, ethereum, bsc, base, arbitrum'),
|
|
22
|
-
include_holders: z.boolean().default(true).describe('Include GMGN holder analysis (slower, needs Playwright)'),
|
|
23
|
+
include_holders: z.boolean().default(true).describe('Include GMGN holder analysis (slower, needs curl or Playwright)'),
|
|
23
24
|
}, async (args) => {
|
|
24
25
|
try {
|
|
25
26
|
const result = await handleAnalyzeToken(args);
|
|
26
|
-
if ('error' in result)
|
|
27
|
+
if ('error' in result && typeof result.error === 'string') {
|
|
27
28
|
return { content: [{ type: 'text', text: JSON.stringify(result) }], isError: true };
|
|
29
|
+
}
|
|
28
30
|
const formatted = formatAnalysis(result);
|
|
29
31
|
return { content: [{ type: 'text', text: formatted }] };
|
|
30
32
|
}
|
|
31
33
|
catch (err) {
|
|
32
|
-
|
|
34
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
35
|
+
return { content: [{ type: 'text', text: JSON.stringify({ error: `Analysis failed: ${message}` }) }], isError: true };
|
|
33
36
|
}
|
|
34
37
|
});
|
|
35
38
|
// ── get_price ──
|
|
36
39
|
server.tool('get_price', 'Quick token price lookup with 24h change, volume, liquidity, and market cap.', {
|
|
37
|
-
token: z.string().describe('Token address or search query'),
|
|
40
|
+
token: z.string().min(1).describe('Token address or search query (symbol/name)'),
|
|
38
41
|
chain: z.string().default('solana').describe('Blockchain: solana, ethereum, bsc, base, arbitrum'),
|
|
39
42
|
}, async (args) => {
|
|
40
43
|
try {
|
|
41
44
|
const result = await handleGetPrice(args);
|
|
42
|
-
return {
|
|
45
|
+
return {
|
|
46
|
+
content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
|
|
47
|
+
...('error' in result ? { isError: true } : {}),
|
|
48
|
+
};
|
|
43
49
|
}
|
|
44
50
|
catch (err) {
|
|
45
|
-
|
|
51
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
52
|
+
return { content: [{ type: 'text', text: JSON.stringify({ error: `Price lookup failed: ${message}` }) }], isError: true };
|
|
46
53
|
}
|
|
47
54
|
});
|
|
48
55
|
// ── get_trending ──
|
|
49
56
|
server.tool('get_trending', 'Get trending/boosted tokens on a blockchain. Returns top tokens by volume and boost activity.', {
|
|
50
57
|
chain: z.string().default('solana').describe('Blockchain: solana, ethereum, bsc, base, arbitrum'),
|
|
51
|
-
limit: z.number().default(20).describe('Number of tokens to return (
|
|
58
|
+
limit: z.number().min(1).max(50).default(20).describe('Number of tokens to return (1-50)'),
|
|
52
59
|
}, async (args) => {
|
|
53
60
|
try {
|
|
54
61
|
const result = await handleGetTrending(args);
|
|
55
62
|
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
|
|
56
63
|
}
|
|
57
64
|
catch (err) {
|
|
58
|
-
|
|
65
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
66
|
+
return { content: [{ type: 'text', text: JSON.stringify({ error: `Trending fetch failed: ${message}` }) }], isError: true };
|
|
59
67
|
}
|
|
60
68
|
});
|
|
61
69
|
// ── get_top_traders ──
|
|
62
70
|
server.tool('get_top_traders', 'Find who made and lost money on a token. Shows top winners and losers with PnL, tags, and Twitter handles.', {
|
|
63
|
-
address: z.string().describe('Token contract address'),
|
|
64
|
-
limit: z.number().default(10).describe('Number of top winners/losers to show'),
|
|
71
|
+
address: z.string().min(1).describe('Token contract address'),
|
|
72
|
+
limit: z.number().min(1).max(50).default(10).describe('Number of top winners/losers to show (1-50)'),
|
|
65
73
|
}, async (args) => {
|
|
66
74
|
try {
|
|
67
75
|
const result = await handleGetTopTraders(args);
|
|
68
|
-
return {
|
|
76
|
+
return {
|
|
77
|
+
content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
|
|
78
|
+
...('error' in result ? { isError: true } : {}),
|
|
79
|
+
};
|
|
69
80
|
}
|
|
70
81
|
catch (err) {
|
|
71
|
-
|
|
82
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
83
|
+
return { content: [{ type: 'text', text: JSON.stringify({ error: `Top traders fetch failed: ${message}` }) }], isError: true };
|
|
72
84
|
}
|
|
73
85
|
});
|
|
74
86
|
return server;
|
package/dist/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,20 +1,9 @@
|
|
|
1
|
-
import type { DexPair } from '../types/index.js';
|
|
2
|
-
/** Get best pair for a token address (highest liquidity) */
|
|
1
|
+
import type { DexPair, PriceResult, TrendingToken } from '../types/index.js';
|
|
2
|
+
/** Get best pair for a token address (highest liquidity on the target chain) */
|
|
3
3
|
export declare function getTokenPair(address: string, chain?: string): Promise<DexPair | null>;
|
|
4
|
-
/** Quick price lookup */
|
|
5
|
-
export declare function getPrice(address: string, chain?: string): Promise<
|
|
6
|
-
address: string;
|
|
7
|
-
symbol: string;
|
|
8
|
-
name: string;
|
|
9
|
-
priceUsd: number;
|
|
10
|
-
priceChange1h: number;
|
|
11
|
-
priceChange24h: number;
|
|
12
|
-
volume24h: number;
|
|
13
|
-
liquidity: number;
|
|
14
|
-
marketCap: number;
|
|
15
|
-
dex: string;
|
|
16
|
-
} | null>;
|
|
4
|
+
/** Quick price lookup — returns null if token not found */
|
|
5
|
+
export declare function getPrice(address: string, chain?: string): Promise<PriceResult | null>;
|
|
17
6
|
/** Search tokens by name or symbol */
|
|
18
7
|
export declare function searchTokens(query: string): Promise<DexPair[]>;
|
|
19
|
-
/** Get trending/boosted tokens */
|
|
20
|
-
export declare function getTrending(chain?: string, limit?: number): Promise<
|
|
8
|
+
/** Get trending/boosted tokens. Enriches with price data in parallel. */
|
|
9
|
+
export declare function getTrending(chain?: string, limit?: number): Promise<(TrendingToken & Partial<PriceResult>)[]>;
|