Skip to content

Commit 414609b

Browse files
fix: combine Safety Score and Danger Level into single 1-100 Safety Score
1 parent 9b13a10 commit 414609b

9 files changed

Lines changed: 22 additions & 150 deletions

.github/assets/c__Users_1337_AppData_Roaming_Cursor_User_workspaceStorage_e0127ad5062ccc5a2160d5891e7af396_images_image-31fdcde5-c831-4792-986a-06fa4194238c.png

Loading

.github/assets/c__Users_1337_AppData_Roaming_Cursor_User_workspaceStorage_e0127ad5062ccc5a2160d5891e7af396_images_image-37b821f7-763c-4f0d-95fe-0007205c2a8d.png

Loading

.github/assets/c__Users_1337_AppData_Roaming_Cursor_User_workspaceStorage_e0127ad5062ccc5a2160d5891e7af396_images_image-7d6a404d-e2ce-4ed9-a77f-953d4e051858.png

Loading

.github/assets/c__Users_1337_AppData_Roaming_Cursor_User_workspaceStorage_e0127ad5062ccc5a2160d5891e7af396_images_image-f4d3da30-3199-4457-b694-82fdb109e82c.png

Loading

client/src/pages/documentation.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,6 @@ const DocumentationPDF = () => (
321321
<Text style={pdfStyles.text}>• Whitepaper: /documentation (this PDF)</Text>
322322
<Text style={pdfStyles.text}>• Discord: @RugKillerAlphaBot</Text>
323323
<Text style={pdfStyles.text}>• Telegram: @RugKillerAlphaBot</Text>
324-
<Text style={pdfStyles.text}>• Token: HeLp6NuQkmYB4pYWo2zYs22mESHXPQYzXbB8n4V98jwC</Text>
325324
</View>
326325
</View>
327326

server/alpha-alerts.ts

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -791,15 +791,9 @@ export class AlphaAlertService {
791791
: analysisMetrics.aiVerdict,
792792
inline: false
793793
}] : []),
794-
// Rug Score Breakdown (uses SAME score as Safety Score for consistency)
794+
// Risk Breakdown (component scores only - no separate score, Safety Score is the main score)
795795
...(analysisMetrics.rugScore ? [{
796-
name: (() => {
797-
// Use the same riskScore as Safety Score for consistency
798-
const safetyScore = Math.max(1, Math.min(100, analysisMetrics.riskScore));
799-
const emoji = safetyScore >= 80 ? '✅' : safetyScore >= 60 ? '⚠️' : safetyScore >= 40 ? '🟠' : '🚨';
800-
const label = safetyScore >= 80 ? 'SAFE' : safetyScore >= 60 ? 'CAUTION' : safetyScore >= 40 ? 'RISKY' : 'DANGER';
801-
return `${emoji} Rug Score: ${safetyScore}/100 (${label})`;
802-
})(),
796+
name: '📊 Risk Breakdown',
803797
value: (() => {
804798
// Show component breakdown (0-10 scale where higher = safer)
805799
const auth = analysisMetrics.mintRevoked && analysisMetrics.freezeRevoked ? 10 :
@@ -1322,15 +1316,9 @@ export class AlphaAlertService {
13221316
: analysisMetrics.aiVerdict,
13231317
inline: false
13241318
}] : []),
1325-
// Rug Score Breakdown (uses SAME score as Safety Score for consistency)
1319+
// Risk Breakdown (component scores only - no separate score, Safety Score is the main score)
13261320
...(analysisMetrics.rugScore ? [{
1327-
name: (() => {
1328-
// Use the same riskScore as Safety Score for consistency
1329-
const safetyScore = Math.max(1, Math.min(100, analysisMetrics.riskScore));
1330-
const emoji = safetyScore >= 80 ? '✅' : safetyScore >= 60 ? '⚠️' : safetyScore >= 40 ? '🟠' : '🚨';
1331-
const label = safetyScore >= 80 ? 'SAFE' : safetyScore >= 60 ? 'CAUTION' : safetyScore >= 40 ? 'RISKY' : 'DANGER';
1332-
return `${emoji} Rug Score: ${safetyScore}/100 (${label})`;
1333-
})(),
1321+
name: '📊 Risk Breakdown',
13341322
value: (() => {
13351323
// Show component breakdown (0-10 scale where higher = safer)
13361324
const auth = analysisMetrics.mintRevoked && analysisMetrics.freezeRevoked ? 10 :

server/bot-formatter.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -113,14 +113,11 @@ export function buildCompactMessage(analysis: TokenAnalysisResponse): CompactMes
113113
const safetyLabel = safetyScore >= 80 ? 'SAFE' : safetyScore >= 60 ? 'CAUTION' : safetyScore >= 40 ? 'RISKY' : 'DANGER';
114114
const riskScore = `${safetyEmoji} **Safety Score: ${safetyScore}/100** (${safetyLabel})`;
115115

116-
// DANGER LEVEL (converted from Rug Score for clarity - lower = safer)
116+
// RISK BREAKDOWN (component scores, no separate danger level)
117117
let rugScoreText: string | undefined;
118118
if (analysis.rugScoreBreakdown) {
119119
const rs = analysis.rugScoreBreakdown;
120-
const dangerLevel = Math.min(100, Math.round(rs.totalScore));
121-
const dangerEmoji = dangerLevel < 10 ? '✅' : dangerLevel < 30 ? '🟢' : dangerLevel < 50 ? '🟡' : dangerLevel < 70 ? '🟠' : '🔴';
122-
const dangerLabel = dangerLevel < 10 ? 'VERY LOW' : dangerLevel < 30 ? 'LOW' : dangerLevel < 50 ? 'MODERATE' : dangerLevel < 70 ? 'HIGH' : 'EXTREME';
123-
rugScoreText = `${dangerEmoji} **Danger Level:** ${dangerLevel}/100 (${dangerLabel})\n\n**Breakdown:**\n` +
120+
rugScoreText = `📊 **Risk Breakdown:**\n` +
124121
`• Authorities: ${Math.round(rs.components.authorities.score)} pts\n` +
125122
`• Holder Dist: ${Math.round(rs.components.holderDistribution.score)} pts\n` +
126123
`• Liquidity: ${Math.round(rs.components.liquidity.score)} pts\n` +

server/discord-bot.ts

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -121,21 +121,17 @@ function createAnalysisEmbed(analysis: TokenAnalysisResponse): EmbedBuilder {
121121
.setTimestamp()
122122
.setThumbnail(`https://dd.dexscreener.com/ds-data/tokens/solana/${analysis.tokenAddress}.png?size=md&t=${Date.now()}`);
123123

124-
// RUG SCORE - Convert to Danger Level for clarity
125-
if (messageData.rugScore && analysis.rugScoreBreakdown) {
124+
// Risk breakdown components (no separate score - Safety Score is the main score)
125+
if (analysis.rugScoreBreakdown) {
126126
const rs = analysis.rugScoreBreakdown;
127-
const dangerLevel = Math.min(100, Math.round(rs.totalScore));
128-
const dangerEmoji = dangerLevel < 10 ? '✅' : dangerLevel < 30 ? '🟢' : dangerLevel < 50 ? '🟡' : dangerLevel < 70 ? '🟠' : '🔴';
129-
const dangerLabel = dangerLevel < 10 ? 'VERY LOW' : dangerLevel < 30 ? 'LOW' : dangerLevel < 50 ? 'MODERATE' : dangerLevel < 70 ? 'HIGH' : 'EXTREME';
130-
131127
const breakdownParts = [
132128
`Auth: ${Math.round(rs.components.authorities.score)}`,
133129
`Holders: ${Math.round(rs.components.holderDistribution.score)}`,
134130
`Liq: ${Math.round(rs.components.liquidity.score)}`
135131
];
136132

137133
embed.addFields({
138-
name: `${dangerEmoji} Danger Level: ${dangerLevel} (${dangerLabel})`,
134+
name: `📊 Risk Breakdown`,
139135
value: breakdownParts.join(' • '),
140136
inline: false
141137
});
@@ -816,7 +812,7 @@ function createDiscordClient(botToken: string, clientId: string): Client {
816812
}, 600); // Update every 600ms
817813

818814
const timeoutPromise = new Promise((_, reject) =>
819-
setTimeout(() => reject(new Error('Analysis timeout after 8 seconds')), 8000)
815+
setTimeout(() => reject(new Error('Analysis timeout after 30 seconds')), 30000)
820816
);
821817

822818
const analysis = await Promise.race([analysisPromise, timeoutPromise]) as any;
@@ -3000,7 +2996,7 @@ function createDiscordClient(botToken: string, clientId: string): Client {
30002996
}, 500);
30012997

30022998
const timeoutPromise = new Promise((_, reject) =>
3003-
setTimeout(() => reject(new Error('Analysis timeout after 8 seconds')), 8000)
2999+
setTimeout(() => reject(new Error('Analysis timeout after 30 seconds')), 30000)
30043000
);
30053001

30063002
const analysis = await Promise.race([analysisPromise, timeoutPromise]) as any;

server/services/rpc-balancer.ts

Lines changed: 11 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ const RPC_PROVIDERS = [
175175
rateLimitWindow: 10000 // 100 reqs per 10s, 40 per method
176176
},
177177

178-
// HIGH-QUALITY FREE PUBLIC RPCs
178+
// HIGH-QUALITY FREE PUBLIC RPCs (only keeping consistently working ones)
179179
{
180180
getUrl: () => "https://solana-rpc.publicnode.com",
181181
weight: 20,
@@ -184,22 +184,6 @@ const RPC_PROVIDERS = [
184184
rateLimit: 50,
185185
rateLimitWindow: 10000
186186
},
187-
{
188-
getUrl: () => "https://solana.api.onfinality.io/public",
189-
weight: 18,
190-
name: "OnFinality",
191-
tier: "fallback" as const,
192-
rateLimit: 30,
193-
rateLimitWindow: 10000
194-
},
195-
{
196-
getUrl: () => "https://rpc.1rpc.io/solana",
197-
weight: 18,
198-
name: "1RPC",
199-
tier: "fallback" as const,
200-
rateLimit: 25,
201-
rateLimitWindow: 10000
202-
},
203187
{
204188
getUrl: () => "https://solana-mainnet.g.alchemy.com/v2/demo",
205189
weight: 15,
@@ -208,36 +192,6 @@ const RPC_PROVIDERS = [
208192
rateLimit: 25,
209193
rateLimitWindow: 60000
210194
},
211-
212-
// COMMUNITY & VALIDATOR RPCs
213-
{
214-
getUrl: () => "https://solana-api.projectserum.com",
215-
weight: 15,
216-
name: "Serum",
217-
tier: "fallback" as const,
218-
rateLimit: 25,
219-
rateLimitWindow: 10000
220-
},
221-
// Helius-Public and Extrnode removed - now require API keys
222-
{
223-
getUrl: () => "https://api.solana.com",
224-
weight: 10,
225-
name: "Solana-Mirror",
226-
tier: "fallback" as const,
227-
rateLimit: 30,
228-
rateLimitWindow: 10000
229-
},
230-
231-
// GEO-DISTRIBUTED PUBLIC RPCs
232-
{
233-
getUrl: () => "https://solana-rpc.kjnodes.com",
234-
weight: 12,
235-
name: "KJNodes",
236-
tier: "fallback" as const,
237-
rateLimit: 20,
238-
rateLimitWindow: 10000
239-
},
240-
// RPCPool-Free removed - returns 403 Forbidden
241195
{
242196
getUrl: () => "https://solana.drpc.org",
243197
weight: 12,
@@ -246,84 +200,22 @@ const RPC_PROVIDERS = [
246200
rateLimit: 20,
247201
rateLimitWindow: 10000
248202
},
249-
{
250-
getUrl: () => "https://rpc.solana.gateway.fm",
251-
weight: 10,
252-
name: "Gateway-FM",
253-
tier: "fallback" as const,
254-
rateLimit: 15,
255-
rateLimitWindow: 10000
256-
},
257-
258-
// BACKUP PUBLIC RPCs (lower priority)
259203
{
260204
getUrl: () => "https://solana-mainnet.phantom.app/YBPpkkN4g91xDiAnTE9r0RcMkjg0sKUIWvAfoFVJ",
261-
weight: 8,
205+
weight: 10,
262206
name: "Phantom-Public",
263207
tier: "fallback" as const,
264208
rateLimit: 15,
265209
rateLimitWindow: 10000
266210
},
267-
// RPCPool-Main removed - returns 403 Forbidden
268-
{
269-
getUrl: () => "https://ssc-dao.genesysgo.net",
270-
weight: 8,
271-
name: "GenesysGo",
272-
tier: "fallback" as const,
273-
rateLimit: 15,
274-
rateLimitWindow: 10000
275-
},
276-
{
277-
getUrl: () => "https://solana.public-rpc.com",
278-
weight: 7,
279-
name: "Public-RPC",
280-
tier: "fallback" as const,
281-
rateLimit: 15,
282-
rateLimitWindow: 10000
283-
},
284-
// HelloMoon and Syndica removed - return 403/401
285-
{
286-
getUrl: () => "https://mainnet.solana.api.triton.one",
287-
weight: 6,
288-
name: "Triton",
289-
tier: "fallback" as const,
290-
rateLimit: 10,
291-
rateLimitWindow: 10000
292-
},
211+
// Removed dead endpoints: OnFinality, 1RPC, Serum, Solana-Mirror, KJNodes, Gateway-FM, GenesysGo, Public-RPC, Triton, Grove, TheIndex, AllThatNode
293212
{
294213
getUrl: () => "https://solana-rpc.debridge.finance",
295214
weight: 5,
296215
name: "DeBridge",
297216
tier: "fallback" as const,
298217
rateLimit: 10,
299218
rateLimitWindow: 10000
300-
},
301-
302-
// ADDITIONAL FREE ENDPOINTS (lower weight for load distribution)
303-
// RPCPool-API removed - returns 403 Forbidden
304-
{
305-
getUrl: () => "https://solana-mainnet.rpc.grove.city/v1/mainnet-beta",
306-
weight: 5,
307-
name: "Grove",
308-
tier: "fallback" as const,
309-
rateLimit: 10,
310-
rateLimitWindow: 10000
311-
},
312-
{
313-
getUrl: () => "https://rpc.theindex.io/mainnet-beta",
314-
weight: 4,
315-
name: "TheIndex",
316-
tier: "fallback" as const,
317-
rateLimit: 10,
318-
rateLimitWindow: 10000
319-
},
320-
{
321-
getUrl: () => "https://solana-mainnet-rpc.allthatnode.com",
322-
weight: 4,
323-
name: "AllThatNode",
324-
tier: "fallback" as const,
325-
rateLimit: 10,
326-
rateLimitWindow: 10000
327219
}
328220
];
329221

@@ -774,23 +666,23 @@ const performHealthChecks = async () => {
774666
}
775667
});
776668

777-
// Run health checks in batches of 5 to avoid 429 rate limits
778-
const batchSize = 5;
669+
// Run health checks in batches of 3 to avoid 429 rate limits (reduced from 5)
670+
const batchSize = 3;
779671
for (let i = 0; i < healthChecks.length; i += batchSize) {
780672
const batch = healthChecks.slice(i, i + batchSize);
781673
await Promise.allSettled(batch);
782-
// Add delay between batches to avoid rate limits
674+
// Add 1 second delay between batches to avoid rate limits (increased from 500ms)
783675
if (i + batchSize < healthChecks.length) {
784-
await new Promise(resolve => setTimeout(resolve, 500));
676+
await new Promise(resolve => setTimeout(resolve, 1000));
785677
}
786678
}
787679

788680
const healthyCount = rpcBalancer.providers.filter(p => p.score > 70).length;
789681
console.log(`[RPC Health] ${healthyCount}/${rpcBalancer.providers.length} providers healthy`);
790682
};
791683

792-
// Run health checks every 60 seconds (reduced from 20s to lower rate limit pressure)
793-
setInterval(performHealthChecks, 60000);
684+
// Run health checks every 2 minutes (reduced frequency to lower rate limit pressure)
685+
setInterval(performHealthChecks, 120000);
794686

795-
// Initial health check after 5 seconds (increased from 2s to let server stabilize)
796-
setTimeout(performHealthChecks, 5000);
687+
// Initial health check after 10 seconds (increased to let server fully stabilize)
688+
setTimeout(performHealthChecks, 10000);

0 commit comments

Comments
 (0)