From 196185aa7eca394ffa52e3031799cb0d9f481624 Mon Sep 17 00:00:00 2001 From: Bill He Date: Mon, 21 Aug 2023 21:10:51 -0700 Subject: [PATCH] deprecate usesquidrouter --- src/constants/localization/app.ts | 1 + src/constants/localization/errors.ts | 3 + src/hooks/index.ts | 2 - src/hooks/useSquidRouter.tsx | 49 -------- src/localization/en/app.json | 3 +- src/localization/en/errors.json | 5 +- .../AccountInfo/AccountInfoConnectedState.tsx | 20 +-- .../AccountManagementForms/DepositForm.tsx | 89 +++++++++----- .../DepositForm/DepositButtonAndReceipt.tsx | 7 +- .../AccountManagementForms/WithdrawForm.tsx | 115 +++++++++++------- .../WithdrawForm/WithdrawButtonAndReceipt.tsx | 10 +- 11 files changed, 163 insertions(+), 141 deletions(-) diff --git a/src/constants/localization/app.ts b/src/constants/localization/app.ts index a392340..f7c2e6d 100644 --- a/src/constants/localization/app.ts +++ b/src/constants/localization/app.ts @@ -930,6 +930,7 @@ export const APP_STRING_KEYS = { SLOW_WITHDRAW_PENDING: 'NOTIFICATIONS.SLOW_WITHDRAW_PENDING', SUSPICIOUS_TRADE: 'NOTIFICATIONS.SUSPICIOUS_TRADE', SUSPICIOUS_TRADE_BODY: 'NOTIFICATIONS.SUSPICIOUS_TRADE_BODY', + WITHDRAW_IN_PROGRESS: 'NOTIFICATIONS.WITHDRAW_IN_PROGRESS', // Email Notifications ACCOUNT_DESCRIPTION: 'EMAIL_NOTIFICATIONS.ACCOUNT_DESCRIPTION', diff --git a/src/constants/localization/errors.ts b/src/constants/localization/errors.ts index a8f931f..5c45f8d 100644 --- a/src/constants/localization/errors.ts +++ b/src/constants/localization/errors.ts @@ -78,6 +78,9 @@ export const ERROR_STRING_KEYS = { RESTRICTED_OPEN_POSITIONS_WITHDRAW: 'ERRORS.WITHDRAW_MODAL.RESTRICTED_OPEN_POSITIONS_WITHDRAW', WITHDRAW_MORE_THAN_FREE_DUE_TO_FEE: 'ERRORS.WITHDRAW_MODAL.WITHDRAW_MORE_THAN_FREE_DUE_TO_FEE', WITHDRAW_MORE_THAN_FREE: 'ERRORS.WITHDRAW_MODAL.WITHDRAW_MORE_THAN_FREE', + WITHDRAW_MUST_SPECIFY_ADDRESS: 'ERRORS.DEPOSIT_MODAL.WITHDRAW_MUST_SPECIFY_ADDRESS', + WITHDRAW_MUST_SPECIFY_ASSET: 'ERRORS.DEPOSIT_MODAL.WITHDRAW_MUST_SPECIFY_ASSET', + WITHDRAW_MUST_SPECIFY_CHAIN: 'ERRORS.DEPOSIT_MODAL.WITHDRAW_MUST_SPECIFY_CHAIN', // Transfer modal errors TRANSFER_INVALID_ETH_ADDRESS: 'ERRORS.TRANSFER_MODAL.TRANSFER_INVALID_ETH_ADDRESS', diff --git a/src/hooks/index.ts b/src/hooks/index.ts index 950dc76..d6c228d 100644 --- a/src/hooks/index.ts +++ b/src/hooks/index.ts @@ -18,7 +18,6 @@ import { useOnClickOutside } from './useOnClickOutside'; import { usePageTitlePriceUpdates } from './usePageTitlePriceUpdates'; import { useShouldShowFooter } from './useShouldShowFooter'; import { useSelectedNetwork } from './useSelectedNetwork'; -import { useSquidRouter } from './useSquidRouter'; import { useStringGetter } from './useStringGetter'; import { useSubaccount } from './useSubaccount'; @@ -44,6 +43,5 @@ export { useShouldShowFooter, useSelectedNetwork, useStringGetter, - useSquidRouter, useSubaccount, }; diff --git a/src/hooks/useSquidRouter.tsx b/src/hooks/useSquidRouter.tsx index 8cd0cf8..d1d7340 100644 --- a/src/hooks/useSquidRouter.tsx +++ b/src/hooks/useSquidRouter.tsx @@ -4,9 +4,7 @@ import { useSelector } from 'react-redux'; import { Squid, type GetRoute, type RouteResponse, ChainData, ChainType } from '@0xsquid/sdk'; import { USDC_DENOM } from '@dydxprotocol/v4-client'; -import { TransferInputs } from '@/constants/abacus'; import { DydxV4Network, isDydxV4Network } from '@/constants/networks'; -import { useAccounts } from '@/hooks/useAccounts'; import { getSelectedNetwork } from '@/state/appSelectors'; @@ -69,50 +67,3 @@ export const SquidProvider = ({ ...props }) => ( ); export const useSquid = () => useContext(SquidContext); - -export const useSquidRouter = () => { - const squid = useSquid(); - const { signerWagmi } = useAccounts(); - - const submitDeposit = useCallback( - async (requestPayload: TransferInputs['requestPayload']) => { - if (!signerWagmi) { - throw new Error('Missing signer'); - } - if ( - !requestPayload?.targetAddress || - !requestPayload.data || - !requestPayload.value || - !requestPayload.gasLimit || - !requestPayload.gasPrice || - !requestPayload.routeType - ) { - throw new Error('Missing request payload'); - } - let tx = { - to: requestPayload.targetAddress as `0x${string}`, - data: requestPayload.data as `0x${string}`, - gasLimit: ethers.toBigInt(requestPayload.gasLimit), - value: - requestPayload.routeType !== 'SEND' ? ethers.toBigInt(requestPayload.value) : undefined, - }; - return await signerWagmi.sendTransaction(tx); - }, - [signerWagmi] - ); - - const getStatus = useCallback( - async (transactionId: string) => { - const status = await squid?.getStatus({ transactionId }); - return status; - }, - [squid] - ); - - return { - getStatus, - submitDeposit, - - axelarscanURL: squid?.axelarscanURL, - }; -}; diff --git a/src/localization/en/app.json b/src/localization/en/app.json index a492d6b..25d5a33 100644 --- a/src/localization/en/app.json +++ b/src/localization/en/app.json @@ -944,7 +944,8 @@ "SLOW_WITHDRAW_PENDING_DESCRIPTION": "You have {AMOUNT_ELEMENT} in pending slow withdraws. You will receive a notification when your funds have been confirmed on Layer 2.", "SLOW_WITHDRAW_PENDING": "Slow withdraw(s) pending", "SUSPICIOUS_TRADE": "Suspicious activity", - "SUSPICIOUS_TRADE_BODY": "We have noticed suspicious trading activity related to your account on dYdX, including potential wash trading activity. We will be reviewing your activity on an ongoing basis. If we notice similar activity in the future, then you will be permanently blocked from performing transfers within the protocol and from placing orders other than market orders that reduce your positions." + "SUSPICIOUS_TRADE_BODY": "We have noticed suspicious trading activity related to your account on dYdX, including potential wash trading activity. We will be reviewing your activity on an ongoing basis. If we notice similar activity in the future, then you will be permanently blocked from performing transfers within the protocol and from placing orders other than market orders that reduce your positions.", + "WITHDRAW_IN_PROGRESS": "Withdrawal(s) in progress" }, "EMAIL_NOTIFICATIONS": { "ACCOUNT_DESCRIPTION": "Deposits, Withdrawals, Account Updates", diff --git a/src/localization/en/errors.json b/src/localization/en/errors.json index 74af281..6953eb0 100644 --- a/src/localization/en/errors.json +++ b/src/localization/en/errors.json @@ -65,7 +65,10 @@ "MIN_SLOW_WITHDRAW_AMOUNT": "Slow withdraw amount must be greater than or equal to 10, or your entire account balance.", "RESTRICTED_OPEN_POSITIONS_WITHDRAW": "Your account is restricted. You must close all your positions before you can withdraw.", "WITHDRAW_MORE_THAN_FREE_DUE_TO_FEE": "You cannot withdraw more than your free collateral. Make sure you account for the fast withdraw fee when entering an amount.", - "WITHDRAW_MORE_THAN_FREE": "You cannot withdraw more than your free collateral." + "WITHDRAW_MORE_THAN_FREE": "You cannot withdraw more than your free collateral.", + "WITHDRAW_MUST_SPECIFY_ADDRESS": "Please enter a destination address.", + "WITHDRAW_MUST_SPECIFY_ASSET": "Please select an asset to withdraw to.", + "WITHDRAW_MUST_SPECIFY_CHAIN": "Please select a source chain to withdraw to." }, "TRANSFER_MODAL": { "TRANSFER_INVALID_ETH_ADDRESS": "We could not find an account associated with this wallet address.", diff --git a/src/views/AccountInfo/AccountInfoConnectedState.tsx b/src/views/AccountInfo/AccountInfoConnectedState.tsx index 3af94e9..fb4db0f 100644 --- a/src/views/AccountInfo/AccountInfoConnectedState.tsx +++ b/src/views/AccountInfo/AccountInfoConnectedState.tsx @@ -73,14 +73,16 @@ export const AccountInfoConnectedState = () => { {stringGetter({ key: STRING_KEYS.ACCOUNT })} - dispatch(openDialog({ type: DialogTypes.Withdraw }))} - shape={ButtonShape.Pill} - size={ButtonSize.XSmall} - > - {stringGetter({ key: STRING_KEYS.WITHDRAW })} - + {import.meta.env.MODE !== 'production' && ( + dispatch(openDialog({ type: DialogTypes.Withdraw }))} + shape={ButtonShape.Pill} + size={ButtonSize.XSmall} + > + {stringGetter({ key: STRING_KEYS.WITHDRAW })} + + )} dispatch(openDialog({ type: DialogTypes.Deposit }))} @@ -284,7 +286,7 @@ Styled.Header = styled.header` Styled.TransferButtons = styled.div` ${layoutMixins.row} gap: 1rem; -` +`; Styled.ConnectedAccountInfoContainer = styled.div<{ $showHeader?: boolean }>` ${layoutMixins.column} diff --git a/src/views/forms/AccountManagementForms/DepositForm.tsx b/src/views/forms/AccountManagementForms/DepositForm.tsx index 0f6bb42..fe37640 100644 --- a/src/views/forms/AccountManagementForms/DepositForm.tsx +++ b/src/views/forms/AccountManagementForms/DepositForm.tsx @@ -2,6 +2,8 @@ import { type FormEvent, useCallback, useEffect, useMemo, useState } from 'react import styled, { type AnyStyledComponent } from 'styled-components'; import { type NumberFormatValues } from 'react-number-format'; import { shallowEqual, useSelector } from 'react-redux'; +import { TESTNET_CHAIN_ID } from '@dydxprotocol/v4-client'; +import { ethers } from 'ethers'; import { TransferInputField, @@ -14,7 +16,7 @@ import { ButtonSize } from '@/constants/buttons'; import { StringGetterFunction, STRING_KEYS } from '@/constants/localization'; import { NumberSign } from '@/constants/numbers'; -import { useDebounce, useStringGetter, useSquidRouter } from '@/hooks'; +import { useAccounts, useDebounce, useStringGetter } from '@/hooks'; import { useAccountBalance } from '@/hooks/useAccountBalance'; import { layoutMixins } from '@/styles/layoutMixins'; @@ -23,7 +25,6 @@ import { AlertMessage } from '@/components/AlertMessage'; import { Button } from '@/components/Button'; import { DiffOutput } from '@/components/DiffOutput'; import { FormInput } from '@/components/FormInput'; -import { Icon, IconName } from '@/components/Icon'; import { InputType } from '@/components/Input'; import { Link } from '@/components/Link'; import { LoadingSpace } from '@/components/Loading/LoadingSpinner'; @@ -40,6 +41,7 @@ import { TokenSelectMenu } from './TokenSelectMenu'; import { DepositButtonAndReceipt } from './DepositForm/DepositButtonAndReceipt'; import { getTransferInputs } from '@/state/inputsSelectors'; +import { set } from 'lodash'; type DepositFormProps = { onDeposit?: () => void; @@ -51,7 +53,7 @@ export const DepositForm = ({ onDeposit, onError }: DepositFormProps) => { const [error, setError] = useState(null); const [isLoading, setIsLoading] = useState(false); - const { submitDeposit, axelarscanURL } = useSquidRouter(); + const { signerWagmi } = useAccounts(); const { requestPayload, token, chain, resources } = useSelector(getTransferInputs) || {}; @@ -156,6 +158,57 @@ export const DepositForm = ({ onDeposit, onError }: DepositFormProps) => { } }, [balance, setFromAmount]); + const onSubmit = useCallback( + async (e: FormEvent) => { + try { + e.preventDefault(); + + if (!signerWagmi) { + throw new Error('Missing signer'); + } + if ( + !requestPayload?.targetAddress || + !requestPayload.data || + !requestPayload.value || + !requestPayload.gasLimit || + !requestPayload.gasPrice || + !requestPayload.routeType + ) { + throw new Error('Missing request payload'); + } + + setIsLoading(true); + + let tx = { + to: requestPayload.targetAddress as `0x${string}`, + data: requestPayload.data as `0x${string}`, + gasLimit: ethers.toBigInt(requestPayload.gasLimit), + value: + requestPayload.routeType !== 'SEND' ? ethers.toBigInt(requestPayload.value) : undefined, + }; + const txHash = await signerWagmi.sendTransaction(tx); + onDeposit?.(); + + if (txHash) { + setTransactionHash(txHash); + abacusStateManager.setTransferStatus({ + hash: txHash, + toChainId: TESTNET_CHAIN_ID, + fromChainId: sourceChain?.chainId?.toString(), + }); + abacusStateManager.clearTransferInputValues(); + setFromAmount(''); + } + + } catch (error) { + setError(error); + } finally { + setIsLoading(false); + } + }, + [requestPayload, signerWagmi, sourceChain] + ); + const amountInputReceipt = [ { key: 'amount', @@ -191,7 +244,7 @@ export const DepositForm = ({ onDeposit, onError }: DepositFormProps) => { }) : stringGetter({ key: STRING_KEYS.SOMETHING_WENT_WRONG }); } - + if (fromAmount) { if (!sourceChain) { return stringGetter({ key: STRING_KEYS.MUST_SPECIFY_CHAIN }); @@ -199,13 +252,13 @@ export const DepositForm = ({ onDeposit, onError }: DepositFormProps) => { return stringGetter({ key: STRING_KEYS.MUST_SPECIFY_ASSET }); } } - + if (MustBigNumber(fromAmount).gt(MustBigNumber(balance))) { return stringGetter({ key: STRING_KEYS.DEPOSIT_MORE_THAN_BALANCE }); } - + return undefined; - }, [error, balance, sourceChain, fromAmount, sourceToken]) + }, [error, balance, sourceChain, fromAmount, sourceToken]); const isDisabled = Boolean(errorMessage) || @@ -219,21 +272,7 @@ export const DepositForm = ({ onDeposit, onError }: DepositFormProps) => { } return ( - { - try { - e.preventDefault(); - setIsLoading(true); - const txHash = await submitDeposit(requestPayload); - onDeposit?.(); - setTransactionHash(txHash); - } catch (error) { - setError(error); - } finally { - setIsLoading(false); - } - }} - > + @@ -257,12 +296,6 @@ export const DepositForm = ({ onDeposit, onError }: DepositFormProps) => { {stringGetter({ key: STRING_KEYS.DEPOSIT_IN_PROGRESS })} - - - {stringGetter({ key: STRING_KEYS.VIEW_TRANSACTION })} - - - ) )} diff --git a/src/views/forms/AccountManagementForms/DepositForm/DepositButtonAndReceipt.tsx b/src/views/forms/AccountManagementForms/DepositForm/DepositButtonAndReceipt.tsx index 9939a8a..7246b2d 100644 --- a/src/views/forms/AccountManagementForms/DepositForm/DepositButtonAndReceipt.tsx +++ b/src/views/forms/AccountManagementForms/DepositForm/DepositButtonAndReceipt.tsx @@ -58,6 +58,7 @@ export const DepositButtonAndReceipt = ({ sourceToken, isDisabled, + isLoading, slotError, }: ElementProps) => { const [showFeeBreakdown, setShowFeeBreakdown] = useState(false); @@ -173,7 +174,6 @@ export const DepositButtonAndReceipt = ({ ]; const isFormValid = !isDisabled && !isEditingSlippage; - const isLoading = isFormValid && !requestPayload; return ( {stringGetter({ key: STRING_KEYS.DEPOSIT_FUNDS })} diff --git a/src/views/forms/AccountManagementForms/WithdrawForm.tsx b/src/views/forms/AccountManagementForms/WithdrawForm.tsx index 770b07c..6d98f3d 100644 --- a/src/views/forms/AccountManagementForms/WithdrawForm.tsx +++ b/src/views/forms/AccountManagementForms/WithdrawForm.tsx @@ -2,9 +2,8 @@ import { useCallback, useEffect, useMemo, useState } from 'react'; import type { ChangeEvent, FormEvent } from 'react'; import styled, { type AnyStyledComponent } from 'styled-components'; import type { NumberFormatValues } from 'react-number-format'; -import type { TokenData, ChainData } from '@0xsquid/sdk'; import { shallowEqual, useSelector } from 'react-redux'; -import { parseUnits } from 'viem'; +import { TESTNET_CHAIN_ID } from '@dydxprotocol/v4-client'; import { TransferInputField, @@ -15,11 +14,9 @@ import { import { AlertType } from '@/constants/alerts'; import { ButtonAction, ButtonSize, ButtonType } from '@/constants/buttons'; import { STRING_KEYS } from '@/constants/localization'; -import { CLIENT_NETWORK_CONFIGS, type DydxV4Network } from '@/constants/networks'; import { NumberSign, QUANTUM_MULTIPLIER } from '@/constants/numbers'; -import { useAccounts, useDebounce, useStringGetter, useSquidRouter, useSubaccount } from '@/hooks'; -import { SQUID_WITHDRAW_ROUTE_DEFAULTS } from '@/hooks/useSquidRouter'; +import { useDebounce, useStringGetter, useSubaccount } from '@/hooks'; import { layoutMixins } from '@/styles/layoutMixins'; @@ -27,7 +24,6 @@ import { AlertMessage } from '@/components/AlertMessage'; import { Button } from '@/components/Button'; import { DiffOutput } from '@/components/DiffOutput'; import { FormInput } from '@/components/FormInput'; -import { Icon, IconName } from '@/components/Icon'; import { InputType } from '@/components/Input'; import { Link } from '@/components/Link'; import { OutputType } from '@/components/Output'; @@ -44,8 +40,6 @@ import { MustBigNumber } from '@/lib/numbers'; import { TokenSelectMenu } from './TokenSelectMenu'; import { WithdrawButtonAndReceipt } from './WithdrawForm/WithdrawButtonAndReceipt'; -import { parse } from 'path'; -import { s } from 'vitest/dist/types-2b1c412e'; export const WithdrawForm = () => { const stringGetter = useStringGetter(); @@ -55,8 +49,6 @@ export const WithdrawForm = () => { const { simulateWithdraw, sendSquidWithdraw } = useSubaccount(); const { freeCollateral } = useSelector(getSubaccount, shallowEqual) || {}; - const { axelarscanURL } = useSquidRouter(); - // User input const [withdrawAmount, setWithdrawAmount] = useState(''); const [slippage, setSlippage] = useState(0.01); // 0.1% slippage @@ -99,52 +91,68 @@ export const WithdrawForm = () => { useEffect(() => { const setTransferValue = async () => { - const hasInvalidInput = debouncedAmountBN.isNaN() || debouncedAmountBN.lte(0); + try { + setIsLoading(true); + const hasInvalidInput = debouncedAmountBN.isNaN() || debouncedAmountBN.lte(0); + if (hasInvalidInput) { + abacusStateManager.setTransferValue({ + value: 0, + field: TransferInputField.usdcSize, + }); + } else { + const stdFee = await simulateWithdraw(parseFloat(debouncedAmount)); + const amount = + parseFloat(debouncedAmount) - + parseFloat(stdFee?.amount[0]?.amount || '0') / QUANTUM_MULTIPLIER; - const stdFee = await simulateWithdraw(parseFloat(debouncedAmount)); - const amount = hasInvalidInput - ? 0 - : parseFloat(debouncedAmount) - - parseFloat(stdFee?.amount[0]?.amount || '0') / QUANTUM_MULTIPLIER; + abacusStateManager.setTransferValue({ + value: amount.toString(), + field: TransferInputField.usdcSize, + }); - abacusStateManager.setTransferValue({ - value: hasInvalidInput ? 0 : amount.toString(), - field: TransferInputField.usdcSize, - }); - - setError(null); + setError(null); + } + } catch (error) { + setError(error); + } finally { + setIsLoading(false); + } }; setTransferValue(); }, [debouncedAmountBN.toNumber()]); - /** - * @todo Withdrawing involves two steps. - * 1. MsgCreateTransfer for withdrawing from the subaccount. - * 2. MsgTransfer to IBC transfer the funds to the destination chain. 0xSquid will provide the IBC path instructions. - */ const onSubmit = useCallback( async (e: FormEvent) => { - e.preventDefault(); try { - + e.preventDefault(); + if (!requestPayload?.data || !debouncedAmountBN.toNumber()) { throw new Error('Invalid request payload'); } - const txHash = await sendSquidWithdraw(debouncedAmountBN.toNumber(), requestPayload?.data); + setIsLoading(true); + const txHash = await sendSquidWithdraw(debouncedAmountBN.toNumber(), requestPayload?.data); + if (txHash?.hash) { + const hash = `0x${Buffer.from(txHash.hash).toString('hex')}`; + + setTransactionHash(hash); abacusStateManager.setTransferStatus({ - hash: `0x${Buffer.from(txHash.hash).toString('hex')}`, - fromChainId: 'dydx-testnet-2', + hash, + fromChainId: TESTNET_CHAIN_ID, toChainId: toChain?.chainId?.toString(), - }) + }); + abacusStateManager.clearTransferInputValues(); + setWithdrawAmount(''); } } catch (error) { setError(error); + } finally { + setIsLoading(false); } }, - [setTransactionHash, requestPayload, debouncedAmountBN] + [setTransactionHash, requestPayload, debouncedAmountBN, toChain] ); const onChangeAddress = useCallback((e: ChangeEvent) => { @@ -165,6 +173,7 @@ export const WithdrawForm = () => { (newSlippage: number) => { setSlippage(newSlippage); + // TODO: to be implemented via abacus // if (MustBigNumber(newSlippage).gt(0) && debouncedAmountBN.gt(0)) { // fetchRoute({ newAmount: debouncedAmount, newSlippage }); // } @@ -221,12 +230,38 @@ export const WithdrawForm = () => { }, ]; - let errorMessage = !toAddress ? 'Please enter a destination address' : undefined; + const errorMessage = useMemo(() => { + if (error) { + return error?.message + ? stringGetter({ + key: STRING_KEYS.SOMETHING_WENT_WRONG_WITH_MESSAGE, + params: { ERROR_MESSAGE: error.message }, + }) + : stringGetter({ key: STRING_KEYS.SOMETHING_WENT_WRONG }); + } + + if (!toAddress) return stringGetter({ key: STRING_KEYS.WITHDRAW_MUST_SPECIFY_ADDRESS }); + + if (debouncedAmountBN) { + if (!toChain) { + return stringGetter({ key: STRING_KEYS.WITHDRAW_MUST_SPECIFY_CHAIN }); + } else if (!toToken) { + return stringGetter({ key: STRING_KEYS.WITHDRAW_MUST_SPECIFY_ASSET }); + } + } + + if (MustBigNumber(debouncedAmountBN).gt(MustBigNumber(freeCollateralBN))) { + return stringGetter({ key: STRING_KEYS.WITHDRAW_MORE_THAN_FREE }); + } + + return undefined; + }, [error, freeCollateralBN, toChain, debouncedAmountBN, toToken]); const isDisabled = !!errorMessage || !toToken || !toChain || + !toAddress || debouncedAmountBN.isNaN() || debouncedAmountBN.isZero(); @@ -271,20 +306,14 @@ export const WithdrawForm = () => { transactionHash && ( - {stringGetter({ key: STRING_KEYS.DEPOSIT_IN_PROGRESS })} - - - - {stringGetter({ key: STRING_KEYS.VIEW_TRANSACTION })} - - + {stringGetter({ key: STRING_KEYS.WITHDRAW_IN_PROGRESS })} ) )} >; setSlippage: (slippage: number) => void; slippage: number; @@ -40,10 +39,10 @@ type ElementProps = { withdrawToken?: TransferInputTokenResource; isDisabled?: boolean; + isLoading?: boolean; }; export const WithdrawButtonAndReceipt = ({ - setError, setSlippage, slippage, @@ -51,6 +50,7 @@ export const WithdrawButtonAndReceipt = ({ withdrawToken, isDisabled, + isLoading, }: ElementProps) => { const [showFeeBreakdown, setShowFeeBreakdown] = useState(false); const [isEditingSlippage, setIsEditingSlipapge] = useState(false); @@ -165,7 +165,6 @@ export const WithdrawButtonAndReceipt = ({ ]; const isFormValid = !isDisabled && !isEditingSlippage && queryStatus !== 'error'; - const isLoading = isFormValid && !requestPayload; return ( setShowFeeBreakdown(!showFeeBreakdown)} + onPressedChange={setShowFeeBreakdown} slotLeft={} > {showSubitemsToggle} @@ -194,7 +192,7 @@ export const WithdrawButtonAndReceipt = ({ type={ButtonType.Submit} state={{ isDisabled: !isFormValid, - isLoading, + isLoading: (isFormValid && !requestPayload) || isLoading, }} > {stringGetter({ key: STRING_KEYS.WITHDRAW })}