deprecate usesquidrouter
This commit is contained in:
@@ -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',
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
};
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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.",
|
||||
|
||||
@@ -73,14 +73,16 @@ export const AccountInfoConnectedState = () => {
|
||||
<Styled.Header>
|
||||
<span>{stringGetter({ key: STRING_KEYS.ACCOUNT })}</span>
|
||||
<Styled.TransferButtons>
|
||||
<Styled.Button
|
||||
state={{ isDisabled: !dydxAccounts }}
|
||||
onClick={() => dispatch(openDialog({ type: DialogTypes.Withdraw }))}
|
||||
shape={ButtonShape.Pill}
|
||||
size={ButtonSize.XSmall}
|
||||
>
|
||||
{stringGetter({ key: STRING_KEYS.WITHDRAW })}
|
||||
</Styled.Button>
|
||||
{import.meta.env.MODE !== 'production' && (
|
||||
<Styled.Button
|
||||
state={{ isDisabled: !dydxAccounts }}
|
||||
onClick={() => dispatch(openDialog({ type: DialogTypes.Withdraw }))}
|
||||
shape={ButtonShape.Pill}
|
||||
size={ButtonSize.XSmall}
|
||||
>
|
||||
{stringGetter({ key: STRING_KEYS.WITHDRAW })}
|
||||
</Styled.Button>
|
||||
)}
|
||||
<Styled.Button
|
||||
state={{ isDisabled: !dydxAccounts }}
|
||||
onClick={() => 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}
|
||||
|
||||
@@ -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<Error | null>(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 (
|
||||
<Styled.Form
|
||||
onSubmit={async (e: FormEvent) => {
|
||||
try {
|
||||
e.preventDefault();
|
||||
setIsLoading(true);
|
||||
const txHash = await submitDeposit(requestPayload);
|
||||
onDeposit?.();
|
||||
setTransactionHash(txHash);
|
||||
} catch (error) {
|
||||
setError(error);
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Styled.Form onSubmit={onSubmit}>
|
||||
<ChainSelectMenu selectedChain={sourceChain || undefined} onSelectChain={onSelectChain} />
|
||||
<TokenSelectMenu selectedToken={sourceToken || undefined} onSelectToken={onSelectToken} />
|
||||
<Styled.WithDetailsReceipt side="bottom" detailItems={amountInputReceipt}>
|
||||
@@ -257,12 +296,6 @@ export const DepositForm = ({ onDeposit, onError }: DepositFormProps) => {
|
||||
<Styled.TransactionInfo>
|
||||
{stringGetter({ key: STRING_KEYS.DEPOSIT_IN_PROGRESS })}
|
||||
</Styled.TransactionInfo>
|
||||
<Styled.TransactionInfo>
|
||||
<Styled.Link href={`${axelarscanURL}/gmp/${transactionHash}`}>
|
||||
{stringGetter({ key: STRING_KEYS.VIEW_TRANSACTION })}
|
||||
<Icon iconName={IconName.LinkOut} />
|
||||
</Styled.Link>
|
||||
</Styled.TransactionInfo>
|
||||
</AlertMessage>
|
||||
)
|
||||
)}
|
||||
|
||||
@@ -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 (
|
||||
<Styled.WithReceipt
|
||||
@@ -209,7 +209,10 @@ export const DepositButtonAndReceipt = ({
|
||||
<Button
|
||||
action={ButtonAction.Primary}
|
||||
type={ButtonType.Submit}
|
||||
state={{ isDisabled: !isFormValid, isLoading }}
|
||||
state={{
|
||||
isDisabled: !isFormValid,
|
||||
isLoading: (isFormValid && !requestPayload) || isLoading,
|
||||
}}
|
||||
>
|
||||
{stringGetter({ key: STRING_KEYS.DEPOSIT_FUNDS })}
|
||||
</Button>
|
||||
|
||||
@@ -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<HTMLInputElement>) => {
|
||||
@@ -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 && (
|
||||
<AlertMessage type={AlertType.Success}>
|
||||
<Styled.TransactionInfo>
|
||||
{stringGetter({ key: STRING_KEYS.DEPOSIT_IN_PROGRESS })}
|
||||
</Styled.TransactionInfo>
|
||||
<Styled.TransactionInfo>
|
||||
<Styled.Link href={`${axelarscanURL}/gmp/${transactionHash}`}>
|
||||
{stringGetter({ key: STRING_KEYS.VIEW_TRANSACTION })}
|
||||
<Icon iconName={IconName.LinkOut} />
|
||||
</Styled.Link>
|
||||
{stringGetter({ key: STRING_KEYS.WITHDRAW_IN_PROGRESS })}
|
||||
</Styled.TransactionInfo>
|
||||
</AlertMessage>
|
||||
)
|
||||
)}
|
||||
<WithdrawButtonAndReceipt
|
||||
isDisabled={isDisabled}
|
||||
setError={undefined}
|
||||
isLoading={isLoading}
|
||||
setSlippage={onSetSlippage}
|
||||
slippage={slippage}
|
||||
withdrawChain={toChain || undefined}
|
||||
|
||||
@@ -32,7 +32,6 @@ import { getSubaccount } from '@/state/accountSelectors';
|
||||
import { getTransferInputs } from '@/state/inputsSelectors';
|
||||
|
||||
type ElementProps = {
|
||||
setError?: Dispatch<SetStateAction<Error | undefined>>;
|
||||
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 (
|
||||
<Styled.WithReceipt
|
||||
@@ -177,9 +176,8 @@ export const WithdrawButtonAndReceipt = ({
|
||||
<Styled.ToggleButton
|
||||
shape={ButtonShape.Pill}
|
||||
size={ButtonSize.XSmall}
|
||||
state={{ isDisabled: !hasSubitems }}
|
||||
isPressed={showFeeBreakdown}
|
||||
onPressedChanged={() => setShowFeeBreakdown(!showFeeBreakdown)}
|
||||
onPressedChange={setShowFeeBreakdown}
|
||||
slotLeft={<Icon iconName={IconName.Caret} />}
|
||||
>
|
||||
{showSubitemsToggle}
|
||||
@@ -194,7 +192,7 @@ export const WithdrawButtonAndReceipt = ({
|
||||
type={ButtonType.Submit}
|
||||
state={{
|
||||
isDisabled: !isFormValid,
|
||||
isLoading,
|
||||
isLoading: (isFormValid && !requestPayload) || isLoading,
|
||||
}}
|
||||
>
|
||||
{stringGetter({ key: STRING_KEYS.WITHDRAW })}
|
||||
|
||||
Reference in New Issue
Block a user