-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Expand file tree
/
Copy pathuseWithdrawValidation.ts
More file actions
106 lines (94 loc) · 3.33 KB
/
useWithdrawValidation.ts
File metadata and controls
106 lines (94 loc) · 3.33 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
import { useMemo } from 'react';
import { strings } from '../../../../../locales/i18n';
import Engine from '../../../../core/Engine';
import {
HYPERLIQUID_ASSET_CONFIGS,
WITHDRAWAL_CONSTANTS,
} from '@metamask/perps-controller';
import {
parseCurrencyString,
truncateToTwoDecimals,
} from '../utils/formatUtils';
import { usePerpsNetwork } from './index';
import { usePerpsLiveAccount } from './stream';
interface UseWithdrawValidationParams {
withdrawAmount: string;
}
/**
* Hook to handle withdrawal validation logic
* @param params - The withdrawal amount to validate
* @returns Validation states and helper functions
*/
export const useWithdrawValidation = ({
withdrawAmount,
}: UseWithdrawValidationParams) => {
const { account } = usePerpsLiveAccount();
const perpsNetwork = usePerpsNetwork();
const isTestnet = perpsNetwork === 'testnet';
// Release-branch bridge for Unified Account: availableToTradeBalance includes
// collateral HL can use in target mode. The full balance contract will replace
// this with an explicit withdrawableBalance field.
const availableBalance = useMemo(() => {
const balance =
account?.availableToTradeBalance ?? account?.availableBalance ?? '0';
return truncateToTwoDecimals(parseCurrencyString(balance)).toString();
}, [account]);
// Get withdrawal route for constraints
const withdrawalRoute = useMemo(() => {
const controller = Engine.context.PerpsController;
const routes = controller.getWithdrawalRoutes();
// Find USDC route
const usdcAssetId = isTestnet
? HYPERLIQUID_ASSET_CONFIGS.usdc.testnet
: HYPERLIQUID_ASSET_CONFIGS.usdc.mainnet;
return routes.find((route) => route.assetId === usdcAssetId);
}, [isTestnet]);
// Validation checks
const hasInsufficientBalance = useMemo(() => {
if (!withdrawAmount || !availableBalance) return false;
return (
Number.parseFloat(withdrawAmount) > Number.parseFloat(availableBalance)
);
}, [withdrawAmount, availableBalance]);
const isBelowMinimum = useMemo(() => {
if (!withdrawAmount) return false;
const minAmount = Number.parseFloat(
withdrawalRoute?.constraints?.minAmount ||
WITHDRAWAL_CONSTANTS.DefaultMinAmount,
);
return Number.parseFloat(withdrawAmount) < minAmount;
}, [withdrawAmount, withdrawalRoute]);
const hasAmount = withdrawAmount && Number.parseFloat(withdrawAmount) > 0;
// Button label helper
const getButtonLabel = () => {
if (hasInsufficientBalance)
return strings('perps.withdrawal.insufficient_funds');
if (isBelowMinimum) {
const minAmount = Number.parseFloat(
withdrawalRoute?.constraints?.minAmount ||
WITHDRAWAL_CONSTANTS.DefaultMinAmount,
);
return strings('perps.withdrawal.minimum_amount_error', {
amount: minAmount,
});
}
if (!withdrawAmount || Number.parseFloat(withdrawAmount) === 0)
return strings('perps.withdrawal.enter_amount');
return strings('perps.withdrawal.withdraw_usdc');
};
// Get minimum amount for display
const getMinimumAmount = () =>
Number.parseFloat(
withdrawalRoute?.constraints?.minAmount ||
WITHDRAWAL_CONSTANTS.DefaultMinAmount,
);
return {
availableBalance,
withdrawalRoute,
hasInsufficientBalance,
isBelowMinimum,
hasAmount,
getButtonLabel,
getMinimumAmount,
};
};