EDUCHAIN Agent Kit

  • src
import { request, gql } from 'graphql-request'; import { TokenQueryResult, PoolQueryResult, FactoryQueryResult, BundleQueryResult, TokenDayDataQueryResult, PoolDayDataQueryResult, Token, Pool, Factory, Bundle, TokenDayData, PoolDayData } from './types.js'; const SUBGRAPH_URL = 'https://api.goldsky.com/api/public/project_cm5nst0b7iiqy01t6hxww7gao/subgraphs/sailfish-v3-occ-mainnet/1.0.0/gn'; // Query to get token information const TOKEN_QUERY = gql` query getToken($id: String!) { tokens(where: { id: $id }) { id symbol name decimals totalSupply volume volumeUSD untrackedVolumeUSD feesUSD txCount poolCount totalValueLocked totalValueLockedUSD totalValueLockedUSDUntracked derivedETH } } `; // Query to get pool information const POOL_QUERY = gql` query getPool($id: String!) { pools(where: { id: $id }) { id createdAtTimestamp createdAtBlockNumber token0 { id symbol name decimals } token1 { id symbol name decimals } feeTier liquidity sqrtPrice token0Price token1Price tick volumeToken0 volumeToken1 volumeUSD untrackedVolumeUSD feesUSD txCount totalValueLockedToken0 totalValueLockedToken1 totalValueLockedETH totalValueLockedUSD totalValueLockedUSDUntracked liquidityProviderCount } } `; // Query to get factory information const FACTORY_QUERY = gql` query getFactory { factories(first: 1) { id poolCount txCount totalVolumeUSD totalVolumeETH totalFeesUSD totalFeesETH untrackedVolumeUSD totalValueLockedUSD totalValueLockedETH totalValueLockedUSDUntracked totalValueLockedETHUntracked owner } } `; // Query to get ETH price const BUNDLE_QUERY = gql` query getBundle { bundles(first: 1) { id ethPriceUSD } } `; // Query to get token day data const TOKEN_DAY_DATA_QUERY = gql` query getTokenDayData($tokenId: String!, $count: Int!) { tokenDayDatas( first: $count orderBy: date orderDirection: desc where: { token: $tokenId } ) { id date token { id symbol name } volume volumeUSD untrackedVolumeUSD totalValueLocked totalValueLockedUSD priceUSD feesUSD open high low close } } `; // Query to get pool day data const POOL_DAY_DATA_QUERY = gql` query getPoolDayData($poolId: String!, $count: Int!) { poolDayDatas( first: $count orderBy: date orderDirection: desc where: { pool: $poolId } ) { id date pool { id token0 { id symbol } token1 { id symbol } } liquidity sqrtPrice token0Price token1Price tick tvlUSD volumeToken0 volumeToken1 volumeUSD feesUSD txCount open high low close } } `; // Query to get top tokens const TOP_TOKENS_QUERY = gql` query getTopTokens($count: Int!) { tokens( first: $count orderBy: totalValueLockedUSD orderDirection: desc ) { id symbol name decimals totalValueLockedUSD volumeUSD feesUSD txCount derivedETH } } `; // Query to get top pools const TOP_POOLS_QUERY = gql` query getTopPools($count: Int!) { pools( first: $count orderBy: totalValueLockedUSD orderDirection: desc ) { id token0 { id symbol name } token1 { id symbol name } feeTier liquidity token0Price token1Price volumeUSD totalValueLockedUSD txCount } } `; // Query to get all pools const ALL_POOLS_QUERY = gql` query getAllPools { pools( first: 1000 orderBy: totalValueLockedUSD orderDirection: desc ) { id token0 { id symbol name } token1 { id symbol name } feeTier liquidity token0Price token1Price volumeUSD totalValueLockedUSD txCount } } `; // Function to get token information by ID export async function getToken(tokenId: string): Promise<Token | null> { try { const data = await request<TokenQueryResult>( SUBGRAPH_URL, TOKEN_QUERY, { id: tokenId.toLowerCase() } ); return data.tokens[0] || null; } catch (error) { console.error('Error fetching token:', error); throw error; } } // Function to get pool information by ID export async function getPool(poolId: string): Promise<Pool | null> { try { const data = await request<PoolQueryResult>( SUBGRAPH_URL, POOL_QUERY, { id: poolId.toLowerCase() } ); return data.pools[0] || null; } catch (error) { console.error('Error fetching pool:', error); throw error; } } // Function to get factory information export async function getFactory(): Promise<Factory | null> { try { const data = await request<FactoryQueryResult>( SUBGRAPH_URL, FACTORY_QUERY ); return data.factories[0] || null; } catch (error) { console.error('Error fetching factory:', error); throw error; } } // Function to get ETH price export async function getEthPrice(): Promise<string | null> { try { const data = await request<BundleQueryResult>( SUBGRAPH_URL, BUNDLE_QUERY ); return data.bundles[0]?.ethPriceUSD || null; } catch (error) { console.error('Error fetching ETH price:', error); throw error; } } // Function to get token day data export async function getTokenDayData(tokenId: string, count: number = 7): Promise<TokenDayData[]> { try { const data = await request<TokenDayDataQueryResult>( SUBGRAPH_URL, TOKEN_DAY_DATA_QUERY, { tokenId: tokenId.toLowerCase(), count } ); return data.tokenDayDatas; } catch (error) { console.error('Error fetching token day data:', error); throw error; } } // Function to get pool day data export async function getPoolDayData(poolId: string, count: number = 7): Promise<PoolDayData[]> { try { const data = await request<PoolDayDataQueryResult>( SUBGRAPH_URL, POOL_DAY_DATA_QUERY, { poolId: poolId.toLowerCase(), count } ); return data.poolDayDatas; } catch (error) { console.error('Error fetching pool day data:', error); throw error; } } // Function to get top tokens by TVL export async function getTopTokens(count: number = 10): Promise<Token[]> { try { const data = await request<TokenQueryResult>( SUBGRAPH_URL, TOP_TOKENS_QUERY, { count } ); return data.tokens; } catch (error) { console.error('Error fetching top tokens:', error); throw error; } } // Function to get top pools by TVL export async function getTopPools(count: number = 10): Promise<Pool[]> { try { const data = await request<PoolQueryResult>( SUBGRAPH_URL, TOP_POOLS_QUERY, { count } ); return data.pools; } catch (error) { console.error('Error fetching top pools:', error); throw error; } } // Function to calculate 24h volume export async function get24HVolume(): Promise<string> { try { const factory = await getFactory(); if (!factory) { throw new Error('Factory data not available'); } // Note: This is a simplified approach. For more accurate 24h volume, // you would need to compare current volume with volume from 24h ago return factory.totalVolumeUSD; } catch (error) { console.error('Error calculating 24h volume:', error); throw error; } } // Function to get total TVL export async function getTotalTVL(): Promise<string> { try { const factory = await getFactory(); if (!factory) { throw new Error('Factory data not available'); } return factory.totalValueLockedUSD; } catch (error) { console.error('Error fetching total TVL:', error); throw error; } } // Function to get token price in USD export async function getTokenPrice(tokenId: string): Promise<string | null> { try { const token = await getToken(tokenId); if (!token) { return null; } const ethPrice = await getEthPrice(); if (!ethPrice) { return null; } // Calculate USD price from ETH price const priceUSD = parseFloat(token.derivedETH) * parseFloat(ethPrice); return priceUSD.toString(); } catch (error) { console.error('Error calculating token price:', error); throw error; } } // Function to get all pools export async function getPools(): Promise<Pool[]> { try { const data = await request<PoolQueryResult>( SUBGRAPH_URL, ALL_POOLS_QUERY ); return data.pools; } catch (error) { console.error('Error fetching all pools:', error); throw error; } }