Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

updates to order book and trust score, virtual confidence, last active, decay score, validation trust, multiple recommenders #175

Merged
merged 5 commits into from
Nov 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 47 additions & 1 deletion core/src/adapters/trustScoreDatabase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ export interface RecommenderMetrics {
riskScore: number;
consistencyScore: number;
virtualConfidence: number;
lastActiveDate: Date;
trustDecay: number;
lastUpdated: Date;
}

Expand All @@ -41,6 +43,7 @@ export interface TokenPerformance {
sustainedGrowth: boolean;
rapidDump: boolean;
suspiciousVolume: boolean;
validationTrust: number;
lastUpdated: Date;
}

Expand All @@ -63,6 +66,7 @@ export interface RecommenderMetricsHistory {
riskScore: number;
consistencyScore: number;
virtualConfidence: number;
trustDecay: number;
recordedAt: Date;
}

Expand Down Expand Up @@ -100,6 +104,8 @@ interface RecommenderMetricsRow {
risk_score: number;
consistency_score: number;
virtual_confidence: number;
last_active_date: Date;
trust_decay: number;
last_updated: string;
}

Expand All @@ -117,6 +123,7 @@ interface TokenPerformanceRow {
sustained_growth: number;
rapid_dump: number;
suspicious_volume: number;
validation_trust: number;
last_updated: string;
}

Expand Down Expand Up @@ -165,6 +172,8 @@ export class TrustScoreDatabase {
risk_score REAL DEFAULT 0,
consistency_score REAL DEFAULT 0,
virtual_confidence REAL DEFAULT 0,
last_active_date DATETIME DEFAULT CURRENT_TIMESTAMP
trust_decay REAL DEFAULT 0,
last_updated DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (recommender_id) REFERENCES recommenders(id) ON DELETE CASCADE
);
Expand All @@ -186,6 +195,7 @@ export class TrustScoreDatabase {
sustained_growth BOOLEAN DEFAULT FALSE,
rapid_dump BOOLEAN DEFAULT FALSE,
suspicious_volume BOOLEAN DEFAULT FALSE,
validation_trust REAL DEFAULT 0,
last_updated DATETIME DEFAULT CURRENT_TIMESTAMP
);
`);
Expand Down Expand Up @@ -378,6 +388,8 @@ export class TrustScoreDatabase {
riskScore: row.risk_score,
consistencyScore: row.consistency_score,
virtualConfidence: row.virtual_confidence,
lastActiveDate: row.last_active_date,
trustDecay: row.trust_decay,
lastUpdated: new Date(row.last_updated),
};
}
Expand Down Expand Up @@ -407,6 +419,7 @@ export class TrustScoreDatabase {
riskScore: currentMetrics.riskScore,
consistencyScore: currentMetrics.consistencyScore,
virtualConfidence: currentMetrics.virtualConfidence,
trustDecay: currentMetrics.trustDecay,
recordedAt: new Date(), // Current timestamp
};

Expand Down Expand Up @@ -492,6 +505,10 @@ export class TrustScoreDatabase {
* @param performance TokenPerformance object
*/
upsertTokenPerformance(performance: TokenPerformance): boolean {
const validationTrust = this.calculateValidationTrust(
performance.tokenAddress
);

const sql = `
INSERT INTO token_performance (
token_address,
Expand All @@ -507,6 +524,7 @@ export class TrustScoreDatabase {
sustained_growth,
rapid_dump,
suspicious_volume,
validation_trust,
last_updated
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP)
ON CONFLICT(token_address) DO UPDATE SET
Expand All @@ -522,6 +540,7 @@ export class TrustScoreDatabase {
sustained_growth = excluded.sustained_growth,
rapid_dump = excluded.rapid_dump,
suspicious_volume = excluded.suspicious_volume,
validation_trust = excluded.validation_trust,
last_updated = CURRENT_TIMESTAMP;
`;
try {
Expand All @@ -536,7 +555,8 @@ export class TrustScoreDatabase {
performance.marketCapChange24h,
performance.sustainedGrowth ? 1 : 0,
performance.rapidDump ? 1 : 0,
performance.suspiciousVolume ? 1 : 0
performance.suspiciousVolume ? 1 : 0,
validationTrust
);
console.log(
`Upserted token performance for ${performance.tokenAddress}`
Expand Down Expand Up @@ -574,12 +594,36 @@ export class TrustScoreDatabase {
sustainedGrowth: row.sustained_growth === 1,
rapidDump: row.rapid_dump === 1,
suspiciousVolume: row.suspicious_volume === 1,
validationTrust: row.validation_trust,
lastUpdated: new Date(row.last_updated),
};
}

// ----- TokenRecommendations Methods -----

/**
* Calculates the average trust score of all recommenders who have recommended a specific token.
* @param tokenAddress The address of the token.
* @returns The average trust score (validationTrust).
*/
calculateValidationTrust(tokenAddress: string): number {
const sql = `
SELECT rm.trust_score
FROM token_recommendations tr
JOIN recommender_metrics rm ON tr.recommender_id = rm.recommender_id
WHERE tr.token_address = ?;
`;
const rows = this.db.prepare(sql).all(tokenAddress) as Array<{
trust_score: number;
}>;

if (rows.length === 0) return 0; // No recommendations found

const totalTrust = rows.reduce((acc, row) => acc + row.trust_score, 0);
const averageTrust = totalTrust / rows.length;
return averageTrust;
}

/**
* Adds a new token recommendation.
* @param recommendation TokenRecommendation object
Expand Down Expand Up @@ -735,6 +779,7 @@ export class TrustScoreDatabase {
risk_score: number;
consistency_score: number;
virtual_confidence: number;
trust_decay: number;
recorded_at: string;
}>;

Expand All @@ -748,6 +793,7 @@ export class TrustScoreDatabase {
riskScore: row.risk_score,
consistencyScore: row.consistency_score,
virtualConfidence: row.virtual_confidence,
trustDecay: row.trust_decay,
recordedAt: new Date(row.recorded_at),
}));
}
Expand Down
69 changes: 63 additions & 6 deletions core/src/providers/trustScoreProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
// HolderData,
} from "../types/token";
import { Connection, PublicKey } from "@solana/web3.js";

import { getAssociatedTokenAddress } from "@solana/spl-token";
import { TokenProvider } from "./token";
import WalletProvider from "./balances";
import {
Expand All @@ -30,14 +30,36 @@ interface sellDetails {
export class TrustScoreProvider {
private tokenProvider: TokenProvider;
private trustScoreDb: TrustScoreDatabase;

private connection: Connection = new Connection(process.env.RPC_URL!);
private baseMint: PublicKey = new PublicKey(process.env.BASE_MINT!);
private DECAY_RATE = 0.95;
private MAX_DECAY_DAYS = 30;
constructor(
tokenProvider: TokenProvider,
trustScoreDb: TrustScoreDatabase
) {
this.tokenProvider = tokenProvider;
this.trustScoreDb = trustScoreDb;
}

//getRecommenederBalance
async getRecommenederBalance(recommenderWallet: string): Promise<number> {
try {
const tokenAta = await getAssociatedTokenAddress(
new PublicKey(recommenderWallet),
this.baseMint
);
const tokenBalInfo =
await this.connection.getTokenAccountBalance(tokenAta);
const tokenBalance = tokenBalInfo.value.amount;
const balance = parseFloat(tokenBalance);
return balance;
} catch (error) {
console.error("Error fetching balance", error);
return 0;
}
}

/**
* Generates and saves trust score based on processed token data and user recommendations.
* @param tokenAddress The address of the token to analyze.
Expand All @@ -46,7 +68,8 @@ export class TrustScoreProvider {
*/
async generateTrustScore(
tokenAddress: string,
recommenderId: string
recommenderId: string,
recommenderWallet: string
): Promise<{
tokenPerformance: TokenPerformance;
recommenderMetrics: RecommenderMetrics;
Expand All @@ -61,6 +84,20 @@ export class TrustScoreProvider {
const isRapidDump = await this.isRapidDump(tokenAddress);
const sustainedGrowth = await this.sustainedGrowth(tokenAddress);
const suspiciousVolume = await this.suspiciousVolume(tokenAddress);
const balance = await this.getRecommenederBalance(recommenderWallet);
const virtualConfidence = balance / 1000000; // TODO: create formula to calculate virtual confidence based on user balance
const lastActive = recommenderMetrics.lastActiveDate;
const now = new Date();
const inactiveDays = Math.floor(
(now.getTime() - lastActive.getTime()) / (1000 * 60 * 60 * 24)
);
const decayFactor = Math.pow(
this.DECAY_RATE,
Math.min(inactiveDays, this.MAX_DECAY_DAYS)
);
const decayedScore = recommenderMetrics.trustScore * decayFactor;
const validationTrustScore =
this.trustScoreDb.calculateValidationTrust(tokenAddress);

return {
tokenPerformance: {
Expand All @@ -83,6 +120,7 @@ export class TrustScoreProvider {
sustainedGrowth: sustainedGrowth,
rapidDump: isRapidDump,
suspiciousVolume: suspiciousVolume,
validationTrust: validationTrustScore,
lastUpdated: new Date(),
},
recommenderMetrics: {
Expand All @@ -93,15 +131,18 @@ export class TrustScoreProvider {
avgTokenPerformance: recommenderMetrics.avgTokenPerformance,
riskScore: recommenderMetrics.riskScore,
consistencyScore: recommenderMetrics.consistencyScore,
virtualConfidence: recommenderMetrics.virtualConfidence,
virtualConfidence: virtualConfidence,
lastActiveDate: now,
trustDecay: decayedScore,
lastUpdated: new Date(),
},
};
}

async updateRecommenderMetrics(
recommenderId: string,
tokenPerformance: TokenPerformance
tokenPerformance: TokenPerformance,
recommenderWallet: string
): Promise<void> {
const recommenderMetrics =
await this.trustScoreDb.getRecommenderMetrics(recommenderId);
Expand Down Expand Up @@ -129,6 +170,20 @@ export class TrustScoreProvider {
tokenPerformance,
recommenderMetrics
);

const balance = await this.getRecommenederBalance(recommenderWallet);
const virtualConfidence = balance / 1000000; // TODO: create formula to calculate virtual confidence based on user balance
const lastActive = recommenderMetrics.lastActiveDate;
const now = new Date();
const inactiveDays = Math.floor(
(now.getTime() - lastActive.getTime()) / (1000 * 60 * 60 * 24)
);
const decayFactor = Math.pow(
this.DECAY_RATE,
Math.min(inactiveDays, this.MAX_DECAY_DAYS)
);
const decayedScore = recommenderMetrics.trustScore * decayFactor;

const newRecommenderMetrics: RecommenderMetrics = {
recommenderId: recommenderId,
trustScore: overallTrustScore,
Expand All @@ -137,7 +192,9 @@ export class TrustScoreProvider {
avgTokenPerformance: avgTokenPerformance,
riskScore: riskScore,
consistencyScore: consistencyScore,
virtualConfidence: recommenderMetrics.virtualConfidence,
virtualConfidence: virtualConfidence,
lastActiveDate: new Date(),
trustDecay: decayedScore,
lastUpdated: new Date(),
};

Expand Down