Skip to content

Commit

Permalink
remove cache
Browse files Browse the repository at this point in the history
  • Loading branch information
ponderingdemocritus committed Nov 17, 2024
1 parent a3c0e28 commit 39855a5
Show file tree
Hide file tree
Showing 3 changed files with 139 additions and 110 deletions.
17 changes: 17 additions & 0 deletions packages/plugin-starknet/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,23 @@
import { Plugin } from "@ai16z/eliza";
import { executeSwap } from "./actions/swap";

export const PROVIDER_CONFIG = {
BIRDEYE_API: "https://public-api.birdeye.so",
MAX_RETRIES: 3,
RETRY_DELAY: 2000,
DEFAULT_RPC: "https://api.mainnet-beta.solana.com",
TOKEN_ADDRESSES: {
SOL: "So11111111111111111111111111111111111111112",
BTC: "qfnqNqs3nCAHjnyCgLRDbBtq4p2MtHZxw8YjSyYhPoL",
ETH: "7vfCXTUXx5WJV5JADk17DUJ4ksgau7utNKj4b963voxs",
Example: "2weMjPLLybRMMva1fM3U31goWWrCpF59CHWNhnCJ9Vyh",
},
TOKEN_SECURITY_ENDPOINT: "/defi/token_security?address=",
TOKEN_TRADE_DATA_ENDPOINT: "/defi/v3/token/trade-data/single?address=",
DEX_SCREENER_API: "https://api.dexscreener.com/latest/dex/tokens/",
MAIN_WALLET: "",
};

export const starknetPlugin: Plugin = {
name: "starknet",
description: "Starknet Plugin for Eliza",
Expand Down
128 changes: 18 additions & 110 deletions packages/plugin-starknet/src/providers/token.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,118 +10,24 @@ import {
CalculatedBuyAmounts,
Prices,
} from "../types/trustDB.ts";
import * as fs from "fs";
import NodeCache from "node-cache";
import * as path from "path";
import { WalletProvider, Item } from "./walletProvider.ts";
import { num } from "starknet";
import {
analyzeHighSupplyHolders,
evaluateTokenTrading,
TokenMetrics,
} from "./utils.ts";
// import { Connection, PublicKey } from "@solana/web3.js";

const PROVIDER_CONFIG = {
BIRDEYE_API: "https://public-api.birdeye.so",
MAX_RETRIES: 3,
RETRY_DELAY: 2000,
DEFAULT_RPC: "https://api.mainnet-beta.solana.com",
TOKEN_ADDRESSES: {
SOL: "So11111111111111111111111111111111111111112",
BTC: "qfnqNqs3nCAHjnyCgLRDbBtq4p2MtHZxw8YjSyYhPoL",
ETH: "7vfCXTUXx5WJV5JADk17DUJ4ksgau7utNKj4b963voxs",
Example: "2weMjPLLybRMMva1fM3U31goWWrCpF59CHWNhnCJ9Vyh",
},
TOKEN_SECURITY_ENDPOINT: "/defi/token_security?address=",
TOKEN_TRADE_DATA_ENDPOINT: "/defi/v3/token/trade-data/single?address=",
DEX_SCREENER_API: "https://api.dexscreener.com/latest/dex/tokens/",
MAIN_WALLET: "",
};
import { PROVIDER_CONFIG } from "../index.ts";
import { Cache } from "../utils/cache.ts";

export class TokenProvider {
private cache: NodeCache;
private cacheDir: string;
private cache: Cache;

constructor(
// private connection: Connection,
private tokenAddress: string,
private walletProvider: WalletProvider
) {
this.cache = new NodeCache({ stdTTL: 300 }); // 5 minutes cache
const __dirname = path.resolve();

// Find the 'eliza' folder in the filepath and adjust the cache directory path
const elizaIndex = __dirname.indexOf("eliza");
if (elizaIndex !== -1) {
const pathToEliza = __dirname.slice(0, elizaIndex + 5); // include 'eliza'
this.cacheDir = path.join(pathToEliza, "cache");
} else {
this.cacheDir = path.join(__dirname, "cache");
}

this.cacheDir = path.join(__dirname, "cache");
if (!fs.existsSync(this.cacheDir)) {
fs.mkdirSync(this.cacheDir);
}
}

private readCacheFromFile<T>(cacheKey: string): T | null {
const filePath = path.join(this.cacheDir, `${cacheKey}.json`);
console.log({ filePath });
if (fs.existsSync(filePath)) {
const fileContent = fs.readFileSync(filePath, "utf-8");
const parsed = JSON.parse(fileContent);
const now = Date.now();
if (now < parsed.expiry) {
console.log(
`Reading cached data from file for key: ${cacheKey}`
);
return parsed.data as T;
} else {
console.log(
`Cache expired for key: ${cacheKey}. Deleting file.`
);
fs.unlinkSync(filePath);
}
}
return null;
}

private writeCacheToFile<T>(cacheKey: string, data: T): void {
const filePath = path.join(this.cacheDir, `${cacheKey}.json`);
const cacheData = {
data: data,
expiry: Date.now() + 300000, // 5 minutes in milliseconds
};
fs.writeFileSync(filePath, JSON.stringify(cacheData), "utf-8");
console.log(`Cached data written to file for key: ${cacheKey}`);
}

private getCachedData<T>(cacheKey: string): T | null {
// Check in-memory cache first
const cachedData = this.cache.get<T>(cacheKey);
if (cachedData) {
return cachedData;
}

// Check file-based cache
const fileCachedData = this.readCacheFromFile<T>(cacheKey);
if (fileCachedData) {
// Populate in-memory cache
this.cache.set(cacheKey, fileCachedData);
return fileCachedData;
}

return null;
}

private setCachedData<T>(cacheKey: string, data: T): void {
// Set in-memory cache
this.cache.set(cacheKey, data);

// Write to file-based cache
this.writeCacheToFile(cacheKey, data);
this.cache = new Cache();
}

// TODO: remove this
Expand Down Expand Up @@ -201,7 +107,7 @@ export class TokenProvider {
async fetchPrices(): Promise<Prices> {
try {
const cacheKey = "prices";
const cachedData = this.getCachedData<Prices>(cacheKey);
const cachedData = this.cache.getCachedData<Prices>(cacheKey);
if (cachedData) {
console.log("Returning cached prices.");
return cachedData;
Expand Down Expand Up @@ -237,7 +143,7 @@ export class TokenProvider {
console.warn(`No price data available for token: ${token}`);
}
}
this.setCachedData(cacheKey, prices);
this.cache.setCachedData(cacheKey, prices);
return prices;
} catch (error) {
console.error("Error fetching prices:", error);
Expand Down Expand Up @@ -297,7 +203,8 @@ export class TokenProvider {
// TODO: Update to Starknet
async fetchTokenSecurity(): Promise<TokenSecurityData> {
const cacheKey = `tokenSecurity_${this.tokenAddress}`;
const cachedData = this.getCachedData<TokenSecurityData>(cacheKey);
const cachedData =
this.cache.getCachedData<TokenSecurityData>(cacheKey);
if (cachedData) {
console.log(
`Returning cached token security data for ${this.tokenAddress}.`
Expand All @@ -319,7 +226,7 @@ export class TokenProvider {
top10HolderBalance: data.data.top10HolderBalance,
top10HolderPercent: data.data.top10HolderPercent,
};
this.setCachedData(cacheKey, security);
this.cache.setCachedData(cacheKey, security);
console.log(`Token security data cached for ${this.tokenAddress}.`);

return security;
Expand All @@ -328,7 +235,7 @@ export class TokenProvider {
// TODO: Update to Starknet
async fetchTokenTradeData(): Promise<TokenTradeData> {
const cacheKey = `tokenTradeData_${this.tokenAddress}`;
const cachedData = this.getCachedData<TokenTradeData>(cacheKey);
const cachedData = this.cache.getCachedData<TokenTradeData>(cacheKey);
if (cachedData) {
console.log(
`Returning cached token trade data for ${this.tokenAddress}.`
Expand Down Expand Up @@ -557,13 +464,13 @@ export class TokenProvider {
volume_sell_24h_change_percent:
data.data.volume_sell_24h_change_percent,
};
this.setCachedData(cacheKey, tradeData);
this.cache.setCachedData(cacheKey, tradeData);
return tradeData;
}

async fetchDexScreenerData(): Promise<DexScreenerData> {
const cacheKey = `dexScreenerData_${this.tokenAddress}`;
const cachedData = this.getCachedData<DexScreenerData>(cacheKey);
const cachedData = this.cache.getCachedData<DexScreenerData>(cacheKey);
if (cachedData) {
console.log("Returning cached DexScreener data.");
return cachedData;
Expand All @@ -590,7 +497,7 @@ export class TokenProvider {
};

// Cache the result
this.setCachedData(cacheKey, dexData);
this.cache.setCachedData(cacheKey, dexData);

return dexData;
} catch (error) {
Expand All @@ -606,7 +513,7 @@ export class TokenProvider {
symbol: string
): Promise<DexScreenerPair | null> {
const cacheKey = `dexScreenerData_search_${symbol}`;
const cachedData = this.getCachedData<DexScreenerData>(cacheKey);
const cachedData = this.cache.getCachedData<DexScreenerData>(cacheKey);
if (cachedData) {
console.log("Returning cached search DexScreener data.");
return this.getHighestLiquidityPair(cachedData);
Expand All @@ -632,7 +539,7 @@ export class TokenProvider {
};

// Cache the result
this.setCachedData(cacheKey, dexData);
this.cache.setCachedData(cacheKey, dexData);

// Return the pair with the highest liquidity and market cap
return this.getHighestLiquidityPair(dexData);
Expand All @@ -641,6 +548,7 @@ export class TokenProvider {
return null;
}
}

getHighestLiquidityPair(dexData: DexScreenerData): DexScreenerPair | null {
if (dexData.pairs.length === 0) {
return null;
Expand Down Expand Up @@ -713,7 +621,7 @@ export class TokenProvider {
// TODO: Update to Starknet
async fetchHolderList(): Promise<HolderData[]> {
const cacheKey = `holderList_${this.tokenAddress}`;
const cachedData = this.getCachedData<HolderData[]>(cacheKey);
const cachedData = this.cache.getCachedData<HolderData[]>(cacheKey);
if (cachedData) {
console.log("Returning cached holder list.");
return cachedData;
Expand Down Expand Up @@ -802,7 +710,7 @@ export class TokenProvider {
console.log(`Total unique holders fetched: ${holders.length}`);

// Cache the result
this.setCachedData(cacheKey, holders);
this.cache.setCachedData(cacheKey, holders);

return holders;
} catch (error) {
Expand Down
104 changes: 104 additions & 0 deletions packages/plugin-starknet/src/utils/cache.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import NodeCache from "node-cache";
import fs from "fs";
import path from "path";

export class Cache {
private cache: NodeCache;
public cacheDir: string;

constructor() {
this.cache = new NodeCache({ stdTTL: 300 }); // 5 minutes cache
const __dirname = path.resolve();

// Find the 'eliza' folder in the filepath and adjust the cache directory path
const elizaIndex = __dirname.indexOf("eliza");
if (elizaIndex !== -1) {
const pathToEliza = __dirname.slice(0, elizaIndex + 5); // include 'eliza'
this.cacheDir = path.join(pathToEliza, "cache");
} else {
this.cacheDir = path.join(__dirname, "cache");
}

if (!fs.existsSync(this.cacheDir)) {
fs.mkdirSync(this.cacheDir);
}
}

private readCacheFromFile<T>(cacheKey: string): T | null {
const filePath = path.join(this.cacheDir, `${cacheKey}.json`);
if (fs.existsSync(filePath)) {
try {
const fileContent = fs.readFileSync(filePath, "utf-8");
const parsed = JSON.parse(fileContent);
const now = Date.now();
if (now < parsed.expiry) {
return parsed.data as T;
} else {
fs.unlinkSync(filePath);
}
} catch (error) {
console.error(
`Error reading cache file for key ${cacheKey}:`,
error
);
// Delete corrupted cache file
try {
fs.unlinkSync(filePath);
} catch (e) {
console.error(`Error deleting corrupted cache file:`, e);
}
}
}
return null;
}

private writeCacheToFile<T>(cacheKey: string, data: T): void {
try {
const filePath = path.join(this.cacheDir, `${cacheKey}.json`);
const cacheData = {
data: data,
expiry: Date.now() + 300000, // 5 minutes in milliseconds
};
fs.writeFileSync(filePath, JSON.stringify(cacheData), "utf-8");
} catch (error) {
console.error(
`Error writing cache file for key ${cacheKey}:`,
error
);
}
}

public get<T>(cacheKey: string): T | undefined {
return this.cache.get<T>(cacheKey);
}

public set<T>(cacheKey: string, data: T): void {
this.cache.set(cacheKey, data);
}

public getCachedData<T>(cacheKey: string): T | null {
// Check in-memory cache first
const cachedData = this.cache.get<T>(cacheKey);
if (cachedData !== undefined) {
return cachedData;
}

// Check file-based cache
const fileCachedData = this.readCacheFromFile<T>(cacheKey);
if (fileCachedData) {
// Populate in-memory cache
this.cache.set(cacheKey, fileCachedData);
return fileCachedData;
}

return null;
}

public setCachedData<T>(cacheKey: string, data: T): void {
// Set in-memory cache
this.cache.set(cacheKey, data);

// Write to file-based cache
this.writeCacheToFile(cacheKey, data);
}
}

0 comments on commit 39855a5

Please sign in to comment.