diff --git a/public/assets/locales/en/translation.json b/public/assets/locales/en/translation.json index 2e3c08b..532f928 100644 --- a/public/assets/locales/en/translation.json +++ b/public/assets/locales/en/translation.json @@ -346,6 +346,7 @@ "seconds": "Seconds", "submitPaymentReq": "Submit Payment Request", "noInventory": "Your balance is not enough.", + "noInventorywithdrawFee": "Insufficient balance, including the fee!", "allowableWithdraw": "Minimum allowable withdrawal amount has not been observed.", "fillAddress": "You must enter an address.", "important": "Important", @@ -388,8 +389,10 @@ "destination": "Origin / Destination", "inventory": "Inventory after transaction", "freeWallet": "Free Asset", - "minWithdraw": "Minimum withdrawal amount", + "minWithdraw": "Minimum Withdrawal Amount", + "maxWithdrawal": "Maximum Withdrawal Amount", "minDeposit": "Minimum Deposit Amount", + "maxDeposit": "Maximum Deposit Amount", "maxWithdraw": "Your daily withdrawal limit", "maxMonthWithdraw": "Your monthly withdrawal limit", "withdrawWarn": "Please note! Incorrect entry of address can result in loss of capital.", diff --git a/public/assets/locales/fa/translation.json b/public/assets/locales/fa/translation.json index 6643f48..e553f4a 100644 --- a/public/assets/locales/fa/translation.json +++ b/public/assets/locales/fa/translation.json @@ -346,6 +346,7 @@ "seconds": "ثانیه", "submitPaymentReq": "ثبت درخواست واریز", "noInventory": "موجودی کافی نیست !", + "noInventorywithdrawFee": "با احتساب کارمزد، موجودی کافی نیست !", "allowableWithdraw": "حداقل مقدار مجاز برداشت رعایت نشده است.", "fillAddress": "وارد کردن آدرس الزامیست.", "important": "مهم", @@ -389,7 +390,9 @@ "inventory": "موجودی بعد از تراکنش", "freeWallet": "موجودی قابل برداشت", "minWithdraw": "حداقل مقدار برداشت", + "maxWithdrawal": "حداکثر مقدار برداشت", "minDeposit": "حداقل مقدار واریز", + "maxDeposit": "حداکثر مقدار واریز", "maxWithdraw": "سقف برداشت روزانه شما", "maxMonthWithdraw": "سقف برداشت ماهانه شما", "withdrawWarn": "لطفا دقت کنید! ورود اشتباه آدرس می تواند به از دست رفتن سرمایه منجر شود.", diff --git a/src/components/TextInput/TextInput.js b/src/components/TextInput/TextInput.js index b1dca7e..401dd18 100644 --- a/src/components/TextInput/TextInput.js +++ b/src/components/TextInput/TextInput.js @@ -75,7 +75,7 @@ const TextInput = (props) => { options={options} ref={customRef} classNamePrefix="select" - className={`${classes.selectBox} select`} + className={`${classes.selectBox} select selectExternalClass`} {...other} /> } diff --git a/src/main/Mobile/Pages/UserPanel/Secttions/Content/components/Wallet/components/Deposit/Deposit.js b/src/main/Mobile/Pages/UserPanel/Secttions/Content/components/Wallet/components/Deposit/Deposit.js index 6db6c57..74553a4 100644 --- a/src/main/Mobile/Pages/UserPanel/Secttions/Content/components/Wallet/components/Deposit/Deposit.js +++ b/src/main/Mobile/Pages/UserPanel/Secttions/Content/components/Wallet/components/Deposit/Deposit.js @@ -1,13 +1,12 @@ -import React, {useEffect, useRef, useState} from 'react'; -import classes from './Deposit.module.css' +import React, {useEffect, useMemo} from 'react'; import {useTranslation} from "react-i18next"; -import TextInput from "../../../../../../../../../../components/TextInput/TextInput"; import {useParams} from "react-router-dom"; -import {useGetCurrencyInfo} from "../../../../../../../../../../queries"; +import {useGetGatewaysByCurrency} from "../../../../../../../../../../queries"; import {toast} from "react-hot-toast"; import Loading from "../../../../../../../../../../components/Loading/Loading"; import Error from "../../../../../../../../../../components/Error/Error"; -import Address from "./components/Address/Address"; +import {useSelector} from "react-redux"; +import OnChainDeposit from "./Module/OnChainDeposit/OnChainDeposit"; const Deposit = () => { @@ -19,49 +18,51 @@ const Deposit = () => { toast.dismiss() }, []) - const [networkName, setNetworkName] = useState({value: 0, error: []}); + const currencies = useSelector((state) => state.exchange.currencies) - const selectRef = useRef() - const {data: currencyInfo, isLoading: CILoading, error: CIError, refetch: refetchCI} = useGetCurrencyInfo(id) - useEffect(() => { - setNetworkName({value: 0, error: []}) + const { data, isLoading, error } = useGetGatewaysByCurrency(id, { + includeManualGateways: false, + includeOffChainGateways: true, + includeOnChainGateways: true + }); + + const { hasOnChain, hasOffChain } = useMemo(() => ({ + hasOnChain: data?.some(gateway => gateway.type === "OnChain"), + hasOffChain: data?.some(gateway => gateway.type === "OffChain") + }), [data]); - }, [id]); - useEffect(() => { - if (id !== "IRT") refetchCI() - }, [id]); + if (!currencies[id]?.depositAllowed) return
+ {t("noData")} +
+ if (isLoading) return
+ if (error) return
+ if (data.length <= 0 ) return
+ {t("noData")} +
- // if (id === "IRT") return - if (id === "IRT") return

{t("comingSoon")}

- if (CILoading) return
- if (CIError) return
- return ( -
- { - return {value: index, label: `${chain.network} - ${chain.currency}`} - })} - lead={t('DepositWithdraw.network')} - type="select" - value={currencyInfo?.chains[networkName.value] && { - value: networkName.value, - label: `${currencyInfo?.chains[networkName.value].network} - ${currencyInfo?.chains[networkName.value].currency}` - }} - onchange={(e) => setNetworkName({value: e?.value || 0, error: []})} - customRef={selectRef} - alerts={networkName.error} - customClass={`width-100 ${classes.thisInput}`} - /> - { currencyInfo &&
} -
- ); + switch (true) { + case hasOnChain && hasOffChain: + return
+ {t("comingSoon")} +
; + case hasOnChain: + return ; + case hasOffChain: + return
+ {t("comingSoon")} +
; + default: + return ( +
+ {t("noData")} +
+ ); + } }; export default Deposit; diff --git a/src/main/Mobile/Pages/UserPanel/Secttions/Content/components/Wallet/components/Deposit/Module/OnChainDeposit/OnChainDeposit.js b/src/main/Mobile/Pages/UserPanel/Secttions/Content/components/Wallet/components/Deposit/Module/OnChainDeposit/OnChainDeposit.js new file mode 100644 index 0000000..a894c0d --- /dev/null +++ b/src/main/Mobile/Pages/UserPanel/Secttions/Content/components/Wallet/components/Deposit/Module/OnChainDeposit/OnChainDeposit.js @@ -0,0 +1,119 @@ +import React, {useEffect, useRef, useState} from 'react'; +import classes from './OnChainDeposit.module.css'; +import {useParams} from "react-router-dom"; +import {Trans, useTranslation} from "react-i18next"; +import {useGetDepositAddress} from "../../../../../../../../../../../../queries"; +import i18n from "i18next"; +import {useSelector} from "react-redux"; +import {BN, getCurrencyNameOrAlias} from "../../../../../../../../../../../../utils/utils"; +import toast from "react-hot-toast"; +import TextInput from "../../../../../../../../../../../../components/TextInput/TextInput"; +import QRCode from "react-qr-code"; +import Icon from "../../../../../../../../../../../../components/Icon/Icon"; + +const OnChainDeposit = ({gateways, currency}) => { + const {t} = useTranslation(); + let {id} = useParams(); + + const [networkName, setNetworkName] = useState({value: 0, error: []}) + + const {data: address, isLoading, error, refetch: refetchAddress} = useGetDepositAddress(id, gateways[networkName.value].chain) + + const selectRef = useRef() + + const language = i18n.language + const currencies = useSelector((state) => state.exchange.currencies) + + + const depositMin = new BN(gateways?.[networkName.value]?.depositMin).decimalPlaces(currencies[id]?.precision ?? 0).toFormat() + const depositMax = new BN(gateways?.[networkName.value]?.depositMax).decimalPlaces(currencies[id]?.precision ?? 0).toFormat() + + useEffect(() => { + refetchAddress() + }, [gateways]); + + const addressRef = useRef(null); + const copyToClipboard = () => { + addressRef.current.select(); + document.execCommand("copy"); + toast.success(); + }; + const content = () => { + if (isLoading) return {t('DepositWithdraw.gettingAddress')} + if (error) return {t('DepositWithdraw.errorGettingAddress')} + + return
+ +
+ +
+ copyToClipboard()} + customClass={`hover-text cursor-pointer`} + /> + } + readOnly={true} + type="text" + customRef={addressRef} + value={address.address} + customClass={`${classes.depositInput} width-100`} + /> + +
+
+ {t('DepositWithdrawTx.minDeposit')}: + {new BN(depositMin).toString()} {getCurrencyNameOrAlias(currencies[id], language)} +
+
+ {t('DepositWithdrawTx.maxDeposit')}: + {new BN(depositMax).toString()} {getCurrencyNameOrAlias(currencies[id], language)} +
+
+ +
+ +
+ +
+ } + + return ( +
+ ({ + value: index, + label: `${chain.chain} - ${chain.implementationSymbol}`, + isDisabled: !chain.isActive // غیرفعال کردن در صورت عدم اجازه‌ی واریز + }))} + lead={t('DepositWithdraw.network')} + type="select" + value={gateways[networkName.value] && { + value: networkName.value, + label: `${gateways[networkName.value].chain} - ${gateways[networkName.value].implementationSymbol}` + }} + onchange={(e) => setNetworkName({ value: e?.value || 0, error: [] })} + customRef={selectRef} + alerts={networkName.error} + customClass={`width-90 ${classes.thisInput}`} + /> + {content()} +
+ ); +}; + +export default OnChainDeposit; diff --git a/src/main/Mobile/Pages/UserPanel/Secttions/Content/components/Wallet/components/Deposit/Module/OnChainDeposit/OnChainDeposit.module.css b/src/main/Mobile/Pages/UserPanel/Secttions/Content/components/Wallet/components/Deposit/Module/OnChainDeposit/OnChainDeposit.module.css new file mode 100644 index 0000000..b0193b9 --- /dev/null +++ b/src/main/Mobile/Pages/UserPanel/Secttions/Content/components/Wallet/components/Deposit/Module/OnChainDeposit/OnChainDeposit.module.css @@ -0,0 +1,18 @@ +.thisInput :global(.lead) { + width: 30%; +} +.thisInput :global(.selectExternalClass) { + width: 70% !important; +} +.depositInput { + width: 100%; +} +.depositInput :global(.after) { + width: 15%; + cursor: pointer; +} +.depositInput :global(input) { + width: 85% !important; + cursor: not-allowed; + font-family: 'Roboto', sans-serif; +} \ No newline at end of file diff --git a/src/main/Mobile/Pages/UserPanel/Secttions/Content/components/Wallet/components/withdrawal/Module/OnChainWithdraw/OnChainWithdraw.js b/src/main/Mobile/Pages/UserPanel/Secttions/Content/components/Wallet/components/withdrawal/Module/OnChainWithdraw/OnChainWithdraw.js new file mode 100644 index 0000000..8b7e0ea --- /dev/null +++ b/src/main/Mobile/Pages/UserPanel/Secttions/Content/components/Wallet/components/withdrawal/Module/OnChainWithdraw/OnChainWithdraw.js @@ -0,0 +1,262 @@ +import React, {useEffect, useRef, useState} from 'react'; +import classes from './OnChainWithdraw.module.css'; +import {useParams} from "react-router-dom"; +import {Trans, useTranslation} from "react-i18next"; +import {useSelector} from "react-redux"; +import {useGetUserAccount} from "../../../../../../../../../../../../queries/hooks/useGetUserAccount"; +import { + useGetUserAssets, + useGetUserAssetsEstimatedValue, + useGetWithdrawHistory +} from "../../../../../../../../../../../../queries"; +import {BN, getCurrencyNameOrAlias, parsePriceString} from "../../../../../../../../../../../../utils/utils"; +import {images} from "../../../../../../../../../../../../assets/images"; +import toast from "react-hot-toast"; +import i18n from "i18next"; +import {sendWithdrawReq} from "js-api-client"; +import TextInput from "../../../../../../../../../../../../components/TextInput/TextInput"; +import NumberInput from "../../../../../../../../../../../../components/NumberInput/NumberInput"; +import Button from "../../../../../../../../../../../../components/Button/Button"; +import Loading from "../../../../../../../../../../../../components/Loading/Loading"; + +const OnChainWithdraw = ({gateways}) => { + + const {t} = useTranslation(); + const {id} = useParams(); + + const refCurrency = useSelector((state) => state.exchange.baseCurrency) + + const [isLoading, setIsLoading] = useState(false) + + const language = i18n.language + const currencies = useSelector((state) => state.exchange.currencies) + + const [input, setInput] = useState({ + network: {value: 0, error: []}, + address: {value: "", error: []}, + txPassword: {value: "", error: []}, + }); + + const [amount, setAmount] = useState({value: new BN(0), error: []}); + + useEffect(() => { + setInput({ + network: {value: 0, error: []}, + address: {value: "", error: []}, + txPassword: {value: "", error: []}, + }) + setAmount({value: new BN(0), error: []}) + }, [id]); + + const selectRef = useRef() + + const {data: userAccount} = useGetUserAccount() + const freeWallet = new BN(userAccount?.wallets[id]?.free || 0).decimalPlaces(currencies[id]?.precision ?? 0).toFormat() || 0 + + const {refetch: getUserAccount} = useGetUserAccount(); + const {refetch: getUserAssets} = useGetUserAssets(refCurrency); + const {refetch: getUserAssetsEstimatedValue} = useGetUserAssetsEstimatedValue(refCurrency); + + const withdrawFee = new BN(gateways?.[input?.network.value]?.withdrawFee).decimalPlaces(currencies[id]?.precision ?? 0).toFormat() + const withdrawMin = new BN(gateways?.[input?.network.value]?.withdrawMin).decimalPlaces(currencies[id]?.precision ?? 0).toFormat() + const withdrawMax = new BN(gateways?.[input?.network.value]?.withdrawMax).decimalPlaces(currencies[id]?.precision ?? 0).toFormat() + + const query = { + "currency": id, // optional + "category": null, // optional [DEPOSIT, FEE, TRADE, WITHDRAW, ORDER_CANCEL, ORDER_CREATE, ORDER_FINALIZED] + "startTime": null, + "endTime": null, + "ascendingByTime": false, + "limit": 10, + "offset": 0, + } + + const {refetch: getWithdrawHistory} = useGetWithdrawHistory(query); + + const validation = (value) => { + + const newAmount = {...amount} + newAmount.error = [] + + if (new BN(value).isGreaterThan(new BN(freeWallet))) { + newAmount.error = [t('DepositWithdraw.noInventory')] + } + + if (new BN(value).isEqualTo(new BN(freeWallet))) { + newAmount.error = [t('DepositWithdraw.noInventorywithdrawFee')] + } + + if (new BN(value).isLessThan(new BN(withdrawMin))) { + newAmount.error = [t('DepositWithdraw.allowableWithdraw')] + } + + if (new BN(value).minus(new BN(withdrawFee)).isLessThanOrEqualTo(0)) { + newAmount.error = [t('DepositWithdraw.noInventorywithdrawFee')] + } + + if (new BN(value).isLessThan(new BN(withdrawFee)) ) { + newAmount.error = [t('DepositWithdraw.allowableWithdraw')] + } + + newAmount.value = new BN(value) + setAmount(newAmount) + } + + + const fillByWallet = () => { + const validateAmount = new BN(freeWallet).isGreaterThan(0) + ? new BN(freeWallet).minus(new BN(withdrawFee)) + : new BN(freeWallet); + validation(validateAmount); + }; + + const fillByMinWithdraw = () => { + validation(new BN(withdrawMin).plus(new BN(withdrawFee))) + }; + + const fillByMaxWithdraw = () => { + validation(new BN(withdrawMax).minus(new BN(withdrawFee))) + }; + + const inputChangeHandler = (value) => { + validation(parsePriceString(value)) + + } + + const submitButtonTextHandler = () => { + if (isLoading) return {t('loading')} + return t('DepositWithdrawTx.withdrawReqSubmit') + } + + const sendWithdrawHandler = async (e) => { + e.preventDefault() + if (isLoading) return + setIsLoading(true) + + const withdrawRequestData = { + "amount": amount.value, + "destSymbol": gateways?.[input?.network.value]?.currencySymbol, + "gatewayUuid": gateways?.[input?.network.value]?.gatewayUuid, + "destAddress": input?.address.value + } + + sendWithdrawReq(withdrawRequestData) + .then(() => { + + setAmount({value: new BN(0), error: []}) + setInput({ + network: {value: 0, error: []}, + address: {value: "", error: []}, + txPassword: {value: "", error: []}, + }) + toast.success(); + getUserAccount() + getWithdrawHistory() + getUserAssets() + getUserAssetsEstimatedValue() + }) + .catch((error) => { + toast.error(t('error')); + }) + .finally(() => setIsLoading(false)) + + } + + return ( +
+ ({ + value: index, + label: `${chain.chain} - ${chain.implementationSymbol}`, + isDisabled: !chain.isActive + }))} + lead={t('DepositWithdraw.network')} + type="select" + value={gateways[input?.network?.value] && { + value: input?.network?.value, + label: `${gateways[input?.network?.value].chain} - ${gateways[input?.network?.value].implementationSymbol}` + }} + onchange={(e) => setInput({...input, network: { value: e?.value || 0, error: [] }}) } + customRef={selectRef} + alerts={input?.input?.error} + customClass={`width-90 ${classes.thisInput}`} + /> + +
sendWithdrawHandler(e)} className={`width-90 column jc-between height-100`}> + +
+
+ {t("DepositWithdrawTx.freeWallet")}: + {fillByWallet()}}>{freeWallet} {getCurrencyNameOrAlias(currencies[id], language)} +
+ +
+ {t('DepositWithdrawTx.minWithdraw')}: + {fillByMinWithdraw()}}>{new BN(withdrawMin).toString()} {getCurrencyNameOrAlias(currencies[id], language)} +
+ +
+ {t('DepositWithdrawTx.maxWithdrawal')}: + {fillByMaxWithdraw()}}>{new BN(withdrawMax).toString()} {getCurrencyNameOrAlias(currencies[id], language)} +
+ +
+ {t('commission')}: + {withdrawFee ? withdrawFee : 0} {getCurrencyNameOrAlias(currencies[id], language)} +
+
+ {t('DepositWithdrawTx.reqAmount')}: + {new BN(amount.value).minus(withdrawFee).isGreaterThan(0) ? new BN(amount.value).minus(withdrawFee).toFormat() : 0} {getCurrencyNameOrAlias(currencies[id], language)} +
+
+ + inputChangeHandler(e.target.value)} + type="text" + /> + +
+ setInput({...input, address: {...input?.address, value: e.target.value}})} + /> + {t('DepositWithdrawTx.withdrawWarn')} +
+ +
+ {t('DepositWithdraw.securityConsiderations')} +
+ +
+
+ + +
+ ); +}; + +export default OnChainWithdraw; diff --git a/src/main/Mobile/Pages/UserPanel/Secttions/Content/components/Wallet/components/withdrawal/Module/OnChainWithdraw/OnChainWithdraw.module.css b/src/main/Mobile/Pages/UserPanel/Secttions/Content/components/Wallet/components/withdrawal/Module/OnChainWithdraw/OnChainWithdraw.module.css new file mode 100644 index 0000000..9aa92b2 --- /dev/null +++ b/src/main/Mobile/Pages/UserPanel/Secttions/Content/components/Wallet/components/withdrawal/Module/OnChainWithdraw/OnChainWithdraw.module.css @@ -0,0 +1,44 @@ +.thisInput :global(.lead) { + width: 30%; +} +.thisInput :global(.selectExternalClass) { + width: 80% !important; +} + +.thisInput :global(input) { + width: 70% !important; +} + +.addressInput :global(.lead) { + width: 30% !important; +} +.addressInput :global(input) { + width: 70% !important; +} + +.withdrawalInput :global(.lead) { + width: 24%; +} +.withdrawalInput :global(input) { + width: 76% !important; +} +.withdrawNumberInput :global(.lead) { + width: 50%; +} +.withdrawNumberInput :global(input) { + width: 50% !important; +} + + +.thisButton.withdrawal{ + background-color: var(--orange); + color: #000; + border: 1px solid var(--cardBorder); +} + +.thisButton:disabled,.button[disabled] { + /*border: 0.3vh solid var(--cardBodyAlpha);*/ + background: var(--cardBodyAlpha); + color: var(--textColor); + cursor: not-allowed; +} diff --git a/src/main/Mobile/Pages/UserPanel/Secttions/Content/components/Wallet/components/withdrawal/withdrawal.js b/src/main/Mobile/Pages/UserPanel/Secttions/Content/components/Wallet/components/withdrawal/withdrawal.js index c505d5a..20dd8b4 100644 --- a/src/main/Mobile/Pages/UserPanel/Secttions/Content/components/Wallet/components/withdrawal/withdrawal.js +++ b/src/main/Mobile/Pages/UserPanel/Secttions/Content/components/Wallet/components/withdrawal/withdrawal.js @@ -1,307 +1,57 @@ -import React, {useEffect, useRef, useState} from 'react'; -import classes from './withdrawal.module.css' +import React, {useMemo} from 'react'; import {useParams} from "react-router-dom"; -import {Trans, useTranslation} from "react-i18next"; -import {useGetUserAccount} from "../../../../../../../../../../queries/hooks/useGetUserAccount"; -import { - useGetCurrencyInfo, - useGetUserAssets, - useGetUserAssetsEstimatedValue, - useWithdrawTxs -} from "../../../../../../../../../../queries"; -import {BN, parsePriceString} from "../../../../../../../../../../utils/utils"; -import {sendWithdrawReq} from "js-api-client"; -import {toast} from "react-hot-toast"; -import {images} from "../../../../../../../../../../assets/images"; -import ReactTooltip from "react-tooltip"; +import {useTranslation} from "react-i18next"; +import {useGetGatewaysByCurrency} from "../../../../../../../../../../queries"; import Loading from "../../../../../../../../../../components/Loading/Loading"; import Error from "../../../../../../../../../../components/Error/Error"; -import NumberInput from "../../../../../../../../../../components/NumberInput/NumberInput"; -import TextInput from "../../../../../../../../../../components/TextInput/TextInput"; -import Button from "../../../../../../../../../../components/Button/Button"; -import Icon from "../../../../../../../../../../components/Icon/Icon"; -import {useGetWithdrawHistory} from "../../../../../../../../../../queries/hooks/useGetWithdrawHistory"; +import {useSelector} from "react-redux"; +import OnChainWithdraw from "./Module/OnChainWithdraw/OnChainWithdraw"; const Withdrawal = () => { const {t} = useTranslation(); const {id} = useParams(); - const [amount, setAmount] = useState({value: 0, error: []}); - const [networkName, setNetworkName] = useState({value: 0, error: []}); - const [address, setAddress] = useState({value: "", error: []}); - const [isLoading, setIsLoading] = useState(false) - - useEffect(() => { - toast.dismiss() - }, []) - - useEffect(() => { - setNetworkName({value: 0, error: []}) - setAmount({value: 0, error: []}) - setAddress({value: "", error: []}) - validation() - }, [id]); - - const {refetch: getUserAccount} = useGetUserAccount(); - const {refetch: getWithdrawTxs} = useWithdrawTxs(id); - const {refetch: getUserAssets} = useGetUserAssets("IRT"); - const {refetch: getUserAssetsEstimatedValue} = useGetUserAssetsEstimatedValue("IRT"); - - const query = { - "currency": id, // optional - "category": null, // optional [DEPOSIT, FEE, TRADE, WITHDRAW, ORDER_CANCEL, ORDER_CREATE, ORDER_FINALIZED] - "startTime": null, - "endTime": null, - "ascendingByTime": false, - "limit": 10, - "offset": 0, - } - - const {refetch: getWithdrawHistory} = useGetWithdrawHistory(query); - - const {data: userAccount} = useGetUserAccount() - const freeAmount = userAccount?.wallets[id]?.free || 0 - - const {data:currencyInfo, isLoading:CILoading, error:CIError} = useGetCurrencyInfo(id) - - const tooltip = useRef() - const selectRef = useRef() - - - - - - const withdrawFee = new BN(currencyInfo?.chains[networkName.value]?.withdrawFee).toFormat() - - - const pasteFromClipboard = (e) => { - e.preventDefault(); - if (navigator.clipboard !== undefined) { - navigator.clipboard.readText() - .then(text => { - setAddress({...address, value: text}) - toast.success(t('DepositWithdraw.paste')); - }) - .catch(err => { - console.error('Failed to read clipboard contents: ', err); - }); - } - else return toast.error(t('error')); - - } - - const validation = () => { - if (new BN(amount.value).isGreaterThan(freeAmount)) { - return t('DepositWithdraw.noInventory') - - - - // return toast.error(t('DepositWithdraw.noInventory')); - } - if (new BN(amount.value).minus(withdrawFee).isLessThanOrEqualTo(0)) { - return t('DepositWithdraw.allowableWithdraw') - } - /*if (currencyInfo?.chains[networkName.value]) { - return t('DepositWithdraw.fillNetwork') - }*/ - if (address.value.length <= 0) { - return t('DepositWithdraw.fillAddress') - } - } - - const sendWithdrawHandler = async (e) => { - e.preventDefault() - if(isLoading) return - setIsLoading(true) - - const withdrawRequestData = { - "currency": currencyInfo?.chains[networkName.value]?.currency, - "amount": amount.value, - "destSymbol": currencyInfo?.chains[networkName.value]?.currency, - "destAddress": address.value, - "destNetwork": currencyInfo?.chains[networkName.value]?.network, - /*"destNote": "Personal wallet", //Optional - "description": "Withdrawal to personal wallet" //Optional*/ - } - - - sendWithdrawReq(withdrawRequestData) - .then(() => { - setNetworkName({value: 0, error: []}) - setAmount({value: 0, error: []}) - setAddress({value: "", error: []}) - toast.success(); - getUserAccount() - /*getWithdrawTxs()*/ - getWithdrawHistory() - getUserAssets() - getUserAssetsEstimatedValue() - }) - .catch(() => { - toast.error(t('error')); - }) - .finally(() => setIsLoading(false)) - } - - const submitButtonTextHandler = () => { - if (isLoading) return linearLoading - return t('DepositWithdrawTx.withdrawReqSubmit') - } - const fillByWallet = () => { - setAmount({ - value: freeAmount, - error: [] - }) - }; - const fillByMinWithdraw = () => { - setAmount({ - value: new BN(currencyInfo?.chains[networkName.value]?.minWithdraw).plus(withdrawFee).toString(), - error: [] - }) - }; - - const enableButton = !(new BN(amount.value).minus(withdrawFee).isGreaterThan(0)) || new BN(amount.value).isGreaterThan(freeAmount) || address.value.length <= 0 - - useEffect(() => { - ReactTooltip.rebuild(); - }, [enableButton]); - - useEffect(() => { - ReactTooltip.hide(tooltip.current) - }, [enableButton]); - - if (id === "IRT") { - return

{t("comingSoon")}

- } - - const content = () => { - if (CILoading) return - if (CIError) return - else return
sendWithdrawHandler(e)} className={`px-2 py-1 column jc-between height-100 ${classes.content}`}> - -
-
- {t("DepositWithdrawTx.freeWallet")}: - {fillByWallet()}}>{freeAmount} {t("currency." + id)} -
-
- {t('DepositWithdrawTx.minWithdraw')}: - {fillByMinWithdraw()}}> {new BN(currencyInfo?.chains[networkName.value]?.minWithdraw).plus(withdrawFee).toString()} {t("currency." + id)} -
-
- {t('DepositWithdrawTx.maxWithdraw')}: - 2 {t("currency." + id)} -
-
- {t('DepositWithdrawTx.maxMonthWithdraw')}: - 2 {t("currency." + id)} -
-
- - - {return {value: index, label: `${chain.network} - ${chain.currency}` }})} - lead={t('DepositWithdraw.network')} - type="select" - value={currencyInfo?.chains[networkName.value] && {value: networkName.value, label: `${currencyInfo?.chains[networkName.value].network} - ${currencyInfo?.chains[networkName.value].currency}` }} - onchange={(e) => setNetworkName({value: e?.value || 0, error: []})} - customRef={selectRef} - alerts={networkName.error} - customClass={`${classes.withdrawalSmallInput} `} - /> - - setAmount({...amount, value: parsePriceString(e.target.value)}) - } - type="text" - /> - -
-
- {t("DepositWithdrawTx.destAddress") + " " + t("currency." + id)} - pasteFromClipboard(e)} - customClass={`hover-text cursor-pointer`} - /> -
- setAddress({...address, value: e.target.value})} - /> - {t('DepositWithdrawTx.withdrawWarn')} -
- - -
-
- {t('commission')}: - - {withdrawFee? withdrawFee : 0} - {t("currency." + id)} - - - -
-
- {t('DepositWithdrawTx.reqAmount')}: - - {new BN(amount.value).minus(withdrawFee).isGreaterThan(0) ? new BN(amount.value).minus(withdrawFee).toFormat() : 0} - {t("currency." + id)} - + const currencies = useSelector((state) => state.exchange.currencies) + + const { data, isLoading, error } = useGetGatewaysByCurrency(id, { + includeManualGateways: false, + includeOffChainGateways: true, + includeOnChainGateways: true + }); + + const { hasOnChain, hasOffChain } = useMemo(() => ({ + hasOnChain: data?.some(gateway => gateway.type === "OnChain"), + hasOffChain: data?.some(gateway => gateway.type === "OffChain") + }), [data]); + + if (!currencies[id]?.withdrawAllowed) return
+ {t("noData")} +
+ if (isLoading) return
+ if (error) return
+ if (data.length <= 0 ) return
+ {t("noData")} +
+ + switch (true) { + case hasOnChain && hasOffChain: + return
+ {t("comingSoon")} +
; + case hasOnChain: + return ; + case hasOffChain: + return
+ {t("comingSoon")} +
; + default: + return ( +
+ {t("noData")}
-
- - -
- {t('DepositWithdraw.securityConsiderations')} -
- - ${validation()}` : ""} - > -