Send native tokens inclusive fee (#118)
* send dv4tnt inclusive of fees
This commit is contained in:
@@ -61,38 +61,53 @@ export const TransferForm = ({
|
||||
const stringGetter = useStringGetter();
|
||||
const { freeCollateral } = useSelector(getSubaccount, shallowEqual) || {};
|
||||
const { dydxAddress } = useAccounts();
|
||||
const {
|
||||
address: recipientAddress,
|
||||
size,
|
||||
fee,
|
||||
} = useSelector(getTransferInputs, shallowEqual) || {};
|
||||
const { transfer } = useSubaccount();
|
||||
const { nativeTokenBalance, usdcBalance } = useAccountBalance();
|
||||
const { selectedNetwork } = useSelectedNetwork();
|
||||
const { tokensConfigs, usdcLabel, chainTokenLabel } = useTokenConfigs();
|
||||
|
||||
// User Input
|
||||
const [asset, setAsset] = useState<DydxChainAsset>(selectedAsset);
|
||||
const {
|
||||
address: recipientAddress,
|
||||
size,
|
||||
fee,
|
||||
token,
|
||||
} = useSelector(getTransferInputs, shallowEqual) || {};
|
||||
|
||||
// Form states
|
||||
const [error, setError] = useState<string>();
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
|
||||
const balance = asset === DydxChainAsset.USDC ? freeCollateral?.current : nativeTokenBalance;
|
||||
const newBalance =
|
||||
asset === DydxChainAsset.USDC
|
||||
? freeCollateral?.postOrder
|
||||
: MustBigNumber(nativeTokenBalance)
|
||||
.minus(size?.size ?? 0)
|
||||
.toNumber();
|
||||
const amount = asset === DydxChainAsset.USDC ? size?.usdcSize : size?.size;
|
||||
// temp fix: TODO: reset fees when changing token in Abacus
|
||||
const [currentFee, setCurrentFee] = useState(fee);
|
||||
useEffect(() => {
|
||||
setCurrentFee(fee);
|
||||
}, [fee]);
|
||||
|
||||
const showNotEnoughGasWarning = fee && asset === DydxChainAsset.USDC && usdcBalance < fee;
|
||||
const asset = (token ?? selectedAsset) as DydxChainAsset;
|
||||
const isUSDCSelected = asset === DydxChainAsset.USDC;
|
||||
const amount = isUSDCSelected ? size?.usdcSize : size?.size;
|
||||
const showNotEnoughGasWarning = fee && isUSDCSelected && usdcBalance < fee;
|
||||
const balance = isUSDCSelected ? freeCollateral?.current : nativeTokenBalance;
|
||||
|
||||
// BN
|
||||
const newBalanceBN = isUSDCSelected
|
||||
? MustBigNumber(freeCollateral?.postOrder)
|
||||
: nativeTokenBalance.minus(size?.size ?? 0);
|
||||
|
||||
const amountBN = MustBigNumber(amount);
|
||||
const balanceBN = MustBigNumber(balance);
|
||||
const newBalanceBN = MustBigNumber(newBalance);
|
||||
|
||||
const onChangeAsset = (asset: DydxChainAsset) => {
|
||||
setError(undefined);
|
||||
setCurrentFee(undefined);
|
||||
|
||||
if (asset) {
|
||||
abacusStateManager.setTransferValue({
|
||||
value: asset,
|
||||
field: TransferInputField.token,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
abacusStateManager.setTransferValue({
|
||||
@@ -100,19 +115,13 @@ export const TransferForm = ({
|
||||
field: TransferInputField.type,
|
||||
});
|
||||
|
||||
onChangeAsset(selectedAsset);
|
||||
|
||||
return () => {
|
||||
abacusStateManager.clearTransferInputValues();
|
||||
};
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
setError(undefined);
|
||||
abacusStateManager.setTransferValue({
|
||||
value: asset,
|
||||
field: TransferInputField.token,
|
||||
});
|
||||
}, [asset]);
|
||||
|
||||
const { sanctionedAddresses } = useRestrictions();
|
||||
|
||||
const isAddressValid = useMemo(
|
||||
@@ -134,11 +143,6 @@ export const TransferForm = ({
|
||||
setError(undefined);
|
||||
|
||||
try {
|
||||
// Subtract fees from amount if sending native tokens
|
||||
const amountToTransfer = (
|
||||
asset === DydxChainAsset.CHAINTOKEN ? amountBN.minus(fee) : amountBN
|
||||
).toNumber();
|
||||
|
||||
const screenResults = await screenAddresses({
|
||||
addresses: [recipientAddress!, dydxAddress!],
|
||||
});
|
||||
@@ -157,9 +161,9 @@ export const TransferForm = ({
|
||||
);
|
||||
} else {
|
||||
const txResponse = await transfer(
|
||||
amountToTransfer,
|
||||
amountBN.toNumber(),
|
||||
recipientAddress as string,
|
||||
tokensConfigs[asset].denom,
|
||||
tokensConfigs[asset]?.denom
|
||||
);
|
||||
|
||||
if (txResponse?.code === 0) {
|
||||
@@ -200,7 +204,7 @@ export const TransferForm = ({
|
||||
const onChangeAmount = (value?: number) => {
|
||||
abacusStateManager.setTransferValue({
|
||||
value,
|
||||
field: asset === DydxChainAsset.USDC ? TransferInputField.usdcSize : TransferInputField.size,
|
||||
field: isUSDCSelected ? TransferInputField.usdcSize : TransferInputField.size,
|
||||
});
|
||||
};
|
||||
|
||||
@@ -226,7 +230,7 @@ export const TransferForm = ({
|
||||
value: DydxChainAsset.CHAINTOKEN,
|
||||
label: (
|
||||
<Styled.InlineRow>
|
||||
{/* <AssetIcon symbol="DYDX" /> */}
|
||||
<AssetIcon symbol={chainTokenLabel} />
|
||||
{chainTokenLabel}
|
||||
</Styled.InlineRow>
|
||||
),
|
||||
@@ -249,15 +253,15 @@ export const TransferForm = ({
|
||||
key: 'amount',
|
||||
label: (
|
||||
<span>
|
||||
{stringGetter({ key: STRING_KEYS.AVAILABLE })} <Tag>{tokensConfigs[asset].name}</Tag>
|
||||
{stringGetter({ key: STRING_KEYS.AVAILABLE })} <Tag>{tokensConfigs[asset]?.name}</Tag>
|
||||
</span>
|
||||
),
|
||||
value: (
|
||||
<DiffOutput
|
||||
type={OutputType.Asset}
|
||||
value={balanceBN.toString()}
|
||||
newValue={newBalanceBN.toString()}
|
||||
value={balanceBN}
|
||||
sign={NumberSign.Negative}
|
||||
newValue={newBalanceBN}
|
||||
hasInvalidNewValue={newBalanceBN.isNegative()}
|
||||
withDiff={Boolean(amount && balance) && !amountBN.isNaN()}
|
||||
/>
|
||||
@@ -340,8 +344,8 @@ export const TransferForm = ({
|
||||
|
||||
<Styled.SelectMenu
|
||||
label={stringGetter({ key: STRING_KEYS.ASSET })}
|
||||
value={asset}
|
||||
onValueChange={setAsset}
|
||||
value={token}
|
||||
onValueChange={onChangeAsset}
|
||||
disabled={isLoading}
|
||||
>
|
||||
{assetOptions.map(({ value, label }) => (
|
||||
@@ -355,12 +359,16 @@ export const TransferForm = ({
|
||||
type={InputType.Number}
|
||||
onChange={({ floatValue }: NumberFormatValues) => onChangeAmount(floatValue)}
|
||||
value={amount ?? undefined}
|
||||
slotRight={renderFormInputButton({
|
||||
label: stringGetter({ key: STRING_KEYS.MAX }),
|
||||
isInputEmpty: size?.usdcSize == null,
|
||||
onClear: () => onChangeAmount(undefined),
|
||||
onClick: () => onChangeAmount(balanceBN.toNumber()),
|
||||
})}
|
||||
slotRight={
|
||||
isUSDCSelected &&
|
||||
balanceBN.gt(0) &&
|
||||
renderFormInputButton({
|
||||
label: stringGetter({ key: STRING_KEYS.MAX }),
|
||||
isInputEmpty: size?.usdcSize == null,
|
||||
onClear: () => onChangeAmount(undefined),
|
||||
onClick: () => onChangeAmount(balanceBN.toNumber()),
|
||||
})
|
||||
}
|
||||
disabled={isLoading}
|
||||
/>
|
||||
</WithDetailsReceipt>
|
||||
@@ -369,7 +377,7 @@ export const TransferForm = ({
|
||||
<AlertMessage type={AlertType.Warning}>
|
||||
{stringGetter({
|
||||
key: STRING_KEYS.TRANSFER_INSUFFICIENT_GAS,
|
||||
params: { USDC_BALANCE: `(${usdcBalance})` },
|
||||
params: { USDC_BALANCE: `(${usdcBalance} USDC)` },
|
||||
})}
|
||||
</AlertMessage>
|
||||
)}
|
||||
@@ -379,9 +387,9 @@ export const TransferForm = ({
|
||||
<Styled.Footer>
|
||||
<TransferButtonAndReceipt
|
||||
selectedAsset={asset}
|
||||
fees={fee || undefined}
|
||||
isDisabled={!isAmountValid || !isAddressValid || !fee || isLoading}
|
||||
isLoading={isLoading || Boolean(isAmountValid && isAddressValid && !fee)}
|
||||
fee={currentFee || undefined}
|
||||
isDisabled={!isAmountValid || !isAddressValid || !currentFee || isLoading}
|
||||
isLoading={isLoading || Boolean(isAmountValid && isAddressValid && !currentFee)}
|
||||
/>
|
||||
</Styled.Footer>
|
||||
</Styled.Form>
|
||||
|
||||
@@ -23,14 +23,14 @@ import { MustBigNumber } from '@/lib/numbers';
|
||||
|
||||
type ElementProps = {
|
||||
selectedAsset: DydxChainAsset;
|
||||
fees?: number;
|
||||
fee?: number;
|
||||
isDisabled?: boolean;
|
||||
isLoading?: boolean;
|
||||
};
|
||||
|
||||
export const TransferButtonAndReceipt = ({
|
||||
selectedAsset,
|
||||
fees,
|
||||
fee,
|
||||
isDisabled,
|
||||
isLoading,
|
||||
}: ElementProps) => {
|
||||
@@ -47,43 +47,46 @@ export const TransferButtonAndReceipt = ({
|
||||
const { current: equity, postOrder: newEquity } = equityInfo || {};
|
||||
const { current: leverage, postOrder: newLeverage } = leverageInfo || {};
|
||||
|
||||
// TODO(@aforaleka): add wallet balance for DYDX
|
||||
const balance = selectedAsset === DydxChainAsset.USDC ? equity : nativeTokenBalance;
|
||||
const newBalance =
|
||||
selectedAsset === DydxChainAsset.USDC
|
||||
? newEquity
|
||||
: MustBigNumber(nativeTokenBalance)
|
||||
.minus(size?.size ?? 0)
|
||||
.toNumber();
|
||||
const isUSDCSelected = selectedAsset === DydxChainAsset.USDC;
|
||||
|
||||
const balance = isUSDCSelected ? equity : nativeTokenBalance;
|
||||
const newNativeTokenBalance = nativeTokenBalance
|
||||
.minus(size?.size ?? 0)
|
||||
.minus(fee ?? 0) // show balance after fees for button receipt
|
||||
.toNumber();
|
||||
|
||||
const newBalance = isUSDCSelected ? newEquity : newNativeTokenBalance;
|
||||
|
||||
const transferDetailItems = [
|
||||
{
|
||||
key: 'fees',
|
||||
label: (
|
||||
<span>
|
||||
{stringGetter({ key: STRING_KEYS.FEES })} <Tag>{tokensConfigs[selectedAsset].name}</Tag>
|
||||
{stringGetter({ key: STRING_KEYS.FEES })} <Tag>{tokensConfigs[selectedAsset]?.name}</Tag>
|
||||
</span>
|
||||
),
|
||||
value: <Output type={OutputType.Asset} value={fees} />,
|
||||
value: <Output type={OutputType.Asset} value={fee} />,
|
||||
},
|
||||
{
|
||||
key: 'balance',
|
||||
label: (
|
||||
<span>
|
||||
{stringGetter({ key: STRING_KEYS.BALANCE })} <Tag>{tokensConfigs[selectedAsset].name}</Tag>
|
||||
{stringGetter({ key: STRING_KEYS.BALANCE })}{' '}
|
||||
<Tag>{tokensConfigs[selectedAsset]?.name}</Tag>
|
||||
</span>
|
||||
),
|
||||
value: (
|
||||
<DiffOutput
|
||||
type={OutputType.Asset}
|
||||
value={balance}
|
||||
newValue={newBalance}
|
||||
sign={NumberSign.Negative}
|
||||
withDiff={Boolean(newBalance) && balance !== newBalance}
|
||||
newValue={newBalance}
|
||||
hasInvalidNewValue={MustBigNumber(newBalance).isNegative()}
|
||||
withDiff={newBalance !== null && !MustBigNumber(balance).eq(newBalance ?? 0)}
|
||||
/>
|
||||
),
|
||||
},
|
||||
selectedAsset === DydxChainAsset.USDC && {
|
||||
isUSDCSelected && {
|
||||
key: 'leverage',
|
||||
label: <span>{stringGetter({ key: STRING_KEYS.LEVERAGE })}</span>,
|
||||
value: (
|
||||
|
||||
Reference in New Issue
Block a user