Skip to content

Commit 0b16744

Browse files
committed
recommender, token performane integration to swap
Signed-off-by: MarcoMandar <malicemandar@gmail.com>
1 parent 7e85609 commit 0b16744

File tree

3 files changed

+184
-9
lines changed

3 files changed

+184
-9
lines changed

core/src/actions/swap.ts

+72-3
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ import settings from "../core/settings.ts";
2323
import { bs58 } from "@coral-xyz/anchor/dist/cjs/utils/bytes/index.js";
2424
import BigNumber from "bignumber.js";
2525
import { WalletProvider } from "../providers/wallet.ts";
26+
import { TrustScoreProvider } from "../providers/trustScoreProvider";
27+
import { TokenProvider } from "../providers/token";
28+
import { TrustScoreDatabase } from "../adapters/trustScoreDatabase";
29+
import { v4 as uuidv4 } from "uuid";
2630

2731
async function swapToken(
2832
connection: Connection,
@@ -155,7 +159,7 @@ async function getTokensInWallet(runtime: IAgentRuntime) {
155159
}
156160

157161
// check if the token symbol is in the wallet
158-
async function checkTokenInWallet(runtime: IAgentRuntime, tokenSymbol: string) {
162+
async function getTokenFromWallet(runtime: IAgentRuntime, tokenSymbol: string) {
159163
try {
160164
const items = await getTokensInWallet(runtime);
161165
const token = items.find((item) => item.symbol === tokenSymbol);
@@ -212,6 +216,8 @@ export const executeSwap: Action = {
212216
});
213217

214218
console.log("Response:", response);
219+
const type =
220+
response.inputTokenSymbol?.toUpperCase() === "SOL" ? "buy" : "sell";
215221

216222
// Add SOL handling logic
217223
if (response.inputTokenSymbol?.toUpperCase() === "SOL") {
@@ -227,7 +233,7 @@ export const executeSwap: Action = {
227233
console.log(
228234
`Attempting to resolve CA for input token symbol: ${response.inputTokenSymbol}`
229235
);
230-
response.inputTokenCA = await checkTokenInWallet(
236+
response.inputTokenCA = await getTokenFromWallet(
231237
runtime,
232238
response.inputTokenSymbol
233239
);
@@ -247,7 +253,7 @@ export const executeSwap: Action = {
247253
console.log(
248254
`Attempting to resolve CA for output token symbol: ${response.outputTokenSymbol}`
249255
);
250-
response.outputTokenCA = await checkTokenInWallet(
256+
response.outputTokenCA = await getTokenFromWallet(
251257
runtime,
252258
response.outputTokenSymbol
253259
);
@@ -387,6 +393,69 @@ export const executeSwap: Action = {
387393
);
388394
}
389395

396+
if (type === "buy") {
397+
const tokenProvider = new TokenProvider(response.outputTokenCA);
398+
const module = await import("better-sqlite3");
399+
const Database = module.default;
400+
const trustScoreDb = new TrustScoreDatabase(
401+
new Database(":memory:")
402+
);
403+
// add or get recommender
404+
const uuid = uuidv4();
405+
const recommender = await trustScoreDb.getOrCreateRecommender({
406+
id: uuid,
407+
address: walletPublicKey.toString(),
408+
solanaPubkey: walletPublicKey.toString(),
409+
});
410+
411+
const trustScoreDatabase = new TrustScoreProvider(
412+
tokenProvider,
413+
trustScoreDb
414+
);
415+
// save the trade
416+
const tradeData = {
417+
buy_amount: response.amount,
418+
is_simulation: false,
419+
};
420+
await trustScoreDatabase.createTradePerformance(
421+
response.outputTokenCA,
422+
recommender.id,
423+
tradeData
424+
);
425+
} else if (type === "sell") {
426+
const tokenProvider = new TokenProvider(response.inputTokenCA);
427+
const module = await import("better-sqlite3");
428+
const Database = module.default;
429+
const trustScoreDb = new TrustScoreDatabase(
430+
new Database(":memory:")
431+
);
432+
// add or get recommender
433+
const uuid = uuidv4();
434+
const recommender = await trustScoreDb.getOrCreateRecommender({
435+
id: uuid,
436+
address: walletPublicKey.toString(),
437+
solanaPubkey: walletPublicKey.toString(),
438+
});
439+
440+
const trustScoreDatabase = new TrustScoreProvider(
441+
tokenProvider,
442+
trustScoreDb
443+
);
444+
// save the trade
445+
const sellDetails = {
446+
sell_amount: response.amount,
447+
sell_recommender_id: recommender.id,
448+
};
449+
const sellTimeStamp = new Date().getTime().toString();
450+
await trustScoreDatabase.updateSellDetails(
451+
response.inputTokenCA,
452+
recommender.id,
453+
sellTimeStamp,
454+
sellDetails,
455+
false
456+
);
457+
}
458+
390459
console.log("Swap completed successfully!");
391460
console.log(`Transaction ID: ${txid}`);
392461

core/src/adapters/trustScoreDatabase.ts

+109-2
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ export class TrustScoreDatabase {
172172
risk_score REAL DEFAULT 0,
173173
consistency_score REAL DEFAULT 0,
174174
virtual_confidence REAL DEFAULT 0,
175-
last_active_date DATETIME DEFAULT CURRENT_TIMESTAMP
175+
last_active_date DATETIME DEFAULT CURRENT_TIMESTAMP,
176176
trust_decay REAL DEFAULT 0,
177177
last_updated DATETIME DEFAULT CURRENT_TIMESTAMP,
178178
FOREIGN KEY (recommender_id) REFERENCES recommenders(id) ON DELETE CASCADE
@@ -349,6 +349,61 @@ export class TrustScoreDatabase {
349349
return recommender || null;
350350
}
351351

352+
/**
353+
* Retrieves an existing recommender or creates a new one if not found.
354+
* Also initializes metrics for the recommender if they haven't been initialized yet.
355+
* @param recommender Recommender object containing at least one identifier
356+
* @returns Recommender object with all details, or null if failed
357+
*/
358+
getOrCreateRecommender(recommender: Recommender): Recommender | null {
359+
try {
360+
// Begin a transaction
361+
const transaction = this.db.transaction(() => {
362+
// Attempt to retrieve the recommender
363+
const existingRecommender = this.getRecommender(
364+
recommender.address
365+
);
366+
if (existingRecommender) {
367+
// Recommender exists, ensure metrics are initialized
368+
this.initializeRecommenderMetrics(existingRecommender.id!);
369+
return existingRecommender;
370+
}
371+
372+
// Recommender does not exist, create a new one
373+
const newRecommenderId = this.addRecommender(recommender);
374+
if (!newRecommenderId) {
375+
throw new Error("Failed to add new recommender.");
376+
}
377+
378+
// Initialize metrics for the new recommender
379+
const metricsInitialized =
380+
this.initializeRecommenderMetrics(newRecommenderId);
381+
if (!metricsInitialized) {
382+
throw new Error(
383+
"Failed to initialize recommender metrics."
384+
);
385+
}
386+
387+
// Retrieve and return the newly created recommender
388+
const newRecommender = this.getRecommender(newRecommenderId);
389+
if (!newRecommender) {
390+
throw new Error(
391+
"Failed to retrieve the newly created recommender."
392+
);
393+
}
394+
395+
return newRecommender;
396+
});
397+
398+
// Execute the transaction and return the recommender
399+
const recommenderResult = transaction();
400+
return recommenderResult;
401+
} catch (error) {
402+
console.error("Error in getOrCreateRecommender:", error);
403+
return null;
404+
}
405+
}
406+
352407
/**
353408
* Initializes metrics for a recommender if not present.
354409
* @param recommenderId Recommender's UUID
@@ -548,6 +603,8 @@ export class TrustScoreDatabase {
548603
performance.tokenAddress,
549604
performance.priceChange24h,
550605
performance.volumeChange24h,
606+
performance.trade_24h_change,
607+
performance.liquidity,
551608
performance.liquidityChange24h,
552609
performance.holderChange24h, // Ensure column name matches schema
553610
performance.rugPull ? 1 : 0,
@@ -916,7 +973,7 @@ export class TrustScoreDatabase {
916973
market_cap_change = ?,
917974
sell_liquidity = ?,
918975
liquidity_change = ?,
919-
rapidDump = ?
976+
rapidDump = ?,
920977
sell_recommender_id = ?
921978
WHERE
922979
token_address = ?
@@ -1016,6 +1073,56 @@ export class TrustScoreDatabase {
10161073
};
10171074
}
10181075

1076+
/**
1077+
* Retrieves the latest trade performance metrics without requiring buyTimeStamp.
1078+
* @param tokenAddress Token's address
1079+
* @param recommenderId Recommender's UUID
1080+
* @param isSimulation Whether the trade is a simulation. If true, retrieves from simulation_trade; otherwise, from trade.
1081+
* @returns TradePerformance object or null
1082+
*/
1083+
getLatestTradePerformance(
1084+
tokenAddress: string,
1085+
recommenderId: string,
1086+
isSimulation: boolean
1087+
): TradePerformance | null {
1088+
const tableName = isSimulation ? "simulation_trade" : "trade";
1089+
const sql = `
1090+
SELECT * FROM ${tableName}
1091+
WHERE token_address = ? AND recommender_id = ?
1092+
ORDER BY buy_timeStamp DESC
1093+
LIMIT 1;
1094+
`;
1095+
const row = this.db.prepare(sql).get(tokenAddress, recommenderId) as
1096+
| TradePerformance
1097+
| undefined;
1098+
if (!row) return null;
1099+
1100+
return {
1101+
token_address: row.token_address,
1102+
recommender_id: row.recommender_id,
1103+
buy_price: row.buy_price,
1104+
sell_price: row.sell_price,
1105+
buy_timeStamp: row.buy_timeStamp,
1106+
sell_timeStamp: row.sell_timeStamp,
1107+
buy_amount: row.buy_amount,
1108+
sell_amount: row.sell_amount,
1109+
buy_sol: row.buy_sol,
1110+
received_sol: row.received_sol,
1111+
buy_value_usd: row.buy_value_usd,
1112+
sell_value_usd: row.sell_value_usd,
1113+
profit_usd: row.profit_usd,
1114+
profit_percent: row.profit_percent,
1115+
buy_market_cap: row.buy_market_cap,
1116+
sell_market_cap: row.sell_market_cap,
1117+
market_cap_change: row.market_cap_change,
1118+
buy_liquidity: row.buy_liquidity,
1119+
sell_liquidity: row.sell_liquidity,
1120+
liquidity_change: row.liquidity_change,
1121+
last_updated: row.last_updated,
1122+
rapidDump: row.rapidDump,
1123+
};
1124+
}
1125+
10191126
/**
10201127
* Close the database connection gracefully.
10211128
*/

core/src/providers/trustScoreProvider.ts

+3-4
Original file line numberDiff line numberDiff line change
@@ -363,8 +363,7 @@ export class TrustScoreProvider {
363363
recommenderId: string,
364364
sellTimeStamp: string,
365365
sellDetails: sellDetails,
366-
isSimulation: boolean,
367-
buyTimeStamp: string
366+
isSimulation: boolean
368367
) {
369368
const processedData: ProcessedTokenData =
370369
await this.tokenProvider.getProcessedTokenData();
@@ -377,12 +376,12 @@ export class TrustScoreProvider {
377376
const sellSol = sellDetails.sell_amount / parseFloat(solPrice);
378377
const sell_value_usd =
379378
sellDetails.sell_amount * processedData.tradeData.price;
380-
const trade = await this.trustScoreDb.getTradePerformance(
379+
const trade = await this.trustScoreDb.getLatestTradePerformance(
381380
tokenAddress,
382381
recommenderId,
383-
buyTimeStamp,
384382
isSimulation
385383
);
384+
const buyTimeStamp = trade.buy_timeStamp;
386385
const marketCap =
387386
processedData.dexScreenerData.pairs[0]?.marketCap || 0;
388387
const liquidity =

0 commit comments

Comments
 (0)