diff --git a/apps/withdraw-pool/src/app/page.tsx b/apps/withdraw-pool/src/app/page.tsx index e0c31be..815ed4a 100644 --- a/apps/withdraw-pool/src/app/page.tsx +++ b/apps/withdraw-pool/src/app/page.tsx @@ -88,7 +88,7 @@ export default function Page() { PoolItemInfo={PoolItemInfo} selectedPool={selectedPool} /> - + ); } diff --git a/apps/withdraw-pool/src/components/PoolBalancePreview.tsx b/apps/withdraw-pool/src/components/PoolBalancePreview.tsx index f0f8aa3..8ec8a8c 100644 --- a/apps/withdraw-pool/src/components/PoolBalancePreview.tsx +++ b/apps/withdraw-pool/src/components/PoolBalancePreview.tsx @@ -1,12 +1,22 @@ "use client"; -import { BalancesPreview, type IBalance } from "@bleu/cow-hooks-ui"; +import { + type IBalance, + InfoTooltip, + Table, + TableBody, + TableCell, + TableHead, + TableHeader, + TableRow, + TokenAmount, + TokenInfo, +} from "@bleu/cow-hooks-ui"; import { useMemo } from "react"; import { useFormContext, useWatch } from "react-hook-form"; +import { formatUnits } from "viem"; import { multiplyValueByPct } from "#/utils/math"; -const PREVIEW_LABELS = ["Current balance", "Withdraw balance"]; - export function PoolBalancesPreview({ poolBalances, }: { @@ -16,7 +26,7 @@ export function PoolBalancesPreview({ const { withdrawPct } = useWatch({ control }); - const withdrawBalance = useMemo(() => { + const _withdrawBalance = useMemo(() => { if (!poolBalances || !withdrawPct) return []; return poolBalances.map((poolBalance) => ({ ...poolBalance, @@ -26,9 +36,64 @@ export function PoolBalancesPreview({ }, [poolBalances, withdrawPct]); return ( - +
+ + + + + Token + + + + Wallet balance + + + + + Withdraw balance + + + + + {poolBalances.map((balance, _index) => { + return ( + + + + + + + + + + + + ); + })} + +
+
); } diff --git a/apps/withdraw-pool/src/components/PoolForm.tsx b/apps/withdraw-pool/src/components/PoolForm.tsx index 044aeec..dde8b2f 100644 --- a/apps/withdraw-pool/src/components/PoolForm.tsx +++ b/apps/withdraw-pool/src/components/PoolForm.tsx @@ -1,16 +1,16 @@ -import { Spinner, useIFrameContext } from "@bleu/cow-hooks-ui"; +import { type IPool, Spinner, useIFrameContext } from "@bleu/cow-hooks-ui"; import { Suspense } from "react"; import { useUserPoolBalance } from "#/hooks/useUserPoolBalance"; import { PoolBalancesPreview } from "./PoolBalancePreview"; import { SubmitButton } from "./SubmitButton"; import { WithdrawPctSlider } from "./WithdrawPctSlider"; -export function PoolForm({ poolId }: { poolId?: string }) { +export function PoolForm({ selectedPool }: { selectedPool?: IPool }) { const { context } = useIFrameContext(); const { data: poolBalances, isLoading } = useUserPoolBalance({ user: context?.account, chainId: context?.chainId, - poolId, + poolId: selectedPool?.id, }); if (!poolBalances?.length && isLoading) { @@ -21,14 +21,15 @@ export function PoolForm({ poolId }: { poolId?: string }) { ); } - if (!context || !poolId || !poolBalances || !poolBalances.length) return null; + if (!context || !selectedPool || !poolBalances || !poolBalances.length) + return null; return ( }>
- +
); diff --git a/apps/withdraw-pool/src/components/PoolItemInfo.tsx b/apps/withdraw-pool/src/components/PoolItemInfo.tsx index f846f8e..2619114 100644 --- a/apps/withdraw-pool/src/components/PoolItemInfo.tsx +++ b/apps/withdraw-pool/src/components/PoolItemInfo.tsx @@ -2,5 +2,5 @@ import type { IPool } from "@bleu/cow-hooks-ui"; import { formatNumber } from "@bleu/ui"; export function PoolItemInfo({ pool }: { pool: IPool }) { - return ${formatNumber(pool.userBalance.totalBalanceUsd, 2)}; + return ${formatNumber(pool.userBalance.walletBalanceUsd, 2)}; } diff --git a/apps/withdraw-pool/src/components/SubmitButton.tsx b/apps/withdraw-pool/src/components/SubmitButton.tsx index 69e0d74..2213ee1 100644 --- a/apps/withdraw-pool/src/components/SubmitButton.tsx +++ b/apps/withdraw-pool/src/components/SubmitButton.tsx @@ -7,7 +7,7 @@ export function SubmitButton({ poolId }: { poolId?: string }) { const { control } = useFormContext(); const { context } = useIFrameContext(); - const { isSubmitting } = useFormState({ control }); + const { isSubmitting, isSubmitSuccessful } = useFormState({ control }); const withdrawPct = useWatch({ control, name: "withdrawPct" }); const buttonProps = useMemo(() => { @@ -27,7 +27,7 @@ export function SubmitButton({ poolId }: { poolId?: string }) { type="submit" className="my-2 w-full rounded-2xl text-lg h-[58px]" disabled={buttonProps.disabled} - loading={isSubmitting} + loading={isSubmitting || isSubmitSuccessful} loadingText="Creating hook..." > {buttonProps.message} diff --git a/apps/withdraw-pool/src/hooks/useGetBalancerGaugeArgs.ts b/apps/withdraw-pool/src/hooks/useGetBalancerGaugeArgs.ts index 7c139f5..735f2c3 100644 --- a/apps/withdraw-pool/src/hooks/useGetBalancerGaugeArgs.ts +++ b/apps/withdraw-pool/src/hooks/useGetBalancerGaugeArgs.ts @@ -41,7 +41,7 @@ export function getSingleBalancerGaugeArgs({ from: cowShedProxy, to: cowShedProxy, amount: amountToWithdraw.toBigInt(), - symbol: "pool stacked", // TODO: get symbol from token + symbol: "pool staked", // TODO: get symbol from token }, { gaugeAddress, @@ -86,7 +86,7 @@ export function useGetBalancerGaugeArgs( stackedBalanceAlreadyWithdraw, ), maxBptToWithdraw: BigNumber.from(stakedBalance.balance), - gaugeAddress: poolData.address, + gaugeAddress: stakedBalance.stakingId as Address, context, cowShedProxy, }); diff --git a/apps/withdraw-pool/src/hooks/useGetHookInfo.ts b/apps/withdraw-pool/src/hooks/useGetHookInfo.ts index d7371d2..76ff6c9 100644 --- a/apps/withdraw-pool/src/hooks/useGetHookInfo.ts +++ b/apps/withdraw-pool/src/hooks/useGetHookInfo.ts @@ -6,34 +6,35 @@ import { import { useCallback } from "react"; import type { IHooksInfo } from "#/types"; import { multiplyValueByPct } from "#/utils/math"; -import { useGetBalancerGaugeArgs } from "./useGetBalancerGaugeArgs"; +// import { useGetBalancerGaugeArgs } from "./useGetBalancerGaugeArgs"; import { useGetPoolWithdrawArgs } from "./useGetPoolWithdrawArgs"; export function useGetHookInfo(pool?: IPool) { const getPoolWithdrawArgs = useGetPoolWithdrawArgs(pool); - const getBalancerGaugeArgs = useGetBalancerGaugeArgs(pool); + // Removed gauge related code + // const getBalancerGaugeArgs = useGetBalancerGaugeArgs(pool); return useCallback( async (withdrawPct: number): Promise => { if (!pool) return; const bptAmount = multiplyValueByPct( - pool.userBalance.totalBalance, + pool.userBalance.walletBalance, withdrawPct, ); - const balancerGaugeArgs = getBalancerGaugeArgs(bptAmount); + // const balancerGaugeArgs = getBalancerGaugeArgs(bptAmount); const poolWithdrawArgs = await getPoolWithdrawArgs(bptAmount); if (!poolWithdrawArgs) return; - const argsArray = [...balancerGaugeArgs, ...poolWithdrawArgs]; + // const argsArray = [...balancerGaugeArgs, ...poolWithdrawArgs]; const txs = await Promise.all( - argsArray.map((arg) => { + poolWithdrawArgs.map((arg) => { return TransactionFactory.createRawTx(arg.type, arg); }), ); - const permitData = argsArray + const permitData = poolWithdrawArgs .filter((arg) => arg.type === TRANSACTION_TYPES.ERC20_TRANSFER_FROM) .map((arg) => { return { @@ -47,6 +48,6 @@ export function useGetHookInfo(pool?: IPool) { permitData: permitData, }; }, - [getPoolWithdrawArgs, getBalancerGaugeArgs, pool], + [getPoolWithdrawArgs, pool], ); } diff --git a/apps/withdraw-pool/src/hooks/useUserPoolBalance.tsx b/apps/withdraw-pool/src/hooks/useUserPoolBalance.tsx index c94fa27..037f6f5 100644 --- a/apps/withdraw-pool/src/hooks/useUserPoolBalance.tsx +++ b/apps/withdraw-pool/src/hooks/useUserPoolBalance.tsx @@ -21,8 +21,8 @@ interface IQuery { totalShares: `${number}`; }; userBalance: { - totalBalance: `${number}`; - totalBalanceUsd: number; + walletBalance: `${number}`; + walletBalanceUsd: number; }; poolTokens: { id: `0x${string}`; @@ -50,8 +50,8 @@ export const POOL_QUERY = gql` totalShares } userBalance { - totalBalance - totalBalanceUsd + walletBalance + walletBalanceUsd } poolTokens { id @@ -85,7 +85,7 @@ async function fetchUserPoolBalance( throw new Error("Pool not found"); } const userBpt = parseUnits( - result.pool.userBalance.totalBalance.toString(), + result.pool.userBalance.walletBalance.toString(), result.pool.decimals, ); const totalBpt = parseUnits( diff --git a/packages/cow-hooks-ui/src/BalancesPreview.tsx b/packages/cow-hooks-ui/src/BalancesPreview.tsx deleted file mode 100644 index 6243f6c..0000000 --- a/packages/cow-hooks-ui/src/BalancesPreview.tsx +++ /dev/null @@ -1,109 +0,0 @@ -"use client"; - -import { cn } from "@bleu/ui"; -import { formatUnits } from "ethers/lib/utils"; -import { useMemo } from "react"; -import { TokenAmount } from "./TokenAmount"; -import { TokenInfo } from "./TokenInfo"; -import type { IBalance } from "./types"; -import { Spinner } from "./ui/Spinner"; -import { - Table, - TableBody, - TableCell, - TableHead, - TableHeader, - TableRow, -} from "./ui/Table"; - -// This component expects that labels and balances are in the same order. -// For example, if labels = ["Pool Balance", "Withdraw Balance"], -// then balances should be an array of arrays where each inner array has two elements. -// TODO: Improve the component interface to make it more clear -export function BalancesPreview({ - labels, - isLoading, - balancesList, -}: { - labels: string[]; - isLoading?: boolean; - balancesList?: IBalance[][]; -}) { - if (isLoading) return ; - - const tokenBalancesList = useMemo( - () => - labels.map((_label, index) => - balancesList?.map((balances) => balances[index]), - ), - [balancesList, labels], - ); - - if (!balancesList && isLoading) return ; - - return ( -
- - - - - Token - - {labels.map((label, index) => ( - - - {label} - - - ))} - - - - {tokenBalancesList.map((balances) => { - if (!balances) return <>; - return ( - - ); - })} - -
-
- ); -} - -function BalancePreview({ - balances, - labels, -}: { - balances: IBalance[]; - labels: string[]; -}) { - return ( - - - - - {balances.map((poolBalance, index) => ( - - - - ))} - - ); -} diff --git a/packages/cow-hooks-ui/src/TokenLogo.tsx b/packages/cow-hooks-ui/src/TokenLogo.tsx index 71747e0..8462474 100644 --- a/packages/cow-hooks-ui/src/TokenLogo.tsx +++ b/packages/cow-hooks-ui/src/TokenLogo.tsx @@ -2,7 +2,7 @@ import { cowTokenList } from "@bleu/utils"; import Image from "next/image"; -import { useState } from "react"; +import { Suspense, useState } from "react"; import { SupportedChainId } from "@cowprotocol/cow-sdk"; import type { Token } from "@uniswap/sdk-core"; @@ -84,28 +84,32 @@ export const TokenLogo = ({ }; return ( -
- {alt { - setReveal(true); - setTokenLogoSrcIndex(token.address, index); + }> +
-
+ > + {alt { + setReveal(true); + setTokenLogoSrcIndex(token.address, index); + }} + unoptimized + /> +
+ ); }; diff --git a/packages/cow-hooks-ui/src/hooks/cowShed/useHookDeadline.ts b/packages/cow-hooks-ui/src/hooks/cowShed/useHookDeadline.ts index 6aed689..300f760 100644 --- a/packages/cow-hooks-ui/src/hooks/cowShed/useHookDeadline.ts +++ b/packages/cow-hooks-ui/src/hooks/cowShed/useHookDeadline.ts @@ -11,7 +11,7 @@ export function useHookDeadline({ const validToOnTimezone = context?.orderParams?.validTo || 0; const validToTimestamp = validToOnTimezone + now.getTimezoneOffset() * 60; const currentTimestamp = new Date().getTime() / 1000; - const oneHourAfter = BigInt(currentTimestamp.toFixed() + 60 * 60); + const oneHourAfter = Number(currentTimestamp.toFixed()) + 60 * 60; if (validToTimestamp < oneHourAfter) return BigInt(oneHourAfter); return BigInt(validToTimestamp); diff --git a/packages/cow-hooks-ui/src/hooks/usePools.ts b/packages/cow-hooks-ui/src/hooks/usePools.ts index fa10671..3c42df3 100644 --- a/packages/cow-hooks-ui/src/hooks/usePools.ts +++ b/packages/cow-hooks-ui/src/hooks/usePools.ts @@ -34,6 +34,7 @@ interface IQuery { totalBalance: string; walletBalance: string; totalBalanceUsd: number; + walletBalanceUsd: number; stakedBalances: { balance: string; stakingId: string; @@ -86,6 +87,7 @@ const USER_POOLS_QUERY = gql` totalBalance walletBalance totalBalanceUsd + walletBalanceUsd stakedBalances { balance stakingId @@ -125,22 +127,25 @@ export function usePools( userBalance: { ...pool.userBalance, walletBalance: parseUnits( - pool.userBalance.walletBalance, + Number(pool.userBalance.walletBalance).toFixed(pool.decimals), pool.decimals, ), totalBalance: parseUnits( - pool.userBalance.totalBalance, + Number(pool.userBalance.totalBalance).toFixed(pool.decimals), pool.decimals, ), stakedBalances: pool.userBalance.stakedBalances.map((staked) => ({ - balance: parseUnits(staked.balance, pool.decimals), + balance: parseUnits( + Number(staked.balance).toFixed(pool.decimals), + pool.decimals, + ), stakingId: staked.stakingId, })), }, dynamicData: { ...pool.dynamicData, totalShares: parseUnits( - pool.dynamicData.totalShares, + Number(pool.dynamicData.totalShares).toFixed(pool.decimals), pool.decimals, ), }, diff --git a/packages/cow-hooks-ui/src/index.tsx b/packages/cow-hooks-ui/src/index.tsx index cffa21b..5f20075 100644 --- a/packages/cow-hooks-ui/src/index.tsx +++ b/packages/cow-hooks-ui/src/index.tsx @@ -12,6 +12,7 @@ export * from "./ui/InputBase"; export * from "./ui/TooltipBase"; export * from "./ui/PeriodWithScaleInput"; export * from "./ui/TokenAmountInput"; +export * from "./ui/Table"; export * from "./hooks"; export * from "./ui/Scrollbar"; export * from "./ui/Spinner"; @@ -22,7 +23,6 @@ export * from "./AddressInput"; export * from "./ButtonPrimary"; export * from "./ClaimableAmountContainer"; export * from "./PoolsDropdownMenu"; -export * from "./BalancesPreview"; export * from "./utils/getAddressByEns"; export * from "./TokenLogoWithWeight"; export * from "./utils/poolDataConverter"; diff --git a/packages/cow-hooks-ui/src/types.ts b/packages/cow-hooks-ui/src/types.ts index e595119..ca47560 100644 --- a/packages/cow-hooks-ui/src/types.ts +++ b/packages/cow-hooks-ui/src/types.ts @@ -65,6 +65,7 @@ export interface IPool { totalBalance: BigNumberish; walletBalance: BigNumberish; totalBalanceUsd: number; + walletBalanceUsd: number; stakedBalances: { balance: BigNumberish; stakingId: string; diff --git a/packages/cow-hooks-ui/src/ui/WaitingSignature.tsx b/packages/cow-hooks-ui/src/ui/WaitingSignature.tsx index de71195..5e1689e 100644 --- a/packages/cow-hooks-ui/src/ui/WaitingSignature.tsx +++ b/packages/cow-hooks-ui/src/ui/WaitingSignature.tsx @@ -21,7 +21,6 @@ export function WaitingSignature({ revalidateOnMount: true, revalidateOnReconnect: false, shouldRetryOnError: false, - onError: (_error) => {}, }); const { reset } = useFormContext();