From 507424e4b4c72fa5f26b53fc9b20c4b45a0f95f1 Mon Sep 17 00:00:00 2001 From: Matthew Pereira Date: Tue, 10 Dec 2024 15:27:57 -0800 Subject: [PATCH] add rate provider confirmation modal --- .../nextjs/app/v3/_components/ChooseToken.tsx | 122 +++++++++++++++++- .../nextjs/hooks/v3/usePoolCreationStore.ts | 2 +- packages/nextjs/hooks/v3/useUserDataStore.ts | 2 +- 3 files changed, 121 insertions(+), 5 deletions(-) diff --git a/packages/nextjs/app/v3/_components/ChooseToken.tsx b/packages/nextjs/app/v3/_components/ChooseToken.tsx index cccabf2..5f3532c 100644 --- a/packages/nextjs/app/v3/_components/ChooseToken.tsx +++ b/packages/nextjs/app/v3/_components/ChooseToken.tsx @@ -2,14 +2,24 @@ import React, { Dispatch, SetStateAction, useEffect, useRef, useState } from "re import { PoolType, TokenType, erc20Abi } from "@balancer/sdk"; import { zeroAddress } from "viem"; import { useAccount, useReadContract } from "wagmi"; -import { Cog6ToothIcon, LockClosedIcon, LockOpenIcon, TrashIcon } from "@heroicons/react/24/outline"; +import { + ArrowTopRightOnSquareIcon, + Cog6ToothIcon, + LockClosedIcon, + LockOpenIcon, + TrashIcon, +} from "@heroicons/react/24/outline"; import { Alert, Checkbox, TextField, TokenField } from "~~/components/common"; +import { useTargetNetwork } from "~~/hooks/scaffold-eth"; import { type Token, useFetchTokenList } from "~~/hooks/token"; import { useBoostableWhitelist, usePoolCreationStore, useUserDataStore, useValidateRateProvider } from "~~/hooks/v3"; import { bgBeigeGradient, bgPrimaryGradient } from "~~/utils"; +import { abbreviateAddress } from "~~/utils/helpers"; +import { getBlockExplorerAddressLink } from "~~/utils/scaffold-eth/"; export function ChooseToken({ index }: { index: number }) { const [showBoostOpportunityModal, setShowBoostOpportunityModal] = useState(false); + const [showRateProviderModal, setShowRateProviderModal] = useState(false); const { updateUserData, userTokenBalances } = useUserDataStore(); const { tokenConfigs, poolType, updatePool, updateTokenConfig } = usePoolCreationStore(); @@ -47,14 +57,18 @@ export function ChooseToken({ index }: { index: number }) { }, [userTokenBalance, address]); const handleTokenSelection = (tokenInfo: Token) => { - // TODO more testing for rate provider UX const tokenType = tokenInfo.priceRateProviderData ? TokenType.TOKEN_WITH_RATE : TokenType.STANDARD; const rateProvider = tokenInfo.priceRateProviderData ? tokenInfo.priceRateProviderData.address : zeroAddress; + // Force user to confirm if Balancer API has rate provider data for selected token + if (rateProvider !== zeroAddress) { + setShowRateProviderModal(true); + } + updateTokenConfig(index, { address: tokenInfo.address, tokenType, - rateProvider, + // rateProvider, paysYieldFees: tokenType === TokenType.TOKEN_WITH_RATE ? true : false, tokenInfo: { ...tokenInfo }, useBoostedVariant: false, @@ -271,6 +285,13 @@ export function ChooseToken({ index }: { index: number }) { )} + {showRateProviderModal && tokenInfo && ( + + )} {showBoostOpportunityModal && tokenInfo && boostedVariant && ( ); }; + +const RateProviderModal = ({ + tokenIndex, + tokenInfo, + setShowRateProviderModal, +}: { + tokenIndex: number; + tokenInfo: Token; + setShowRateProviderModal: Dispatch>; +}) => { + const { targetNetwork } = useTargetNetwork(); + const { updateTokenConfig } = usePoolCreationStore(); + + const rateProviderData = tokenInfo.priceRateProviderData; + + const rateProviderLink = rateProviderData + ? getBlockExplorerAddressLink(targetNetwork, rateProviderData.address) + : undefined; + + return ( +
+
+

Rate Provider

+ +
+
+ The Balancer API offers the following option for {tokenInfo.symbol} +
+ {rateProviderData ? ( +
+ + + + + + + + + + + + + + + + + + + +
Name{rateProviderData.name}
Address + + {abbreviateAddress(rateProviderData.address)} + + +
Reviewed{rateProviderData.reviewed ? "Yes" : "No"}
Summary{rateProviderData.summary}
+
+ ) : ( +
No rate provider data
+ )} +
If you wish to use this rate provider, please click confirm
+
Otherwise, choose deny and paste in a rate provider address
+
+
+ + +
+
+
+ ); +}; diff --git a/packages/nextjs/hooks/v3/usePoolCreationStore.ts b/packages/nextjs/hooks/v3/usePoolCreationStore.ts index 111e4d0..60e922f 100644 --- a/packages/nextjs/hooks/v3/usePoolCreationStore.ts +++ b/packages/nextjs/hooks/v3/usePoolCreationStore.ts @@ -113,6 +113,6 @@ export function usePoolStoreDebug() { const poolState = usePoolCreationStore(); useEffect(() => { - console.log("Pool Store State:", poolState); + console.log("Persistent Pool Store:", poolState); }, [poolState]); } diff --git a/packages/nextjs/hooks/v3/useUserDataStore.ts b/packages/nextjs/hooks/v3/useUserDataStore.ts index a1f9cb5..4a10937 100644 --- a/packages/nextjs/hooks/v3/useUserDataStore.ts +++ b/packages/nextjs/hooks/v3/useUserDataStore.ts @@ -36,6 +36,6 @@ export function useUserDataStoreDebug() { const userDataState = useUserDataStore(); useEffect(() => { - console.log("User Data Store State:", userDataState); + console.log("Persistent User Data Store:", userDataState); }, [userDataState]); }