From 5ae25d8755acc0c00cc16eb238cd06635ace3f2b Mon Sep 17 00:00:00 2001 From: Karelian Pie Date: Mon, 22 May 2023 14:20:16 +0300 Subject: [PATCH 1/3] refactor: Validate data coming from api.curve.fi --- apps/common/contexts/useCurve.tsx | 68 ++++++++----------- apps/common/schemas/curveSchemas.ts | 63 +++++++++++++++++ apps/common/types/curves.tsx | 26 ------- apps/ybribe/components/bribe/GaugeListRow.tsx | 4 +- apps/ybribe/components/claim/GaugeListRow.tsx | 4 +- .../rewardFeed/RewardFeedTableRow.tsx | 6 +- pages/ybribe/index.tsx | 8 +-- pages/ybribe/offer-bribe.tsx | 12 ++-- pages/ycrv/holdings.tsx | 12 +++- 9 files changed, 118 insertions(+), 85 deletions(-) create mode 100644 apps/common/schemas/curveSchemas.ts diff --git a/apps/common/contexts/useCurve.tsx b/apps/common/contexts/useCurve.tsx index d9fa8026c..bd999e539 100755 --- a/apps/common/contexts/useCurve.tsx +++ b/apps/common/contexts/useCurve.tsx @@ -1,33 +1,26 @@ import React, {createContext, useContext, useMemo} from 'react'; import useSWR from 'swr'; import {toAddress} from '@yearn-finance/web-lib/utils/address'; -import {baseFetcher, curveFetcher} from '@yearn-finance/web-lib/utils/fetchers'; +import {baseFetcher} from '@yearn-finance/web-lib/utils/fetchers'; +import {useFetch} from '@common/hooks/useFetch'; +import {curveAllGaugesSchema, curveWeeklyFeesSchema} from '@common/schemas/curveSchemas'; import type {SWRResponse} from 'swr'; import type {TDict} from '@yearn-finance/web-lib/types'; -import type {TCurveGauges, TCurveGaugesFromYearn} from '@common/types/curves'; +import type {TCurveAllGauges, TCurveWeeklyFees} from '@common/schemas/curveSchemas'; +import type {TCurveGaugesFromYearn} from '@common/types/curves'; -type TCurveWeeklyFees = { - weeklyFeesTable: { - date: string; - ts: number; - rawFees: number; - }[]; - totalFees: { - fees: number - } -} type TCoinGeckoPrices = { usd: number } export type TCurveContext = { - curveWeeklyFees: TCurveWeeklyFees; + curveWeeklyFees: TCurveWeeklyFees['data']; cgPrices: TDict; - gauges: TCurveGauges[]; + gauges: TCurveAllGauges['data'][string][]; isLoadingGauges: boolean; gaugesFromYearn: TCurveGaugesFromYearn[]; } -const defaultProps: TCurveContext = { +const defaultProps: TCurveContext = { curveWeeklyFees: { weeklyFeesTable: [], totalFees: { @@ -42,37 +35,35 @@ const defaultProps: TCurveContext = { const CurveContext = createContext(defaultProps); -export const CurveContextApp = ({children}: {children: React.ReactElement}): React.ReactElement => { - /* 🔵 - Yearn Finance ****************************************************** - ** Fetch all the CurveGauges to be able to create some new if required - ***************************************************************************/ - const {data: curveWeeklyFees} = useSWR( - 'https://api.curve.fi/api/getWeeklyFees', - curveFetcher, - {revalidateOnFocus: false} - ) as SWRResponse; - - const {data: cgPrices} = useSWR( +export const CurveContextApp = ({children}: { children: React.ReactElement }): React.ReactElement => { + const {data: curveWeeklyFees} = useFetch({ + endpoint: 'https://api.curve.fi/api/getWeeklyFees', + schema: curveWeeklyFeesSchema + }); + + const {data: cgPrices} = useSWR( 'https://api.coingecko.com/api/v3/simple/price?ids=curve-dao-token&vs_currencies=usd', baseFetcher, {revalidateOnFocus: false} ) as SWRResponse>; + + /* 🔵 - Yearn Finance ****************************************************** + ** Fetch all the CurveGauges to be able to create some new if required + ***************************************************************************/ + const {data: gaugesWrapper, isLoading: isLoadingGauges} = useFetch({ + endpoint: 'https://api.curve.fi/api/getAllGauges?blockchainId=ethereum', + schema: curveAllGaugesSchema + }); - const {data: gaugesWrapper, isLoading: isLoadingGauges} = useSWR( - 'https://api.curve.fi/api/getAllGauges?blockchainId=ethereum', - curveFetcher, - {revalidateOnFocus: false} - ); - - const {data: gaugesFromYearn} = useSWR( + const {data: gaugesFromYearn} = useSWR( 'https://api.yearn.finance/v1/chains/1/apy-previews/curve-factory', baseFetcher, {revalidateOnFocus: false} ) as SWRResponse; - const gauges = useMemo((): TCurveGauges[] => { - const _gaugesForMainnet: TCurveGauges[] = []; - for (const gauge of Object.values(gaugesWrapper || {})) { + const gauges = useMemo((): TCurveAllGauges['data'][string][] => { + const _gaugesForMainnet: TCurveAllGauges['data'][string][] = []; + for (const gauge of Object.values(gaugesWrapper?.data || {})) { if (gauge.is_killed) { continue; } @@ -93,8 +84,8 @@ export const CurveContextApp = ({children}: {children: React.ReactElement}): Rea /* 🔵 - Yearn Finance ****************************************************** ** Setup and render the Context provider to use in the app. ***************************************************************************/ - const contextValue = useMemo((): TCurveContext => ({ - curveWeeklyFees: curveWeeklyFees || defaultProps.curveWeeklyFees, + const contextValue = useMemo((): TCurveContext => ({ + curveWeeklyFees: curveWeeklyFees?.data || defaultProps.curveWeeklyFees, cgPrices: cgPrices || defaultProps.cgPrices, gauges: gauges || defaultProps.gauges, isLoadingGauges: isLoadingGauges || defaultProps.isLoadingGauges, @@ -108,6 +99,5 @@ export const CurveContextApp = ({children}: {children: React.ReactElement}): Rea ); }; - export const useCurve = (): TCurveContext => useContext(CurveContext); export default useCurve; diff --git a/apps/common/schemas/curveSchemas.ts b/apps/common/schemas/curveSchemas.ts new file mode 100644 index 000000000..b9aabf8bd --- /dev/null +++ b/apps/common/schemas/curveSchemas.ts @@ -0,0 +1,63 @@ +import {z} from 'zod'; + +export const curveWeeklyFeesSchema = z.object({ + success: z.boolean().optional(), + data: z.object({ + weeklyFeesTable: z + .object({ + date: z.string(), + ts: z.number(), + rawFees: z.number() + }) + .array() + .optional() + .nullable(), + totalFees: z.object({ + fees: z.number() + }) + }), + generatedTimeMs: z.number().optional() +}); + +export const curveAllGaugesSchema = z.object({ + success: z.boolean().optional(), + data: z.record( + z.string(), + z.object({ + poolUrls: z.object({ + swap: z.string().array().optional().nullable(), + deposit: z.string().array().optional().nullable(), + withdraw: z.string().array().optional().nullable() + }).optional(), + swap: z.string().optional(), + swap_token: z.string().optional(), + name: z.string(), + shortName: z.string().optional(), + gauge: z.string().optional(), + swap_data: z + .object({virtual_price: z.string().or(z.number().optional())}) + .optional(), + gauge_data: z.object({ + inflation_rate: z.string().optional(), + working_supply: z.string().optional() + }).optional(), + gauge_controller: z.object({ + gauge_relative_weight: z.string().optional(), + get_gauge_weight: z.string().optional(), + inflation_rate: z.string().optional() + }).optional(), + factory: z.boolean(), + side_chain: z.boolean().optional(), + is_killed: z.boolean().optional(), + hasNoCrv: z.boolean().optional(), + type: z.string().optional(), + lpTokenPrice: z.number().nullable().optional(), + rewardPerGauge: z.string().array().optional() + }) + ), + generatedTimeMs: z.number().optional() +}); + +export type TCurveWeeklyFees = z.infer; + +export type TCurveAllGauges = z.infer; diff --git a/apps/common/types/curves.tsx b/apps/common/types/curves.tsx index d6682b338..30c10f05b 100755 --- a/apps/common/types/curves.tsx +++ b/apps/common/types/curves.tsx @@ -18,32 +18,6 @@ export type TCurveGaugesFromYearn = { block: number, } -export type TCurveGauges = { - gauge_name: string - swap: string - swap_token: string - name: string - gauge: string - type: string - side_chain: boolean - is_killed: boolean - factory: boolean - gauge_controller: { - get_gauge_weight: string - gauge_relative_weight: string - inflation_rate: string - } - gauge_data: { - working_supply: string - inflation_rate: string - } - swap_data: { - virtual_price: string - }, - rewardPerGauge?: string[] - rewardPerTokenPerGauge?: TDict -} - export type TCurveGaugeVersionRewards = { v3: TDict>, } diff --git a/apps/ybribe/components/bribe/GaugeListRow.tsx b/apps/ybribe/components/bribe/GaugeListRow.tsx index aedce2c96..a9a49dc48 100755 --- a/apps/ybribe/components/bribe/GaugeListRow.tsx +++ b/apps/ybribe/components/bribe/GaugeListRow.tsx @@ -14,7 +14,7 @@ import {useBribes} from '@yBribe/contexts/useBribes'; import type {BigNumber} from 'ethers'; import type {ReactElement} from 'react'; import type {TAddress, TDict} from '@yearn-finance/web-lib/types'; -import type {TCurveGauges} from '@common/types/curves'; +import type {TCurveAllGauges} from '@common/schemas/curveSchemas'; function GaugeRowItemWithExtraData({address, value}: {address: TAddress, value: BigNumber}): ReactElement { const {tokens, prices} = useYearn(); @@ -40,7 +40,7 @@ function GaugeRowItemWithExtraData({address, value}: {address: TAddress, value: ); } -function GaugeListRow({currentGauge}: {currentGauge: TCurveGauges}): ReactElement { +function GaugeListRow({currentGauge}: {currentGauge: TCurveAllGauges['data'][string]}): ReactElement { const {isActive} = useWeb3(); const {currentRewards, nextRewards} = useBribes(); const [hasModal, set_hasModal] = useState(false); diff --git a/apps/ybribe/components/claim/GaugeListRow.tsx b/apps/ybribe/components/claim/GaugeListRow.tsx index 9ede7d165..fdb8917e5 100755 --- a/apps/ybribe/components/claim/GaugeListRow.tsx +++ b/apps/ybribe/components/claim/GaugeListRow.tsx @@ -16,7 +16,7 @@ import {claimReward} from '@yBribe/utils/actions/claimReward'; import type {BigNumber} from 'ethers'; import type {ReactElement} from 'react'; import type {TAddress, TDict} from '@yearn-finance/web-lib/types'; -import type {TCurveGauges} from '@common/types/curves'; +import type {TCurveAllGauges} from '@common/schemas/curveSchemas'; function GaugeRowItemWithExtraData({ address, @@ -78,7 +78,7 @@ function GaugeRowItemAPR({address, value}: {address: TAddress, value: BigNumber} } -function GaugeListRow({currentGauge, category}: {currentGauge: TCurveGauges, category: string}): ReactElement { +function GaugeListRow({currentGauge, category}: {currentGauge: TCurveAllGauges['data'][string], category: string}): ReactElement { const {isActive, provider} = useWeb3(); const {currentRewards, nextRewards, claimable, dryRunClaimRewards, refresh} = useBribes(); const [txStatusClaim, set_txStatusClaim] = useState(defaultTxStatus); diff --git a/apps/ybribe/components/rewardFeed/RewardFeedTableRow.tsx b/apps/ybribe/components/rewardFeed/RewardFeedTableRow.tsx index c6950d58b..8d0f06ddf 100755 --- a/apps/ybribe/components/rewardFeed/RewardFeedTableRow.tsx +++ b/apps/ybribe/components/rewardFeed/RewardFeedTableRow.tsx @@ -10,8 +10,8 @@ import {useYearn} from '@common/contexts/useYearn'; import type {BigNumber} from 'ethers'; import type {ReactElement} from 'react'; import type {TAddress} from '@yearn-finance/web-lib/types'; +import type {TCurveAllGauges} from '@common/schemas/curveSchemas'; import type {TYDaemonGaugeRewardsFeed} from '@common/schemas/yDaemonGaugeRewardsFeedSchema'; -import type {TCurveGauges} from '@common/types/curves'; function RewardFeedRowItemWithExtraData({ address, @@ -43,8 +43,8 @@ function RewardFeedRowItemWithExtraData({ function RewardFeedTableRow({currentRewardAdded}: {currentRewardAdded: TYDaemonGaugeRewardsFeed[0]}): ReactElement | null { const {gauges} = useCurve(); - const gaugesObject = useMemo((): {[key: string]: TCurveGauges} => { - const _gaugesObject: {[key: string]: TCurveGauges} = {}; + const gaugesObject = useMemo((): {[key: string]: TCurveAllGauges['data'][string]} => { + const _gaugesObject: {[key: string]: TCurveAllGauges['data'][string]} = {}; for (const gauge of gauges) { _gaugesObject[toAddress(gauge.gauge)] = gauge; } diff --git a/pages/ybribe/index.tsx b/pages/ybribe/index.tsx index 5cbf21db1..09abb62ad 100755 --- a/pages/ybribe/index.tsx +++ b/pages/ybribe/index.tsx @@ -21,7 +21,7 @@ import type {BigNumber} from 'ethers'; import type {NextRouter} from 'next/router'; import type {ReactElement, ReactNode} from 'react'; import type {TAddress} from '@yearn-finance/web-lib/types'; -import type {TCurveGauges} from '@common/types/curves'; +import type {TCurveAllGauges} from '@common/schemas/curveSchemas'; import type {TSortDirection} from '@common/types/types'; function GaugeList(): ReactElement { @@ -43,7 +43,7 @@ function GaugeList(): ReactElement { return bribeValue; }, [prices, tokens]); - const filteredGauges = useMemo((): TCurveGauges[] => { + const filteredGauges = useMemo((): TCurveAllGauges['data'][string][] => { if (category === 'claimable') { return gauges.filter((gauge): boolean => { const currentClaimableMapV3 = Object.values(claimable?.v3?.[toAddress(gauge.gauge)] || {}); @@ -57,7 +57,7 @@ function GaugeList(): ReactElement { }); }, [category, gauges, currentRewards, nextRewards, claimable]); - const searchedGauges = useMemo((): TCurveGauges[] => { + const searchedGauges = useMemo((): TCurveAllGauges['data'][string][] => { const gaugesToSearch = [...filteredGauges]; if (searchValue === '') { @@ -69,7 +69,7 @@ function GaugeList(): ReactElement { }); }, [filteredGauges, searchValue]); - const sortedGauges = useMemo((): TCurveGauges[] => { + const sortedGauges = useMemo((): TCurveAllGauges['data'][string][] => { if (sort.sortBy === 'name') { return searchedGauges.sort((a, b): number => stringSort({a: a.name, b: b.name, sortDirection: sort.sortDirection})); } diff --git a/pages/ybribe/offer-bribe.tsx b/pages/ybribe/offer-bribe.tsx index d41a85060..97798aae3 100755 --- a/pages/ybribe/offer-bribe.tsx +++ b/pages/ybribe/offer-bribe.tsx @@ -20,7 +20,7 @@ import Wrapper from '@yBribe/Wrapper'; import type {BigNumber} from 'ethers'; import type {NextRouter} from 'next/router'; import type {ReactElement, ReactNode} from 'react'; -import type {TCurveGauges} from '@common/types/curves'; +import type {TCurveAllGauges} from '@common/schemas/curveSchemas'; import type {TSortDirection} from '@common/types/types'; function GaugeList(): ReactElement { @@ -45,9 +45,9 @@ function GaugeList(): ReactElement { return bribeValue; }, [prices, tokens]); - const standardGauges = useMemo((): TCurveGauges[] => gauges.filter((gauge): boolean => !gauge.factory), [gauges]); - const factoryGauges = useMemo((): TCurveGauges[] => gauges.filter((gauge): boolean => gauge.factory), [gauges]); - const filteredGauges = useMemo((): TCurveGauges[] => { + const standardGauges = useMemo((): TCurveAllGauges['data'][string][] => gauges.filter((gauge): boolean => !gauge.factory), [gauges]); + const factoryGauges = useMemo((): TCurveAllGauges['data'][string][] => gauges.filter((gauge): boolean => gauge.factory), [gauges]); + const filteredGauges = useMemo((): TCurveAllGauges['data'][string][] => { if (category === 'standard') { return standardGauges; } @@ -57,7 +57,7 @@ function GaugeList(): ReactElement { return gauges; }, [category, gauges, factoryGauges, standardGauges]); - const searchedGauges = useMemo((): TCurveGauges[] => { + const searchedGauges = useMemo((): TCurveAllGauges['data'][string][] => { const gaugesToSearch = [...filteredGauges]; if (searchValue === '') { @@ -69,7 +69,7 @@ function GaugeList(): ReactElement { }); }, [filteredGauges, searchValue]); - const sortedGauges = useMemo((): TCurveGauges[] => { + const sortedGauges = useMemo((): TCurveAllGauges['data'][string][] => { if (sort.sortBy === 'name') { return searchedGauges.sort((a, b): number => stringSort({a: a.name, b: b.name, sortDirection: sort.sortDirection})); } diff --git a/pages/ycrv/holdings.tsx b/pages/ycrv/holdings.tsx index 48f29bcd5..b4d25e6ca 100755 --- a/pages/ycrv/holdings.tsx +++ b/pages/ycrv/holdings.tsx @@ -97,11 +97,17 @@ function Holdings(): ReactElement { }, []); const latestCurveFeesValue = useMemo((): number => { - if (curveWeeklyFees?.weeklyFeesTable?.[0]?.rawFees > 0) { - return curveWeeklyFees.weeklyFeesTable[0].rawFees; + const {weeklyFeesTable} = curveWeeklyFees; + + if (!weeklyFeesTable) { + return 0; + } + + if (weeklyFeesTable[0]?.rawFees > 0) { + return weeklyFeesTable[0].rawFees; } - return curveWeeklyFees?.weeklyFeesTable?.[1]?.rawFees || 0; + return weeklyFeesTable[1]?.rawFees || 0; }, [curveWeeklyFees]); const currentVeCRVAPY = useMemo((): number => { From 19ca85356c6762e0ee6d4f6f5e795ac7c5426a56 Mon Sep 17 00:00:00 2001 From: Karelian Pie Date: Mon, 22 May 2023 14:27:13 +0300 Subject: [PATCH 2/3] fix: Module '@common/types/curves' has no exported member --- apps/ybribe/components/bribe/GaugeBribeModal.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/ybribe/components/bribe/GaugeBribeModal.tsx b/apps/ybribe/components/bribe/GaugeBribeModal.tsx index fa1776e99..28158d3d0 100755 --- a/apps/ybribe/components/bribe/GaugeBribeModal.tsx +++ b/apps/ybribe/components/bribe/GaugeBribeModal.tsx @@ -19,11 +19,11 @@ import {addReward} from '@yBribe/utils/actions/addReward'; import type {BigNumber} from 'ethers'; import type {ChangeEvent, ReactElement} from 'react'; -import type {TCurveGauges} from '@common/types/curves'; +import type {TCurveAllGauges} from '@common/schemas/curveSchemas'; import type {TNormalizedBN} from '@common/types/types'; -function GaugeBribeModal({currentGauge, onClose}: {currentGauge: TCurveGauges, onClose: VoidFunction}): ReactElement { +function GaugeBribeModal({currentGauge, onClose}: {currentGauge: TCurveAllGauges['data'][string], onClose: VoidFunction}): ReactElement { const {chainID, safeChainID} = useChainID(); const {address, provider, isActive, openLoginModal, onSwitchChain} = useWeb3(); const {refresh} = useBribes(); From be02ac48d30a89c86509f31b6bc26a29432aa950 Mon Sep 17 00:00:00 2001 From: Karelian Pie Date: Tue, 23 May 2023 11:05:08 +0300 Subject: [PATCH 3/3] refactor: TCurveAllGauges['data'][string] to TCurveGauge --- apps/common/contexts/useCurve.tsx | 8 +-- apps/common/schemas/curveSchemas.ts | 66 ++++++++++--------- .../components/bribe/GaugeBribeModal.tsx | 4 +- apps/ybribe/components/bribe/GaugeListRow.tsx | 4 +- apps/ybribe/components/claim/GaugeListRow.tsx | 4 +- .../rewardFeed/RewardFeedTableRow.tsx | 6 +- pages/ybribe/index.tsx | 8 +-- pages/ybribe/offer-bribe.tsx | 12 ++-- 8 files changed, 58 insertions(+), 54 deletions(-) diff --git a/apps/common/contexts/useCurve.tsx b/apps/common/contexts/useCurve.tsx index bd999e539..9fb37a62a 100755 --- a/apps/common/contexts/useCurve.tsx +++ b/apps/common/contexts/useCurve.tsx @@ -7,7 +7,7 @@ import {curveAllGaugesSchema, curveWeeklyFeesSchema} from '@common/schemas/curve import type {SWRResponse} from 'swr'; import type {TDict} from '@yearn-finance/web-lib/types'; -import type {TCurveAllGauges, TCurveWeeklyFees} from '@common/schemas/curveSchemas'; +import type {TCurveAllGauges, TCurveGauge, TCurveWeeklyFees} from '@common/schemas/curveSchemas'; import type {TCurveGaugesFromYearn} from '@common/types/curves'; type TCoinGeckoPrices = { @@ -16,7 +16,7 @@ type TCoinGeckoPrices = { export type TCurveContext = { curveWeeklyFees: TCurveWeeklyFees['data']; cgPrices: TDict; - gauges: TCurveAllGauges['data'][string][]; + gauges: TCurveGauge[]; isLoadingGauges: boolean; gaugesFromYearn: TCurveGaugesFromYearn[]; } @@ -61,8 +61,8 @@ export const CurveContextApp = ({children}: { children: React.ReactElement }): R {revalidateOnFocus: false} ) as SWRResponse; - const gauges = useMemo((): TCurveAllGauges['data'][string][] => { - const _gaugesForMainnet: TCurveAllGauges['data'][string][] = []; + const gauges = useMemo((): TCurveGauge[] => { + const _gaugesForMainnet: TCurveGauge[] = []; for (const gauge of Object.values(gaugesWrapper?.data || {})) { if (gauge.is_killed) { continue; diff --git a/apps/common/schemas/curveSchemas.ts b/apps/common/schemas/curveSchemas.ts index b9aabf8bd..7f100ea30 100644 --- a/apps/common/schemas/curveSchemas.ts +++ b/apps/common/schemas/curveSchemas.ts @@ -19,45 +19,49 @@ export const curveWeeklyFeesSchema = z.object({ generatedTimeMs: z.number().optional() }); +const curveGaugeSchema = z.object({ + poolUrls: z.object({ + swap: z.string().array().optional().nullable(), + deposit: z.string().array().optional().nullable(), + withdraw: z.string().array().optional().nullable() + }).optional(), + swap: z.string().optional(), + swap_token: z.string().optional(), + name: z.string(), + shortName: z.string().optional(), + gauge: z.string().optional(), + swap_data: z + .object({virtual_price: z.string().or(z.number().optional())}) + .optional(), + gauge_data: z.object({ + inflation_rate: z.string().optional(), + working_supply: z.string().optional() + }).optional(), + gauge_controller: z.object({ + gauge_relative_weight: z.string().optional(), + get_gauge_weight: z.string().optional(), + inflation_rate: z.string().optional() + }).optional(), + factory: z.boolean(), + side_chain: z.boolean().optional(), + is_killed: z.boolean().optional(), + hasNoCrv: z.boolean().optional(), + type: z.string().optional(), + lpTokenPrice: z.number().nullable().optional(), + rewardPerGauge: z.string().array().optional() +}); + export const curveAllGaugesSchema = z.object({ success: z.boolean().optional(), data: z.record( z.string(), - z.object({ - poolUrls: z.object({ - swap: z.string().array().optional().nullable(), - deposit: z.string().array().optional().nullable(), - withdraw: z.string().array().optional().nullable() - }).optional(), - swap: z.string().optional(), - swap_token: z.string().optional(), - name: z.string(), - shortName: z.string().optional(), - gauge: z.string().optional(), - swap_data: z - .object({virtual_price: z.string().or(z.number().optional())}) - .optional(), - gauge_data: z.object({ - inflation_rate: z.string().optional(), - working_supply: z.string().optional() - }).optional(), - gauge_controller: z.object({ - gauge_relative_weight: z.string().optional(), - get_gauge_weight: z.string().optional(), - inflation_rate: z.string().optional() - }).optional(), - factory: z.boolean(), - side_chain: z.boolean().optional(), - is_killed: z.boolean().optional(), - hasNoCrv: z.boolean().optional(), - type: z.string().optional(), - lpTokenPrice: z.number().nullable().optional(), - rewardPerGauge: z.string().array().optional() - }) + curveGaugeSchema ), generatedTimeMs: z.number().optional() }); export type TCurveWeeklyFees = z.infer; +export type TCurveGauge = z.infer; + export type TCurveAllGauges = z.infer; diff --git a/apps/ybribe/components/bribe/GaugeBribeModal.tsx b/apps/ybribe/components/bribe/GaugeBribeModal.tsx index 28158d3d0..8dc7e5318 100755 --- a/apps/ybribe/components/bribe/GaugeBribeModal.tsx +++ b/apps/ybribe/components/bribe/GaugeBribeModal.tsx @@ -19,11 +19,11 @@ import {addReward} from '@yBribe/utils/actions/addReward'; import type {BigNumber} from 'ethers'; import type {ChangeEvent, ReactElement} from 'react'; -import type {TCurveAllGauges} from '@common/schemas/curveSchemas'; +import type {TCurveGauge} from '@common/schemas/curveSchemas'; import type {TNormalizedBN} from '@common/types/types'; -function GaugeBribeModal({currentGauge, onClose}: {currentGauge: TCurveAllGauges['data'][string], onClose: VoidFunction}): ReactElement { +function GaugeBribeModal({currentGauge, onClose}: {currentGauge: TCurveGauge, onClose: VoidFunction}): ReactElement { const {chainID, safeChainID} = useChainID(); const {address, provider, isActive, openLoginModal, onSwitchChain} = useWeb3(); const {refresh} = useBribes(); diff --git a/apps/ybribe/components/bribe/GaugeListRow.tsx b/apps/ybribe/components/bribe/GaugeListRow.tsx index a9a49dc48..9dcf9afce 100755 --- a/apps/ybribe/components/bribe/GaugeListRow.tsx +++ b/apps/ybribe/components/bribe/GaugeListRow.tsx @@ -14,7 +14,7 @@ import {useBribes} from '@yBribe/contexts/useBribes'; import type {BigNumber} from 'ethers'; import type {ReactElement} from 'react'; import type {TAddress, TDict} from '@yearn-finance/web-lib/types'; -import type {TCurveAllGauges} from '@common/schemas/curveSchemas'; +import type {TCurveGauge} from '@common/schemas/curveSchemas'; function GaugeRowItemWithExtraData({address, value}: {address: TAddress, value: BigNumber}): ReactElement { const {tokens, prices} = useYearn(); @@ -40,7 +40,7 @@ function GaugeRowItemWithExtraData({address, value}: {address: TAddress, value: ); } -function GaugeListRow({currentGauge}: {currentGauge: TCurveAllGauges['data'][string]}): ReactElement { +function GaugeListRow({currentGauge}: {currentGauge: TCurveGauge}): ReactElement { const {isActive} = useWeb3(); const {currentRewards, nextRewards} = useBribes(); const [hasModal, set_hasModal] = useState(false); diff --git a/apps/ybribe/components/claim/GaugeListRow.tsx b/apps/ybribe/components/claim/GaugeListRow.tsx index fdb8917e5..6d0191c95 100755 --- a/apps/ybribe/components/claim/GaugeListRow.tsx +++ b/apps/ybribe/components/claim/GaugeListRow.tsx @@ -16,7 +16,7 @@ import {claimReward} from '@yBribe/utils/actions/claimReward'; import type {BigNumber} from 'ethers'; import type {ReactElement} from 'react'; import type {TAddress, TDict} from '@yearn-finance/web-lib/types'; -import type {TCurveAllGauges} from '@common/schemas/curveSchemas'; +import type {TCurveGauge} from '@common/schemas/curveSchemas'; function GaugeRowItemWithExtraData({ address, @@ -78,7 +78,7 @@ function GaugeRowItemAPR({address, value}: {address: TAddress, value: BigNumber} } -function GaugeListRow({currentGauge, category}: {currentGauge: TCurveAllGauges['data'][string], category: string}): ReactElement { +function GaugeListRow({currentGauge, category}: {currentGauge: TCurveGauge, category: string}): ReactElement { const {isActive, provider} = useWeb3(); const {currentRewards, nextRewards, claimable, dryRunClaimRewards, refresh} = useBribes(); const [txStatusClaim, set_txStatusClaim] = useState(defaultTxStatus); diff --git a/apps/ybribe/components/rewardFeed/RewardFeedTableRow.tsx b/apps/ybribe/components/rewardFeed/RewardFeedTableRow.tsx index 8d0f06ddf..c59b42d52 100755 --- a/apps/ybribe/components/rewardFeed/RewardFeedTableRow.tsx +++ b/apps/ybribe/components/rewardFeed/RewardFeedTableRow.tsx @@ -10,7 +10,7 @@ import {useYearn} from '@common/contexts/useYearn'; import type {BigNumber} from 'ethers'; import type {ReactElement} from 'react'; import type {TAddress} from '@yearn-finance/web-lib/types'; -import type {TCurveAllGauges} from '@common/schemas/curveSchemas'; +import type {TCurveGauge} from '@common/schemas/curveSchemas'; import type {TYDaemonGaugeRewardsFeed} from '@common/schemas/yDaemonGaugeRewardsFeedSchema'; function RewardFeedRowItemWithExtraData({ @@ -43,8 +43,8 @@ function RewardFeedRowItemWithExtraData({ function RewardFeedTableRow({currentRewardAdded}: {currentRewardAdded: TYDaemonGaugeRewardsFeed[0]}): ReactElement | null { const {gauges} = useCurve(); - const gaugesObject = useMemo((): {[key: string]: TCurveAllGauges['data'][string]} => { - const _gaugesObject: {[key: string]: TCurveAllGauges['data'][string]} = {}; + const gaugesObject = useMemo((): {[key: string]: TCurveGauge} => { + const _gaugesObject: {[key: string]: TCurveGauge} = {}; for (const gauge of gauges) { _gaugesObject[toAddress(gauge.gauge)] = gauge; } diff --git a/pages/ybribe/index.tsx b/pages/ybribe/index.tsx index 09abb62ad..6bfed1092 100755 --- a/pages/ybribe/index.tsx +++ b/pages/ybribe/index.tsx @@ -21,7 +21,7 @@ import type {BigNumber} from 'ethers'; import type {NextRouter} from 'next/router'; import type {ReactElement, ReactNode} from 'react'; import type {TAddress} from '@yearn-finance/web-lib/types'; -import type {TCurveAllGauges} from '@common/schemas/curveSchemas'; +import type {TCurveGauge} from '@common/schemas/curveSchemas'; import type {TSortDirection} from '@common/types/types'; function GaugeList(): ReactElement { @@ -43,7 +43,7 @@ function GaugeList(): ReactElement { return bribeValue; }, [prices, tokens]); - const filteredGauges = useMemo((): TCurveAllGauges['data'][string][] => { + const filteredGauges = useMemo((): TCurveGauge[] => { if (category === 'claimable') { return gauges.filter((gauge): boolean => { const currentClaimableMapV3 = Object.values(claimable?.v3?.[toAddress(gauge.gauge)] || {}); @@ -57,7 +57,7 @@ function GaugeList(): ReactElement { }); }, [category, gauges, currentRewards, nextRewards, claimable]); - const searchedGauges = useMemo((): TCurveAllGauges['data'][string][] => { + const searchedGauges = useMemo((): TCurveGauge[] => { const gaugesToSearch = [...filteredGauges]; if (searchValue === '') { @@ -69,7 +69,7 @@ function GaugeList(): ReactElement { }); }, [filteredGauges, searchValue]); - const sortedGauges = useMemo((): TCurveAllGauges['data'][string][] => { + const sortedGauges = useMemo((): TCurveGauge[] => { if (sort.sortBy === 'name') { return searchedGauges.sort((a, b): number => stringSort({a: a.name, b: b.name, sortDirection: sort.sortDirection})); } diff --git a/pages/ybribe/offer-bribe.tsx b/pages/ybribe/offer-bribe.tsx index 97798aae3..d99753ebf 100755 --- a/pages/ybribe/offer-bribe.tsx +++ b/pages/ybribe/offer-bribe.tsx @@ -20,7 +20,7 @@ import Wrapper from '@yBribe/Wrapper'; import type {BigNumber} from 'ethers'; import type {NextRouter} from 'next/router'; import type {ReactElement, ReactNode} from 'react'; -import type {TCurveAllGauges} from '@common/schemas/curveSchemas'; +import type {TCurveGauge} from '@common/schemas/curveSchemas'; import type {TSortDirection} from '@common/types/types'; function GaugeList(): ReactElement { @@ -45,9 +45,9 @@ function GaugeList(): ReactElement { return bribeValue; }, [prices, tokens]); - const standardGauges = useMemo((): TCurveAllGauges['data'][string][] => gauges.filter((gauge): boolean => !gauge.factory), [gauges]); - const factoryGauges = useMemo((): TCurveAllGauges['data'][string][] => gauges.filter((gauge): boolean => gauge.factory), [gauges]); - const filteredGauges = useMemo((): TCurveAllGauges['data'][string][] => { + const standardGauges = useMemo((): TCurveGauge[] => gauges.filter((gauge): boolean => !gauge.factory), [gauges]); + const factoryGauges = useMemo((): TCurveGauge[] => gauges.filter((gauge): boolean => gauge.factory), [gauges]); + const filteredGauges = useMemo((): TCurveGauge[] => { if (category === 'standard') { return standardGauges; } @@ -57,7 +57,7 @@ function GaugeList(): ReactElement { return gauges; }, [category, gauges, factoryGauges, standardGauges]); - const searchedGauges = useMemo((): TCurveAllGauges['data'][string][] => { + const searchedGauges = useMemo((): TCurveGauge[] => { const gaugesToSearch = [...filteredGauges]; if (searchValue === '') { @@ -69,7 +69,7 @@ function GaugeList(): ReactElement { }); }, [filteredGauges, searchValue]); - const sortedGauges = useMemo((): TCurveAllGauges['data'][string][] => { + const sortedGauges = useMemo((): TCurveGauge[] => { if (sort.sortBy === 'name') { return searchedGauges.sort((a, b): number => stringSort({a: a.name, b: b.name, sortDirection: sort.sortDirection})); }