Send native tokens inclusive fee (#118)

* send dv4tnt inclusive of fees
This commit is contained in:
aleka
2023-11-07 22:42:41 -05:00
committed by GitHub
parent 766209baf1
commit 5e2d426cd1
2 changed files with 76 additions and 65 deletions
+57 -49
View File
@@ -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: (