Skip to content

Commit 73564bc

Browse files
committed
fix types
Signed-off-by: MarcoMandar <malicemandar@gmail.com>
1 parent b860c17 commit 73564bc

File tree

2 files changed

+401
-332
lines changed

2 files changed

+401
-332
lines changed

core/src/providers/token.ts

+82-24
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,19 @@
1+
import { Connection } from "@solana/web3.js";
12
// import fetch from "cross-fetch";
3+
import { IAgentRuntime, Memory, Provider, State } from "../core/types";
4+
import settings from "../core/settings";
25
import BigNumber from "bignumber.js";
3-
import * as fs from "fs";
4-
import NodeCache from "node-cache";
5-
import * as path from "path";
6-
import settings from "../core/settings.ts";
7-
import { IAgentRuntime, Memory, Provider, State } from "../core/types.ts";
86
import {
9-
DexScreenerData,
10-
HolderData,
117
ProcessedTokenData,
128
TokenSecurityData,
139
TokenTradeData,
14-
} from "../types/token.ts";
15-
import { fileURLToPath } from "url";
10+
DexScreenerData,
11+
// DexScreenerPair,
12+
HolderData,
13+
} from "../types/token";
14+
import NodeCache from "node-cache";
15+
import * as fs from "fs";
16+
import * as path from "path";
1617

1718
const PROVIDER_CONFIG = {
1819
BIRDEYE_API: "https://public-api.birdeye.so",
@@ -39,25 +40,28 @@ export class TokenProvider {
3940
private tokenAddress: string
4041
) {
4142
this.cache = new NodeCache({ stdTTL: 300 }); // 5 minutes cache
42-
const __filename = fileURLToPath(import.meta.url);
43-
44-
const __dirname = path.dirname(__filename);
45-
46-
this.cacheDir = path.join(__dirname, "../../tokencache");
43+
this.cacheDir = path.join(__dirname, "cache");
4744
if (!fs.existsSync(this.cacheDir)) {
4845
fs.mkdirSync(this.cacheDir);
4946
}
5047
}
5148

5249
private readCacheFromFile<T>(cacheKey: string): T | null {
5350
const filePath = path.join(this.cacheDir, `${cacheKey}.json`);
51+
console.log({ filePath });
5452
if (fs.existsSync(filePath)) {
5553
const fileContent = fs.readFileSync(filePath, "utf-8");
5654
const parsed = JSON.parse(fileContent);
5755
const now = Date.now();
5856
if (now < parsed.expiry) {
57+
console.log(
58+
`Reading cached data from file for key: ${cacheKey}`
59+
);
5960
return parsed.data as T;
6061
} else {
62+
console.log(
63+
`Cache expired for key: ${cacheKey}. Deleting file.`
64+
);
6165
fs.unlinkSync(filePath);
6266
}
6367
}
@@ -71,6 +75,7 @@ export class TokenProvider {
7175
expiry: Date.now() + 300000, // 5 minutes in milliseconds
7276
};
7377
fs.writeFileSync(filePath, JSON.stringify(cacheData), "utf-8");
78+
console.log(`Cached data written to file for key: ${cacheKey}`);
7479
}
7580

7681
private getCachedData<T>(cacheKey: string): T | null {
@@ -102,6 +107,7 @@ export class TokenProvider {
102107
private async fetchWithRetry(
103108
url: string,
104109
options: RequestInit = {}
110+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
105111
): Promise<any> {
106112
let lastError: Error;
107113

@@ -127,9 +133,11 @@ export class TokenProvider {
127133
const data = await response.json();
128134
return data;
129135
} catch (error) {
136+
console.error(`Attempt ${i + 1} failed:`, error);
130137
lastError = error as Error;
131138
if (i < PROVIDER_CONFIG.MAX_RETRIES - 1) {
132139
const delay = PROVIDER_CONFIG.RETRY_DELAY * Math.pow(2, i);
140+
console.log(`Waiting ${delay}ms before retrying...`);
133141
await new Promise((resolve) => setTimeout(resolve, delay));
134142
continue;
135143
}
@@ -147,6 +155,9 @@ export class TokenProvider {
147155
const cacheKey = `tokenSecurity_${this.tokenAddress}`;
148156
const cachedData = this.getCachedData<TokenSecurityData>(cacheKey);
149157
if (cachedData) {
158+
console.log(
159+
`Returning cached token security data for ${this.tokenAddress}.`
160+
);
150161
return cachedData;
151162
}
152163
const url = `${PROVIDER_CONFIG.BIRDEYE_API}${PROVIDER_CONFIG.TOKEN_SECURITY_ENDPOINT}${this.tokenAddress}`;
@@ -165,14 +176,18 @@ export class TokenProvider {
165176
top10HolderPercent: data.data.top10HolderPercent,
166177
};
167178
this.setCachedData(cacheKey, security);
179+
console.log(`Token security data cached for ${this.tokenAddress}.`);
168180

169181
return security;
170182
}
171183

172-
async fetchTokenTradeData(runtime: IAgentRuntime): Promise<TokenTradeData> {
184+
async fetchTokenTradeData(): Promise<TokenTradeData> {
173185
const cacheKey = `tokenTradeData_${this.tokenAddress}`;
174186
const cachedData = this.getCachedData<TokenTradeData>(cacheKey);
175187
if (cachedData) {
188+
console.log(
189+
`Returning cached token trade data for ${this.tokenAddress}.`
190+
);
176191
return cachedData;
177192
}
178193

@@ -181,7 +196,7 @@ export class TokenProvider {
181196
method: "GET",
182197
headers: {
183198
accept: "application/json",
184-
"X-API-KEY": runtime.getSetting("BIRDEYE_API_KEY") || "",
199+
"X-API-KEY": settings.BIRDEYE_API_KEY || "",
185200
},
186201
};
187202

@@ -405,11 +420,15 @@ export class TokenProvider {
405420
const cacheKey = `dexScreenerData_${this.tokenAddress}`;
406421
const cachedData = this.getCachedData<DexScreenerData>(cacheKey);
407422
if (cachedData) {
423+
console.log("Returning cached DexScreener data.");
408424
return cachedData;
409425
}
410426

411427
const url = `https://api.dexscreener.com/latest/dex/search?q=${this.tokenAddress}`;
412428
try {
429+
console.log(
430+
`Fetching DexScreener data for token: ${this.tokenAddress}`
431+
);
413432
const data = await fetch(url)
414433
.then((res) => res.json())
415434
.catch((err) => {
@@ -488,6 +507,7 @@ export class TokenProvider {
488507
const cacheKey = `holderList_${this.tokenAddress}`;
489508
const cachedData = this.getCachedData<HolderData[]>(cacheKey);
490509
if (cachedData) {
510+
console.log("Returning cached holder list.");
491511
return cachedData;
492512
}
493513

@@ -497,8 +517,10 @@ export class TokenProvider {
497517
let cursor;
498518
//HELIOUS_API_KEY needs to be added
499519
const url = `https://mainnet.helius-rpc.com/?api-key=${settings.HELIOUS_API_KEY || ""}`;
520+
console.log({ url });
500521

501522
try {
523+
// eslint-disable-next-line no-constant-condition
502524
while (true) {
503525
const params = {
504526
limit: limit,
@@ -509,7 +531,7 @@ export class TokenProvider {
509531
if (cursor != undefined) {
510532
params.cursor = cursor;
511533
}
512-
534+
console.log(`Fetching holders - Page ${page}`);
513535
if (page > 2) {
514536
break;
515537
}
@@ -534,9 +556,17 @@ export class TokenProvider {
534556
!data.result.token_accounts ||
535557
data.result.token_accounts.length === 0
536558
) {
559+
console.log(
560+
`No more holders found. Total pages fetched: ${page - 1}`
561+
);
537562
break;
538563
}
539564

565+
console.log(
566+
`Processing ${data.result.token_accounts.length} holders from page ${page}`
567+
);
568+
569+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
540570
data.result.token_accounts.forEach((account: any) => {
541571
const owner = account.owner;
542572
const balance = parseFloat(account.amount);
@@ -561,6 +591,8 @@ export class TokenProvider {
561591
balance: balance.toString(),
562592
}));
563593

594+
console.log(`Total unique holders fetched: ${holders.length}`);
595+
564596
// Cache the result
565597
this.setCachedData(cacheKey, holders);
566598

@@ -620,27 +652,47 @@ export class TokenProvider {
620652
}
621653
}
622654

623-
async getProcessedTokenData(
624-
runtime: IAgentRuntime
625-
): Promise<ProcessedTokenData> {
655+
async getProcessedTokenData(): Promise<ProcessedTokenData> {
626656
try {
657+
console.log(
658+
`Fetching security data for token: ${this.tokenAddress}`
659+
);
627660
const security = await this.fetchTokenSecurity();
628661

629-
const tradeData = await this.fetchTokenTradeData(runtime);
662+
console.log(`Fetching trade data for token: ${this.tokenAddress}`);
663+
const tradeData = await this.fetchTokenTradeData();
630664

665+
console.log(
666+
`Fetching DexScreener data for token: ${this.tokenAddress}`
667+
);
631668
const dexData = await this.fetchDexScreenerData();
632669

670+
console.log(
671+
`Analyzing holder distribution for token: ${this.tokenAddress}`
672+
);
633673
const holderDistributionTrend =
634674
await this.analyzeHolderDistribution(tradeData);
635675

676+
console.log(
677+
`Filtering high-value holders for token: ${this.tokenAddress}`
678+
);
636679
const highValueHolders =
637680
await this.filterHighValueHolders(tradeData);
638681

682+
console.log(
683+
`Checking recent trades for token: ${this.tokenAddress}`
684+
);
639685
const recentTrades = await this.checkRecentTrades(tradeData);
640686

687+
console.log(
688+
`Counting high-supply holders for token: ${this.tokenAddress}`
689+
);
641690
const highSupplyHoldersCount =
642691
await this.countHighSupplyHolders(security);
643692

693+
console.log(
694+
`Determining DexScreener listing status for token: ${this.tokenAddress}`
695+
);
644696
const isDexScreenerListed = dexData.pairs.length > 0;
645697
const isDexScreenerPaid = dexData.pairs.some(
646698
(pair) => pair.boosts && pair.boosts.active > 0
@@ -658,6 +710,7 @@ export class TokenProvider {
658710
isDexScreenerPaid,
659711
};
660712

713+
// console.log("Processed token data:", processedData);
661714
return processedData;
662715
} catch (error) {
663716
console.error("Error processing token data:", error);
@@ -725,12 +778,14 @@ export class TokenProvider {
725778
}
726779
output += `\n`;
727780

781+
console.log("Formatted token data:", output);
728782
return output;
729783
}
730784

731-
async getFormattedTokenReport(runtime: IAgentRuntime): Promise<string> {
785+
async getFormattedTokenReport(): Promise<string> {
732786
try {
733-
const processedData = await this.getProcessedTokenData(runtime);
787+
console.log("Generating formatted token report...");
788+
const processedData = await this.getProcessedTokenData();
734789
return this.formatTokenData(processedData);
735790
} catch (error) {
736791
console.error("Error generating token report:", error);
@@ -740,15 +795,18 @@ export class TokenProvider {
740795
}
741796

742797
const tokenAddress = PROVIDER_CONFIG.TOKEN_ADDRESSES.Example;
798+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
799+
const connection = new Connection(PROVIDER_CONFIG.DEFAULT_RPC);
743800
const tokenProvider: Provider = {
744801
get: async (
802+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
745803
runtime: IAgentRuntime,
746804
_message: Memory,
747805
_state?: State
748806
): Promise<string> => {
749807
try {
750808
const provider = new TokenProvider(tokenAddress);
751-
return provider.getFormattedTokenReport(runtime);
809+
return provider.getFormattedTokenReport();
752810
} catch (error) {
753811
console.error("Error fetching token data:", error);
754812
return "Unable to fetch token information. Please try again later.";

0 commit comments

Comments
 (0)