From 451bb2626283672b5cdb07feceb3ac271748cdbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Ribeiro?= Date: Tue, 28 May 2024 22:58:51 -0300 Subject: [PATCH] fix ts issues --- .../(components)/BalancerPriceInformation.tsx | 42 ++----------- .../ChainlinkPriceInformation.tsx | 63 ++++++++++++++----- .../[id]/(components)/PriceInformation.tsx | 26 +++++++- .../(components)/SushiV2PriceInformation.tsx | 10 ++- .../UniswapV2PriceInformation.tsx | 11 +++- .../src/app/new/(components)/AmmForm.tsx | 10 +-- .../src/components/HomeWrapper.tsx | 2 +- .../src/hooks/useDecodedPriceOracleData.ts | 37 +++++++++++ .../src/hooks/useStandaloneAmm/index.ts | 8 +-- apps/cow-amm-deployer/src/lib/schema.ts | 18 +++--- pnpm-lock.yaml | 12 ++-- 11 files changed, 155 insertions(+), 84 deletions(-) create mode 100644 apps/cow-amm-deployer/src/hooks/useDecodedPriceOracleData.ts diff --git a/apps/cow-amm-deployer/src/app/amms/[id]/(components)/BalancerPriceInformation.tsx b/apps/cow-amm-deployer/src/app/amms/[id]/(components)/BalancerPriceInformation.tsx index f74e380b9..296d1e71f 100644 --- a/apps/cow-amm-deployer/src/app/amms/[id]/(components)/BalancerPriceInformation.tsx +++ b/apps/cow-amm-deployer/src/app/amms/[id]/(components)/BalancerPriceInformation.tsx @@ -1,54 +1,22 @@ -import { Address, NetworkFromNetworkChainId } from "@bleu/utils"; +import { NetworkFromNetworkChainId } from "@bleu/utils"; import { useSafeAppsSDK } from "@gnosis.pm/safe-apps-react-sdk"; import { ArrowTopRightIcon } from "@radix-ui/react-icons"; import Link from "next/link"; -import { useEffect, useState } from "react"; -import { decodePriceOracleWithData } from "#/lib/decodePriceOracle"; -import { ICowAmm, PRICE_ORACLES, PriceOracleData } from "#/lib/types"; +import { useDecodedPriceOracleData } from "#/hooks/useDecodedPriceOracleData"; +import { ICowAmm } from "#/lib/types"; import { ChainId } from "#/utils/chainsPublicClients"; -type DecodedPriceOracleData = [PRICE_ORACLES, PriceOracleData]; - -interface UseDecodedPriceOracleWithDataState { - loading: boolean; - decodedData?: DecodedPriceOracleData; -} - -function useDecodedPriceOracleWithData({ - priceOracleAddress, - priceOracleData, - chainId, -}: { - priceOracleAddress: Address; - priceOracleData: Address; - chainId: ChainId; -}): UseDecodedPriceOracleWithDataState { - const [state, setState] = useState({ - loading: true, - }); - - useEffect(() => { - decodePriceOracleWithData({ - address: priceOracleAddress, - priceOracleData, - chainId, - }).then((data) => setState({ loading: false, decodedData: data })); - }, [priceOracleAddress, priceOracleData, chainId]); - - return state; -} - export function BalancerPriceInformation({ cowAmm }: { cowAmm: ICowAmm }) { const { safe } = useSafeAppsSDK(); - const { loading, decodedData } = useDecodedPriceOracleWithData({ + const { isLoading, decodedData } = useDecodedPriceOracleData({ priceOracleAddress: cowAmm.priceOracleAddress, priceOracleData: cowAmm.priceOracleData, chainId: safe.chainId as ChainId, }); - if (loading || !decodedData) { + if (isLoading || !decodedData) { return Loading price information...; } diff --git a/apps/cow-amm-deployer/src/app/amms/[id]/(components)/ChainlinkPriceInformation.tsx b/apps/cow-amm-deployer/src/app/amms/[id]/(components)/ChainlinkPriceInformation.tsx index 399edce14..ad550328f 100644 --- a/apps/cow-amm-deployer/src/app/amms/[id]/(components)/ChainlinkPriceInformation.tsx +++ b/apps/cow-amm-deployer/src/app/amms/[id]/(components)/ChainlinkPriceInformation.tsx @@ -1,36 +1,65 @@ import { useSafeAppsSDK } from "@gnosis.pm/safe-apps-react-sdk"; +import { ResultOf } from "gql.tada"; import Link from "next/link"; import { useEffect, useState } from "react"; import { Address } from "viem"; import { gnosis, sepolia } from "viem/chains"; +import { useDecodedPriceOracleData } from "#/hooks/useDecodedPriceOracleData"; +import { AMM_QUERY } from "#/hooks/useStandaloneAmm"; import { priceFeedAbi } from "#/lib/abis/priceFeed"; -import { ICowAmm } from "#/lib/types"; import { ChainId, publicClientsFromIds } from "#/utils/chainsPublicClients"; -export function ChainlinkPriceInformation({ cowAmm }: { cowAmm: ICowAmm }) { +function usePriceFeedLinks(cowAmm: ResultOf) { const { safe } = useSafeAppsSDK(); const [priceFeed0Link, setPriceFeed0Link] = useState(); const [priceFeed1Link, setPriceFeed1Link] = useState(); - const fetchPriceFeedLinks = async () => { - const [priceFeed0Link, priceFeed1Link] = await Promise.all([ - getPriceFeedLink( - safe.chainId as ChainId, - cowAmm.priceOracleData.chainlinkPriceFeed0, - ), - getPriceFeedLink( - safe.chainId as ChainId, - cowAmm.priceOracleData.chainlinkPriceFeed1, - ), - ]); - setPriceFeed0Link(priceFeed0Link); - setPriceFeed1Link(priceFeed1Link); - }; + if (!cowAmm || !cowAmm.constantProductData) + return { error: "No price oracle data" }; + + const { isLoading, decodedData } = useDecodedPriceOracleData({ + priceOracleAddress: cowAmm.constantProductData.priceOracle as Address, + priceOracleData: cowAmm.constantProductData.priceOracleData as Address, + chainId: safe.chainId as ChainId, + }); + + if (isLoading || !decodedData) { + return { isLoading }; + } useEffect(() => { + const fetchPriceFeedLinks = async () => { + const [priceFeed0Link, priceFeed1Link] = await Promise.all([ + getPriceFeedLink( + safe.chainId as ChainId, + decodedData[1].chainlinkPriceFeed0, + ), + getPriceFeedLink( + safe.chainId as ChainId, + decodedData[1].chainlinkPriceFeed1, + ), + ]); + setPriceFeed0Link(priceFeed0Link); + setPriceFeed1Link(priceFeed1Link); + }; + fetchPriceFeedLinks(); - }, []); + }, [cowAmm]); + + return { isLoading, priceFeed0Link, priceFeed1Link }; +} + +export function ChainlinkPriceInformation({ + cowAmm, +}: { + cowAmm: ResultOf; +}) { + const { isLoading, priceFeed0Link, priceFeed1Link } = + usePriceFeedLinks(cowAmm); + + if (isLoading) return Loading price information...; + return (
Using price information from Chainlink diff --git a/apps/cow-amm-deployer/src/app/amms/[id]/(components)/PriceInformation.tsx b/apps/cow-amm-deployer/src/app/amms/[id]/(components)/PriceInformation.tsx index 2dbf5f236..6828c0ea4 100644 --- a/apps/cow-amm-deployer/src/app/amms/[id]/(components)/PriceInformation.tsx +++ b/apps/cow-amm-deployer/src/app/amms/[id]/(components)/PriceInformation.tsx @@ -1,4 +1,11 @@ -import { ICowAmm, PRICE_ORACLES } from "#/lib/types"; +import { Address } from "@bleu/utils"; +import { useSafeAppsSDK } from "@gnosis.pm/safe-apps-react-sdk"; +import { ResultOf } from "gql.tada"; + +import { useDecodedPriceOracleData } from "#/hooks/useDecodedPriceOracleData"; +import { AMM_QUERY } from "#/hooks/useStandaloneAmm"; +import { PRICE_ORACLES } from "#/lib/types"; +import { ChainId } from "#/utils/chainsPublicClients"; import { BalancerPriceInformation } from "./BalancerPriceInformation"; import { ChainlinkPriceInformation } from "./ChainlinkPriceInformation"; @@ -6,8 +13,21 @@ import { CustomPriceInformation } from "./CustomPriceInformation"; import { SushiV2PriceInformation } from "./SushiV2PriceInformation"; import { UniswapV2PriceInformation } from "./UniswapV2PriceInformation"; -export function PriceInformation({ cowAmm }: { cowAmm: ICowAmm }) { - switch (cowAmm.priceOracle) { +export function PriceInformation({ + cowAmm, +}: { + cowAmm: ResultOf; +}) { + const { safe } = useSafeAppsSDK(); + const { isLoading, decodedData } = useDecodedPriceOracleData({ + priceOracleAddress: cowAmm.constantProductData?.priceOracle as Address, + priceOracleData: cowAmm.constantProductData?.priceOracleData as Address, + chainId: safe.chainId as ChainId, + }); + + if (isLoading || !decodedData) return <>Loading...; + + switch (decodedData[0]) { case PRICE_ORACLES.UNI: return ; case PRICE_ORACLES.BALANCER: diff --git a/apps/cow-amm-deployer/src/app/amms/[id]/(components)/SushiV2PriceInformation.tsx b/apps/cow-amm-deployer/src/app/amms/[id]/(components)/SushiV2PriceInformation.tsx index e42744851..a231908d9 100644 --- a/apps/cow-amm-deployer/src/app/amms/[id]/(components)/SushiV2PriceInformation.tsx +++ b/apps/cow-amm-deployer/src/app/amms/[id]/(components)/SushiV2PriceInformation.tsx @@ -2,15 +2,23 @@ import { useSafeAppsSDK } from "@gnosis.pm/safe-apps-react-sdk"; import { ArrowTopRightIcon } from "@radix-ui/react-icons"; import Link from "next/link"; +import { useDecodedPriceOracleData } from "#/hooks/useDecodedPriceOracleData"; import { ICowAmm } from "#/lib/types"; import { ChainId } from "#/utils/chainsPublicClients"; export function SushiV2PriceInformation({ cowAmm }: { cowAmm: ICowAmm }) { const { safe } = useSafeAppsSDK(); + const { isLoading, decodedData } = useDecodedPriceOracleData({ + priceOracleAddress: cowAmm.priceOracleAddress, + priceOracleData: cowAmm.priceOracleData, + chainId: safe.chainId as ChainId, + }); + + if (isLoading || !decodedData) return <>Loading...; const priceOracleLink = getSushiV2Pair( safe.chainId as ChainId, - cowAmm.priceOracleData?.sushiSwapPairAddress, + decodedData[1].sushiSwapPairAddress, ); return ( diff --git a/apps/cow-amm-deployer/src/app/amms/[id]/(components)/UniswapV2PriceInformation.tsx b/apps/cow-amm-deployer/src/app/amms/[id]/(components)/UniswapV2PriceInformation.tsx index 00f93b0c1..b91aae5de 100644 --- a/apps/cow-amm-deployer/src/app/amms/[id]/(components)/UniswapV2PriceInformation.tsx +++ b/apps/cow-amm-deployer/src/app/amms/[id]/(components)/UniswapV2PriceInformation.tsx @@ -4,15 +4,24 @@ import { ArrowTopRightIcon } from "@radix-ui/react-icons"; import Link from "next/link"; import { gnosis } from "viem/chains"; +import { useDecodedPriceOracleData } from "#/hooks/useDecodedPriceOracleData"; import { ICowAmm } from "#/lib/types"; import { ChainId } from "#/utils/chainsPublicClients"; export function UniswapV2PriceInformation({ cowAmm }: { cowAmm: ICowAmm }) { const { safe } = useSafeAppsSDK(); + const { isLoading, decodedData } = useDecodedPriceOracleData({ + priceOracleAddress: cowAmm.priceOracleAddress, + priceOracleData: cowAmm.priceOracleData, + chainId: safe.chainId as ChainId, + }); + + if (isLoading || !decodedData) return <>Loading...; + const priceOracleLink = getUniV2PairUrl( safe.chainId as ChainId, - cowAmm.priceOracleData?.uniswapV2PairAddress, + decodedData[1].uniswapV2PairAddress, ); return ( diff --git a/apps/cow-amm-deployer/src/app/new/(components)/AmmForm.tsx b/apps/cow-amm-deployer/src/app/new/(components)/AmmForm.tsx index 14a9d0d55..5323b206b 100644 --- a/apps/cow-amm-deployer/src/app/new/(components)/AmmForm.tsx +++ b/apps/cow-amm-deployer/src/app/new/(components)/AmmForm.tsx @@ -49,9 +49,9 @@ const getNewMinTradeToken0 = async (newToken0: IToken, chainId: ChainId) => { Number( formatUnits( parseUnits(String(amount), newToken0.decimals), - newToken0.decimals - ) - ) + newToken0.decimals, + ), + ), ) .catch(() => 0); }; @@ -126,7 +126,7 @@ export function AmmForm({ }); setValue( "minTradedToken0", - await getNewMinTradeToken0(token, chainId as ChainId) + await getNewMinTradeToken0(token, chainId as ChainId), ); }} selectedToken={(formData?.token0 as IToken) ?? undefined} @@ -189,7 +189,7 @@ export function AmmForm({ Advanced Options diff --git a/apps/cow-amm-deployer/src/components/HomeWrapper.tsx b/apps/cow-amm-deployer/src/components/HomeWrapper.tsx index f05379e56..6cec0c7bd 100644 --- a/apps/cow-amm-deployer/src/components/HomeWrapper.tsx +++ b/apps/cow-amm-deployer/src/components/HomeWrapper.tsx @@ -53,7 +53,7 @@ export function HomeWrapper({ goToSafe = false }: { goToSafe?: boolean }) { const userId = `${safe.safeAddress}-${safe.chainId}`; const { data, isLoading } = useSWR(CREATED_AMMS_FOR_USER_QUERY, (query) => - request(NEXT_PUBLIC_API_URL, query, { userId }) + request(NEXT_PUBLIC_API_URL, query, { userId }), ); if (isLoading || !data) return <>Loading...; diff --git a/apps/cow-amm-deployer/src/hooks/useDecodedPriceOracleData.ts b/apps/cow-amm-deployer/src/hooks/useDecodedPriceOracleData.ts new file mode 100644 index 000000000..a80a18016 --- /dev/null +++ b/apps/cow-amm-deployer/src/hooks/useDecodedPriceOracleData.ts @@ -0,0 +1,37 @@ +import { Address } from "@bleu/utils"; +import { useEffect, useState } from "react"; + +import { decodePriceOracleWithData } from "#/lib/decodePriceOracle"; +import { PRICE_ORACLES, PriceOracleData } from "#/lib/types"; +import { ChainId } from "#/utils/chainsPublicClients"; + +type DecodedPriceOracleData = [PRICE_ORACLES, PriceOracleData]; + +interface UseDecodedPriceOracleWithDataState { + isLoading: boolean; + decodedData?: DecodedPriceOracleData; +} + +export function useDecodedPriceOracleData({ + priceOracleAddress, + priceOracleData, + chainId, +}: { + priceOracleAddress: Address; + priceOracleData: Address; + chainId: ChainId; +}): UseDecodedPriceOracleWithDataState { + const [state, setState] = useState({ + isLoading: true, + }); + + useEffect(() => { + decodePriceOracleWithData({ + address: priceOracleAddress, + priceOracleData, + chainId, + }).then((data) => setState({ isLoading: false, decodedData: data })); + }, [priceOracleAddress, priceOracleData, chainId]); + + return state; +} diff --git a/apps/cow-amm-deployer/src/hooks/useStandaloneAmm/index.ts b/apps/cow-amm-deployer/src/hooks/useStandaloneAmm/index.ts index 4b9f2b9ad..cab26deed 100644 --- a/apps/cow-amm-deployer/src/hooks/useStandaloneAmm/index.ts +++ b/apps/cow-amm-deployer/src/hooks/useStandaloneAmm/index.ts @@ -10,7 +10,7 @@ import { ChainId } from "#/utils/chainsPublicClients"; import { getBalancesFromContract } from "./getBalancesFromContract"; import { getTokensExternalPrices } from "./getTokesFrom"; -const AMM_QUERY = graphql(` +export const AMM_QUERY = graphql(` query fetchAmmData($ammId: String!) { constantProductData(id: $ammId) { token0 { @@ -41,7 +41,7 @@ export function useStandaloneAMM(ammId: Address) { error: subgraphError, isLoading: isSubgraphLoading, } = useSWR(ammId, (ammId) => - request(NEXT_PUBLIC_API_URL, AMM_QUERY, { ammId }) + request(NEXT_PUBLIC_API_URL, AMM_QUERY, { ammId }), ); const token0SubgraphData = subgraphData?.constantProductData?.token0; @@ -62,7 +62,7 @@ export function useStandaloneAMM(ammId: Address) { token0SubgraphData as IToken, token1SubgraphData as IToken, ], - getBalancesFromContract + getBalancesFromContract, ); const { @@ -76,7 +76,7 @@ export function useStandaloneAMM(ammId: Address) { token0SubgraphData as IToken, token1SubgraphData as IToken, ], - getTokensExternalPrices + getTokensExternalPrices, ); if ( diff --git a/apps/cow-amm-deployer/src/lib/schema.ts b/apps/cow-amm-deployer/src/lib/schema.ts index d8a38c608..1f998827c 100644 --- a/apps/cow-amm-deployer/src/lib/schema.ts +++ b/apps/cow-amm-deployer/src/lib/schema.ts @@ -69,7 +69,7 @@ export const ammFormSchema = z { message: "Balancer Pool ID is required", path: ["balancerPoolId"], - } + }, ) .refine( // validate if uniswap v2 pool address is required @@ -83,7 +83,7 @@ export const ammFormSchema = z { message: "Uniswap V2 Pool Address is required", path: ["uniswapV2Pair"], - } + }, ) .refine( // validate if sushi v2 pool address is required @@ -97,7 +97,7 @@ export const ammFormSchema = z { message: "Sushi V2 Pool Address is required", path: ["sushiV2Pair"], - } + }, ) .refine( // validate if custom price oracle data is required @@ -111,7 +111,7 @@ export const ammFormSchema = z { message: "Custom price oracle data is required", path: ["customPriceOracleData"], - } + }, ) .refine( // validate if chainlink oracle data is required @@ -129,7 +129,7 @@ export const ammFormSchema = z { message: "Chainlink price feed addresses are required", path: ["chainlinkPriceFeed0", "chainlinkPriceFeed1"], - } + }, ) .refine( // validate if tokens are different @@ -143,7 +143,7 @@ export const ammFormSchema = z { message: "Tokens must be different", path: ["token0"], - } + }, ) // @ts-ignore .superRefine(async (data, ctx) => { @@ -179,7 +179,7 @@ export const ammFormSchema = z code: z.ZodIssueCode.custom, message: `Insufficient balance`, path: [x], - }) + }), ); return !path.length; }) @@ -209,10 +209,10 @@ export const ammFormSchema = z // validate if price oracle is working try { const priceOracleData = encodePriceOracleData( - data as IEncodePriceOracleData + data as IEncodePriceOracleData, ); const priceOracleAddress = getPriceOracleAddress( - data as IGetPriceOracleAddress + data as IGetPriceOracleAddress, ); const publicClient = publicClientsFromIds[data.chainId as ChainId]; await publicClient.readContract({ diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 88337b445..3233dc060 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -16321,7 +16321,7 @@ snapshots: '@radix-ui/react-dismissable-layer@1.0.5(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@babel/runtime': 7.24.5 + '@babel/runtime': 7.23.6 '@radix-ui/primitive': 1.0.1 '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.3.3)(react@18.3.1) '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -16363,7 +16363,7 @@ snapshots: '@radix-ui/react-focus-guards@1.0.1(@types/react@18.3.3)(react@18.3.1)': dependencies: - '@babel/runtime': 7.24.5 + '@babel/runtime': 7.23.6 react: 18.3.1 optionalDependencies: '@types/react': 18.3.3 @@ -16403,7 +16403,7 @@ snapshots: '@radix-ui/react-focus-scope@1.0.4(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@babel/runtime': 7.24.5 + '@babel/runtime': 7.23.6 '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.3.3)(react@18.3.1) '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.3.3)(react@18.3.1) @@ -16634,7 +16634,7 @@ snapshots: '@radix-ui/react-popper@1.1.3(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@babel/runtime': 7.24.5 + '@babel/runtime': 7.23.6 '@floating-ui/react-dom': 2.0.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-arrow': 1.0.3(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.3.3)(react@18.3.1) @@ -16680,7 +16680,7 @@ snapshots: '@radix-ui/react-portal@1.0.4(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@babel/runtime': 7.24.5 + '@babel/runtime': 7.23.6 '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -17300,7 +17300,7 @@ snapshots: '@radix-ui/react-visually-hidden@1.0.3(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@babel/runtime': 7.24.5 + '@babel/runtime': 7.23.6 '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1)