@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
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
export declare function handleGetTopTraders(args: {
|
|
2
|
+
address: string;
|
|
3
|
+
limit?: number;
|
|
4
|
+
}): Promise<{
|
|
5
|
+
error: string;
|
|
6
|
+
token?: undefined;
|
|
7
|
+
totalHoldersAnalyzed?: undefined;
|
|
8
|
+
profitSummary?: undefined;
|
|
9
|
+
topWinners?: undefined;
|
|
10
|
+
topLosers?: undefined;
|
|
11
|
+
} | {
|
|
12
|
+
token: string;
|
|
13
|
+
totalHoldersAnalyzed: number;
|
|
14
|
+
profitSummary: {
|
|
15
|
+
totalProfit: number;
|
|
16
|
+
totalLoss: number;
|
|
17
|
+
profitableCount: number;
|
|
18
|
+
losingCount: number;
|
|
19
|
+
};
|
|
20
|
+
topWinners: {
|
|
21
|
+
address: string;
|
|
22
|
+
pnl: number;
|
|
23
|
+
profitMultiple: number;
|
|
24
|
+
tags: string[];
|
|
25
|
+
twitterHandle: string | null;
|
|
26
|
+
buyTx: number;
|
|
27
|
+
sellTx: number;
|
|
28
|
+
stillHolding: boolean;
|
|
29
|
+
isDeployer: boolean;
|
|
30
|
+
isDiamondHands: boolean;
|
|
31
|
+
}[];
|
|
32
|
+
topLosers: {
|
|
33
|
+
address: string;
|
|
34
|
+
pnl: number;
|
|
35
|
+
profitMultiple: number;
|
|
36
|
+
tags: string[];
|
|
37
|
+
twitterHandle: string | null;
|
|
38
|
+
buyTx: number;
|
|
39
|
+
sellTx: number;
|
|
40
|
+
stillHolding: boolean;
|
|
41
|
+
isDeployer: boolean;
|
|
42
|
+
isDiamondHands: boolean;
|
|
43
|
+
}[];
|
|
44
|
+
error?: undefined;
|
|
45
|
+
}>;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* get_top_traders tool — Who made/lost money on a token
|
|
3
|
+
* Uses GMGN holder data already collected by analyze_token
|
|
4
|
+
*/
|
|
5
|
+
import * as gmgn from '../sources/gmgn.js';
|
|
6
|
+
export async function handleGetTopTraders(args) {
|
|
7
|
+
const limit = args.limit || 10;
|
|
8
|
+
if (!(await gmgn.isPlaywrightAvailable())) {
|
|
9
|
+
return { error: 'Playwright not installed. Run: npm install playwright && npx playwright install chromium' };
|
|
10
|
+
}
|
|
11
|
+
const { holders } = await gmgn.getHolders(args.address);
|
|
12
|
+
if (holders.length === 0)
|
|
13
|
+
return { error: 'No holder data found' };
|
|
14
|
+
const withPnl = holders.filter(h => h.totalPnl !== 0);
|
|
15
|
+
const winners = [...withPnl].sort((a, b) => b.totalPnl - a.totalPnl).slice(0, limit);
|
|
16
|
+
const losers = [...withPnl].sort((a, b) => a.totalPnl - b.totalPnl).slice(0, limit);
|
|
17
|
+
const totalProfit = withPnl.filter(h => h.totalPnl > 0).reduce((s, h) => s + h.totalPnl, 0);
|
|
18
|
+
const totalLoss = withPnl.filter(h => h.totalPnl < 0).reduce((s, h) => s + h.totalPnl, 0);
|
|
19
|
+
const format = (h) => ({
|
|
20
|
+
address: h.address,
|
|
21
|
+
pnl: Math.round(h.totalPnl * 100) / 100,
|
|
22
|
+
profitMultiple: Math.round(h.profitMultiple * 100) / 100,
|
|
23
|
+
tags: h.tags,
|
|
24
|
+
twitterHandle: h.twitterHandle,
|
|
25
|
+
buyTx: h.buyTxCount,
|
|
26
|
+
sellTx: h.sellTxCount,
|
|
27
|
+
stillHolding: h.balance > 0,
|
|
28
|
+
isDeployer: h.isDeployer,
|
|
29
|
+
isDiamondHands: h.tags.some(t => /diamond/i.test(t)),
|
|
30
|
+
});
|
|
31
|
+
return {
|
|
32
|
+
token: args.address,
|
|
33
|
+
totalHoldersAnalyzed: holders.length,
|
|
34
|
+
profitSummary: {
|
|
35
|
+
totalProfit: Math.round(totalProfit),
|
|
36
|
+
totalLoss: Math.round(totalLoss),
|
|
37
|
+
profitableCount: withPnl.filter(h => h.totalPnl > 0).length,
|
|
38
|
+
losingCount: withPnl.filter(h => h.totalPnl < 0).length,
|
|
39
|
+
},
|
|
40
|
+
topWinners: winners.map(format),
|
|
41
|
+
topLosers: losers.map(format),
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=getTopTraders.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getTopTraders.js","sourceRoot":"","sources":["../../src/tools/getTopTraders.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,IAAI,MAAM,oBAAoB,CAAC;AAE3C,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,IAAyC;IACjF,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;IAE/B,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,qBAAqB,EAAE,CAAC,EAAE,CAAC;QAC1C,OAAO,EAAE,KAAK,EAAE,0FAA0F,EAAE,CAAC;IAC/G,CAAC;IAED,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACxD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,KAAK,EAAE,sBAAsB,EAAE,CAAC;IAEnE,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,CAAC,CAAC,CAAC;IACtD,MAAM,OAAO,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;IACrF,MAAM,MAAM,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;IAEpF,MAAM,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;IAC5F,MAAM,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;IAE1F,MAAM,MAAM,GAAG,CAAC,CAAoB,EAAE,EAAE,CAAC,CAAC;QACxC,OAAO,EAAE,CAAC,CAAC,OAAO;QAClB,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,GAAG,GAAG,CAAC,GAAG,GAAG;QACvC,cAAc,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,cAAc,GAAG,GAAG,CAAC,GAAG,GAAG;QACxD,IAAI,EAAE,CAAC,CAAC,IAAI;QACZ,aAAa,EAAE,CAAC,CAAC,aAAa;QAC9B,KAAK,EAAE,CAAC,CAAC,UAAU;QACnB,MAAM,EAAE,CAAC,CAAC,WAAW;QACrB,YAAY,EAAE,CAAC,CAAC,OAAO,GAAG,CAAC;QAC3B,UAAU,EAAE,CAAC,CAAC,UAAU;QACxB,cAAc,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;KACrD,CAAC,CAAC;IAEH,OAAO;QACL,KAAK,EAAE,IAAI,CAAC,OAAO;QACnB,oBAAoB,EAAE,OAAO,CAAC,MAAM;QACpC,aAAa,EAAE;YACb,WAAW,EAAE,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC;YACpC,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC;YAChC,eAAe,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,MAAM;YAC3D,WAAW,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,MAAM;SACxD;QACD,UAAU,EAAE,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC;QAC/B,SAAS,EAAE,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC;KAC9B,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* get_trending tool — Trending/boosted tokens
|
|
3
|
+
*/
|
|
4
|
+
import { getTrending } from '../sources/dexscreener.js';
|
|
5
|
+
export async function handleGetTrending(args) {
|
|
6
|
+
const chain = args.chain || 'solana';
|
|
7
|
+
const limit = args.limit || 20;
|
|
8
|
+
const tokens = await getTrending(chain, limit);
|
|
9
|
+
return {
|
|
10
|
+
chain,
|
|
11
|
+
count: tokens.length,
|
|
12
|
+
tokens,
|
|
13
|
+
fetchedAt: new Date().toISOString(),
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=getTrending.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getTrending.js","sourceRoot":"","sources":["../../src/tools/getTrending.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAExD,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,IAAwC;IAC9E,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,QAAQ,CAAC;IACrC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;IAC/B,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IAE/C,OAAO;QACL,KAAK;QACL,KAAK,EAAE,MAAM,CAAC,MAAM;QACpB,MAAM;QACN,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KACpC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
export interface DexPair {
|
|
2
|
+
chainId: string;
|
|
3
|
+
dexId: string;
|
|
4
|
+
pairAddress: string;
|
|
5
|
+
baseToken: {
|
|
6
|
+
address: string;
|
|
7
|
+
name: string;
|
|
8
|
+
symbol: string;
|
|
9
|
+
};
|
|
10
|
+
quoteToken: {
|
|
11
|
+
address: string;
|
|
12
|
+
name: string;
|
|
13
|
+
symbol: string;
|
|
14
|
+
};
|
|
15
|
+
priceNative: string;
|
|
16
|
+
priceUsd: string;
|
|
17
|
+
volume: {
|
|
18
|
+
h24: number;
|
|
19
|
+
h6: number;
|
|
20
|
+
h1: number;
|
|
21
|
+
m5: number;
|
|
22
|
+
};
|
|
23
|
+
priceChange: {
|
|
24
|
+
h24: number;
|
|
25
|
+
h6: number;
|
|
26
|
+
h1: number;
|
|
27
|
+
m5: number;
|
|
28
|
+
};
|
|
29
|
+
liquidity: {
|
|
30
|
+
usd: number;
|
|
31
|
+
base: number;
|
|
32
|
+
quote: number;
|
|
33
|
+
};
|
|
34
|
+
fdv: number;
|
|
35
|
+
marketCap: number;
|
|
36
|
+
info?: {
|
|
37
|
+
imageUrl?: string;
|
|
38
|
+
websites?: {
|
|
39
|
+
url: string;
|
|
40
|
+
}[];
|
|
41
|
+
socials?: {
|
|
42
|
+
type: string;
|
|
43
|
+
url: string;
|
|
44
|
+
}[];
|
|
45
|
+
};
|
|
46
|
+
pairCreatedAt?: number;
|
|
47
|
+
}
|
|
48
|
+
export interface Holder {
|
|
49
|
+
address: string;
|
|
50
|
+
tags: string[];
|
|
51
|
+
twitterHandle: string | null;
|
|
52
|
+
twitterName: string | null;
|
|
53
|
+
name: string | null;
|
|
54
|
+
balance: number;
|
|
55
|
+
supplyPercent: number;
|
|
56
|
+
valueUsd: number;
|
|
57
|
+
avgBuyPrice: number;
|
|
58
|
+
cost: number;
|
|
59
|
+
unrealizedPnl: number;
|
|
60
|
+
realizedPnl: number;
|
|
61
|
+
totalPnl: number;
|
|
62
|
+
profitMultiple: number;
|
|
63
|
+
buyAmount: number;
|
|
64
|
+
sellAmount: number;
|
|
65
|
+
buyTxCount: number;
|
|
66
|
+
sellTxCount: number;
|
|
67
|
+
isDeployer: boolean;
|
|
68
|
+
isFreshWallet: boolean;
|
|
69
|
+
lastActiveAt: string | null;
|
|
70
|
+
}
|
|
71
|
+
export interface RiskFlag {
|
|
72
|
+
type: string;
|
|
73
|
+
severity: 'low' | 'medium' | 'high' | 'critical';
|
|
74
|
+
message: string;
|
|
75
|
+
}
|
|
76
|
+
export interface RiskAssessment {
|
|
77
|
+
score: number;
|
|
78
|
+
level: 'LOW' | 'MEDIUM' | 'HIGH' | 'CRITICAL';
|
|
79
|
+
flags: RiskFlag[];
|
|
80
|
+
summary: string;
|
|
81
|
+
}
|
|
82
|
+
export interface TokenAnalysis {
|
|
83
|
+
token: {
|
|
84
|
+
address: string;
|
|
85
|
+
name: string;
|
|
86
|
+
symbol: string;
|
|
87
|
+
chain: string;
|
|
88
|
+
imageUrl?: string;
|
|
89
|
+
};
|
|
90
|
+
price: {
|
|
91
|
+
usd: number;
|
|
92
|
+
nativePrice: string;
|
|
93
|
+
change1h: number;
|
|
94
|
+
change24h: number;
|
|
95
|
+
};
|
|
96
|
+
market: {
|
|
97
|
+
marketCap: number;
|
|
98
|
+
fdv: number;
|
|
99
|
+
volume24h: number;
|
|
100
|
+
volume1h: number;
|
|
101
|
+
liquidity: number;
|
|
102
|
+
dex: string;
|
|
103
|
+
pairAddress: string;
|
|
104
|
+
pairCreatedAt?: string;
|
|
105
|
+
};
|
|
106
|
+
holders?: {
|
|
107
|
+
total: number;
|
|
108
|
+
top: Holder[];
|
|
109
|
+
devWallet: {
|
|
110
|
+
address: string;
|
|
111
|
+
holdingPercent: number;
|
|
112
|
+
status: string;
|
|
113
|
+
} | null;
|
|
114
|
+
distribution: {
|
|
115
|
+
top10Percent: number;
|
|
116
|
+
top20Percent: number;
|
|
117
|
+
freshWalletPercent: number;
|
|
118
|
+
sniperCount: number;
|
|
119
|
+
kolCount: number;
|
|
120
|
+
};
|
|
121
|
+
};
|
|
122
|
+
risk: RiskAssessment;
|
|
123
|
+
meta: {
|
|
124
|
+
sources: string[];
|
|
125
|
+
fetchTimeMs: number;
|
|
126
|
+
};
|
|
127
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":""}
|
package/package.json
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@0xprotovox/deficlaw",
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "DeFi MCP Server for Claude Code — token analysis, prices, trending, holder intelligence",
|
|
5
|
+
"author": "0xprotovox",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"bin": {
|
|
9
|
+
"deficlaw": "dist/index.js"
|
|
10
|
+
},
|
|
11
|
+
"main": "dist/server.js",
|
|
12
|
+
"scripts": {
|
|
13
|
+
"build": "tsc",
|
|
14
|
+
"start": "node dist/index.js",
|
|
15
|
+
"dev": "tsx src/index.ts"
|
|
16
|
+
},
|
|
17
|
+
"dependencies": {
|
|
18
|
+
"@modelcontextprotocol/sdk": "^1.27.1",
|
|
19
|
+
"zod": "^3.23.0"
|
|
20
|
+
},
|
|
21
|
+
"peerDependencies": {
|
|
22
|
+
"playwright": "^1.58.2"
|
|
23
|
+
},
|
|
24
|
+
"peerDependenciesMeta": {
|
|
25
|
+
"playwright": {
|
|
26
|
+
"optional": true
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"@types/node": "^22.0.0",
|
|
31
|
+
"tsx": "^4.19.0",
|
|
32
|
+
"typescript": "^5.5.0"
|
|
33
|
+
},
|
|
34
|
+
"engines": {
|
|
35
|
+
"node": ">=18.0.0"
|
|
36
|
+
},
|
|
37
|
+
"keywords": [
|
|
38
|
+
"mcp",
|
|
39
|
+
"defi",
|
|
40
|
+
"solana",
|
|
41
|
+
"crypto",
|
|
42
|
+
"token-analysis",
|
|
43
|
+
"claude-code",
|
|
44
|
+
"ai-tools"
|
|
45
|
+
]
|
|
46
|
+
}
|