Skip to content

Commit c988337

Browse files
committed
add last active and decay score, update token recommendations, add validation trust to token performance and add calculateValidationTrust
Signed-off-by: MarcoMandar <malicemandar@gmail.com>
1 parent 362470a commit c988337

File tree

2 files changed

+83
-4
lines changed

2 files changed

+83
-4
lines changed

core/src/adapters/trustScoreDatabase.ts

+47-1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ export interface RecommenderMetrics {
2424
riskScore: number;
2525
consistencyScore: number;
2626
virtualConfidence: number;
27+
lastActiveDate: Date;
28+
trustDecay: number;
2729
lastUpdated: Date;
2830
}
2931

@@ -41,6 +43,7 @@ export interface TokenPerformance {
4143
sustainedGrowth: boolean;
4244
rapidDump: boolean;
4345
suspiciousVolume: boolean;
46+
validationTrust: number;
4447
lastUpdated: Date;
4548
}
4649

@@ -63,6 +66,7 @@ export interface RecommenderMetricsHistory {
6366
riskScore: number;
6467
consistencyScore: number;
6568
virtualConfidence: number;
69+
trustDecay: number;
6670
recordedAt: Date;
6771
}
6872

@@ -100,6 +104,8 @@ interface RecommenderMetricsRow {
100104
risk_score: number;
101105
consistency_score: number;
102106
virtual_confidence: number;
107+
last_active_date: Date;
108+
trust_decay: number;
103109
last_updated: string;
104110
}
105111

@@ -117,6 +123,7 @@ interface TokenPerformanceRow {
117123
sustained_growth: number;
118124
rapid_dump: number;
119125
suspicious_volume: number;
126+
validation_trust: number;
120127
last_updated: string;
121128
}
122129

@@ -165,6 +172,8 @@ export class TrustScoreDatabase {
165172
risk_score REAL DEFAULT 0,
166173
consistency_score REAL DEFAULT 0,
167174
virtual_confidence REAL DEFAULT 0,
175+
last_active_date DATETIME DEFAULT CURRENT_TIMESTAMP
176+
trust_decay REAL DEFAULT 0,
168177
last_updated DATETIME DEFAULT CURRENT_TIMESTAMP,
169178
FOREIGN KEY (recommender_id) REFERENCES recommenders(id) ON DELETE CASCADE
170179
);
@@ -186,6 +195,7 @@ export class TrustScoreDatabase {
186195
sustained_growth BOOLEAN DEFAULT FALSE,
187196
rapid_dump BOOLEAN DEFAULT FALSE,
188197
suspicious_volume BOOLEAN DEFAULT FALSE,
198+
validation_trust REAL DEFAULT 0,
189199
last_updated DATETIME DEFAULT CURRENT_TIMESTAMP
190200
);
191201
`);
@@ -378,6 +388,8 @@ export class TrustScoreDatabase {
378388
riskScore: row.risk_score,
379389
consistencyScore: row.consistency_score,
380390
virtualConfidence: row.virtual_confidence,
391+
lastActiveDate: row.last_active_date,
392+
trustDecay: row.trust_decay,
381393
lastUpdated: new Date(row.last_updated),
382394
};
383395
}
@@ -407,6 +419,7 @@ export class TrustScoreDatabase {
407419
riskScore: currentMetrics.riskScore,
408420
consistencyScore: currentMetrics.consistencyScore,
409421
virtualConfidence: currentMetrics.virtualConfidence,
422+
trustDecay: currentMetrics.trustDecay,
410423
recordedAt: new Date(), // Current timestamp
411424
};
412425

@@ -492,6 +505,10 @@ export class TrustScoreDatabase {
492505
* @param performance TokenPerformance object
493506
*/
494507
upsertTokenPerformance(performance: TokenPerformance): boolean {
508+
const validationTrust = this.calculateValidationTrust(
509+
performance.tokenAddress
510+
);
511+
495512
const sql = `
496513
INSERT INTO token_performance (
497514
token_address,
@@ -507,6 +524,7 @@ export class TrustScoreDatabase {
507524
sustained_growth,
508525
rapid_dump,
509526
suspicious_volume,
527+
validation_trust,
510528
last_updated
511529
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP)
512530
ON CONFLICT(token_address) DO UPDATE SET
@@ -522,6 +540,7 @@ export class TrustScoreDatabase {
522540
sustained_growth = excluded.sustained_growth,
523541
rapid_dump = excluded.rapid_dump,
524542
suspicious_volume = excluded.suspicious_volume,
543+
validation_trust = excluded.validation_trust,
525544
last_updated = CURRENT_TIMESTAMP;
526545
`;
527546
try {
@@ -536,7 +555,8 @@ export class TrustScoreDatabase {
536555
performance.marketCapChange24h,
537556
performance.sustainedGrowth ? 1 : 0,
538557
performance.rapidDump ? 1 : 0,
539-
performance.suspiciousVolume ? 1 : 0
558+
performance.suspiciousVolume ? 1 : 0,
559+
validationTrust
540560
);
541561
console.log(
542562
`Upserted token performance for ${performance.tokenAddress}`
@@ -574,12 +594,36 @@ export class TrustScoreDatabase {
574594
sustainedGrowth: row.sustained_growth === 1,
575595
rapidDump: row.rapid_dump === 1,
576596
suspiciousVolume: row.suspicious_volume === 1,
597+
validationTrust: row.validation_trust,
577598
lastUpdated: new Date(row.last_updated),
578599
};
579600
}
580601

581602
// ----- TokenRecommendations Methods -----
582603

604+
/**
605+
* Calculates the average trust score of all recommenders who have recommended a specific token.
606+
* @param tokenAddress The address of the token.
607+
* @returns The average trust score (validationTrust).
608+
*/
609+
calculateValidationTrust(tokenAddress: string): number {
610+
const sql = `
611+
SELECT rm.trust_score
612+
FROM token_recommendations tr
613+
JOIN recommender_metrics rm ON tr.recommender_id = rm.recommender_id
614+
WHERE tr.token_address = ?;
615+
`;
616+
const rows = this.db.prepare(sql).all(tokenAddress) as Array<{
617+
trust_score: number;
618+
}>;
619+
620+
if (rows.length === 0) return 0; // No recommendations found
621+
622+
const totalTrust = rows.reduce((acc, row) => acc + row.trust_score, 0);
623+
const averageTrust = totalTrust / rows.length;
624+
return averageTrust;
625+
}
626+
583627
/**
584628
* Adds a new token recommendation.
585629
* @param recommendation TokenRecommendation object
@@ -735,6 +779,7 @@ export class TrustScoreDatabase {
735779
risk_score: number;
736780
consistency_score: number;
737781
virtual_confidence: number;
782+
trust_decay: number;
738783
recorded_at: string;
739784
}>;
740785

@@ -748,6 +793,7 @@ export class TrustScoreDatabase {
748793
riskScore: row.risk_score,
749794
consistencyScore: row.consistency_score,
750795
virtualConfidence: row.virtual_confidence,
796+
trustDecay: row.trust_decay,
751797
recordedAt: new Date(row.recorded_at),
752798
}));
753799
}

core/src/providers/trustScoreProvider.ts

+36-3
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ export class TrustScoreProvider {
3232
private trustScoreDb: TrustScoreDatabase;
3333
private connection: Connection = new Connection(process.env.RPC_URL!);
3434
private baseMint: PublicKey = new PublicKey(process.env.BASE_MINT!);
35-
35+
private DECAY_RATE = 0.95;
36+
private MAX_DECAY_DAYS = 30;
3637
constructor(
3738
tokenProvider: TokenProvider,
3839
trustScoreDb: TrustScoreDatabase
@@ -85,6 +86,18 @@ export class TrustScoreProvider {
8586
const suspiciousVolume = await this.suspiciousVolume(tokenAddress);
8687
const balance = await this.getRecommenederBalance(recommenderWallet);
8788
const virtualConfidence = balance / 1000000; // TODO: create formula to calculate virtual confidence based on user balance
89+
const lastActive = recommenderMetrics.lastActiveDate;
90+
const now = new Date();
91+
const inactiveDays = Math.floor(
92+
(now.getTime() - lastActive.getTime()) / (1000 * 60 * 60 * 24)
93+
);
94+
const decayFactor = Math.pow(
95+
this.DECAY_RATE,
96+
Math.min(inactiveDays, this.MAX_DECAY_DAYS)
97+
);
98+
const decayedScore = recommenderMetrics.trustScore * decayFactor;
99+
const validationTrustScore =
100+
this.trustScoreDb.calculateValidationTrust(tokenAddress);
88101

89102
return {
90103
tokenPerformance: {
@@ -107,6 +120,7 @@ export class TrustScoreProvider {
107120
sustainedGrowth: sustainedGrowth,
108121
rapidDump: isRapidDump,
109122
suspiciousVolume: suspiciousVolume,
123+
validationTrust: validationTrustScore,
110124
lastUpdated: new Date(),
111125
},
112126
recommenderMetrics: {
@@ -118,14 +132,17 @@ export class TrustScoreProvider {
118132
riskScore: recommenderMetrics.riskScore,
119133
consistencyScore: recommenderMetrics.consistencyScore,
120134
virtualConfidence: virtualConfidence,
135+
lastActiveDate: now,
136+
trustDecay: decayedScore,
121137
lastUpdated: new Date(),
122138
},
123139
};
124140
}
125141

126142
async updateRecommenderMetrics(
127143
recommenderId: string,
128-
tokenPerformance: TokenPerformance
144+
tokenPerformance: TokenPerformance,
145+
recommenderWallet: string
129146
): Promise<void> {
130147
const recommenderMetrics =
131148
await this.trustScoreDb.getRecommenderMetrics(recommenderId);
@@ -153,6 +170,20 @@ export class TrustScoreProvider {
153170
tokenPerformance,
154171
recommenderMetrics
155172
);
173+
174+
const balance = await this.getRecommenederBalance(recommenderWallet);
175+
const virtualConfidence = balance / 1000000; // TODO: create formula to calculate virtual confidence based on user balance
176+
const lastActive = recommenderMetrics.lastActiveDate;
177+
const now = new Date();
178+
const inactiveDays = Math.floor(
179+
(now.getTime() - lastActive.getTime()) / (1000 * 60 * 60 * 24)
180+
);
181+
const decayFactor = Math.pow(
182+
this.DECAY_RATE,
183+
Math.min(inactiveDays, this.MAX_DECAY_DAYS)
184+
);
185+
const decayedScore = recommenderMetrics.trustScore * decayFactor;
186+
156187
const newRecommenderMetrics: RecommenderMetrics = {
157188
recommenderId: recommenderId,
158189
trustScore: overallTrustScore,
@@ -161,7 +192,9 @@ export class TrustScoreProvider {
161192
avgTokenPerformance: avgTokenPerformance,
162193
riskScore: riskScore,
163194
consistencyScore: consistencyScore,
164-
virtualConfidence: recommenderMetrics.virtualConfidence,
195+
virtualConfidence: virtualConfidence,
196+
lastActiveDate: new Date(),
197+
trustDecay: decayedScore,
165198
lastUpdated: new Date(),
166199
};
167200

0 commit comments

Comments
 (0)