From f7a579d043aa1bbf5891dbd98ef45831f60664d6 Mon Sep 17 00:00:00 2001 From: cryptickoan Date: Fri, 22 Apr 2022 09:50:52 -0600 Subject: [PATCH 1/2] WIP --- .../Fuse/FusePoolsPage/FusePoolsPage.tsx | 113 +++++++++++++++++- .../pages/Fuse/FusePoolsPage/PoolList.tsx | 3 + src/hooks/fuse/useFusePools.ts | 108 ++++++++++++++--- 3 files changed, 201 insertions(+), 23 deletions(-) diff --git a/src/components/pages/Fuse/FusePoolsPage/FusePoolsPage.tsx b/src/components/pages/Fuse/FusePoolsPage/FusePoolsPage.tsx index 2e98c912..10badc19 100644 --- a/src/components/pages/Fuse/FusePoolsPage/FusePoolsPage.tsx +++ b/src/components/pages/Fuse/FusePoolsPage/FusePoolsPage.tsx @@ -1,4 +1,4 @@ -import { memo } from "react"; +import { memo, useEffect, useState } from "react"; // Components import DashboardBox from "components/shared/DashboardBox"; @@ -6,18 +6,26 @@ import FuseStatsBar from "../FuseStatsBar"; import FuseTabBar from "../FuseTabBar"; // Hooks -import { useIsSmallScreen } from "hooks/useIsSmallScreen"; +import { useIsSmallScreen } from "hooks/useIsSmallScreen" +import { Fuse } from "../../../../esm/index"; // Utils import { Column } from "lib/chakraUtils"; import { PoolList } from "./PoolList"; import { useFilter } from "hooks/useFilter"; -import { useFusePools } from "hooks/fuse/useFusePools"; +import { createMergedPools, MergedPool, fetchPoolsManual, LensFusePool, LensFusePoolData, useFusePools, useFusePoolsList, useInifinitePools } from "hooks/fuse/useFusePools"; +import { useRari } from "context/RariContext"; +import { useInfiniteQuery } from "react-query"; +import { BigNumber } from "ethers"; +import { providers } from "@0xsequence/multicall"; +import { fetchCurrentETHPrice } from "utils/coingecko"; +import { ChainID } from "constants/networks"; +import { Spinner } from "@chakra-ui/react"; const FusePoolsPage = memo(() => { const isMobile = useIsSmallScreen(); const filter = useFilter(); -const filteredPools = useFusePools(filter); + return ( <> @@ -35,7 +43,7 @@ const filteredPools = useFusePools(filter); - + {filter === "unverified-pools" ? : } @@ -43,3 +51,98 @@ const filteredPools = useFusePools(filter); }); export default FusePoolsPage; + +const VerifiedPools = ({filter}: {filter: string | null}) => { + const filteredPools = useFusePools(filter); + return ( + + ) +} + +const UnverifiedPools = ({filter}: {filter: string}) => { + const [poolListLength, setPoolListLength] = useState(0) + const [poolBatch, setPoolBatch] = useState([0,20]) + const [poolSlice, setPoolSlice] = useState([[]]) + + const { fuse, address, chainId } = useRari() + const poolList: [][] = useFusePoolsList(fuse, address) + + useEffect(() => { + if(poolList) { + setPoolListLength(poolList[1].length) + setPoolSlice([poolList[0].slice(...poolBatch),poolList[1].slice(...poolBatch)]) + } + }, [poolList]) + + + const fetchPoolsManual = async ({pageParam = poolSlice}: any) => { + if (pageParam.length === 1) return + console.log({pageParam}) + // Extract data from Directory call + let ids: string[] = (poolSlice[0] ?? []).map((bn: BigNumber) => + bn.toString() + ); + let fusePools: LensFusePool[] = poolSlice[1]; + let comptrollers = fusePools.map(({ comptroller }) => comptroller); + + // Query lens.getPoolSummary + let fusePoolsData: LensFusePoolData[] = await Promise.all( + comptrollers.map(async (comptroller) => { + const _data = await fuse.contracts.FusePoolLens.callStatic.getPoolSummary( + comptroller + ); + const data: LensFusePoolData = { + totalSupply: _data[0], + totalBorrow: _data[1], + underlyingTokens: _data[2], + underlyingSymbols: _data[3], + whitelistedAdmin: _data[4], + }; + return data; + }) + ).catch((err) => { + console.error("Error querying poolSummaries", err); + return []; + }); + + const multicallProvider = new providers.MulticallProvider(fuse.contracts.FusePoolLens.provider) + const multicallFuse = new Fuse(multicallProvider, chainId as any) + const poolRewardTokens = await Promise.all(fusePools.map((pool) => { + return multicallFuse.contracts.FusePoolLensSecondary.callStatic.getRewardSpeedsByPool( + pool.comptroller + ).then((rewards) => { + //reward token list + return rewards[2] + }) + })) + + const fetchETHPrice = fetchCurrentETHPrice(); + const merged: MergedPool[] = await createMergedPools(ids, fusePools, fusePoolsData, poolRewardTokens, fetchETHPrice); + console.log({merged}) + return merged + }; + + const { + isLoading, + isError, + error, + data, + fetchNextPage, + isFetching, + isFetchingNextPage + //@ts-ignore + } = useInfiniteQuery(['colors'], fetchPoolsManual, { + enabled: poolList && poolSlice.length > 1, + getNextPageParam: (lastPage, pages) => { + return poolSlice + } + }) + + console.log({data}) + if (!data?.pages[0] || data?.pages[0].length < 1) return + + return ( + + ) +} + diff --git a/src/components/pages/Fuse/FusePoolsPage/PoolList.tsx b/src/components/pages/Fuse/FusePoolsPage/PoolList.tsx index 3651abc0..e9063ff7 100644 --- a/src/components/pages/Fuse/FusePoolsPage/PoolList.tsx +++ b/src/components/pages/Fuse/FusePoolsPage/PoolList.tsx @@ -13,6 +13,8 @@ import { filterPoolName } from "utils/fetchFusePoolData"; import { useState } from "react"; export const PoolList = ({ pools }: { pools: MergedPool[] | null }) => { + + console.log({pools}) const { t } = useTranslation(); const isMobile = useIsMobile(); @@ -66,6 +68,7 @@ export const PoolList = ({ pools }: { pools: MergedPool[] | null }) => { h="100%" > {!!pools ? !!pools.length ? pools.map((pool, index) => { + console.log({pool, index, tokens: pool.rewardTokens}) return ( { - // Query Directory - let fusePoolsDirectoryResult = - await fuse.contracts.FusePoolDirectory.callStatic.getPublicPoolsByVerification( - verification, - { from: address } - ); - // Extract data from Directory call let ids: string[] = (fusePoolsDirectoryResult[0] ?? []).map((bn: BigNumber) => bn.toString() @@ -136,6 +131,17 @@ export const fetchPoolsManual = async ({ return await createMergedPools(ids, fusePools, fusePoolsData, poolRewardTokens, fetchETHPrice); }; +export const fetchPoolsList = async ( + fuse: Fuse, + address: string, +) => { + const answer = await fuse.contracts.FusePoolDirectory.connect(fuse.contracts.FusePoolLens.provider).callStatic.getPublicPoolsByVerification( + false, + { from: address } + ) + return answer +} + export const fetchPools = async ({ fuse, address, @@ -209,7 +215,7 @@ export const fetchPools = async ({ return await createMergedPools(ids, fusePools, fusePoolsData, poolRewardTokens, fetchETHPrice); }; -const createMergedPools = async ( +export const createMergedPools = async ( ids: string[], fusePools: LensFusePool[], fusePoolsData: LensFusePoolData[], @@ -252,14 +258,6 @@ export const useFusePools = (filter: string | null): MergedPool[] | null => { const { data: pools } = useQuery( `${address} fusePoolList ${filter ?? ""} chainId: ${chainId}`, async () => { - if (chainId === ChainID.ARBITRUM && filter === "unverified-pools") { - return await fetchPoolsManual({ - fuse, - address, - verification: false, - chainId, - }); - } return await fetchPools({ fuse, address, filter, chainId }); } ); @@ -299,3 +297,77 @@ export const useFusePools = (filter: string | null): MergedPool[] | null => { return filteredPools; }; + +export const useFusePoolsList = ( + fuse: Fuse, + address: string, +) => { + const { data: pools } = useQuery('Fuse unverified pools list', async () => await fetchPoolsList(fuse, address)) + + return pools +} + +export const useInifinitePools = (fuse: Fuse, chainId: number, address: string) => { + + const fetchPoolsManual = async ({ + fusePoolsDirectoryResult + }: { + fusePoolsDirectoryResult: any + }) => { + // Extract data from Directory call + let ids: string[] = (fusePoolsDirectoryResult[0] ?? []).map((bn: BigNumber) => + bn.toString() + ); + let fusePools: LensFusePool[] = fusePoolsDirectoryResult[1]; + let comptrollers = fusePools.map(({ comptroller }) => comptroller); + + // Query lens.getPoolSummary + let fusePoolsData: LensFusePoolData[] = await Promise.all( + comptrollers.map(async (comptroller) => { + const _data = await fuse.contracts.FusePoolLens.callStatic.getPoolSummary( + comptroller + ); + const data: LensFusePoolData = { + totalSupply: _data[0], + totalBorrow: _data[1], + underlyingTokens: _data[2], + underlyingSymbols: _data[3], + whitelistedAdmin: _data[4], + }; + return data; + }) + ).catch((err) => { + console.error("Error querying poolSummaries", err); + return []; + }); + + const multicallProvider = new providers.MulticallProvider(fuse.provider) + const multicallFuse = new Fuse(multicallProvider, chainId) + const poolRewardTokens = await Promise.all(fusePools.map((pool) => { + return multicallFuse.contracts.FusePoolLensSecondary.callStatic.getRewardSpeedsByPool( + pool.comptroller + ).then((rewards) => { + //reward token list + return rewards[2] + }) + })) + + const fetchETHPrice = fetchCurrentETHPrice(); + return await createMergedPools(ids, fusePools, fusePoolsData, poolRewardTokens, fetchETHPrice); + }; + + const { + isLoading, + isError, + error, + data, + fetchNextPage, + isFetching, + isFetchingNextPage + //@ts-ignore + } = useInfiniteQuery(['colors'], fetchPoolsManual, { + getNextPageParam: (lastPage: any, pages: any) => { + return {} + } + }) +} From 8186ea80ce186e4e61e06d5100ff285da786cc09 Mon Sep 17 00:00:00 2001 From: cryptickoan Date: Fri, 22 Apr 2022 11:27:11 -0600 Subject: [PATCH 2/2] :fire: --- .../Fuse/FusePoolsPage/FusePoolsPage.tsx | 59 +++++++++++++++---- .../pages/Fuse/FusePoolsPage/PoolList.tsx | 7 +-- 2 files changed, 52 insertions(+), 14 deletions(-) diff --git a/src/components/pages/Fuse/FusePoolsPage/FusePoolsPage.tsx b/src/components/pages/Fuse/FusePoolsPage/FusePoolsPage.tsx index 10badc19..89039206 100644 --- a/src/components/pages/Fuse/FusePoolsPage/FusePoolsPage.tsx +++ b/src/components/pages/Fuse/FusePoolsPage/FusePoolsPage.tsx @@ -10,7 +10,7 @@ import { useIsSmallScreen } from "hooks/useIsSmallScreen" import { Fuse } from "../../../../esm/index"; // Utils -import { Column } from "lib/chakraUtils"; +import { Center, Column, Row } from "lib/chakraUtils"; import { PoolList } from "./PoolList"; import { useFilter } from "hooks/useFilter"; import { createMergedPools, MergedPool, fetchPoolsManual, LensFusePool, LensFusePoolData, useFusePools, useFusePoolsList, useInifinitePools } from "hooks/fuse/useFusePools"; @@ -21,6 +21,8 @@ import { providers } from "@0xsequence/multicall"; import { fetchCurrentETHPrice } from "utils/coingecko"; import { ChainID } from "constants/networks"; import { Spinner } from "@chakra-ui/react"; +import { ModalDivider } from "components/shared/Modal"; +import { Text } from "rari-components"; const FusePoolsPage = memo(() => { const isMobile = useIsSmallScreen(); @@ -77,13 +79,12 @@ const UnverifiedPools = ({filter}: {filter: string}) => { const fetchPoolsManual = async ({pageParam = poolSlice}: any) => { if (pageParam.length === 1) return - console.log({pageParam}) // Extract data from Directory call - let ids: string[] = (poolSlice[0] ?? []).map((bn: BigNumber) => + let ids: string[] = (pageParam[0] ?? []).map((bn: BigNumber) => bn.toString() ); - let fusePools: LensFusePool[] = poolSlice[1]; - let comptrollers = fusePools.map(({ comptroller }) => comptroller); + let fusePools: LensFusePool[] = pageParam[1]; + let comptrollers = fusePools.map((pool: any) => pool[2]); // Query lens.getPoolSummary let fusePoolsData: LensFusePoolData[] = await Promise.all( @@ -118,7 +119,6 @@ const UnverifiedPools = ({filter}: {filter: string}) => { const fetchETHPrice = fetchCurrentETHPrice(); const merged: MergedPool[] = await createMergedPools(ids, fusePools, fusePoolsData, poolRewardTokens, fetchETHPrice); - console.log({merged}) return merged }; @@ -133,16 +133,55 @@ const UnverifiedPools = ({filter}: {filter: string}) => { //@ts-ignore } = useInfiniteQuery(['colors'], fetchPoolsManual, { enabled: poolList && poolSlice.length > 1, + refetchOnWindowFocus: false, getNextPageParam: (lastPage, pages) => { return poolSlice } }) - console.log({data}) - if (!data?.pages[0] || data?.pages[0].length < 1) return - + + const handleInifiniteScrollClick = () => { + setPoolBatch([poolBatch[0] + 20, poolBatch[1] + 20]) + setPoolSlice([ + poolList[0].slice(poolBatch[0] + 20, poolBatch[1] + 20), + poolList[1].slice(poolBatch[0] + 20, poolBatch[1] + 20) + ]) + fetchNextPage({ + pageParam: [ + poolList[0].slice(poolBatch[0] + 20, poolBatch[1] + 20), + poolList[1].slice(poolBatch[0] + 20, poolBatch[1] + 20) + ] + }) + } + return ( - + <> + { data?.pages.map((page, index) => 0}/>)} + + { poolBatch[1] < poolListLength ? + <> + + + + Load more... + + + + + : null + } + ) } diff --git a/src/components/pages/Fuse/FusePoolsPage/PoolList.tsx b/src/components/pages/Fuse/FusePoolsPage/PoolList.tsx index e9063ff7..abbb171d 100644 --- a/src/components/pages/Fuse/FusePoolsPage/PoolList.tsx +++ b/src/components/pages/Fuse/FusePoolsPage/PoolList.tsx @@ -12,9 +12,7 @@ import { Column, Row, useIsMobile } from "lib/chakraUtils"; import { filterPoolName } from "utils/fetchFusePoolData"; import { useState } from "react"; -export const PoolList = ({ pools }: { pools: MergedPool[] | null }) => { - - console.log({pools}) +export const PoolList = ({ pools, infiniteScroll }: { pools: MergedPool[] | null | undefined, infiniteScroll?: boolean }) => { const { t } = useTranslation(); const isMobile = useIsMobile(); @@ -25,6 +23,7 @@ export const PoolList = ({ pools }: { pools: MergedPool[] | null }) => { crossAxisAlignment="flex-start" expand > + {infiniteScroll ? null : { )} + } @@ -68,7 +68,6 @@ export const PoolList = ({ pools }: { pools: MergedPool[] | null }) => { h="100%" > {!!pools ? !!pools.length ? pools.map((pool, index) => { - console.log({pool, index, tokens: pool.rewardTokens}) return (