From 75490a4fcd8780945a638d8a856266b751a80760 Mon Sep 17 00:00:00 2001 From: akiraonstarknet Date: Mon, 30 Sep 2024 20:58:08 +0530 Subject: [PATCH] optimization: load strkfarm apy from api --- src/app/api/strategies/route.ts | 16 ++++++++-- .../[strategyId]/_components/Strategy.tsx | 5 ++++ src/components/HarvestTime.tsx | 29 +++++++++++++++++-- src/constants.ts | 3 ++ src/store/protocols.ts | 20 ++++++------- src/store/strategies.atoms.ts | 13 ++++++++- src/store/strkfarm.atoms.ts | 16 ++++++---- 7 files changed, 80 insertions(+), 22 deletions(-) diff --git a/src/app/api/strategies/route.ts b/src/app/api/strategies/route.ts index 9b8ef1dd..29a3de66 100755 --- a/src/app/api/strategies/route.ts +++ b/src/app/api/strategies/route.ts @@ -4,7 +4,7 @@ import ZkLendAtoms from '@/store/zklend.store'; import { PoolInfo } from '@/store/pools'; import NostraLendingAtoms from '@/store/nostralending.store'; import { RpcProvider } from 'starknet'; -import { getStrategies } from '@/store/strategies.atoms'; +import { getLiveStatusNumber, getStrategies } from '@/store/strategies.atoms'; import { MY_STORE } from '@/store'; import MyNumber from '@/utils/MyNumber'; import { IStrategy, NFTInfo, TokenInfo } from '@/strategies/IStrategy'; @@ -42,7 +42,12 @@ async function getStrategyInfo(strategy: IStrategy) { id: strategy.id, apy: strategy.netYield, depositToken: strategy - .depositMethods(MyNumber.fromZero(), '', provider) + .depositMethods({ + amount: MyNumber.fromZero(), + address: '', + provider, + isMax: false, + }) .map((t) => t.tokenInfo.token), leverage: strategy.leverage, contract: strategy.holdingTokens.map((t) => ({ @@ -50,7 +55,12 @@ async function getStrategyInfo(strategy: IStrategy) { address: (t).token ? (t).token : (t).address, })), tvlUsd: tvl.usdValue || 0, - status: strategy.liveStatus, + status: { + number: getLiveStatusNumber(strategy.liveStatus), + value: strategy.liveStatus, + }, + riskFactor: strategy.riskFactor, + logo: strategy.holdingTokens[0].logo, }; } diff --git a/src/app/strategy/[strategyId]/_components/Strategy.tsx b/src/app/strategy/[strategyId]/_components/Strategy.tsx index d9866875..c8470759 100755 --- a/src/app/strategy/[strategyId]/_components/Strategy.tsx +++ b/src/app/strategy/[strategyId]/_components/Strategy.tsx @@ -440,6 +440,11 @@ const Strategy = ({ params }: StrategyParams) => { ))} + {strategy.actions.length == 0 && ( +
+ +
+ )} diff --git a/src/components/HarvestTime.tsx b/src/components/HarvestTime.tsx index 7fa6a5b5..7c1b372f 100644 --- a/src/components/HarvestTime.tsx +++ b/src/components/HarvestTime.tsx @@ -2,6 +2,7 @@ import React, { useMemo } from 'react'; import { Box, Flex, + Spinner, Stat, StatLabel, StatNumber, @@ -15,6 +16,9 @@ import { HarvestTimeAtom } from '@/store/harvest.atom'; import { useAtomValue } from 'jotai'; import { formatTimediff, getDisplayCurrencyAmount, timeAgo } from '@/utils'; import { isMobile } from 'react-device-detect'; +import STRKFarmAtoms, { + STRKFarmStrategyAPIResult, +} from '@/store/strkfarm.atoms'; interface HarvestTimeProps { strategy: StrategyInfo; @@ -70,6 +74,24 @@ const HarvestTime: React.FC = ({ strategy, balData }) => { return formatTimediff(nextHarvest); }, [data?.timestamp, lastHarvest]); + const strategiesInfo = useAtomValue(STRKFarmAtoms.baseAPRs!); + + const strategyInfo = useMemo(() => { + if (!strategiesInfo || !strategiesInfo.data) return null; + + const strategiesList: STRKFarmStrategyAPIResult[] = + strategiesInfo.data.strategies; + const strategyInfo = strategiesList.find( + (strat) => strat.id == strategy.id, + ); + return strategyInfo ? strategyInfo : null; + }, [strategiesInfo]); + + const leverage = useMemo(() => { + if (!strategyInfo) return 0; + return strategyInfo.leverage || 0; + }, [strategyInfo]); + return ( @@ -82,7 +104,7 @@ const HarvestTime: React.FC = ({ strategy, balData }) => { > APY - {(strategy.netYield * 100).toFixed(2)}% + {((strategyInfo?.apy || 0) * 100).toFixed(2)}% @@ -93,7 +115,10 @@ const HarvestTime: React.FC = ({ strategy, balData }) => { fontSize={'12px'} padding={'2px 5px'} > - 🔥{strategy.leverage.toFixed(2)}x boosted + 🔥{leverage.toFixed(2)}x boosted + {leverage == 0 && ( + + )} diff --git a/src/constants.ts b/src/constants.ts index bf22ad80..e69827ce 100755 --- a/src/constants.ts +++ b/src/constants.ts @@ -42,6 +42,9 @@ const CONSTANTS = { HAIKO: { BASE_APR_API: 'haiko/markets?network=mainnet', }, + STRKFarm: { + BASE_APR_API: '/api/strategies', + }, MY_SWAP: { POOLS_API: '/myswap/data/pools/all.json', BASE_APR_API: '/myswap/data/pools', diff --git a/src/store/protocols.ts b/src/store/protocols.ts index 4ad5a43a..14e0a707 100644 --- a/src/store/protocols.ts +++ b/src/store/protocols.ts @@ -17,8 +17,14 @@ import { Category, PoolInfo, PoolType } from './pools'; import { strategiesAtom } from './strategies.atoms'; import strkfarmLogo from '@public/logo.png'; import { IStrategyProps } from '@/strategies/IStrategy'; +import STRKFarmAtoms, { strkfarm } from './strkfarm.atoms'; export const PROTOCOLS = [ + { + name: strkfarm.name, + class: strkfarm, + atoms: STRKFarmAtoms, + }, { name: ekubo.name, class: ekubo, @@ -98,16 +104,10 @@ export const PROTOCOLS = [ export const ALL_FILTER = 'All'; -const allProtocols = [ - { - name: 'STRKFarm', - logo: strkfarmLogo.src, - }, - ...PROTOCOLS.map((p) => ({ - name: p.name, - logo: p.class.logo, - })), -]; +const allProtocols = PROTOCOLS.map((p) => ({ + name: p.name, + logo: p.class.logo, +})); export const filters = { categories: [...Object.values(Category)], types: [...Object.values(PoolType)], diff --git a/src/store/strategies.atoms.ts b/src/store/strategies.atoms.ts index dd465c5f..aba4eeca 100755 --- a/src/store/strategies.atoms.ts +++ b/src/store/strategies.atoms.ts @@ -110,7 +110,7 @@ export const strategiesAtom = atom((get) => { return strategies; }); -function getLiveStatusNumber(status: StrategyLiveStatus) { +export function getLiveStatusNumber(status: StrategyLiveStatus) { if (status == StrategyLiveStatus.NEW) { return 1; } else if (status == StrategyLiveStatus.ACTIVE) { @@ -120,3 +120,14 @@ function getLiveStatusNumber(status: StrategyLiveStatus) { } return 4; } + +export function getLiveStatusEnum(status: number) { + if (status == 1) { + return StrategyLiveStatus.NEW; + } else if (status == 2) { + return StrategyLiveStatus.ACTIVE; + } else if (status == 3) { + return StrategyLiveStatus.COMING_SOON; + } + return StrategyLiveStatus.RETIRED; +} diff --git a/src/store/strkfarm.atoms.ts b/src/store/strkfarm.atoms.ts index 9938e664..6bda9228 100644 --- a/src/store/strkfarm.atoms.ts +++ b/src/store/strkfarm.atoms.ts @@ -13,7 +13,7 @@ import { AtomWithQueryResult, atomWithQuery } from 'jotai-tanstack-query'; import strkfarmLogo from '@public/logo.png'; import { getLiveStatusEnum } from './strategies.atoms'; -interface MyBaseAprDoc { +export interface STRKFarmStrategyAPIResult { name: string; id: string; apy: number; @@ -29,19 +29,19 @@ interface MyBaseAprDoc { logo: string; } -export class STRKFarm extends IDapp { +export class STRKFarm extends IDapp { name = 'STRKFarm'; link = strkfarmLogo.src; logo = 'https://app.jediswap.xyz/favicon/favicon-32x32.png'; incentiveDataKey = 'Jediswap_v1'; _computePoolsInfo(data: any) { - const rawPools: MyBaseAprDoc[] = data.strategies; + const rawPools: STRKFarmStrategyAPIResult[] = data.strategies; const pools: PoolInfo[] = []; return rawPools.map((rawPool) => { let category = Category.Others; const poolName = rawPool.name; - const riskFactor = 0.75; // todo + const riskFactor = rawPool.riskFactor; if (poolName.includes('USDC') || poolName.includes('USDT')) { category = Category.Stable; } else if (poolName.includes('STRK')) { @@ -81,7 +81,7 @@ export class STRKFarm extends IDapp { } getBaseAPY(p: PoolInfo, data: AtomWithQueryResult) { - const aprData: MyBaseAprDoc[] = data.data.strategies; + const aprData: STRKFarmStrategyAPIResult[] = data.data.strategies; let baseAPY: number | 'Err' = 'Err'; let splitApr: APRSplit | null = null; const metadata: PoolMetadata | null = null; @@ -108,7 +108,11 @@ export const strkfarm = new STRKFarm(); const STRKFarmAtoms: ProtocolAtoms = { baseAPRs: atomWithQuery((get) => ({ queryKey: ['strkfarm_base_aprs'], - queryFn: async ({ queryKey }) => { + queryFn: async ({ + queryKey, + }): Promise<{ + strategies: STRKFarmStrategyAPIResult[]; + }> => { const response = await fetch(`${CONSTANTS.STRKFarm.BASE_APR_API}`); const data = await response.json(); return data;