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

feat(starknet): enhance token provider implementation and type safety #3132

Closed
wants to merge 3 commits into from
Closed
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
86 changes: 37 additions & 49 deletions packages/plugin-starknet/src/providers/token.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import type {
Prices,
} from "../types/trustDB.ts";
import { WalletProvider, type TokenBalances } from "./portfolioProvider.ts";
import { num } from "starknet";
import { Contract, Provider as StarknetProvider, num } from "starknet";
import {
analyzeHighSupplyHolders,
evaluateTokenTrading,
Expand Down Expand Up @@ -80,59 +80,41 @@ export const PORTFOLIO_TOKENS = {

export class TokenProvider {
private cache: Cache;
private provider: StarknetProvider;

constructor(
private tokenAddress: string,
private walletProvider: WalletProvider
) {
this.cache = new Cache();
this.provider = new StarknetProvider({
sequencer: { network: "mainnet-alpha" },
});
}

// TODO: remove this
private async fetchWithRetry<T>(
url: string,
options: RequestInit = {}
): Promise<T> {
let lastError: Error;
async getTokensInWallet(): Promise<TokenBalances> {
try {
// Get token balances from the wallet provider with caching
const cacheKey = `wallet_tokens_${this.tokenAddress}`;
const cachedBalances =
this.cache.getCachedData<TokenBalances>(cacheKey);

for (let i = 0; i < PROVIDER_CONFIG.MAX_RETRIES; i++) {
try {
const response = await fetch(url, {
...options,
headers: {
"Content-Type": "application/json",
...options.headers,
},
});
if (cachedBalances) {
return cachedBalances;
}

if (!response.ok) {
throw new Error(
`HTTP error! status: ${
response.status
}, message: ${await response.text()}`
);
}
// Fetch fresh balances from the wallet provider
const tokenBalances =
await this.walletProvider.getWalletPortfolio();

return await response.json();
} catch (error) {
console.error(`Request attempt ${i + 1} failed:`, error);
lastError = error as Error;
// Cache the results for better performance
this.cache.setCachedData(cacheKey, tokenBalances);

if (i < PROVIDER_CONFIG.MAX_RETRIES - 1) {
const delay = PROVIDER_CONFIG.RETRY_DELAY * Math.pow(2, i);
await new Promise((resolve) => setTimeout(resolve, delay));
}
}
return tokenBalances;
} catch (error) {
console.error("Error fetching token balances:", error);
throw new Error("Failed to fetch token balances from wallet");
}

throw lastError;
}

// TODO: Update to Starknet
async getTokensInWallet(): Promise<TokenBalances> {
const tokenBalances =
await this.walletProvider.getWalletPortfolio();
return tokenBalances;
}

// check if the token symbol is in the wallet
Expand All @@ -144,7 +126,9 @@ export class TokenProvider {
);

if (!portfolioToken) {
console.warn(`Token with symbol ${tokenSymbol} not found in PORTFOLIO_TOKENS`);
console.warn(
`Token with symbol ${tokenSymbol} not found in PORTFOLIO_TOKENS`
);
return null;
}

Expand All @@ -157,7 +141,9 @@ export class TokenProvider {
if (items[tokenAddress]) {
return tokenAddress;
} else {
console.warn(`Token with address ${tokenAddress} not found in wallet`);
console.warn(
`Token with address ${tokenAddress} not found in wallet`
);
return null;
}
} catch (error) {
Expand Down Expand Up @@ -205,8 +191,8 @@ export class TokenProvider {
token === STRK
? "starknet"
: token === BTC
? "bitcoin"
: "ethereum";
? "bitcoin"
: "ethereum";

prices[priceKey].usd = tokenInfo.market.currentPrice.toString();
});
Expand Down Expand Up @@ -682,8 +668,9 @@ export class TokenProvider {
console.log(
`Filtering high-value holders for token: ${this.tokenAddress}`
);
const highValueHolders =
await this.filterHighValueHolders(tradeData);
const highValueHolders = await this.filterHighValueHolders(
tradeData
);

console.log(
`Checking recent trades for token: ${this.tokenAddress}`
Expand All @@ -695,8 +682,9 @@ export class TokenProvider {
console.log(
`Counting high-supply holders for token: ${this.tokenAddress}`
);
const highSupplyHoldersCount =
await this.countHighSupplyHolders(security);
const highSupplyHoldersCount = await this.countHighSupplyHolders(
security
);

console.log(
`Determining DexScreener listing status for token: ${this.tokenAddress}`
Expand Down
43 changes: 43 additions & 0 deletions packages/plugin-starknet/src/types/declarations.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
declare module "@elizaos/core" {
export interface IAgentRuntime {
composeState(message: Memory): Promise<State>;
updateRecentMessageState(state: State): Promise<State>;
}

export interface Memory {
[key: string]: any;
}

export interface Provider {
[key: string]: any;
}

export interface State {
[key: string]: any;
}

export const settings: {
[key: string]: any;
};
}

declare module "starknet" {
export interface Provider {
sequencer: {
network: string;
};
}

export class Contract {
constructor(address: string, abi: any[], provider: Provider);
}

export class Provider {
constructor(config: { sequencer: { network: string } });
}

export const num: {
toBigInt(value: string | number): bigint;
};
}

Loading