From 82b53cac32cbf9982948a3ae8b97153306331291 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Fri, 31 Oct 2025 14:21:36 +0100 Subject: [PATCH 01/12] chore: return proper promises --- .../PageVeCrv/components/FormLockCreate.tsx | 5 ++-- .../PageVeCrv/components/FormLockCrv.tsx | 5 ++-- .../PageVeCrv/components/FormLockDate.tsx | 5 ++-- .../dex/components/PagePool/Swap/index.tsx | 20 ++++++++----- .../src/dex/components/PagePool/index.tsx | 6 +--- .../src/dex/components/PagePoolList/index.tsx | 10 +++---- apps/main/src/dex/hooks/useAutoRefresh.tsx | 17 +++++------ .../PageLoanCreate/LoanFormCreate/index.tsx | 24 ++++++++++------ .../PageLoanManage/LoanBorrowMore/index.tsx | 28 +++++++++++-------- .../PageLoanManage/LoanRepay/index.tsx | 27 ++++++++++-------- .../main/src/lend/hooks/useAbiTotalSupply.tsx | 4 +-- .../loan/components/PageLoanCreate/Page.tsx | 6 +--- .../PageLoanManage/LoanDeleverage/index.tsx | 24 +++++++--------- .../loan/components/PageLoanManage/Page.tsx | 14 ++++++---- .../curve-ui-kit/src/hooks/useDebounce.ts | 2 +- .../src/shared/ui/LargeTokenInput.tsx | 2 +- .../src/themes/design/0_primitives.ts | 2 +- packages/curve-ui-kit/src/utils/timers.ts | 7 +++++ 18 files changed, 113 insertions(+), 95 deletions(-) diff --git a/apps/main/src/dao/components/PageVeCrv/components/FormLockCreate.tsx b/apps/main/src/dao/components/PageVeCrv/components/FormLockCreate.tsx index a8a40098c9..244b77719c 100644 --- a/apps/main/src/dao/components/PageVeCrv/components/FormLockCreate.tsx +++ b/apps/main/src/dao/components/PageVeCrv/components/FormLockCreate.tsx @@ -22,6 +22,7 @@ import usePageVisibleInterval from '@ui-kit/hooks/usePageVisibleInterval' import dayjs from '@ui-kit/lib/dayjs' import { t } from '@ui-kit/lib/i18n' import { REFRESH_INTERVAL } from '@ui-kit/lib/model' +import { useThrottle } from '@ui-kit/utils/timers' const FormLockCreate = ({ curve, rChainId, rFormType, vecrvInfo }: PageVecrv) => { const isSubscribed = useRef(false) @@ -34,7 +35,7 @@ const FormLockCreate = ({ curve, rChainId, rFormType, vecrvInfo }: PageVecrv) => const formValues = useStore((state) => state.lockedCrv.formValues) const fetchStepApprove = useStore((state) => state.lockedCrv.fetchStepApprove) const fetchStepCreate = useStore((state) => state.lockedCrv.fetchStepCreate) - const setFormValues = useStore((state) => state.lockedCrv.setFormValues) + const setFormValues = useThrottle(useStore((state) => state.lockedCrv.setFormValues)) const [steps, setSteps] = useState([]) const [txInfoBar, setTxInfoBar] = useState(null) @@ -48,7 +49,7 @@ const FormLockCreate = ({ curve, rChainId, rFormType, vecrvInfo }: PageVecrv) => const updateFormValues = useCallback( (updatedFormValues: Partial, isFullReset?: boolean) => { setTxInfoBar(null) - setFormValues(curve, isLoadingCurve, rFormType, updatedFormValues, vecrvInfo, isFullReset) + return setFormValues(curve, isLoadingCurve, rFormType, updatedFormValues, vecrvInfo, isFullReset) }, [curve, isLoadingCurve, vecrvInfo, rFormType, setFormValues], ) diff --git a/apps/main/src/dao/components/PageVeCrv/components/FormLockCrv.tsx b/apps/main/src/dao/components/PageVeCrv/components/FormLockCrv.tsx index 7e41c9bb0b..a9e49693a3 100644 --- a/apps/main/src/dao/components/PageVeCrv/components/FormLockCrv.tsx +++ b/apps/main/src/dao/components/PageVeCrv/components/FormLockCrv.tsx @@ -17,6 +17,7 @@ import { type CurveApi, isLoading, notify, useConnection } from '@ui-kit/feature import usePageVisibleInterval from '@ui-kit/hooks/usePageVisibleInterval' import { t } from '@ui-kit/lib/i18n' import { REFRESH_INTERVAL } from '@ui-kit/lib/model' +import { useThrottle } from '@ui-kit/utils/timers' const FormLockCrv = ({ curve, rChainId, rFormType, vecrvInfo }: PageVecrv) => { const isSubscribed = useRef(false) @@ -29,7 +30,7 @@ const FormLockCrv = ({ curve, rChainId, rFormType, vecrvInfo }: PageVecrv) => { const formValues = useStore((state) => state.lockedCrv.formValues) const fetchStepApprove = useStore((state) => state.lockedCrv.fetchStepApprove) const fetchStepIncreaseCrv = useStore((state) => state.lockedCrv.fetchStepIncreaseCrv) - const setFormValues = useStore((state) => state.lockedCrv.setFormValues) + const setFormValues = useThrottle(useStore((state) => state.lockedCrv.setFormValues)) const [steps, setSteps] = useState([]) const [txInfoBar, setTxInfoBar] = useState(null) @@ -40,7 +41,7 @@ const FormLockCrv = ({ curve, rChainId, rFormType, vecrvInfo }: PageVecrv) => { const updateFormValues = useCallback( (updatedFormValues: Partial, isFullReset?: boolean) => { setTxInfoBar(null) - setFormValues(curve, isLoadingCurve, rFormType, updatedFormValues, vecrvInfo, isFullReset) + return setFormValues(curve, isLoadingCurve, rFormType, updatedFormValues, vecrvInfo, isFullReset) }, [curve, isLoadingCurve, vecrvInfo, rFormType, setFormValues], ) diff --git a/apps/main/src/dao/components/PageVeCrv/components/FormLockDate.tsx b/apps/main/src/dao/components/PageVeCrv/components/FormLockDate.tsx index c8b70f1406..d2236b33d7 100644 --- a/apps/main/src/dao/components/PageVeCrv/components/FormLockDate.tsx +++ b/apps/main/src/dao/components/PageVeCrv/components/FormLockDate.tsx @@ -22,6 +22,7 @@ import usePageVisibleInterval from '@ui-kit/hooks/usePageVisibleInterval' import dayjs from '@ui-kit/lib/dayjs' import { t } from '@ui-kit/lib/i18n' import { REFRESH_INTERVAL } from '@ui-kit/lib/model' +import { useThrottle } from '@ui-kit/utils/timers' const FormLockDate = ({ curve, rChainId, rFormType, vecrvInfo }: PageVecrv) => { const isSubscribed = useRef(false) @@ -33,7 +34,7 @@ const FormLockDate = ({ curve, rChainId, rFormType, vecrvInfo }: PageVecrv) => { const formStatus = useStore((state) => state.lockedCrv.formStatus) const formValues = useStore((state) => state.lockedCrv.formValues) const fetchStepIncreaseTime = useStore((state) => state.lockedCrv.fetchStepIncreaseTime) - const setFormValues = useStore((state) => state.lockedCrv.setFormValues) + const setFormValues = useThrottle(useStore((state) => state.lockedCrv.setFormValues)) const [steps, setSteps] = useState([]) const [txInfoBar, setTxInfoBar] = useState(null) @@ -58,7 +59,7 @@ const FormLockDate = ({ curve, rChainId, rFormType, vecrvInfo }: PageVecrv) => { const updateFormValues = useCallback( async (updatedFormValues: Partial, isFullReset?: boolean) => { setTxInfoBar(null) - setFormValues(curve, isLoadingCurve, rFormType, updatedFormValues, vecrvInfo, isFullReset) + return setFormValues(curve, isLoadingCurve, rFormType, updatedFormValues, vecrvInfo, isFullReset) }, [curve, isLoadingCurve, vecrvInfo, rFormType, setFormValues], ) diff --git a/apps/main/src/dex/components/PagePool/Swap/index.tsx b/apps/main/src/dex/components/PagePool/Swap/index.tsx index 78fab98c0b..c051e2d05f 100644 --- a/apps/main/src/dex/components/PagePool/Swap/index.tsx +++ b/apps/main/src/dex/components/PagePool/Swap/index.tsx @@ -42,6 +42,7 @@ import { REFRESH_INTERVAL } from '@ui-kit/lib/model' import { useTokenUsdRate } from '@ui-kit/lib/model/entities/token-usd-rate' import { LargeTokenInput } from '@ui-kit/shared/ui/LargeTokenInput' import { ReleaseChannel, decimal, type Decimal } from '@ui-kit/utils' +import { useThrottle } from '@ui-kit/utils/timers' const { cloneDeep, isNaN, isUndefined } = lodash @@ -82,7 +83,7 @@ const Swap = ({ const fetchStepApprove = useStore((state) => state.poolSwap.fetchStepApprove) const fetchStepSwap = useStore((state) => state.poolSwap.fetchStepSwap) const resetState = useStore((state) => state.poolSwap.resetState) - const setFormValues = useStore((state) => state.poolSwap.setFormValues) + const setFormValues = useThrottle(useStore((state) => state.poolSwap.setFormValues)) const setPoolIsWrapped = useStore((state) => state.pools.setPoolIsWrapped) const { data: networks } = useNetworks() const network = (chainId && networks[chainId]) || null @@ -124,7 +125,7 @@ const Swap = ({ setConfirmedLoss(false) setTxInfoBar(null) - void setFormValues( + return setFormValues( curve, poolDataCacheOrApi.pool.id, poolData, @@ -249,11 +250,16 @@ const Swap = ({ [fetchStepApprove, handleSwapClick], ) - const fetchData = useCallback(() => { - if (curve && poolData && isPageVisible && !formStatus.formProcessing && !formStatus.formTypeCompleted) { - updateFormValues({}, null, '') - } - }, [curve, formStatus.formProcessing, formStatus.formTypeCompleted, isPageVisible, poolData, updateFormValues]) + const fetchData = useCallback( + () => + curve && + poolData && + isPageVisible && + !formStatus.formProcessing && + !formStatus.formTypeCompleted && + updateFormValues({}, null, ''), + [curve, formStatus.formProcessing, formStatus.formTypeCompleted, isPageVisible, poolData, updateFormValues], + ) // onMount useEffect(() => { diff --git a/apps/main/src/dex/components/PagePool/index.tsx b/apps/main/src/dex/components/PagePool/index.tsx index c2663062fd..f943767845 100644 --- a/apps/main/src/dex/components/PagePool/index.tsx +++ b/apps/main/src/dex/components/PagePool/index.tsx @@ -119,11 +119,7 @@ const Transfer = (pageTransferProps: PageTransferProps) => { return pool.isCrypto ? '0.1' : '0.03' }, [storeMaxSlippage, pool]) - usePageVisibleInterval(() => { - if (curve && poolData) { - void fetchPoolStats(curve, poolData) - } - }, REFRESH_INTERVAL['5m']) + usePageVisibleInterval(() => curve && poolData && fetchPoolStats(curve, poolData), REFRESH_INTERVAL['5m']) useEffect(() => { if ( diff --git a/apps/main/src/dex/components/PagePoolList/index.tsx b/apps/main/src/dex/components/PagePoolList/index.tsx index f5f0eec58c..8808cce7cc 100644 --- a/apps/main/src/dex/components/PagePoolList/index.tsx +++ b/apps/main/src/dex/components/PagePoolList/index.tsx @@ -1,3 +1,4 @@ +import { isEmpty } from 'lodash' import { useCallback, useEffect, useMemo, useState } from 'react' import { PoolRow } from '@/dex/components/PagePoolList/components/PoolRow' import TableHead from '@/dex/components/PagePoolList/components/TableHead' @@ -132,11 +133,10 @@ const PoolList = ({ ], ) - usePageVisibleInterval(() => { - if (curve && rewardsApyMapper && Object.keys(rewardsApyMapper).length > 0) { - void fetchPoolsRewardsApy(rChainId, poolDatas) - } - }, REFRESH_INTERVAL['11m']) + usePageVisibleInterval( + () => curve && !isEmpty(rewardsApyMapper) && fetchPoolsRewardsApy(rChainId, poolDatas), + REFRESH_INTERVAL['11m'], + ) // init useEffect(() => { diff --git a/apps/main/src/dex/hooks/useAutoRefresh.tsx b/apps/main/src/dex/hooks/useAutoRefresh.tsx index 076a3a882c..db32126183 100644 --- a/apps/main/src/dex/hooks/useAutoRefresh.tsx +++ b/apps/main/src/dex/hooks/useAutoRefresh.tsx @@ -33,19 +33,16 @@ export const useAutoRefresh = (networkDef: NetworkDef) => { [fetchPoolsTvl, fetchPoolsVolume, poolDataMapper, setTokensMapper], ) - usePageVisibleInterval(() => { - if (curveApi) { - void fetchPoolsVolumeTvl(curveApi) - - if (curveApi.signerAddress) { - void fetchAllStoredBalances(curveApi) - } - } - }, REFRESH_INTERVAL['5m']) + usePageVisibleInterval( + () => + curveApi && + Promise.all([fetchPoolsVolumeTvl(curveApi), curveApi.signerAddress && fetchAllStoredBalances(curveApi)]), + REFRESH_INTERVAL['5m'], + ) usePageVisibleInterval(async () => { if (!curveApi || !network) return console.warn('Curve API or network is not defined, cannot refetch pools') const poolIds = await curvejsApi.network.fetchAllPoolsList(curveApi, network) - void fetchPools(curveApi, poolIds, null) + await fetchPools(curveApi, poolIds, null) }, REFRESH_INTERVAL['11m']) } diff --git a/apps/main/src/lend/components/PageLoanCreate/LoanFormCreate/index.tsx b/apps/main/src/lend/components/PageLoanCreate/LoanFormCreate/index.tsx index 8504b8958f..312518c8cb 100644 --- a/apps/main/src/lend/components/PageLoanCreate/LoanFormCreate/index.tsx +++ b/apps/main/src/lend/components/PageLoanCreate/LoanFormCreate/index.tsx @@ -36,6 +36,7 @@ import { useNavigate } from '@ui-kit/hooks/router' import usePageVisibleInterval from '@ui-kit/hooks/usePageVisibleInterval' import { t } from '@ui-kit/lib/i18n' import { REFRESH_INTERVAL } from '@ui-kit/lib/model' +import { useThrottle } from '@ui-kit/utils/timers' const LoanCreate = ({ isLeverage = false, @@ -60,7 +61,7 @@ const LoanCreate = ({ const fetchStepApprove = useStore((state) => state.loanCreate.fetchStepApprove) const fetchStepCreate = useStore((state) => state.loanCreate.fetchStepCreate) const setStateByKeyMarkets = useStore((state) => state.markets.setStateByKey) - const setFormValues = useStore((state) => state.loanCreate.setFormValues) + const setFormValues = useThrottle(useStore((state) => state.loanCreate.setFormValues)) const resetState = useStore((state) => state.loanCreate.resetState) const isAdvancedMode = useUserProfileStore((state) => state.isAdvancedMode) @@ -84,7 +85,8 @@ const LoanCreate = ({ const updateFormValues = useCallback( (updatedFormValues: Partial, isFullReset?: boolean, shouldRefetch?: boolean) => { setConfirmWarning(DEFAULT_CONFIRM_WARNING) - void setFormValues( + if (isFullReset) setHealthMode(DEFAULT_HEALTH_MODE) + return setFormValues( isLoaded ? api : null, market, isFullReset ? DEFAULT_FORM_VALUES : updatedFormValues, @@ -92,8 +94,6 @@ const LoanCreate = ({ isLeverage, shouldRefetch, ) - - if (isFullReset) setHealthMode(DEFAULT_HEALTH_MODE) }, [setFormValues, isLoaded, api, market, maxSlippage, isLeverage], ) @@ -253,11 +253,17 @@ const LoanCreate = ({ } }, []) - usePageVisibleInterval(() => { - if (isLoaded && isLeverage && !formStatus.isComplete && !formStatus.step && !formStatus.error && !isConfirming) { - updateFormValues({}) - } - }, REFRESH_INTERVAL['10s']) + usePageVisibleInterval( + () => + isLoaded && + isLeverage && + !formStatus.isComplete && + !formStatus.step && + !formStatus.error && + !isConfirming && + updateFormValues({}), + REFRESH_INTERVAL['10s'], + ) // steps useEffect(() => { diff --git a/apps/main/src/lend/components/PageLoanManage/LoanBorrowMore/index.tsx b/apps/main/src/lend/components/PageLoanManage/LoanBorrowMore/index.tsx index 1db0892d6a..b20dc771e2 100644 --- a/apps/main/src/lend/components/PageLoanManage/LoanBorrowMore/index.tsx +++ b/apps/main/src/lend/components/PageLoanManage/LoanBorrowMore/index.tsx @@ -35,6 +35,7 @@ import usePageVisibleInterval from '@ui-kit/hooks/usePageVisibleInterval' import { t } from '@ui-kit/lib/i18n' import { REFRESH_INTERVAL } from '@ui-kit/lib/model' import { SizesAndSpaces } from '@ui-kit/themes/design/1_sizes_spaces' +import { useThrottle } from '@ui-kit/utils/timers' const { Spacing } = SizesAndSpaces @@ -61,7 +62,7 @@ const LoanBorrowMore = ({ const fetchStepApprove = useStore((state) => state.loanBorrowMore.fetchStepApprove) const fetchStepIncrease = useStore((state) => state.loanBorrowMore.fetchStepIncrease) const refetchMaxRecv = useStore((state) => state.loanBorrowMore.refetchMaxRecv) - const setFormValues = useStore((state) => state.loanBorrowMore.setFormValues) + const setFormValues = useThrottle(useStore((state) => state.loanBorrowMore.setFormValues)) const resetState = useStore((state) => state.loanBorrowMore.resetState) const maxSlippage = useUserProfileStore((state) => state.maxSlippage.crypto) @@ -88,7 +89,8 @@ const LoanBorrowMore = ({ shouldRefetch?: boolean, ) => { setConfirmWarning(DEFAULT_CONFIRM_WARNING) - void setFormValues( + if (isFullReset) setHealthMode(DEFAULT_HEALTH_MODE) + return setFormValues( isLoaded ? api : null, market, isFullReset ? DEFAULT_FORM_VALUES : updatedFormValues, @@ -96,8 +98,6 @@ const LoanBorrowMore = ({ isLeverage, shouldRefetch, ) - - if (isFullReset) setHealthMode(DEFAULT_HEALTH_MODE) }, [api, isLeverage, isLoaded, maxSlippage, market, setFormValues], ) @@ -267,23 +267,29 @@ const LoanBorrowMore = ({ } }, []) - usePageVisibleInterval(() => { - if (isLoaded && isLeverage && !formStatus.isComplete && !formStatus.step && !formStatus.error && !isConfirming) { - updateFormValues({}) - } - }, REFRESH_INTERVAL['10s']) + usePageVisibleInterval( + () => + isLoaded && + isLeverage && + !formStatus.isComplete && + !formStatus.step && + !formStatus.error && + !isConfirming && + updateFormValues({}), + REFRESH_INTERVAL['10s'], + ) useEffect(() => { if (isLoaded) { resetState() - updateFormValues({}) + void updateFormValues({}) } // eslint-disable-next-line react-hooks/exhaustive-deps }, [isLoaded]) // form changed to leverage, reset form useEffect(() => { - if (isLoaded) updateFormValues(DEFAULT_FORM_VALUES, '', true) + if (isLoaded) void updateFormValues(DEFAULT_FORM_VALUES, '', true) // eslint-disable-next-line react-hooks/exhaustive-deps }, [isLeverage]) diff --git a/apps/main/src/lend/components/PageLoanManage/LoanRepay/index.tsx b/apps/main/src/lend/components/PageLoanManage/LoanRepay/index.tsx index 825f1169a8..77bb473ed0 100644 --- a/apps/main/src/lend/components/PageLoanManage/LoanRepay/index.tsx +++ b/apps/main/src/lend/components/PageLoanManage/LoanRepay/index.tsx @@ -44,6 +44,7 @@ import { t } from '@ui-kit/lib/i18n' import { REFRESH_INTERVAL } from '@ui-kit/lib/model' import { SizesAndSpaces } from '@ui-kit/themes/design/1_sizes_spaces' import { getPercentage, isGreaterThan, isGreaterThanOrEqualTo, sum } from '@ui-kit/utils' +import { useThrottle } from '@ui-kit/utils/timers' const { Spacing } = SizesAndSpaces @@ -68,7 +69,7 @@ const LoanRepay = ({ const fetchStepApprove = useStore((state) => state.loanRepay.fetchStepApprove) const fetchStepRepay = useStore((state) => state.loanRepay.fetchStepRepay) const fetchAllUserDetails = useStore((state) => state.user.fetchAll) - const setFormValues = useStore((state) => state.loanRepay.setFormValues) + const setFormValues = useThrottle(useStore((state) => state.loanRepay.setFormValues)) const resetState = useStore((state) => state.loanRepay.resetState) const maxSlippage = useUserProfileStore((state) => state.maxSlippage.crypto) @@ -98,15 +99,14 @@ const LoanRepay = ({ shouldRefetch?: boolean, ) => { setConfirmWarning(DEFAULT_CONFIRM_WARNING) - void setFormValues( + if (isFullReset) setHealthMode(DEFAULT_HEALTH_MODE) + return setFormValues( isLoaded ? api : null, market, updatedFormValues, updatedMaxSlippage || maxSlippage, shouldRefetch, ) - - if (isFullReset) setHealthMode(DEFAULT_HEALTH_MODE) }, [api, isLoaded, maxSlippage, market, setFormValues], ) @@ -131,10 +131,9 @@ const LoanRepay = ({ txHash={scanTxPath(networks[rChainId], resp.hash)} onClose={() => { if (resp.loanExists) { - updateFormValues(DEFAULT_FORM_VALUES, '', true) - } else { - push(getCollateralListPathname(params)) + return updateFormValues(DEFAULT_FORM_VALUES, '', true) } + push(getCollateralListPathname(params)) }} />, ) @@ -286,21 +285,27 @@ const LoanRepay = ({ usePageVisibleInterval(() => { const { swapRequired } = _parseValues(formValues) - if (isLoaded && swapRequired && !formStatus.isComplete && !formStatus.step && !formStatus.error && !isConfirming) { + return ( + isLoaded && + swapRequired && + !formStatus.isComplete && + !formStatus.step && + !formStatus.error && + !isConfirming && updateFormValues({}) - } + ) }, REFRESH_INTERVAL['10s']) useEffect(() => { if (isLoaded) { resetState() - updateFormValues({}) + void updateFormValues({}) } // eslint-disable-next-line react-hooks/exhaustive-deps }, [isLoaded]) useEffect(() => { - if (isLoaded) updateFormValues({}, maxSlippage) + if (isLoaded) void updateFormValues({}, maxSlippage) // eslint-disable-next-line react-hooks/exhaustive-deps }, [maxSlippage]) diff --git a/apps/main/src/lend/hooks/useAbiTotalSupply.tsx b/apps/main/src/lend/hooks/useAbiTotalSupply.tsx index fea9a111b2..13650600c6 100644 --- a/apps/main/src/lend/hooks/useAbiTotalSupply.tsx +++ b/apps/main/src/lend/hooks/useAbiTotalSupply.tsx @@ -26,9 +26,7 @@ const useAbiTotalSupply = (rChainId: ChainId, contractAddress: string | undefine if (contract && isValidAddress) void getTotalSupply(contract) }, [contract, isValidAddress, getTotalSupply]) - usePageVisibleInterval(() => { - if (contract && isValidAddress) void getTotalSupply(contract) - }, REFRESH_INTERVAL['1m']) + usePageVisibleInterval(() => contract && isValidAddress && getTotalSupply(contract), REFRESH_INTERVAL['1m']) return totalSupply } diff --git a/apps/main/src/loan/components/PageLoanCreate/Page.tsx b/apps/main/src/loan/components/PageLoanCreate/Page.tsx index f0acf91cd2..e5eb7a2754 100644 --- a/apps/main/src/loan/components/PageLoanCreate/Page.tsx +++ b/apps/main/src/loan/components/PageLoanCreate/Page.tsx @@ -157,11 +157,7 @@ const Page = () => { // eslint-disable-next-line react-hooks/exhaustive-deps }, [maxSlippage]) - usePageVisibleInterval(() => { - if (curve && llamma) { - void fetchLoanDetails(curve, llamma) - } - }, REFRESH_INTERVAL['1m']) + usePageVisibleInterval(() => curve && llamma && fetchLoanDetails(curve, llamma), REFRESH_INTERVAL['1m']) useEffect(() => { if (!isMdUp && chartExpanded) { diff --git a/apps/main/src/loan/components/PageLoanManage/LoanDeleverage/index.tsx b/apps/main/src/loan/components/PageLoanManage/LoanDeleverage/index.tsx index bff04a9ced..c82264e30e 100644 --- a/apps/main/src/loan/components/PageLoanManage/LoanDeleverage/index.tsx +++ b/apps/main/src/loan/components/PageLoanManage/LoanDeleverage/index.tsx @@ -50,6 +50,7 @@ import { useTokenUsdRate } from '@ui-kit/lib/model/entities/token-usd-rate' import { LargeTokenInput } from '@ui-kit/shared/ui/LargeTokenInput' import { TokenLabel } from '@ui-kit/shared/ui/TokenLabel' import { ReleaseChannel, decimal, type Decimal } from '@ui-kit/utils' +import { useThrottle } from '@ui-kit/utils/timers' // Loan Deleverage const LoanDeleverage = ({ @@ -72,7 +73,7 @@ const LoanDeleverage = ({ const userLoanDetails = useUserLoanDetails(llammaId) const userWalletBalancesLoading = useStore((state) => state.loans.userWalletBalancesLoading) const fetchStepRepay = useStore((state) => state.loanDeleverage.fetchStepRepay) - const setFormValues = useStore((state) => state.loanDeleverage.setFormValues) + const setFormValues = useThrottle(useStore((state) => state.loanDeleverage.setFormValues)) const isAdvancedMode = useUserProfileStore((state) => state.isAdvancedMode) const maxSlippage = useUserProfileStore((state) => state.maxSlippage.crypto) @@ -99,7 +100,7 @@ const LoanDeleverage = ({ setHealthMode(DEFAULT_HEALTH_MODE) } - void setFormValues( + return setFormValues( llammaId, curve, llamma, @@ -136,7 +137,7 @@ const LoanDeleverage = ({ txHash={scanTxPath(networks[rChainId], resp.hash)} onClose={() => { if (resp.loanExists) { - updateFormValues({}, '', true) + void updateFormValues({}, '', true) } else { push(getCollateralListPathname(params)) } @@ -206,7 +207,7 @@ const LoanDeleverage = ({ // onMount useEffect(() => { isSubscribed.current = true - updateFormValues(DEFAULT_FORM_VALUES, '', true) + void updateFormValues(DEFAULT_FORM_VALUES, '', true) return () => { isSubscribed.current = false @@ -216,15 +217,14 @@ const LoanDeleverage = ({ // signer changed useEffect(() => { - updateFormValues(DEFAULT_FORM_VALUES, '', true) - + void updateFormValues(DEFAULT_FORM_VALUES, '', true) // eslint-disable-next-line react-hooks/exhaustive-deps }, [curve?.signerAddress]) // update formValues useEffect(() => { if (chainId && llamma) { - updateFormValues({}, '', false) + void updateFormValues({}, '', false) } // eslint-disable-next-line react-hooks/exhaustive-deps }, [chainId, llamma, userState?.collateral, userLoanDetails?.userIsCloseToLiquidation]) @@ -232,7 +232,7 @@ const LoanDeleverage = ({ // maxSlippage useEffect(() => { if (maxSlippage) { - updateFormValues({}, maxSlippage, false) + void updateFormValues({}, maxSlippage, false) } // eslint-disable-next-line react-hooks/exhaustive-deps }, [maxSlippage]) @@ -240,17 +240,13 @@ const LoanDeleverage = ({ // pageVisible useEffect(() => { if (!formStatus.isInProgress) { - updateFormValues({}, '', false) + void updateFormValues({}, '', false) } // eslint-disable-next-line react-hooks/exhaustive-deps }, [isPageVisible]) // interval - usePageVisibleInterval(() => { - if (!formStatus.isInProgress) { - updateFormValues({}, '', false) - } - }, REFRESH_INTERVAL['1m']) + usePageVisibleInterval(() => !formStatus.isInProgress && updateFormValues({}, '', false), REFRESH_INTERVAL['1m']) // steps useEffect(() => { diff --git a/apps/main/src/loan/components/PageLoanManage/Page.tsx b/apps/main/src/loan/components/PageLoanManage/Page.tsx index fb888ed370..79df8d790e 100644 --- a/apps/main/src/loan/components/PageLoanManage/Page.tsx +++ b/apps/main/src/loan/components/PageLoanManage/Page.tsx @@ -133,12 +133,14 @@ const Page = () => { // eslint-disable-next-line react-hooks/exhaustive-deps }, [loaded, rFormType, llamma]) - usePageVisibleInterval(() => { - if (curve?.signerAddress && llamma && loanExists) { - void fetchLoanDetails(curve, llamma) - void fetchUserLoanDetails(curve, llamma) - } - }, REFRESH_INTERVAL['1m']) + usePageVisibleInterval( + () => + curve?.signerAddress && + llamma && + loanExists && + Promise.all([fetchLoanDetails(curve, llamma), fetchUserLoanDetails(curve, llamma)]), + REFRESH_INTERVAL['1m'], + ) useEffect(() => { if (!isMdUp && chartExpanded) { diff --git a/packages/curve-ui-kit/src/hooks/useDebounce.ts b/packages/curve-ui-kit/src/hooks/useDebounce.ts index 1e7fa509d6..262c8e76e2 100644 --- a/packages/curve-ui-kit/src/hooks/useDebounce.ts +++ b/packages/curve-ui-kit/src/hooks/useDebounce.ts @@ -79,7 +79,7 @@ export function useDebounce(initialValue: T, debounceMs: number, callback: (v */ export function useDebouncedValue( givenValue: T, - { defaultValue = givenValue, debounceMs = Duration.FormDebounce }: { defaultValue?: T; debounceMs?: number } = {}, + { defaultValue = givenValue, debounceMs = Duration.FormThrottle }: { defaultValue?: T; debounceMs?: number } = {}, ) { const [value, setValue] = useState(defaultValue) useEffect(() => { diff --git a/packages/curve-ui-kit/src/shared/ui/LargeTokenInput.tsx b/packages/curve-ui-kit/src/shared/ui/LargeTokenInput.tsx index c45bc963ce..0618956dfa 100644 --- a/packages/curve-ui-kit/src/shared/ui/LargeTokenInput.tsx +++ b/packages/curve-ui-kit/src/shared/ui/LargeTokenInput.tsx @@ -268,7 +268,7 @@ export const LargeTokenInput = ({ const [balance, setBalance, cancelSetBalance] = useUniqueDebounce({ defaultValue: externalBalance, callback: onBalance, - debounceMs: Duration.FormDebounce, + debounceMs: Duration.FormThrottle, // We don't want to trigger onBalance if the value is effectively the same, e.g. "0.0" and "0.00" equals: bigNumEquals, }) diff --git a/packages/curve-ui-kit/src/themes/design/0_primitives.ts b/packages/curve-ui-kit/src/themes/design/0_primitives.ts index 9b5f1a956f..3ba18f3a4a 100644 --- a/packages/curve-ui-kit/src/themes/design/0_primitives.ts +++ b/packages/curve-ui-kit/src/themes/design/0_primitives.ts @@ -103,10 +103,10 @@ export const Duration = { Snackbar: 6000, Tooltip: { Enter: 500, Exit: 500 }, Flicker: 1000, - FormDebounce: 500, Transition: 256, Focus: 50, Delay: 100, + FormThrottle: 166, // ~10fps at 60Hz } export const TransitionFunction = `ease-out ${Duration.Transition}ms` diff --git a/packages/curve-ui-kit/src/utils/timers.ts b/packages/curve-ui-kit/src/utils/timers.ts index f9ebc44990..88d9cc4d02 100644 --- a/packages/curve-ui-kit/src/utils/timers.ts +++ b/packages/curve-ui-kit/src/utils/timers.ts @@ -1,3 +1,7 @@ +import { throttle } from 'lodash' +import { useMemo } from 'react' +import { Duration } from '@ui-kit/themes/design/0_primitives' + /** * Replaces setInterval using recursive setTimeout. * Returns a cancel function to stop future executions. @@ -27,3 +31,6 @@ export function setTimeoutInterval(callback: () => unknown, delay: number): () = clearTimeout(timeoutId) } } + +export const useThrottle = any>(f: T, duration = Duration.FormThrottle) => + useMemo(() => throttle(f, duration), [f, duration]) From 74e5e7143e5a1b5c66cd0800dcf767f973df2a42 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Fri, 31 Oct 2025 16:27:51 +0100 Subject: [PATCH 02/12] chore: replace void by errorCallback --- .../Charts/GaugeWeightHistoryChart/index.tsx | 5 +- .../PageAnalytics/DailyLocksChart/index.tsx | 3 +- .../PageAnalytics/VeCrvFeesTable/index.tsx | 3 +- .../dao/components/PageAnalytics/index.tsx | 3 +- .../PageGauge/GaugeVotesTable/index.tsx | 3 +- .../GaugeListItem/SmallScreenCard.tsx | 5 +- .../PageGauges/GaugeListItem/index.tsx | 5 +- .../GaugeVoting/VoteGaugeField/index.tsx | 3 +- .../src/dao/components/PageProposal/index.tsx | 3 +- .../src/dao/components/PageUser/index.tsx | 5 +- .../PageVeCrv/components/FormLockCreate.tsx | 4 +- .../PageVeCrv/components/FormLockCrv.tsx | 4 +- .../PageVeCrv/components/FormLockDate.tsx | 18 ++-- .../src/dao/store/createLockedCrvSlice.ts | 3 +- apps/main/src/dex/components/ChipToken.tsx | 3 +- .../dex/components/PageCompensation/Page.tsx | 3 +- .../dex/components/PageCompensation/index.tsx | 5 +- .../TokensInPool/SelectTokenButton.tsx | 3 +- .../components/TableCellRewardsTooltip.tsx | 5 +- .../PageDashboard/dashboardContext.ts | 2 +- .../dex/components/PageDashboard/index.tsx | 5 +- .../dex/components/PageIntegrations/Page.tsx | 3 +- .../Deposit/components/FieldsDeposit.tsx | 7 +- .../Deposit/components/FormDeposit.tsx | 9 +- .../Deposit/components/FormDepositStake.tsx | 9 +- .../PagePool/Deposit/components/FormStake.tsx | 12 ++- .../main/src/dex/components/PagePool/Page.tsx | 5 +- .../PagePool/PoolDetails/PoolStats/index.tsx | 3 +- .../dex/components/PagePool/Swap/index.tsx | 21 +++-- .../Withdraw/components/FormClaim.tsx | 14 ++-- .../Withdraw/components/FormUnstake.tsx | 5 +- .../Withdraw/components/FormWithdraw.tsx | 5 +- .../src/dex/components/PagePool/index.tsx | 5 +- .../components/RouterSwapAlerts.tsx | 2 +- .../dex/components/PageRouterSwap/index.tsx | 84 ++++++++++--------- apps/main/src/dex/hooks/useAutoRefresh.tsx | 3 +- .../main/src/dex/hooks/usePoolTotalStaked.tsx | 5 +- apps/main/src/dex/lib/curvejs.ts | 19 +++-- apps/main/src/dex/store/createCacheSlice.ts | 3 +- .../src/dex/store/createDashboardSlice.ts | 12 ++- apps/main/src/dex/store/createGlobalSlice.ts | 14 ++-- .../src/dex/store/createLockedCrvSlice.ts | 7 +- .../src/dex/store/createPoolDepositSlice.ts | 11 ++- .../main/src/dex/store/createPoolListSlice.ts | 12 +-- .../main/src/dex/store/createPoolSwapSlice.ts | 27 ++++-- .../src/dex/store/createPoolWithdrawSlice.ts | 17 ++-- apps/main/src/dex/store/createPoolsSlice.ts | 9 +- .../src/dex/store/createQuickSwapSlice.ts | 32 +++---- .../ChartOhlcWrapper/PoolActivity.tsx | 3 +- .../components/ChartOhlcWrapper/index.tsx | 47 ++++++----- .../lend/components/PageIntegrations/Page.tsx | 3 +- .../PageLoanCreate/LoanFormCreate/index.tsx | 22 ++--- .../lend/components/PageLoanCreate/types.ts | 2 +- .../PageLoanManage/LoanBorrowMore/index.tsx | 9 +- .../LoanCollateralAdd/index.tsx | 5 +- .../LoanCollateralRemove/index.tsx | 3 +- .../PageLoanManage/LoanRepay/index.tsx | 7 +- .../LoanSelfLiquidation/index.tsx | 5 +- .../lend/components/PageLoanManage/Page.tsx | 20 +++-- .../components/PageVault/VaultClaim/index.tsx | 16 ++-- .../PageVault/VaultDepositMint/index.tsx | 14 ++-- .../components/PageVault/VaultStake/index.tsx | 14 ++-- .../PageVault/VaultUnstake/index.tsx | 10 +-- .../PageVault/VaultWithdrawRedeem/index.tsx | 18 ++-- apps/main/src/lend/components/TokenLabel.tsx | 3 +- apps/main/src/lend/hooks/useContract.ts | 3 +- .../lend/store/createLoanBorrowMoreSlice.ts | 13 +-- .../store/createLoanCollateralAddSlice.ts | 15 ++-- .../store/createLoanCollateralRemoveSlice.ts | 17 ++-- .../src/lend/store/createLoanCreateSlice.ts | 13 +-- .../src/lend/store/createLoanRepaySlice.ts | 13 +-- .../store/createLoanSelfLiquidationSlice.ts | 11 +-- .../src/lend/store/createVaultClaimSlice.ts | 12 +-- .../lend/store/createVaultDepositMintSlice.ts | 15 ++-- .../src/lend/store/createVaultStakeSlice.ts | 14 ++-- .../src/lend/store/createVaultUnstakeSlice.ts | 13 +-- .../store/createVaultWithdrawRedeemSlice.ts | 17 ++-- .../borrow/components/BorrowTabContents.tsx | 3 +- .../components/ChartOhlcWrapper/index.tsx | 39 +++++---- .../DepositWithdraw/DeployButton.tsx | 16 ++-- .../DepositWithdraw/index.tsx | 7 +- .../components/PageCrvUsdStaking/index.tsx | 26 +++--- .../loan/components/PageIntegrations/Page.tsx | 3 +- .../PageLoanCreate/LoanFormCreate/index.tsx | 7 +- .../loan/components/PageLoanCreate/Page.tsx | 16 ++-- .../loan/components/PageLoanCreate/types.ts | 2 +- .../CollateralDecrease/index.tsx | 9 +- .../CollateralIncrease/index.tsx | 4 +- .../PageLoanManage/LoanDecrease/index.tsx | 4 +- .../PageLoanManage/LoanDeleverage/index.tsx | 17 ++-- .../PageLoanManage/LoanIncrease/index.tsx | 5 +- .../PageLoanManage/LoanLiquidate/index.tsx | 5 +- .../loan/components/PageLoanManage/Page.tsx | 5 +- .../src/loan/store/createCollateralsSlice.ts | 5 +- .../createLoanCollateralDecreaseSlice.ts | 15 ++-- .../createLoanCollateralIncreaseSlice.ts | 13 ++- .../src/loan/store/createLoanCreateSlice.ts | 41 ++++----- .../src/loan/store/createLoanDecreaseSlice.ts | 16 ++-- .../loan/store/createLoanDeleverageSlice.ts | 7 +- .../src/loan/store/createLoanIncreaseSlice.ts | 15 ++-- .../src/loan/store/createLoanLiquidate.ts | 9 +- apps/main/src/loan/store/createLoansSlice.ts | 6 +- .../main/src/loan/store/createScrvUsdSlice.ts | 3 +- .../connect-wallet/lib/ConnectionProvider.tsx | 3 +- .../curve-ui-kit/src/hooks/useLocalStorage.ts | 3 + .../curve-ui-kit/src/shared/ui/ActionInfo.tsx | 3 +- .../curve-ui-kit/src/shared/ui/Metric.tsx | 3 +- packages/curve-ui-kit/src/utils/error.util.ts | 18 ++++ .../src/widgets/ErrorBoundary.tsx | 2 + packages/ui/src/Chart/CandleChart.tsx | 2 +- 110 files changed, 649 insertions(+), 488 deletions(-) create mode 100644 packages/curve-ui-kit/src/utils/error.util.ts diff --git a/apps/main/src/dao/components/Charts/GaugeWeightHistoryChart/index.tsx b/apps/main/src/dao/components/Charts/GaugeWeightHistoryChart/index.tsx index d811073e45..c6e491666d 100644 --- a/apps/main/src/dao/components/Charts/GaugeWeightHistoryChart/index.tsx +++ b/apps/main/src/dao/components/Charts/GaugeWeightHistoryChart/index.tsx @@ -5,6 +5,7 @@ import ErrorMessage from '@/dao/components/ErrorMessage' import useStore from '@/dao/store/useStore' import Spinner, { SpinnerWrapper } from '@ui/Spinner' import { t } from '@ui-kit/lib/i18n' +import { errorFallback } from '@ui-kit/utils/error.util' interface GaugeWeightHistoryChartProps { gaugeAddress: string @@ -21,7 +22,7 @@ const GaugeWeightHistoryChart = ({ gaugeAddress, minHeight }: GaugeWeightHistory useEffect(() => { if (!gaugeWeightHistoryMapper[gaugeAddress]) { - void getHistoricGaugeWeights(gaugeAddress) + getHistoricGaugeWeights(gaugeAddress).catch(errorFallback) } }, [gaugeAddress, gaugeWeightHistoryMapper, getHistoricGaugeWeights]) @@ -33,7 +34,7 @@ const GaugeWeightHistoryChart = ({ gaugeAddress, minHeight }: GaugeWeightHistory message={t`Error fetching historical gauge weights data`} onClick={(e?: MouseEvent) => { e?.stopPropagation() - void getHistoricGaugeWeights(gaugeAddress) + getHistoricGaugeWeights(gaugeAddress).catch(errorFallback) }} /> diff --git a/apps/main/src/dao/components/PageAnalytics/DailyLocksChart/index.tsx b/apps/main/src/dao/components/PageAnalytics/DailyLocksChart/index.tsx index 4fe8ab0aa1..190520f82f 100644 --- a/apps/main/src/dao/components/PageAnalytics/DailyLocksChart/index.tsx +++ b/apps/main/src/dao/components/PageAnalytics/DailyLocksChart/index.tsx @@ -4,6 +4,7 @@ import ErrorMessage from '@/dao/components/ErrorMessage' import useStore from '@/dao/store/useStore' import Box from '@ui/Box' import { t } from '@ui-kit/lib/i18n' +import { errorFallback } from '@ui-kit/utils/error.util' import Spinner from '../../Spinner' import PositiveAndNegativeBarChart from './PositiveAndNegativeBarChart' @@ -17,7 +18,7 @@ const DailyLocks = () => { useEffect(() => { if (veCrvLocks.locks.length === 0 && veCrvLocks.fetchStatus !== 'ERROR') { - void getVeCrvLocks() + getVeCrvLocks().catch(errorFallback) } }, [getVeCrvLocks, veCrvLocks.locks.length, veCrvLocks.fetchStatus]) diff --git a/apps/main/src/dao/components/PageAnalytics/VeCrvFeesTable/index.tsx b/apps/main/src/dao/components/PageAnalytics/VeCrvFeesTable/index.tsx index 9cda510769..ae8128e746 100644 --- a/apps/main/src/dao/components/PageAnalytics/VeCrvFeesTable/index.tsx +++ b/apps/main/src/dao/components/PageAnalytics/VeCrvFeesTable/index.tsx @@ -5,6 +5,7 @@ import useStore from '@/dao/store/useStore' import Box from '@ui/Box' import { formatDate, formatNumber } from '@ui/utils' import { t } from '@ui-kit/lib/i18n' +import { errorFallback } from '@ui-kit/utils/error.util' import Spinner from '../../Spinner' import VeCrvFeesChart from '../VeCrvFeesChart' @@ -18,7 +19,7 @@ const VeCrcFees = () => { useEffect(() => { if (veCrvFees.fees.length === 0 && !feesError) { - void getVeCrvFees() + getVeCrvFees().catch(errorFallback) } }, [getVeCrvFees, veCrvFees, feesError]) diff --git a/apps/main/src/dao/components/PageAnalytics/index.tsx b/apps/main/src/dao/components/PageAnalytics/index.tsx index a7c0bf8197..7ed997906c 100644 --- a/apps/main/src/dao/components/PageAnalytics/index.tsx +++ b/apps/main/src/dao/components/PageAnalytics/index.tsx @@ -4,6 +4,7 @@ import useStore from '@/dao/store/useStore' import Box from '@ui/Box' import { t } from '@ui-kit/lib/i18n' import { TabsSwitcher, type TabOption } from '@ui-kit/shared/ui/TabsSwitcher' +import { errorFallback } from '@ui-kit/utils/error.util' import CrvStats from './CrvStats' import DailyLocks from './DailyLocksChart' import HoldersTable from './HoldersTable' @@ -24,7 +25,7 @@ const Analytics = () => { useEffect(() => { if (veCrvHolders.topHolders.length === 0 && veCrvHolders.fetchStatus !== 'ERROR') { - void getVeCrvHolders() + getVeCrvHolders().catch(errorFallback) } }, [getVeCrvHolders, veCrvHolders.topHolders.length, veCrvHolders.fetchStatus]) diff --git a/apps/main/src/dao/components/PageGauge/GaugeVotesTable/index.tsx b/apps/main/src/dao/components/PageGauge/GaugeVotesTable/index.tsx index 31a17bc8be..4967ebeaf4 100644 --- a/apps/main/src/dao/components/PageGauge/GaugeVotesTable/index.tsx +++ b/apps/main/src/dao/components/PageGauge/GaugeVotesTable/index.tsx @@ -9,6 +9,7 @@ import { formatLocaleDate } from '@ui/utils/' import { t } from '@ui-kit/lib/i18n' import { DAO_ROUTES } from '@ui-kit/shared/routes' import { shortenAddress } from '@ui-kit/utils' +import { errorFallback } from '@ui-kit/utils/error.util' import { GAUGE_VOTES_TABLE_LABELS } from './constants' interface GaugeVotesTableProps { @@ -40,7 +41,7 @@ const GaugeVotesTable = ({ gaugeAddress, tableMinWidth }: GaugeVotesTableProps) // Get user proposal votes useEffect(() => { if (!gaugeVotesMapper[gaugeAddress] && gaugeVotesLoading && !gaugeVotesError) { - void getGaugeVotes(gaugeAddress) + getGaugeVotes(gaugeAddress).catch(errorFallback) } }, [getGaugeVotes, gaugeAddress, gaugeVotesLoading, gaugeVotesError, gaugeVotesMapper]) diff --git a/apps/main/src/dao/components/PageGauges/GaugeListItem/SmallScreenCard.tsx b/apps/main/src/dao/components/PageGauges/GaugeListItem/SmallScreenCard.tsx index 9368bf275e..bf91e46a37 100644 --- a/apps/main/src/dao/components/PageGauges/GaugeListItem/SmallScreenCard.tsx +++ b/apps/main/src/dao/components/PageGauges/GaugeListItem/SmallScreenCard.tsx @@ -12,6 +12,7 @@ import Spinner, { SpinnerWrapper } from '@ui/Spinner' import { t } from '@ui-kit/lib/i18n' import { DAO_ROUTES } from '@ui-kit/shared/routes' import { formatNumber } from '@ui-kit/utils' +import { errorFallback } from '@ui-kit/utils/error.util' import VoteGaugeField from '../GaugeVoting/VoteGaugeField' import GaugeDetailsSm from './GaugeDetailsSm' import TitleComp from './TitleComp' @@ -45,7 +46,7 @@ const SmallScreenCard = ({ useEffect(() => { if (open && !gaugeWeightHistoryMapper[gaugeData.address]) { - void getHistoricGaugeWeights(gaugeData.address) + getHistoricGaugeWeights(gaugeData.address).catch(errorFallback) } }, [gaugeData.address, gaugeWeightHistoryMapper, getHistoricGaugeWeights, open]) @@ -115,7 +116,7 @@ const SmallScreenCard = ({ message={t`Error fetching historical gauge weights data`} onClick={(e?: MouseEvent) => { e?.stopPropagation() - void getHistoricGaugeWeights(gaugeData.address) + getHistoricGaugeWeights(gaugeData.address).catch(errorFallback) }} /> diff --git a/apps/main/src/dao/components/PageGauges/GaugeListItem/index.tsx b/apps/main/src/dao/components/PageGauges/GaugeListItem/index.tsx index a4c0f4244b..bc4dd9d84a 100644 --- a/apps/main/src/dao/components/PageGauges/GaugeListItem/index.tsx +++ b/apps/main/src/dao/components/PageGauges/GaugeListItem/index.tsx @@ -19,6 +19,7 @@ import IconButton from '@ui/IconButton' import Spinner, { SpinnerWrapper } from '@ui/Spinner' import { t } from '@ui-kit/lib/i18n' import { DAO_ROUTES } from '@ui-kit/shared/routes' +import { errorFallback } from '@ui-kit/utils/error.util' import { Chain } from '@ui-kit/utils/network' type Props = { @@ -69,7 +70,7 @@ const GaugeListItem = ({ useEffect(() => { if (open && !gaugeWeightHistoryMapper[gaugeData.address]) { - void getHistoricGaugeWeights(gaugeData.address) + getHistoricGaugeWeights(gaugeData.address).catch(errorFallback) } }, [gaugeData.address, gaugeWeightHistoryMapper, getHistoricGaugeWeights, open]) @@ -113,7 +114,7 @@ const GaugeListItem = ({ message={t`Error fetching historical gauge weights data`} onClick={(e?: MouseEvent) => { e?.stopPropagation() - void getHistoricGaugeWeights(gaugeData.address) + getHistoricGaugeWeights(gaugeData.address).catch(errorFallback) }} /> diff --git a/apps/main/src/dao/components/PageGauges/GaugeVoting/VoteGaugeField/index.tsx b/apps/main/src/dao/components/PageGauges/GaugeVoting/VoteGaugeField/index.tsx index ba5fdfcdb0..aa2e3501c7 100644 --- a/apps/main/src/dao/components/PageGauges/GaugeVoting/VoteGaugeField/index.tsx +++ b/apps/main/src/dao/components/PageGauges/GaugeVoting/VoteGaugeField/index.tsx @@ -9,6 +9,7 @@ import Button from '@ui/Button' import TooltipIcon from '@ui/Tooltip/TooltipIcon' import { convertToLocaleTimestamp, formatDate, formatNumber } from '@ui/utils' import { t } from '@ui-kit/lib/i18n' +import { errorFallback } from '@ui-kit/utils/error.util' import { Chain } from '@ui-kit/utils/network' import NumberField from './NumberField' @@ -49,7 +50,7 @@ const VoteGaugeField = ({ powerUsed, userGaugeVoteData, userVeCrv, newVote = fal const handleCastVote = () => { if (!address) return - void castVote(address, gaugeAddress, power) + castVote(address, gaugeAddress, power).catch(errorFallback) } return ( diff --git a/apps/main/src/dao/components/PageProposal/index.tsx b/apps/main/src/dao/components/PageProposal/index.tsx index f7b6ae8cc9..08a7c04fe2 100644 --- a/apps/main/src/dao/components/PageProposal/index.tsx +++ b/apps/main/src/dao/components/PageProposal/index.tsx @@ -19,6 +19,7 @@ import { useWallet } from '@ui-kit/features/connect-wallet' import { t } from '@ui-kit/lib/i18n' import { DAO_ROUTES } from '@ui-kit/shared/routes' import { copyToClipboard } from '@ui-kit/utils' +import { errorFallback } from '@ui-kit/utils/error.util' import BackButton from '../BackButton' import ProposalVoteStatusBox from '../ProposalVoteStatusBox' import UserBox from '../UserBox' @@ -72,7 +73,7 @@ export const Proposal = ({ proposalId: rProposalId, network }: ProposalUrlParams setSnapshotVeCrv(signer, userAddress, proposal.block, rProposalId) } - void getVeCrv() + getVeCrv().catch(errorFallback) } }, [provider, rChainId, rProposalId, setSnapshotVeCrv, proposal?.block, snapshotVeCrv, userAddress]) diff --git a/apps/main/src/dao/components/PageUser/index.tsx b/apps/main/src/dao/components/PageUser/index.tsx index e34ccf4e01..18908ecb8c 100644 --- a/apps/main/src/dao/components/PageUser/index.tsx +++ b/apps/main/src/dao/components/PageUser/index.tsx @@ -7,6 +7,7 @@ import Box from '@ui/Box' import { useWallet } from '@ui-kit/features/connect-wallet' import { t } from '@ui-kit/lib/i18n' import { TabsSwitcher, type TabOption } from '@ui-kit/shared/ui/TabsSwitcher' +import { errorFallback } from '@ui-kit/utils/error.util' import UserGaugeVotesTable from './UserGaugeVotesTable' import UserHeader from './UserHeader' import UserLocksTable from './UserLocksTable' @@ -51,14 +52,14 @@ const UserPage = ({ routerParams: { userAddress: rUserAddress } }: UserPageProps useEffect(() => { if (Object.keys(allHolders).length === 0 && holdersLoading && !holdersError) { - void getVeCrvHolders() + getVeCrvHolders().catch(errorFallback) } }, [getVeCrvHolders, allHolders, holdersLoading, holdersError]) // Get user ENS useEffect(() => { if (!userMapper[userAddress] && provider) { - void getUserEns(userAddress) + getUserEns(userAddress).catch(errorFallback) } }, [getUserEns, userAddress, userMapper, provider]) diff --git a/apps/main/src/dao/components/PageVeCrv/components/FormLockCreate.tsx b/apps/main/src/dao/components/PageVeCrv/components/FormLockCreate.tsx index 244b77719c..6afaa76c49 100644 --- a/apps/main/src/dao/components/PageVeCrv/components/FormLockCreate.tsx +++ b/apps/main/src/dao/components/PageVeCrv/components/FormLockCreate.tsx @@ -47,9 +47,9 @@ const FormLockCreate = ({ curve, rChainId, rFormType, vecrvInfo }: PageVecrv) => const maxUtcDate = dayjs.utc().add(4, 'year') const updateFormValues = useCallback( - (updatedFormValues: Partial, isFullReset?: boolean) => { + async (updatedFormValues: Partial, isFullReset?: boolean) => { setTxInfoBar(null) - return setFormValues(curve, isLoadingCurve, rFormType, updatedFormValues, vecrvInfo, isFullReset) + await setFormValues(curve, isLoadingCurve, rFormType, updatedFormValues, vecrvInfo, isFullReset) }, [curve, isLoadingCurve, vecrvInfo, rFormType, setFormValues], ) diff --git a/apps/main/src/dao/components/PageVeCrv/components/FormLockCrv.tsx b/apps/main/src/dao/components/PageVeCrv/components/FormLockCrv.tsx index a9e49693a3..1f7d91db75 100644 --- a/apps/main/src/dao/components/PageVeCrv/components/FormLockCrv.tsx +++ b/apps/main/src/dao/components/PageVeCrv/components/FormLockCrv.tsx @@ -39,9 +39,9 @@ const FormLockCrv = ({ curve, rChainId, rFormType, vecrvInfo }: PageVecrv) => { const haveSigner = !!signerAddress const updateFormValues = useCallback( - (updatedFormValues: Partial, isFullReset?: boolean) => { + async (updatedFormValues: Partial, isFullReset?: boolean) => { setTxInfoBar(null) - return setFormValues(curve, isLoadingCurve, rFormType, updatedFormValues, vecrvInfo, isFullReset) + await setFormValues(curve, isLoadingCurve, rFormType, updatedFormValues, vecrvInfo, isFullReset) }, [curve, isLoadingCurve, vecrvInfo, rFormType, setFormValues], ) diff --git a/apps/main/src/dao/components/PageVeCrv/components/FormLockDate.tsx b/apps/main/src/dao/components/PageVeCrv/components/FormLockDate.tsx index d2236b33d7..67318017d4 100644 --- a/apps/main/src/dao/components/PageVeCrv/components/FormLockDate.tsx +++ b/apps/main/src/dao/components/PageVeCrv/components/FormLockDate.tsx @@ -22,6 +22,7 @@ import usePageVisibleInterval from '@ui-kit/hooks/usePageVisibleInterval' import dayjs from '@ui-kit/lib/dayjs' import { t } from '@ui-kit/lib/i18n' import { REFRESH_INTERVAL } from '@ui-kit/lib/model' +import { errorFallback } from '@ui-kit/utils/error.util' import { useThrottle } from '@ui-kit/utils/timers' const FormLockDate = ({ curve, rChainId, rFormType, vecrvInfo }: PageVecrv) => { @@ -59,7 +60,7 @@ const FormLockDate = ({ curve, rChainId, rFormType, vecrvInfo }: PageVecrv) => { const updateFormValues = useCallback( async (updatedFormValues: Partial, isFullReset?: boolean) => { setTxInfoBar(null) - return setFormValues(curve, isLoadingCurve, rFormType, updatedFormValues, vecrvInfo, isFullReset) + await setFormValues(curve, isLoadingCurve, rFormType, updatedFormValues, vecrvInfo, isFullReset) }, [curve, isLoadingCurve, vecrvInfo, rFormType, setFormValues], ) @@ -78,7 +79,7 @@ const FormLockDate = ({ curve, rChainId, rFormType, vecrvInfo }: PageVecrv) => { const fn = networks[rChainId].api.lockCrv.calcUnlockTime const calcdUtcDate = fn(curve, rFormType, currUnlockTime, days) - void updateFormValues( + updateFormValues( { utcDate: toCalendarDate(utcDate), utcDateError, @@ -87,7 +88,7 @@ const FormLockDate = ({ curve, rChainId, rFormType, vecrvInfo }: PageVecrv) => { days, }, false, - ) + ).catch(errorFallback) }, [currUnlockTime, currUnlockUtcTime, haveSigner, maxUtcDate, minUtcDate, rChainId, rFormType, updateFormValues], ) @@ -99,10 +100,10 @@ const FormLockDate = ({ curve, rChainId, rFormType, vecrvInfo }: PageVecrv) => { if (!value || !unit) { const days = maxUtcDate.diff(currUnlockUtcTime, 'd') const calcdUtcDate = calcUnlockTime(curve, rFormType, currUnlockTime, days) - void updateFormValues( + updateFormValues( { utcDate: toCalendarDate(calcdUtcDate), utcDateError: '', days, calcdUtcDate: '' }, false, - ) + ).catch(errorFallback) return maxUtcDate } @@ -110,7 +111,10 @@ const FormLockDate = ({ curve, rChainId, rFormType, vecrvInfo }: PageVecrv) => { const days = utcDate.diff(currUnlockUtcTime, 'd') const calcdUtcDate = calcUnlockTime(curve, rFormType, currUnlockTime, days) - void updateFormValues({ utcDate: toCalendarDate(calcdUtcDate), calcdUtcDate: '', utcDateError: '', days }, false) + updateFormValues( + { utcDate: toCalendarDate(calcdUtcDate), calcdUtcDate: '', utcDateError: '', days }, + false, + ).catch(errorFallback) return calcdUtcDate }, [currUnlockTime, currUnlockUtcTime, maxUtcDate, rChainId, rFormType, updateFormValues], @@ -161,7 +165,7 @@ const FormLockDate = ({ curve, rChainId, rFormType, vecrvInfo }: PageVecrv) => { // onMount useEffect(() => { isSubscribed.current = true - void updateFormValues({}, true) + updateFormValues({}, true).catch(errorFallback) return () => { isSubscribed.current = false diff --git a/apps/main/src/dao/store/createLockedCrvSlice.ts b/apps/main/src/dao/store/createLockedCrvSlice.ts index 40d66982e5..455c9ff60c 100644 --- a/apps/main/src/dao/store/createLockedCrvSlice.ts +++ b/apps/main/src/dao/store/createLockedCrvSlice.ts @@ -19,6 +19,7 @@ import { getErrorMessage } from '@/dao/utils' import { shortenAccount } from '@ui/utils' import { notify, requireLib, useWallet } from '@ui-kit/features/connect-wallet' import { t } from '@ui-kit/lib/i18n' +import { errorFallback } from '@ui-kit/utils/error.util' import { setMissingProvider } from '@ui-kit/utils/store.util' type StateKey = keyof typeof DEFAULT_STATE @@ -113,7 +114,7 @@ const createLockedCrvSlice = (set: StoreApi['setState'], get: StoreApi { if (usdRate == null) { - void fetchTokenUsdRate({ chainId, tokenAddress }).then(setUsdRate) + fetchTokenUsdRate({ chainId, tokenAddress }).then(setUsdRate).catch(errorFallback) } }, [usdRate, chainId, tokenAddress]) diff --git a/apps/main/src/dex/components/PageCompensation/Page.tsx b/apps/main/src/dex/components/PageCompensation/Page.tsx index 896c68f024..9a1cc4dfb3 100644 --- a/apps/main/src/dex/components/PageCompensation/Page.tsx +++ b/apps/main/src/dex/components/PageCompensation/Page.tsx @@ -14,6 +14,7 @@ import Spinner, { SpinnerWrapper } from '@ui/Spinner' import { isLoading, useConnection, useWallet } from '@ui-kit/features/connect-wallet' import { useParams } from '@ui-kit/hooks/router' import { t } from '@ui-kit/lib/i18n' +import { errorFallback } from '@ui-kit/utils/error.util' export const PageCompensation = () => { const { network } = useParams() @@ -38,7 +39,7 @@ export const PageCompensation = () => { // get initial data useEffect(() => { if (!isConnecting && provider) { - void fetchData(provider) + fetchData(provider).catch(errorFallback) } }, [fetchData, isConnecting, provider]) diff --git a/apps/main/src/dex/components/PageCompensation/index.tsx b/apps/main/src/dex/components/PageCompensation/index.tsx index d4f6b389b9..511ab6f2d6 100644 --- a/apps/main/src/dex/components/PageCompensation/index.tsx +++ b/apps/main/src/dex/components/PageCompensation/index.tsx @@ -7,6 +7,7 @@ import type { Balances, EtherContract, VestedTotals } from '@/dex/components/Pag import { CurveApi, ChainId, Provider } from '@/dex/types/main.types' import { getErrorMessage } from '@/dex/utils' import Box from '@ui/Box' +import { errorFallback } from '@ui-kit/utils/error.util' const FormCompensation = ({ rChainId, @@ -98,8 +99,8 @@ const FormCompensation = ({ setVestedTotals({}) if (signerAddress) { - void getBalances(signerAddress, contracts) - void getVestContract(signerAddress, contracts) + getBalances(signerAddress, contracts).catch(errorFallback) + getVestContract(signerAddress, contracts).catch(errorFallback) } // eslint-disable-next-line react-hooks/exhaustive-deps }, [signerAddress]) diff --git a/apps/main/src/dex/components/PageCreatePool/TokensInPool/SelectTokenButton.tsx b/apps/main/src/dex/components/PageCreatePool/TokensInPool/SelectTokenButton.tsx index fbdedf323c..027c11e257 100644 --- a/apps/main/src/dex/components/PageCreatePool/TokensInPool/SelectTokenButton.tsx +++ b/apps/main/src/dex/components/PageCreatePool/TokensInPool/SelectTokenButton.tsx @@ -19,6 +19,7 @@ import { useIsMobile } from '@ui-kit/hooks/useBreakpoints' import { t } from '@ui-kit/lib/i18n' import { TokenIcon } from '@ui-kit/shared/ui/TokenIcon' import { type Address, filterTokens, shortenAddress } from '@ui-kit/utils' +import { errorFallback } from '@ui-kit/utils/error.util' type Props = { curve: CurveApi @@ -119,7 +120,7 @@ const SelectTokenButton = ({ } } } - void updateUserAddedToken() + updateUserAddedToken().catch(errorFallback) }, [basePools, chainId, curve, filterValue, options, updateUserAddedTokens, userAddedTokens]) const selectedToken = useMemo( diff --git a/apps/main/src/dex/components/PageDashboard/components/TableCellRewardsTooltip.tsx b/apps/main/src/dex/components/PageDashboard/components/TableCellRewardsTooltip.tsx index 3a01c81fa1..15887f2711 100644 --- a/apps/main/src/dex/components/PageDashboard/components/TableCellRewardsTooltip.tsx +++ b/apps/main/src/dex/components/PageDashboard/components/TableCellRewardsTooltip.tsx @@ -5,6 +5,7 @@ import { RewardCrv } from '@/dex/types/main.types' import { rewardsApyCrvText } from '@/dex/utils/utilsCurvejs' import Box from '@ui/Box' import { FORMAT_OPTIONS, formatNumber } from '@ui/utils' +import { errorFallback } from '@ui-kit/utils/error.util' type Props = { crv?: RewardCrv[] @@ -18,13 +19,13 @@ const TableCellRewardsTooltip = ({ crv = [], userCrvApy, fetchUserPoolBoost }: P useEffect(() => { isSubscribed.current = true - void (async () => { + ;(async () => { const fetchedBoosted = await fetchUserPoolBoost() if (isSubscribed.current) { setBoost(fetchedBoosted) } - })() + })().catch(errorFallback) return () => { isSubscribed.current = false diff --git a/apps/main/src/dex/components/PageDashboard/dashboardContext.ts b/apps/main/src/dex/components/PageDashboard/dashboardContext.ts index 2f2ead4e3c..2d549240dc 100644 --- a/apps/main/src/dex/components/PageDashboard/dashboardContext.ts +++ b/apps/main/src/dex/components/PageDashboard/dashboardContext.ts @@ -14,7 +14,7 @@ type DashboardContextType = { isValidAddress: boolean dashboardDataPoolIds: string[] | undefined dashboardDataMapper: DashboardDataMapper | undefined - updateFormValues: (updatedFormValues: Partial) => void + updateFormValues: (updatedFormValues: Partial) => Promise } export const DashboardContext = createContext(null) diff --git a/apps/main/src/dex/components/PageDashboard/index.tsx b/apps/main/src/dex/components/PageDashboard/index.tsx index 5aca073045..449236f431 100644 --- a/apps/main/src/dex/components/PageDashboard/index.tsx +++ b/apps/main/src/dex/components/PageDashboard/index.tsx @@ -74,9 +74,8 @@ const Dashboard = ({ } const updateFormValues = useCallback( - (updatedFormValues: Partial) => { - setFormValues(rChainId, !pageLoaded ? null : curve, poolsMapper, updatedFormValues) - }, + async (updatedFormValues: Partial) => + setFormValues(rChainId, !pageLoaded ? null : curve, poolsMapper, updatedFormValues), [curve, pageLoaded, poolsMapper, rChainId, setFormValues], ) diff --git a/apps/main/src/dex/components/PageIntegrations/Page.tsx b/apps/main/src/dex/components/PageIntegrations/Page.tsx index 610dca3c1b..415be88720 100644 --- a/apps/main/src/dex/components/PageIntegrations/Page.tsx +++ b/apps/main/src/dex/components/PageIntegrations/Page.tsx @@ -9,6 +9,7 @@ import Spinner, { SpinnerWrapper } from '@ui/Spinner' import { breakpoints } from '@ui/utils/responsive' import { useParams } from '@ui-kit/hooks/router' import { Trans } from '@ui-kit/lib/i18n' +import { errorFallback } from '@ui-kit/utils/error.util' const Page = () => { const { network } = useParams() @@ -17,7 +18,7 @@ const Page = () => { const integrationsTags = useStore((state) => state.integrations.integrationsTags) useEffect(() => { - void init(rChainId) + init(rChainId).catch(errorFallback) }, [init, rChainId]) return ( diff --git a/apps/main/src/dex/components/PagePool/Deposit/components/FieldsDeposit.tsx b/apps/main/src/dex/components/PagePool/Deposit/components/FieldsDeposit.tsx index 1e33b6c262..7251fe665c 100644 --- a/apps/main/src/dex/components/PagePool/Deposit/components/FieldsDeposit.tsx +++ b/apps/main/src/dex/components/PagePool/Deposit/components/FieldsDeposit.tsx @@ -11,6 +11,7 @@ import type { CurrencyReserves } from '@/dex/types/main.types' import { getChainPoolIdActiveKey } from '@/dex/utils' import Checkbox from '@ui/Checkbox' import { t } from '@ui-kit/lib/i18n' +import { errorFallback } from '@ui-kit/utils/error.util' import { Amount } from '../../utils' /** @@ -74,7 +75,7 @@ const FieldsDeposit = ({ updatedFormValues: Partial, loadMaxAmount: LoadMaxAmount | null, updatedMaxSlippage: string | null, - ) => void + ) => Promise } & Pick) => { const { data: network } = useNetworkByChain({ chainId: rChainId }) const balancesLoading = useStore((state) => state.user.walletBalancesLoading) @@ -102,7 +103,7 @@ const FieldsDeposit = ({ }, null, null, - ) + ).catch(errorFallback) }, [updateFormValues, isBalancedAmounts, reserves, poolDataCacheOrApi.tokenAddresses], ) @@ -123,7 +124,7 @@ const FieldsDeposit = ({ const afterMaxClick = useCallback( (idx: number) => { const tokenAddress = poolDataCacheOrApi.tokenAddresses[idx] - updateFormValues({ isBalancedAmounts: false }, { tokenAddress, idx }, null) + updateFormValues({ isBalancedAmounts: false }, { tokenAddress, idx }, null).catch(errorFallback) }, [poolDataCacheOrApi.tokenAddresses, updateFormValues], ) diff --git a/apps/main/src/dex/components/PagePool/Deposit/components/FormDeposit.tsx b/apps/main/src/dex/components/PagePool/Deposit/components/FormDeposit.tsx index 563f47e5b0..78752e1926 100644 --- a/apps/main/src/dex/components/PagePool/Deposit/components/FormDeposit.tsx +++ b/apps/main/src/dex/components/PagePool/Deposit/components/FormDeposit.tsx @@ -28,6 +28,7 @@ import TxInfoBar from '@ui/TxInfoBar' import { scanTxPath } from '@ui/utils' import { notify } from '@ui-kit/features/connect-wallet' import { t } from '@ui-kit/lib/i18n' +import { errorFallback } from '@ui-kit/utils/error.util' const FormDeposit = ({ chainIdPoolId, @@ -68,14 +69,14 @@ const FormDeposit = ({ const haveSigner = !!signerAddress const updateFormValues = useCallback( - ( + async ( updatedFormValues: Partial, loadMaxAmount: LoadMaxAmount | null, updatedMaxSlippage: string | null, ) => { setTxInfoBar(null) setSlippageConfirmed(false) - void setFormValues( + await setFormValues( 'DEPOSIT', curve, poolDataCacheOrApi.pool.id, @@ -206,7 +207,7 @@ const FormDeposit = ({ // curve state change useEffect(() => { if (chainId && poolId) { - updateFormValues({}, null, null) + updateFormValues({}, null, null).catch(errorFallback) } // eslint-disable-next-line react-hooks/exhaustive-deps }, [chainId, poolId, signerAddress, seed.isSeed]) @@ -214,7 +215,7 @@ const FormDeposit = ({ // max Slippage useEffect(() => { if (maxSlippage) { - updateFormValues({}, null, maxSlippage) + updateFormValues({}, null, maxSlippage).catch(errorFallback) } // eslint-disable-next-line react-hooks/exhaustive-deps }, [maxSlippage]) diff --git a/apps/main/src/dex/components/PagePool/Deposit/components/FormDepositStake.tsx b/apps/main/src/dex/components/PagePool/Deposit/components/FormDepositStake.tsx index de10456eaa..a15188b00a 100644 --- a/apps/main/src/dex/components/PagePool/Deposit/components/FormDepositStake.tsx +++ b/apps/main/src/dex/components/PagePool/Deposit/components/FormDepositStake.tsx @@ -30,6 +30,7 @@ import TxInfoBar from '@ui/TxInfoBar' import { scanTxPath } from '@ui/utils' import { notify } from '@ui-kit/features/connect-wallet' import { t } from '@ui-kit/lib/i18n' +import { errorFallback } from '@ui-kit/utils/error.util' const FormDepositStake = ({ chainIdPoolId, @@ -71,14 +72,14 @@ const FormDepositStake = ({ const haveSigner = !!signerAddress const updateFormValues = useCallback( - ( + async ( updatedFormValues: Partial, loadMaxAmount: LoadMaxAmount | null, updatedMaxSlippage: string | null, ) => { setTxInfoBar(null) setSlippageConfirmed(false) - void setFormValues( + await setFormValues( 'DEPOSIT_STAKE', curve, poolDataCacheOrApi.pool.id, @@ -209,7 +210,7 @@ const FormDepositStake = ({ // curve state change useEffect(() => { if (chainId && poolId) { - updateFormValues({}, null, null) + updateFormValues({}, null, null).catch(errorFallback) } // eslint-disable-next-line react-hooks/exhaustive-deps }, [chainId, poolId, signerAddress, seed.isSeed]) @@ -217,7 +218,7 @@ const FormDepositStake = ({ // max Slippage useEffect(() => { if (maxSlippage) { - updateFormValues({}, null, maxSlippage) + updateFormValues({}, null, maxSlippage).catch(errorFallback) } // eslint-disable-next-line react-hooks/exhaustive-deps }, [maxSlippage]) diff --git a/apps/main/src/dex/components/PagePool/Deposit/components/FormStake.tsx b/apps/main/src/dex/components/PagePool/Deposit/components/FormStake.tsx index 0edb8f24f6..a873275995 100644 --- a/apps/main/src/dex/components/PagePool/Deposit/components/FormStake.tsx +++ b/apps/main/src/dex/components/PagePool/Deposit/components/FormStake.tsx @@ -21,6 +21,7 @@ import TxInfoBar from '@ui/TxInfoBar' import { scanTxPath } from '@ui/utils' import { notify } from '@ui-kit/features/connect-wallet' import { t } from '@ui-kit/lib/i18n' +import { errorFallback } from '@ui-kit/utils/error.util' const FormStake = ({ curve, poolData, poolDataCacheOrApi, routerParams, seed, userPoolBalances }: TransferProps) => { const isSubscribed = useRef(false) @@ -49,7 +50,16 @@ const FormStake = ({ curve, poolData, poolDataCacheOrApi, routerParams, seed, us const updateFormValues = useCallback( (updatedFormValues: Partial) => { setTxInfoBar(null) - void setFormValues('STAKE', curve, poolDataCacheOrApi.pool.id, poolData, updatedFormValues, null, seed.isSeed, '') + setFormValues( + 'STAKE', + curve, + poolDataCacheOrApi.pool.id, + poolData, + updatedFormValues, + null, + seed.isSeed, + '', + ).catch(errorFallback) }, [curve, poolData, poolDataCacheOrApi.pool.id, seed.isSeed, setFormValues], ) diff --git a/apps/main/src/dex/components/PagePool/Page.tsx b/apps/main/src/dex/components/PagePool/Page.tsx index e5a0b76d97..0624e18689 100644 --- a/apps/main/src/dex/components/PagePool/Page.tsx +++ b/apps/main/src/dex/components/PagePool/Page.tsx @@ -8,6 +8,7 @@ import type { PoolUrlParams } from '@/dex/types/main.types' import { getPath } from '@/dex/utils/utilsRouter' import { useConnection } from '@ui-kit/features/connect-wallet' import { useNavigate, useParams } from '@ui-kit/hooks/router' +import { errorFallback } from '@ui-kit/utils/error.util' export const PagePool = () => { const push = useNavigate() @@ -35,12 +36,12 @@ export const PagePool = () => { return } if (!isHydrated && curveApi?.chainId === rChainId && haveAllPools && !poolData) { - void (async () => { + ;(async () => { const foundPoolData = await fetchNewPool(curveApi, rPoolId) if (!foundPoolData) { push(reRoutePathname) } - })() + })().catch(errorFallback) } }, [curveApi, fetchNewPool, haveAllPools, network, isHydrated, props, poolData, push, rChainId]) diff --git a/apps/main/src/dex/components/PagePool/PoolDetails/PoolStats/index.tsx b/apps/main/src/dex/components/PagePool/PoolDetails/PoolStats/index.tsx index b3cb6969ce..06c29a0283 100644 --- a/apps/main/src/dex/components/PagePool/PoolDetails/PoolStats/index.tsx +++ b/apps/main/src/dex/components/PagePool/PoolDetails/PoolStats/index.tsx @@ -15,6 +15,7 @@ import ExternalLink from '@ui/Link/ExternalLink' import { breakpoints } from '@ui/utils/responsive' import { useParams } from '@ui-kit/hooks/router' import { t } from '@ui-kit/lib/i18n' +import { errorFallback } from '@ui-kit/utils/error.util' type PoolStatsProps = { poolAlert: PoolAlert | null @@ -32,7 +33,7 @@ const PoolStats = ({ curve, routerParams, poolAlert, poolData, poolDataCacheOrAp useEffect(() => { if (curve && poolData && !poolData?.parameters.virtualPrice) { - void fetchPoolStats(curve, poolData) + fetchPoolStats(curve, poolData).catch(errorFallback) } }, [curve, fetchPoolStats, poolData]) diff --git a/apps/main/src/dex/components/PagePool/Swap/index.tsx b/apps/main/src/dex/components/PagePool/Swap/index.tsx index c051e2d05f..fa8fc57728 100644 --- a/apps/main/src/dex/components/PagePool/Swap/index.tsx +++ b/apps/main/src/dex/components/PagePool/Swap/index.tsx @@ -42,6 +42,7 @@ import { REFRESH_INTERVAL } from '@ui-kit/lib/model' import { useTokenUsdRate } from '@ui-kit/lib/model/entities/token-usd-rate' import { LargeTokenInput } from '@ui-kit/shared/ui/LargeTokenInput' import { ReleaseChannel, decimal, type Decimal } from '@ui-kit/utils' +import { errorFallback } from '@ui-kit/utils/error.util' import { useThrottle } from '@ui-kit/utils/timers' const { cloneDeep, isNaN, isUndefined } = lodash @@ -121,11 +122,11 @@ const Swap = ({ const toToken = selectList.find((x) => x.address.toLocaleLowerCase() == formValues.toAddress) const updateFormValues = useCallback( - (updatedFormValues: Partial, isGetMaxFrom: boolean | null, updatedMaxSlippage: string | null) => { + async (updatedFormValues: Partial, isGetMaxFrom: boolean | null, updatedMaxSlippage: string | null) => { setConfirmedLoss(false) setTxInfoBar(null) - return setFormValues( + await setFormValues( curve, poolDataCacheOrApi.pool.id, poolData, @@ -251,13 +252,13 @@ const Swap = ({ ) const fetchData = useCallback( - () => + async () => curve && poolData && isPageVisible && !formStatus.formProcessing && !formStatus.formTypeCompleted && - updateFormValues({}, null, ''), + (await updateFormValues({}, null, '')), [curve, formStatus.formProcessing, formStatus.formTypeCompleted, isPageVisible, poolData, updateFormValues], ) @@ -280,21 +281,21 @@ const Swap = ({ // get user balances useEffect(() => { if (curve && poolId && haveSigner && (isUndefined(userFromBalance) || isUndefined(userToBalance))) { - void fetchUserPoolInfo(curve, poolId, true) + fetchUserPoolInfo(curve, poolId, true).catch(errorFallback) } }, [chainId, poolId, haveSigner, userFromBalance, userToBalance, curve, fetchUserPoolInfo]) // curve state change useEffect(() => { if (chainId && poolId) { - updateFormValues({}, null, null) + updateFormValues({}, null, null).catch(errorFallback) } // eslint-disable-next-line react-hooks/exhaustive-deps }, [chainId, poolId, signerAddress, seed.isSeed]) // maxSlippage useEffect(() => { - updateFormValues({}, null, maxSlippage) + updateFormValues({}, null, maxSlippage).catch(errorFallback) // eslint-disable-next-line react-hooks/exhaustive-deps }, [maxSlippage]) @@ -331,8 +332,10 @@ const Swap = ({ ]) // pageVisible - // eslint-disable-next-line react-hooks/exhaustive-deps - useEffect(() => fetchData(), [isPageVisible]) + + useEffect(() => { + fetchData().catch(errorFallback) + }, [isPageVisible]) // re-fetch data usePageVisibleInterval(() => fetchData(), REFRESH_INTERVAL['1m']) diff --git a/apps/main/src/dex/components/PagePool/Withdraw/components/FormClaim.tsx b/apps/main/src/dex/components/PagePool/Withdraw/components/FormClaim.tsx index bb37a1c154..8793a1ecf5 100644 --- a/apps/main/src/dex/components/PagePool/Withdraw/components/FormClaim.tsx +++ b/apps/main/src/dex/components/PagePool/Withdraw/components/FormClaim.tsx @@ -20,6 +20,7 @@ import TxInfoBar from '@ui/TxInfoBar' import { formatNumber, scanTxPath } from '@ui/utils' import { notify } from '@ui-kit/features/connect-wallet' import { t, Trans } from '@ui-kit/lib/i18n' +import { errorFallback } from '@ui-kit/utils/error.util' const FormClaim = ({ curve, poolData, poolDataCacheOrApi, routerParams, seed, userPoolBalances }: TransferProps) => { const isSubscribed = useRef(false) @@ -49,7 +50,7 @@ const FormClaim = ({ curve, poolData, poolDataCacheOrApi, routerParams, seed, us const updateFormValues = useCallback(() => { setTxInfoBar(null) setSlippageConfirmed(false) - void setFormValues('CLAIM', curve, poolDataCacheOrApi.pool.id, poolData, {}, null, seed.isSeed, '') + setFormValues('CLAIM', curve, poolDataCacheOrApi.pool.id, poolData, {}, null, seed.isSeed, '').catch(errorFallback) }, [curve, poolData, poolDataCacheOrApi.pool.id, seed.isSeed, setFormValues]) const handleClaimClick = useCallback( @@ -108,9 +109,10 @@ const FormClaim = ({ curve, poolData, poolDataCacheOrApi, routerParams, seed, us : isClaimCrv ? getClaimText(formValues, formStatus, 'claimCrvButton', rewardsNeedNudging) : t`Claim Rewards`, - onClick: () => { - void handleClaimClick(activeKey, curve, poolData, formValues, formStatus, rewardsNeedNudging) - }, + onClick: () => + handleClaimClick(activeKey, curve, poolData, formValues, formStatus, rewardsNeedNudging).catch( + errorFallback, + ), }, } @@ -146,7 +148,7 @@ const FormClaim = ({ curve, poolData, poolDataCacheOrApi, routerParams, seed, us // fetch claimable useEffect(() => { if (chainId && poolData && haveSigner) { - void fetchClaimable(activeKey, chainId, poolData.pool) + fetchClaimable(activeKey, chainId, poolData.pool).catch(errorFallback) } // eslint-disable-next-line react-hooks/exhaustive-deps }, [chainId, poolId, signerAddress]) @@ -171,7 +173,7 @@ const FormClaim = ({ curve, poolData, poolDataCacheOrApi, routerParams, seed, us cFormStatus.isClaimRewards = isClaimRewards setStateByKey('formStatus', cFormStatus) - void handleClaimClick(activeKey, curve, poolData, formValues, cFormStatus, rewardsNeedNudging) + handleClaimClick(activeKey, curve, poolData, formValues, cFormStatus, rewardsNeedNudging).catch(errorFallback) } } diff --git a/apps/main/src/dex/components/PagePool/Withdraw/components/FormUnstake.tsx b/apps/main/src/dex/components/PagePool/Withdraw/components/FormUnstake.tsx index 26c8b6ffec..5a0b4ab151 100644 --- a/apps/main/src/dex/components/PagePool/Withdraw/components/FormUnstake.tsx +++ b/apps/main/src/dex/components/PagePool/Withdraw/components/FormUnstake.tsx @@ -16,6 +16,7 @@ import TxInfoBar from '@ui/TxInfoBar' import { scanTxPath } from '@ui/utils' import { notify } from '@ui-kit/features/connect-wallet' import { t } from '@ui-kit/lib/i18n' +import { errorFallback } from '@ui-kit/utils/error.util' const FormUnstake = ({ curve, poolData, poolDataCacheOrApi, routerParams, seed, userPoolBalances }: TransferProps) => { const isSubscribed = useRef(false) @@ -41,7 +42,7 @@ const FormUnstake = ({ curve, poolData, poolDataCacheOrApi, routerParams, seed, const updateFormValues = useCallback( (updatedFormValues: Partial) => { setTxInfoBar(null) - void setFormValues( + setFormValues( 'UNSTAKE', curve, poolDataCacheOrApi.pool.id, @@ -50,7 +51,7 @@ const FormUnstake = ({ curve, poolData, poolDataCacheOrApi, routerParams, seed, null, seed.isSeed, '', - ) + ).catch(errorFallback) }, [curve, poolData, poolDataCacheOrApi.pool.id, seed.isSeed, setFormValues], ) diff --git a/apps/main/src/dex/components/PagePool/Withdraw/components/FormWithdraw.tsx b/apps/main/src/dex/components/PagePool/Withdraw/components/FormWithdraw.tsx index 645fbfba8c..b0c6d6f131 100644 --- a/apps/main/src/dex/components/PagePool/Withdraw/components/FormWithdraw.tsx +++ b/apps/main/src/dex/components/PagePool/Withdraw/components/FormWithdraw.tsx @@ -32,6 +32,7 @@ import { mediaQueries } from '@ui/utils/responsive' import { notify } from '@ui-kit/features/connect-wallet' import { t } from '@ui-kit/lib/i18n' import { useTokenUsdRates } from '@ui-kit/lib/model/entities/token-usd-rate' +import { errorFallback } from '@ui-kit/utils/error.util' const FormWithdraw = ({ chainIdPoolId, @@ -73,7 +74,7 @@ const FormWithdraw = ({ (updatedFormValues: Partial, updatedMaxSlippage: string | null) => { setTxInfoBar(null) setSlippageConfirmed(false) - void setFormValues( + setFormValues( 'WITHDRAW', curve, poolDataCacheOrApi.pool.id, @@ -82,7 +83,7 @@ const FormWithdraw = ({ null, seed.isSeed, updatedMaxSlippage || maxSlippage, - ) + ).catch(errorFallback) }, [setFormValues, curve, poolDataCacheOrApi.pool.id, poolData, seed.isSeed, maxSlippage], ) diff --git a/apps/main/src/dex/components/PagePool/index.tsx b/apps/main/src/dex/components/PagePool/index.tsx index f943767845..3cf05f895d 100644 --- a/apps/main/src/dex/components/PagePool/index.tsx +++ b/apps/main/src/dex/components/PagePool/index.tsx @@ -45,6 +45,7 @@ import usePageVisibleInterval from '@ui-kit/hooks/usePageVisibleInterval' import { t } from '@ui-kit/lib/i18n' import { REFRESH_INTERVAL } from '@ui-kit/lib/model' import { type TabOption, TabsSwitcher } from '@ui-kit/shared/ui/TabsSwitcher' +import { errorFallback } from '@ui-kit/utils/error.util' const DEFAULT_SEED: Seed = { isSeed: null, loaded: false } @@ -129,7 +130,7 @@ const Transfer = (pageTransferProps: PageTransferProps) => { pricesApiPoolsMapper[poolAddress] !== undefined && !snapshotsMapper[poolAddress] ) { - void fetchPricesPoolSnapshots(rChainId, poolAddress) + fetchPricesPoolSnapshots(rChainId, poolAddress).catch(errorFallback) } }, [curve, fetchPricesPoolSnapshots, poolAddress, pricesApi, pricesApiPoolsMapper, rChainId, snapshotsMapper]) @@ -147,7 +148,7 @@ const Transfer = (pageTransferProps: PageTransferProps) => { // fetch user pool info useEffect(() => { if (curve && poolId && signerAddress) { - void fetchUserPoolInfo(curve, poolId) + fetchUserPoolInfo(curve, poolId).catch(errorFallback) } }, [rChainId, poolId, signerAddress, curve, fetchUserPoolInfo]) diff --git a/apps/main/src/dex/components/PageRouterSwap/components/RouterSwapAlerts.tsx b/apps/main/src/dex/components/PageRouterSwap/components/RouterSwapAlerts.tsx index 27fa8d01c4..5775cde661 100644 --- a/apps/main/src/dex/components/PageRouterSwap/components/RouterSwapAlerts.tsx +++ b/apps/main/src/dex/components/PageRouterSwap/components/RouterSwapAlerts.tsx @@ -34,7 +34,7 @@ const RouterSwapAlerts = ({ isGetMaxFrom?: boolean, maxSlippage?: string, isFullReset?: boolean, - ) => void + ) => Promise }) => { const { error, swapError } = formStatus const { toAddress } = searchedParams diff --git a/apps/main/src/dex/components/PageRouterSwap/index.tsx b/apps/main/src/dex/components/PageRouterSwap/index.tsx index fbf1ab34bd..253d83b10f 100644 --- a/apps/main/src/dex/components/PageRouterSwap/index.tsx +++ b/apps/main/src/dex/components/PageRouterSwap/index.tsx @@ -46,6 +46,7 @@ import { REFRESH_INTERVAL } from '@ui-kit/lib/model' import { useTokenUsdRate, useTokenUsdRates } from '@ui-kit/lib/model/entities/token-usd-rate' import { LargeTokenInput } from '@ui-kit/shared/ui/LargeTokenInput' import { ReleaseChannel, decimal, type Decimal } from '@ui-kit/utils' +import { errorFallback } from '@ui-kit/utils/error.util' const QuickSwap = ({ pageLoaded, @@ -132,7 +133,7 @@ const QuickSwap = ({ const toToken = tokens.find((x) => x.address.toLocaleLowerCase() == toAddress) const updateFormValues = useCallback( - ( + async ( updatedFormValues: Partial, isGetMaxFrom?: boolean, maxSlippage?: string, @@ -142,7 +143,7 @@ const QuickSwap = ({ setTxInfoBar(null) setConfirmedLoss(false) - void setFormValues( + await setFormValues( pageLoaded ? curve : null, updatedFormValues, searchedParams, @@ -250,42 +251,38 @@ const QuickSwap = ({ onClick: () => setConfirmedLoss(false), }, primaryBtnProps: { - onClick: () => { - if (typeof routesAndOutput !== 'undefined') { - void handleBtnClickSwap( - activeKey, - curve, - formValues, - storeMaxSlippage, - !!slippageImpact?.isExpectedToAmount, - routesAndOutput.toAmountOutput, - searchedParams, - toSymbol, - fromSymbol, - ) - } - }, + onClick: () => + routesAndOutput && + handleBtnClickSwap( + activeKey, + curve, + formValues, + storeMaxSlippage, + !!slippageImpact?.isExpectedToAmount, + routesAndOutput.toAmountOutput, + searchedParams, + toSymbol, + fromSymbol, + ).catch(errorFallback), disabled: !confirmedLoss, }, primaryBtnLabel: 'Swap anyway', }, } : { - onClick: () => { - if (typeof routesAndOutput !== 'undefined') { - void handleBtnClickSwap( - activeKey, - curve, - formValues, - storeMaxSlippage, - !!slippageImpact?.isExpectedToAmount, - routesAndOutput.toAmountOutput, - searchedParams, - toSymbol, - fromSymbol, - ) - } - }, + onClick: () => + routesAndOutput && + handleBtnClickSwap( + activeKey, + curve, + formValues, + storeMaxSlippage, + !!slippageImpact?.isExpectedToAmount, + routesAndOutput.toAmountOutput, + searchedParams, + toSymbol, + fromSymbol, + ).catch(errorFallback), }), }, } @@ -303,11 +300,14 @@ const QuickSwap = ({ [confirmedLoss, fetchStepApprove, storeMaxSlippage, handleBtnClickSwap, slippageImpact?.isExpectedToAmount, steps], ) - const fetchData = useCallback(() => { - if (isReady && !formStatus.formProcessing && formStatus.formTypeCompleted !== 'SWAP') { - updateFormValues({}, false, '', false, true) - } - }, [formStatus.formProcessing, formStatus.formTypeCompleted, isReady, updateFormValues]) + const fetchData = useCallback( + async () => + isReady && + !formStatus.formProcessing && + formStatus.formTypeCompleted !== 'SWAP' && + (await updateFormValues({}, false, '', false, true)), + [formStatus.formProcessing, formStatus.formTypeCompleted, isReady, updateFormValues], + ) // onMount useEffect(() => { @@ -334,16 +334,18 @@ const QuickSwap = ({ // network switched useEffect(() => { - updateFormValues({ isFrom: true, fromAmount: '', toAmount: '' }) + updateFormValues({ isFrom: true, fromAmount: '', toAmount: '' }).catch(errorFallback) // eslint-disable-next-line react-hooks/exhaustive-deps }, [curve?.chainId]) // updateForm - // eslint-disable-next-line react-hooks/exhaustive-deps - useEffect(() => fetchData(), [tokensMapperStr, searchedParams.fromAddress, searchedParams.toAddress]) useEffect(() => { - void updateTokenList(isReady ? curve : null, tokensMapper) + fetchData().catch(errorFallback) + }, [tokensMapperStr, searchedParams.fromAddress, searchedParams.toAddress]) + + useEffect(() => { + updateTokenList(isReady ? curve : null, tokensMapper).catch(errorFallback) // eslint-disable-next-line react-hooks/exhaustive-deps }, [isReady, tokensMapperStr, curve?.signerAddress]) diff --git a/apps/main/src/dex/hooks/useAutoRefresh.tsx b/apps/main/src/dex/hooks/useAutoRefresh.tsx index db32126183..2f0e9d40d4 100644 --- a/apps/main/src/dex/hooks/useAutoRefresh.tsx +++ b/apps/main/src/dex/hooks/useAutoRefresh.tsx @@ -6,6 +6,7 @@ import { type CurveApi, useConnection } from '@ui-kit/features/connect-wallet' import usePageVisibleInterval from '@ui-kit/hooks/usePageVisibleInterval' import { REFRESH_INTERVAL } from '@ui-kit/lib/model' import { useGasInfoAndUpdateLib } from '@ui-kit/lib/model/entities/gas-info' +import { errorFallback } from '@ui-kit/utils/error.util' import { useNetworkByChain, useNetworks } from '../entities/networks' export const useAutoRefresh = (networkDef: NetworkDef) => { @@ -28,7 +29,7 @@ export const useAutoRefresh = (networkDef: NetworkDef) => { const { chainId } = curve const poolsData = Object.values(poolDataMapper) await Promise.all([fetchPoolsVolume(chainId, poolsData), fetchPoolsTvl(curve, poolsData)]) - void setTokensMapper(curve, poolsData) + setTokensMapper(curve, poolsData).catch(errorFallback) }, [fetchPoolsTvl, fetchPoolsVolume, poolDataMapper, setTokensMapper], ) diff --git a/apps/main/src/dex/hooks/usePoolTotalStaked.tsx b/apps/main/src/dex/hooks/usePoolTotalStaked.tsx index b7a2d338d6..00eb423864 100644 --- a/apps/main/src/dex/hooks/usePoolTotalStaked.tsx +++ b/apps/main/src/dex/hooks/usePoolTotalStaked.tsx @@ -5,6 +5,7 @@ import { PoolDataCacheOrApi, Provider } from '@/dex/types/main.types' import { isValidAddress } from '@/dex/utils' import { useConnection, useWallet } from '@ui-kit/features/connect-wallet' import dayjs from '@ui-kit/lib/dayjs' +import { errorFallback } from '@ui-kit/utils/error.util' import { useNetworks } from '../entities/networks' const usePoolTotalStaked = (poolDataCacheOrApi: PoolDataCacheOrApi) => { @@ -60,7 +61,7 @@ const usePoolTotalStaked = (poolDataCacheOrApi: PoolDataCacheOrApi) => { const shouldCallApi = staked?.timestamp ? dayjs().diff(staked.timestamp, 'seconds') > 30 : true if (address && rpcUrl && shouldCallApi) { - void (async () => { + ;(async () => { const provider = walletProvider || new JsonRpcProvider(rpcUrl) const gaugeContract = isValidAddress(gauge.address) ? await getContract('gaugeTotalSupply', gauge.address, provider) @@ -76,7 +77,7 @@ const usePoolTotalStaked = (poolDataCacheOrApi: PoolDataCacheOrApi) => { } else { updateTotalStakeValue({ totalStakedPercent: 'N/A', gaugeTotalSupply: 'N/A' }) } - })() + })().catch(errorFallback) } // eslint-disable-next-line react-hooks/exhaustive-deps }, [curveApi?.signerAddress, curveApi?.chainId, address, rpcUrl, walletProvider]) diff --git a/apps/main/src/dex/lib/curvejs.ts b/apps/main/src/dex/lib/curvejs.ts index 39fe11d27d..367ea0afce 100644 --- a/apps/main/src/dex/lib/curvejs.ts +++ b/apps/main/src/dex/lib/curvejs.ts @@ -42,6 +42,7 @@ import dayjs from '@ui-kit/lib/dayjs' import { waitForTransaction, waitForTransactions } from '@ui-kit/lib/ethers' import { t } from '@ui-kit/lib/i18n' import { log } from '@ui-kit/lib/logging' +import { errorFallback } from '@ui-kit/utils/error.util' import { fetchNetworks } from '../entities/networks' const { chunk, flatten, isUndefined } = lodash @@ -358,7 +359,7 @@ const router = { ? await curve.router.estimateGas.swap(fromAddress, toAddress, fromAmount) : await curve.router.estimateGas.approve(fromAddress, fromAmount) } - void warnIncorrectEstGas(curve.chainId, resp.estimatedGas) + warnIncorrectEstGas(curve.chainId, resp.estimatedGas).catch(errorFallback) return resp } catch (error) { console.error(error) @@ -472,7 +473,7 @@ const poolDeposit = { ? await p.estimateGas.depositWrappedApprove(amounts) : await p.estimateGas.depositApprove(amounts) } - void warnIncorrectEstGas(chainId, resp.estimatedGas) + warnIncorrectEstGas(chainId, resp.estimatedGas).catch(errorFallback) return resp } catch (error) { resp.error = getErrorMessage(error, 'error-est-gas-approval') @@ -565,7 +566,7 @@ const poolDeposit = { ? await p.estimateGas.depositAndStakeWrappedApprove(amounts) : await p.estimateGas.depositAndStakeApprove(amounts) } - void warnIncorrectEstGas(chainId, resp.estimatedGas) + warnIncorrectEstGas(chainId, resp.estimatedGas).catch(errorFallback) return resp } catch (error) { console.error(error) @@ -624,7 +625,7 @@ const poolDeposit = { resp.estimatedGas = resp.isApproved ? await p.estimateGas.stake(lpTokenAmount) : await p.estimateGas.stakeApprove(lpTokenAmount) - void warnIncorrectEstGas(chainId, resp.estimatedGas) + warnIncorrectEstGas(chainId, resp.estimatedGas).catch(errorFallback) return resp } catch (error) { resp.error = getErrorMessage(error, 'error-est-gas-approval') @@ -772,7 +773,7 @@ const poolSwap = { ? await p.estimateGas.swapWrappedApprove(fromAddress, fromAmount) : await p.estimateGas.swapApprove(fromAddress, fromAmount) } - void warnIncorrectEstGas(chainId, resp.estimatedGas) + warnIncorrectEstGas(chainId, resp.estimatedGas).catch(errorFallback) return resp } catch (error) { console.error(error) @@ -863,7 +864,7 @@ const poolWithdraw = { } else { resp.estimatedGas = await p.estimateGas.withdrawApprove(lpTokenAmount) } - void warnIncorrectEstGas(chainId, resp.estimatedGas) + warnIncorrectEstGas(chainId, resp.estimatedGas).catch(errorFallback) return resp } catch (error) { console.error(error) @@ -944,7 +945,7 @@ const poolWithdraw = { } else { resp.estimatedGas = await p.estimateGas.withdrawImbalanceApprove(amounts) } - void warnIncorrectEstGas(chainId, resp.estimatedGas) + warnIncorrectEstGas(chainId, resp.estimatedGas).catch(errorFallback) return resp } catch (error) { console.error(error) @@ -1035,7 +1036,7 @@ const poolWithdraw = { } else { resp.estimatedGas = await p.estimateGas.withdrawOneCoinApprove(lpTokenAmount) } - void warnIncorrectEstGas(chainId, resp.estimatedGas) + warnIncorrectEstGas(chainId, resp.estimatedGas).catch(errorFallback) return resp } catch (error) { console.error(error) @@ -1086,7 +1087,7 @@ const poolWithdraw = { const resp = { activeKey, estimatedGas: null as EstimatedGas, isApproved: true, error: '' } try { resp.estimatedGas = await p.estimateGas.unstake(lpTokenAmount) - void warnIncorrectEstGas(chainId, resp.estimatedGas) + warnIncorrectEstGas(chainId, resp.estimatedGas).catch(errorFallback) return resp } catch (error) { console.error(error) diff --git a/apps/main/src/dex/store/createCacheSlice.ts b/apps/main/src/dex/store/createCacheSlice.ts index 218558cc42..795bcafa9a 100644 --- a/apps/main/src/dex/store/createCacheSlice.ts +++ b/apps/main/src/dex/store/createCacheSlice.ts @@ -2,6 +2,7 @@ import { StoreApi } from 'zustand' import type { State } from '@/dex/store/useStore' import { ChainId, PoolDataCacheMapper, type ValueMapperCached } from '@/dex/types/main.types' import { sleep } from '@/dex/utils' +import { errorFallback } from '@ui-kit/utils/error.util' export type SwapFormValuesCache = { fromAddress: string @@ -56,7 +57,7 @@ const createCacheSlice = (_: StoreApi['setState'], get: StoreApi[' parsedMapper[k] = { value } }) - void sliceState.setStateByActiveKey(key, chainId.toString(), parsedMapper) + sliceState.setStateByActiveKey(key, chainId.toString(), parsedMapper).catch(errorFallback) }, // slice helpers diff --git a/apps/main/src/dex/store/createDashboardSlice.ts b/apps/main/src/dex/store/createDashboardSlice.ts index 5e30f6c08d..3b566ec6b0 100644 --- a/apps/main/src/dex/store/createDashboardSlice.ts +++ b/apps/main/src/dex/store/createDashboardSlice.ts @@ -95,13 +95,11 @@ const createDashboardSlice = (_: StoreApi['setState'], get: StoreApi { const { @@ -366,7 +364,7 @@ const createDashboardSlice = (_: StoreApi['setState'], get: StoreApi['setState'], get: StoreApi['setState'], get: StoreApi['setState'], get: StoreApi['setState'], get: StoreApi['setState'], get: StoreApi r.item.pool.id).map((r) => r.item) }, filterSmallTvl: (poolDatas, tvlMapper, chainId) => { - const networks = getNetworks() - const { hideSmallPoolsTvl } = networks[chainId] - - const result = takeTopWithMin(poolDatas, (pd) => +(tvlMapper?.[pd.pool.id]?.value || '0'), hideSmallPoolsTvl, 10) - - return result + const { hideSmallPoolsTvl } = getNetworks()[chainId] + return takeTopWithMin(poolDatas, (pd) => +(tvlMapper?.[pd.pool.id]?.value || '0'), hideSmallPoolsTvl, 10) }, sortFn: (sortKey, order, poolDatas, rewardsApyMapper, tvlMapper, volumeMapper, isCrvRewardsEnabled, chainId) => { const networks = getNetworks() @@ -286,7 +282,7 @@ const createPoolListSlice = (set: StoreApi['setState'], get: StoreApi['setState'], get: StoreApi['setState'], get: StoreApi['setState'], get: StoreApi['setState'], get: StoreApi['setState'], get: StoreApi { @@ -192,7 +193,7 @@ const createPoolWithdrawSlice = ( // get gas if (signerAddress) { - void get()[sliceKey].fetchEstGasApproval(activeKey, curve, formType, pool, cFormValues) + get()[sliceKey].fetchEstGasApproval(activeKey, curve, formType, pool, cFormValues).catch(errorFallback) } } }, @@ -283,7 +284,7 @@ const createPoolWithdrawSlice = ( // get gas if (signerAddress) { - void get()[sliceKey].fetchEstGasApproval(activeKey, curve, formType, pool, cFormValues) + get()[sliceKey].fetchEstGasApproval(activeKey, curve, formType, pool, cFormValues).catch(errorFallback) } }, fetchClaimable: async (activeKey, chainId, pool) => { @@ -350,16 +351,16 @@ const createPoolWithdrawSlice = ( maxSlippage, } if (cFormValues.selected === 'token') { - void get()[sliceKey].fetchWithdrawToken(props) + await get()[sliceKey].fetchWithdrawToken(props) } else if (cFormValues.selected === 'lpToken') { - void get()[sliceKey].fetchWithdrawLpToken(props) + await get()[sliceKey].fetchWithdrawLpToken(props) } else if (cFormValues.selected === 'imbalance') { - void get()[sliceKey].fetchWithdrawCustom(props) + await get()[sliceKey].fetchWithdrawCustom(props) } } else if (formType === 'UNSTAKE' && !!signerAddress && +cFormValues.stakedLpToken > 0) { - void get()[sliceKey].fetchEstGasApproval(activeKey, curve, formType, pool, cFormValues) + await get()[sliceKey].fetchEstGasApproval(activeKey, curve, formType, pool, cFormValues) } else if (formType === 'CLAIM') { - void get()[sliceKey].fetchClaimable(activeKey, chainId, pool) + await get()[sliceKey].fetchClaimable(activeKey, chainId, pool) } }, diff --git a/apps/main/src/dex/store/createPoolsSlice.ts b/apps/main/src/dex/store/createPoolsSlice.ts index 2f88b2c0bd..3a620f2168 100644 --- a/apps/main/src/dex/store/createPoolsSlice.ts +++ b/apps/main/src/dex/store/createPoolsSlice.ts @@ -43,6 +43,7 @@ import { convertToLocaleTimestamp } from '@ui/Chart/utils' import { requireLib } from '@ui-kit/features/connect-wallet' import { log } from '@ui-kit/lib/logging' import { fetchTokenUsdRate, getTokenUsdRateQueryData } from '@ui-kit/lib/model/entities/token-usd-rate' +import { errorFallback } from '@ui-kit/utils/error.util' import { fetchNetworks } from '../entities/networks' import { getPools } from '../lib/pools' @@ -269,7 +270,7 @@ const createPoolsSlice = (set: StoreApi['setState'], get: StoreApi ) // update cache - void storeCache.setStateByActiveKey('poolsMapper', chainId.toString(), poolsMapperCache) + storeCache.setStateByActiveKey('poolsMapper', chainId.toString(), poolsMapperCache).catch(errorFallback) const partialPoolDatas = poolIds.map((poolId) => poolsMapper[poolId]) @@ -286,7 +287,7 @@ const createPoolsSlice = (set: StoreApi['setState'], get: StoreApi const partialTokens = await tokens.setTokensMapper(curve, partialPoolDatas) if (curve.signerAddress) { - void userBalances.fetchUserBalancesByTokens(curve, partialTokens) + await userBalances.fetchUserBalancesByTokens(curve, partialTokens) } return { poolsMapper, poolDatas: partialPoolDatas } @@ -427,7 +428,7 @@ const createPoolsSlice = (set: StoreApi['setState'], get: StoreApi if (missingRewardsPoolIds.length > 0) { log('fetchMissingPoolsRewardsApy', chainId, missingRewardsPoolIds.length) - void fetchPoolsRewardsApy(chainId, missingRewardsPoolIds) + await fetchPoolsRewardsApy(chainId, missingRewardsPoolIds) } // const missingRewardsPoolIds = [] @@ -495,7 +496,7 @@ const createPoolsSlice = (set: StoreApi['setState'], get: StoreApi state.pools.poolsMapper[chainId][poolData.pool.id] = cPoolData }), ) - void get().pools.fetchPoolCurrenciesReserves(curve, cPoolData) + get().pools.fetchPoolCurrenciesReserves(curve, cPoolData).catch(errorFallback) return { tokens, tokenAddresses } }, updatePool: (chainId, poolId, updatedPoolData) => { diff --git a/apps/main/src/dex/store/createQuickSwapSlice.ts b/apps/main/src/dex/store/createQuickSwapSlice.ts index 50dbcd4e88..1db3f45c57 100644 --- a/apps/main/src/dex/store/createQuickSwapSlice.ts +++ b/apps/main/src/dex/store/createQuickSwapSlice.ts @@ -18,6 +18,7 @@ import { getMaxAmountMinusGas } from '@/dex/utils/utilsGasPrices' import { getSlippageImpact, getSwapActionModalType } from '@/dex/utils/utilsSwap' import { useWallet } from '@ui-kit/features/connect-wallet' import { fetchGasInfoAndUpdateLib } from '@ui-kit/lib/model/entities/gas-info' +import { errorFallback } from '@ui-kit/utils/error.util' import { setMissingProvider } from '@ui-kit/utils/store.util' import { fetchNetworks } from '../entities/networks' @@ -326,16 +327,16 @@ const createQuickSwapSlice = (set: StoreApi['setState'], get: StoreApi['setState'], get: StoreApi['setState'], get: StoreApi { @@ -23,7 +24,7 @@ const PoolActivity = ({ chainId, poolAddress, coins }: PoolActivityProps) => { const minHeight = chartExpanded ? 548 : 330 useEffect(() => { - void fetchPoolActivity(chainId, poolAddress) + fetchPoolActivity(chainId, poolAddress).catch(errorFallback) }, [chainId, fetchPoolActivity, poolAddress]) return ( diff --git a/apps/main/src/lend/components/ChartOhlcWrapper/index.tsx b/apps/main/src/lend/components/ChartOhlcWrapper/index.tsx index e82b145cb0..273a68095e 100644 --- a/apps/main/src/lend/components/ChartOhlcWrapper/index.tsx +++ b/apps/main/src/lend/components/ChartOhlcWrapper/index.tsx @@ -15,6 +15,7 @@ import TextCaption from '@ui/TextCaption' import { useLayoutStore } from '@ui-kit/features/layout' import { useUserProfileStore } from '@ui-kit/features/user-profile' import { t } from '@ui-kit/lib/i18n' +import { errorFallback } from '@ui-kit/utils/error.util' import { ChartOhlcWrapperProps, LendingMarketTokens } from './types' const ChartOhlcWrapper = ({ rChainId, userActiveKey, rOwmId, betaBackgroundColor }: ChartOhlcWrapperProps) => { @@ -266,27 +267,27 @@ const ChartOhlcWrapper = ({ rChainId, userActiveKey, rOwmId, betaBackgroundColor }, [timeOption]) const refetchPricesData = useCallback(() => { - if (market?.addresses.controller) { - void fetchOraclePoolOhlcData( - rChainId, - market.addresses.controller, - chartInterval, - timeUnit, - chartTimeSettings.start, - chartTimeSettings.end, - ) - } - if (market?.addresses.amm) { - void fetchLlammaOhlcData( - rChainId, - rOwmId, - market.addresses.amm, - chartInterval, - timeUnit, - chartTimeSettings.start, - chartTimeSettings.end, - ) - } + Promise.all([ + market?.addresses.controller && + fetchOraclePoolOhlcData( + rChainId, + market.addresses.controller, + chartInterval, + timeUnit, + chartTimeSettings.start, + chartTimeSettings.end, + ), + market?.addresses.amm && + fetchLlammaOhlcData( + rChainId, + rOwmId, + market.addresses.amm, + chartInterval, + timeUnit, + chartTimeSettings.start, + chartTimeSettings.end, + ), + ]).catch(errorFallback) }, [ chartInterval, chartTimeSettings.end, @@ -316,7 +317,7 @@ const ChartOhlcWrapper = ({ rChainId, userActiveKey, rOwmId, betaBackgroundColor const startTime = getThreeHundredResultsAgo(timeOption, endTime) if (market?.addresses.controller && market?.addresses.amm) { - void fetchMoreData( + fetchMoreData( rChainId, market?.addresses.controller, market?.addresses.amm, @@ -324,7 +325,7 @@ const ChartOhlcWrapper = ({ rChainId, userActiveKey, rOwmId, betaBackgroundColor timeUnit, startTime, endTime, - ) + ).catch(errorFallback) } }, [timeOption, fetchMoreData, rChainId, market?.addresses.amm, market?.addresses.controller, chartInterval, timeUnit], diff --git a/apps/main/src/lend/components/PageIntegrations/Page.tsx b/apps/main/src/lend/components/PageIntegrations/Page.tsx index 7f58150190..95cf9e5fd4 100644 --- a/apps/main/src/lend/components/PageIntegrations/Page.tsx +++ b/apps/main/src/lend/components/PageIntegrations/Page.tsx @@ -9,6 +9,7 @@ import Spinner, { SpinnerWrapper } from '@ui/Spinner' import { breakpoints } from '@ui/utils/responsive' import { useSearchParams, useParams } from '@ui-kit/hooks/router' import { Trans } from '@ui-kit/lib/i18n' +import { errorFallback } from '@ui-kit/utils/error.util' const Page = () => { const params = useParams() @@ -19,7 +20,7 @@ const Page = () => { const integrationsTags = useStore((state) => state.integrations.integrationsTags) useEffect(() => { - void init(rChainId) + init(rChainId).catch(errorFallback) // eslint-disable-next-line react-hooks/exhaustive-deps }, []) diff --git a/apps/main/src/lend/components/PageLoanCreate/LoanFormCreate/index.tsx b/apps/main/src/lend/components/PageLoanCreate/LoanFormCreate/index.tsx index 312518c8cb..e1f487fcaa 100644 --- a/apps/main/src/lend/components/PageLoanCreate/LoanFormCreate/index.tsx +++ b/apps/main/src/lend/components/PageLoanCreate/LoanFormCreate/index.tsx @@ -83,17 +83,19 @@ const LoanCreate = ({ }) const updateFormValues = useCallback( - (updatedFormValues: Partial, isFullReset?: boolean, shouldRefetch?: boolean) => { + async (updatedFormValues: Partial, isFullReset?: boolean, shouldRefetch?: boolean) => { setConfirmWarning(DEFAULT_CONFIRM_WARNING) - if (isFullReset) setHealthMode(DEFAULT_HEALTH_MODE) - return setFormValues( - isLoaded ? api : null, - market, - isFullReset ? DEFAULT_FORM_VALUES : updatedFormValues, - maxSlippage, - isLeverage, - shouldRefetch, - ) + await Promise.all([ + setFormValues( + isLoaded ? api : null, + market, + isFullReset ? DEFAULT_FORM_VALUES : updatedFormValues, + maxSlippage, + isLeverage, + shouldRefetch, + ), + isFullReset && setHealthMode(DEFAULT_HEALTH_MODE), + ]) }, [setFormValues, isLoaded, api, market, maxSlippage, isLeverage], ) diff --git a/apps/main/src/lend/components/PageLoanCreate/types.ts b/apps/main/src/lend/components/PageLoanCreate/types.ts index 9623108db0..503c722976 100644 --- a/apps/main/src/lend/components/PageLoanCreate/types.ts +++ b/apps/main/src/lend/components/PageLoanCreate/types.ts @@ -40,7 +40,7 @@ export type DetailInfoCompProps = { market: OneWayMarketTemplate | null steps: Step[] setHealthMode: Dispatch> - updateFormValues: (updatedFormValues: FormValues) => void + updateFormValues: (updatedFormValues: FormValues) => Promise } export type DetailInfoCompAdditionalProps = { diff --git a/apps/main/src/lend/components/PageLoanManage/LoanBorrowMore/index.tsx b/apps/main/src/lend/components/PageLoanManage/LoanBorrowMore/index.tsx index b20dc771e2..e81288026c 100644 --- a/apps/main/src/lend/components/PageLoanManage/LoanBorrowMore/index.tsx +++ b/apps/main/src/lend/components/PageLoanManage/LoanBorrowMore/index.tsx @@ -35,6 +35,7 @@ import usePageVisibleInterval from '@ui-kit/hooks/usePageVisibleInterval' import { t } from '@ui-kit/lib/i18n' import { REFRESH_INTERVAL } from '@ui-kit/lib/model' import { SizesAndSpaces } from '@ui-kit/themes/design/1_sizes_spaces' +import { errorFallback } from '@ui-kit/utils/error.util' import { useThrottle } from '@ui-kit/utils/timers' const { Spacing } = SizesAndSpaces @@ -82,7 +83,7 @@ const LoanBorrowMore = ({ }) const updateFormValues = useCallback( - ( + async ( updatedFormValues: Partial, updatedMaxSlippage?: string, isFullReset?: boolean, @@ -90,7 +91,7 @@ const LoanBorrowMore = ({ ) => { setConfirmWarning(DEFAULT_CONFIRM_WARNING) if (isFullReset) setHealthMode(DEFAULT_HEALTH_MODE) - return setFormValues( + await setFormValues( isLoaded ? api : null, market, isFullReset ? DEFAULT_FORM_VALUES : updatedFormValues, @@ -282,7 +283,7 @@ const LoanBorrowMore = ({ useEffect(() => { if (isLoaded) { resetState() - void updateFormValues({}) + updateFormValues({}).catch(errorFallback) } // eslint-disable-next-line react-hooks/exhaustive-deps }, [isLoaded]) @@ -329,7 +330,7 @@ const LoanBorrowMore = ({ ]) useEffect(() => { - if (isLoaded) updateFormValues({}, maxSlippage) + if (isLoaded) updateFormValues({}, maxSlippage).catch(errorFallback) // eslint-disable-next-line react-hooks/exhaustive-deps }, [maxSlippage]) diff --git a/apps/main/src/lend/components/PageLoanManage/LoanCollateralAdd/index.tsx b/apps/main/src/lend/components/PageLoanManage/LoanCollateralAdd/index.tsx index 881f8ae4ca..e7559aa33b 100644 --- a/apps/main/src/lend/components/PageLoanManage/LoanCollateralAdd/index.tsx +++ b/apps/main/src/lend/components/PageLoanManage/LoanCollateralAdd/index.tsx @@ -29,6 +29,7 @@ import { formatNumber, scanTxPath } from '@ui/utils' import { notify } from '@ui-kit/features/connect-wallet' import { useUserProfileStore } from '@ui-kit/features/user-profile' import { t } from '@ui-kit/lib/i18n' +import { errorFallback } from '@ui-kit/utils/error.util' const LoanCollateralAdd = ({ rChainId, rOwmId, api, isLoaded, market, userActiveKey }: PageContentProps) => { const isSubscribed = useRef(false) @@ -61,7 +62,9 @@ const LoanCollateralAdd = ({ rChainId, rOwmId, api, isLoaded, market, userActive const updateFormValues = useCallback( (updatedFormValues: Partial, isFullReset?: boolean) => { - void setFormValues(isLoaded ? api : null, market, isFullReset ? DEFAULT_FORM_VALUES : updatedFormValues) + setFormValues(isLoaded ? api : null, market, isFullReset ? DEFAULT_FORM_VALUES : updatedFormValues).catch( + errorFallback, + ) }, [api, isLoaded, market, setFormValues], ) diff --git a/apps/main/src/lend/components/PageLoanManage/LoanCollateralRemove/index.tsx b/apps/main/src/lend/components/PageLoanManage/LoanCollateralRemove/index.tsx index 2e9bf7479d..23b8fc1d70 100644 --- a/apps/main/src/lend/components/PageLoanManage/LoanCollateralRemove/index.tsx +++ b/apps/main/src/lend/components/PageLoanManage/LoanCollateralRemove/index.tsx @@ -30,6 +30,7 @@ import { formatNumber, scanTxPath } from '@ui/utils' import { notify } from '@ui-kit/features/connect-wallet' import { useUserProfileStore } from '@ui-kit/features/user-profile' import { t } from '@ui-kit/lib/i18n' +import { errorFallback } from '@ui-kit/utils/error.util' const LoanCollateralRemove = ({ rChainId, rOwmId, isLoaded, api, market, userActiveKey }: PageContentProps) => { const isSubscribed = useRef(false) @@ -66,7 +67,7 @@ const LoanCollateralRemove = ({ rChainId, rOwmId, isLoaded, api, market, userAct const updateFormValues = useCallback( (updatedFormValues: Partial, isFullReset?: boolean) => { setConfirmWarning(DEFAULT_CONFIRM_WARNING) - void setFormValues(isLoaded ? api : null, market, updatedFormValues) + setFormValues(isLoaded ? api : null, market, updatedFormValues).catch(errorFallback) if (isFullReset) setHealthMode(DEFAULT_HEALTH_MODE) }, diff --git a/apps/main/src/lend/components/PageLoanManage/LoanRepay/index.tsx b/apps/main/src/lend/components/PageLoanManage/LoanRepay/index.tsx index 77bb473ed0..9150652271 100644 --- a/apps/main/src/lend/components/PageLoanManage/LoanRepay/index.tsx +++ b/apps/main/src/lend/components/PageLoanManage/LoanRepay/index.tsx @@ -44,6 +44,7 @@ import { t } from '@ui-kit/lib/i18n' import { REFRESH_INTERVAL } from '@ui-kit/lib/model' import { SizesAndSpaces } from '@ui-kit/themes/design/1_sizes_spaces' import { getPercentage, isGreaterThan, isGreaterThanOrEqualTo, sum } from '@ui-kit/utils' +import { errorFallback } from '@ui-kit/utils/error.util' import { useThrottle } from '@ui-kit/utils/timers' const { Spacing } = SizesAndSpaces @@ -92,7 +93,7 @@ const LoanRepay = ({ }) const updateFormValues = useCallback( - ( + async ( updatedFormValues: Partial, updatedMaxSlippage?: string, isFullReset?: boolean, @@ -100,7 +101,7 @@ const LoanRepay = ({ ) => { setConfirmWarning(DEFAULT_CONFIRM_WARNING) if (isFullReset) setHealthMode(DEFAULT_HEALTH_MODE) - return setFormValues( + await setFormValues( isLoaded ? api : null, market, updatedFormValues, @@ -299,7 +300,7 @@ const LoanRepay = ({ useEffect(() => { if (isLoaded) { resetState() - void updateFormValues({}) + updateFormValues({}).catch(errorFallback) } // eslint-disable-next-line react-hooks/exhaustive-deps }, [isLoaded]) diff --git a/apps/main/src/lend/components/PageLoanManage/LoanSelfLiquidation/index.tsx b/apps/main/src/lend/components/PageLoanManage/LoanSelfLiquidation/index.tsx index b1647b2693..e76b6c8c35 100644 --- a/apps/main/src/lend/components/PageLoanManage/LoanSelfLiquidation/index.tsx +++ b/apps/main/src/lend/components/PageLoanManage/LoanSelfLiquidation/index.tsx @@ -36,6 +36,7 @@ import { formatNumber, scanTxPath } from '@ui/utils' import { notify } from '@ui-kit/features/connect-wallet' import { useUserProfileStore } from '@ui-kit/features/user-profile' import { t, Trans } from '@ui-kit/lib/i18n' +import { errorFallback } from '@ui-kit/utils/error.util' const LoanSelfLiquidation = ({ rChainId, @@ -75,7 +76,7 @@ const LoanSelfLiquidation = ({ setTxInfoBar(null) if (isLoaded && api && market) { - void fetchDetails(api, market, maxSlippage) + fetchDetails(api, market, maxSlippage).catch(errorFallback) } }, [isLoaded, api, market, fetchDetails, maxSlippage]) @@ -192,7 +193,7 @@ const LoanSelfLiquidation = ({ useEffect(() => { if (isLoaded && api && market && maxSlippage) { resetState() - void fetchDetails(api, market, maxSlippage) + fetchDetails(api, market, maxSlippage).catch(errorFallback) } // eslint-disable-next-line react-hooks/exhaustive-deps }, [isLoaded]) diff --git a/apps/main/src/lend/components/PageLoanManage/Page.tsx b/apps/main/src/lend/components/PageLoanManage/Page.tsx index 92eb08a6c7..4975467cf1 100644 --- a/apps/main/src/lend/components/PageLoanManage/Page.tsx +++ b/apps/main/src/lend/components/PageLoanManage/Page.tsx @@ -38,6 +38,7 @@ import { useParams } from '@ui-kit/hooks/router' import { t } from '@ui-kit/lib/i18n' import { REFRESH_INTERVAL } from '@ui-kit/lib/model' import { SizesAndSpaces } from '@ui-kit/themes/design/1_sizes_spaces' +import { errorFallback } from '@ui-kit/utils/error.util' const { Spacing } = SizesAndSpaces @@ -108,13 +109,18 @@ const Page = () => { useEffect(() => { // delay fetch rest after form details are fetched first - const timer = setTimeout(async () => { - if (!api || !market || !isPageVisible || !isLoaded) return - void fetchAllMarketDetails(api, market, true) - if (api.signerAddress && loanExists) { - void fetchAllUserMarketDetails(api, market, true) - } - }, REFRESH_INTERVAL['3s']) + const timer = setTimeout( + () => + api && + market && + isPageVisible && + isLoaded && + Promise.all([ + fetchAllMarketDetails(api, market, true), + api.signerAddress && loanExists && fetchAllUserMarketDetails(api, market, true), + ]).catch(errorFallback), + REFRESH_INTERVAL['3s'], + ) return () => clearTimeout(timer) }, [api, fetchAllMarketDetails, fetchAllUserMarketDetails, isLoaded, isPageVisible, loanExists, market]) diff --git a/apps/main/src/lend/components/PageVault/VaultClaim/index.tsx b/apps/main/src/lend/components/PageVault/VaultClaim/index.tsx index 79ee59401f..ff42f50530 100644 --- a/apps/main/src/lend/components/PageVault/VaultClaim/index.tsx +++ b/apps/main/src/lend/components/PageVault/VaultClaim/index.tsx @@ -19,6 +19,7 @@ import TxInfoBar from '@ui/TxInfoBar' import { formatNumber, scanTxPath } from '@ui/utils' import { notify } from '@ui-kit/features/connect-wallet' import { t } from '@ui-kit/lib/i18n' +import { errorFallback } from '@ui-kit/utils/error.util' const VaultClaim = ({ isLoaded, api, market, userActiveKey }: PageContentProps) => { const isSubscribed = useRef(false) @@ -38,13 +39,14 @@ const VaultClaim = ({ isLoaded, api, market, userActiveKey }: PageContentProps) const haveClaimableCrv = +crv > 0 const haveClaimableRewards = rewards.some((r) => +r.amount > 0) - const updateFormValues = useCallback(() => { - void setFormValues(userActiveKey, isLoaded ? api : null, market) - }, [api, isLoaded, market, setFormValues, userActiveKey]) + const updateFormValues = useCallback( + () => setFormValues(userActiveKey, isLoaded ? api : null, market), + [api, isLoaded, market, setFormValues, userActiveKey], + ) const reset = useCallback(() => { setTxInfoBar(null) - updateFormValues() + return updateFormValues() }, [updateFormValues]) const handleBtnClickClaim = useCallback( @@ -71,7 +73,7 @@ const VaultClaim = ({ isLoaded, api, market, userActiveKey }: PageContentProps) reset()} + onClose={() => reset().catch(errorFallback)} />, ) } @@ -182,7 +184,9 @@ const VaultClaim = ({ isLoaded, api, market, userActiveKey }: PageContentProps) {/* actions */} - {formStatus.error ? reset()} /> : null} + {formStatus.error ? ( + reset().catch(errorFallback)} /> + ) : null} {txInfoBar} {api && market && ( diff --git a/apps/main/src/lend/components/PageVault/VaultDepositMint/index.tsx b/apps/main/src/lend/components/PageVault/VaultDepositMint/index.tsx index b652fd5c8d..8e13432133 100644 --- a/apps/main/src/lend/components/PageVault/VaultDepositMint/index.tsx +++ b/apps/main/src/lend/components/PageVault/VaultDepositMint/index.tsx @@ -28,6 +28,7 @@ import { useTokenUsdRate } from '@ui-kit/lib/model/entities/token-usd-rate' import { LargeTokenInput } from '@ui-kit/shared/ui/LargeTokenInput' import { TokenLabel } from '@ui-kit/shared/ui/TokenLabel' import { ReleaseChannel, decimal, type Decimal } from '@ui-kit/utils' +import { errorFallback } from '@ui-kit/utils/error.util' const VaultDepositMint = ({ rChainId, rOwmId, rFormType, isLoaded, api, market, userActiveKey }: PageContentProps) => { const isSubscribed = useRef(false) @@ -53,16 +54,15 @@ const VaultDepositMint = ({ rChainId, rOwmId, rFormType, isLoaded, api, market, const { signerAddress } = api ?? {} const updateFormValues = useCallback( - (updatedFormValues: Partial) => { - void setFormValues(rChainId, rFormType, isLoaded ? api : null, market, updatedFormValues) - }, + (updatedFormValues: Partial) => + setFormValues(rChainId, rFormType, isLoaded ? api : null, market, updatedFormValues), [api, isLoaded, market, rChainId, rFormType, setFormValues], ) const reset = useCallback( (updatedFormValues: Partial) => { setTxInfoBar(null) - updateFormValues(updatedFormValues) + return updateFormValues(updatedFormValues) }, [updateFormValues], ) @@ -72,7 +72,7 @@ const VaultDepositMint = ({ rChainId, rOwmId, rFormType, isLoaded, api, market, const onBalance = useCallback((amount?: Decimal) => reset({ amount: amount ?? '' }), [reset]) const handleInpAmountChange = (amount: string) => { - reset({ amount }) + reset({ amount }).catch(errorFallback) } const handleBtnClickDeposit = useCallback( @@ -98,7 +98,7 @@ const VaultDepositMint = ({ rChainId, rOwmId, rFormType, isLoaded, api, market, reset({})} + onClose={() => reset({}).catch(errorFallback)} />, ) } @@ -171,7 +171,7 @@ const VaultDepositMint = ({ rChainId, rOwmId, rFormType, isLoaded, api, market, }, [resetState]) useEffect(() => { - if (isLoaded) updateFormValues({}) + if (isLoaded) updateFormValues({}).catch(errorFallback) // eslint-disable-next-line react-hooks/exhaustive-deps }, [isLoaded]) diff --git a/apps/main/src/lend/components/PageVault/VaultStake/index.tsx b/apps/main/src/lend/components/PageVault/VaultStake/index.tsx index 023f21f031..9e5be85c3d 100644 --- a/apps/main/src/lend/components/PageVault/VaultStake/index.tsx +++ b/apps/main/src/lend/components/PageVault/VaultStake/index.tsx @@ -23,6 +23,7 @@ import { useReleaseChannel } from '@ui-kit/hooks/useLocalStorage' import { t } from '@ui-kit/lib/i18n' import { LargeTokenInput } from '@ui-kit/shared/ui/LargeTokenInput' import { ReleaseChannel, decimal, type Decimal } from '@ui-kit/utils' +import { errorFallback } from '@ui-kit/utils/error.util' const VaultStake = ({ rChainId, rOwmId, rFormType, isLoaded, api, market, userActiveKey }: PageContentProps) => { const isSubscribed = useRef(false) @@ -44,22 +45,21 @@ const VaultStake = ({ rChainId, rOwmId, rFormType, isLoaded, api, market, userAc const { signerAddress } = api ?? {} const updateFormValues = useCallback( - (updatedFormValues: Partial) => { - void setFormValues(rChainId, rFormType, isLoaded ? api : null, market, updatedFormValues) - }, + (updatedFormValues: Partial) => + setFormValues(rChainId, rFormType, isLoaded ? api : null, market, updatedFormValues), [api, isLoaded, market, rChainId, rFormType, setFormValues], ) const reset = useCallback( (updatedFormValues: Partial) => { setTxInfoBar(null) - updateFormValues(updatedFormValues) + return updateFormValues(updatedFormValues) }, [updateFormValues], ) const handleInpAmountChange = (amount: string) => { - reset({ amount }) + reset({ amount }).catch(errorFallback) } const handleBtnClickStake = useCallback( @@ -153,7 +153,7 @@ const VaultStake = ({ rChainId, rOwmId, rFormType, isLoaded, api, market, userAc }, [resetState]) useEffect(() => { - if (isLoaded) updateFormValues({}) + if (isLoaded) updateFormValues({}).catch(errorFallback) // eslint-disable-next-line react-hooks/exhaustive-deps }, [isLoaded]) @@ -168,7 +168,7 @@ const VaultStake = ({ rChainId, rOwmId, rFormType, isLoaded, api, market, userAc const activeStep = signerAddress ? getActiveStep(steps) : null const disabled = !!formStatus.step - const onBalance = useCallback((amount?: Decimal) => reset({ amount: amount ?? '' }), [reset]) + const onBalance = useCallback((amount?: Decimal) => reset({ amount: amount ?? '' }).catch(errorFallback), [reset]) const detailInfoCrvIncentivesComp = DetailInfoCrvIncentives({ rChainId, rOwmId, lpTokenAmount: formValues.amount }) return ( diff --git a/apps/main/src/lend/components/PageVault/VaultUnstake/index.tsx b/apps/main/src/lend/components/PageVault/VaultUnstake/index.tsx index f48bd66181..c7e21bbc8a 100644 --- a/apps/main/src/lend/components/PageVault/VaultUnstake/index.tsx +++ b/apps/main/src/lend/components/PageVault/VaultUnstake/index.tsx @@ -22,6 +22,7 @@ import { useReleaseChannel } from '@ui-kit/hooks/useLocalStorage' import { t } from '@ui-kit/lib/i18n' import { LargeTokenInput } from '@ui-kit/shared/ui/LargeTokenInput' import { ReleaseChannel, decimal, type Decimal } from '@ui-kit/utils' +import { errorFallback } from '@ui-kit/utils/error.util' const VaultUnstake = ({ rChainId, rOwmId, rFormType, isLoaded, api, market, userActiveKey }: PageContentProps) => { const isSubscribed = useRef(false) @@ -42,16 +43,15 @@ const VaultUnstake = ({ rChainId, rOwmId, rFormType, isLoaded, api, market, user const { signerAddress } = api ?? {} const updateFormValues = useCallback( - (updatedFormValues: Partial) => { - void setFormValues(rChainId, rFormType, isLoaded ? api : null, market, updatedFormValues) - }, + (updatedFormValues: Partial) => + setFormValues(rChainId, rFormType, isLoaded ? api : null, market, updatedFormValues), [api, isLoaded, market, rChainId, rFormType, setFormValues], ) const reset = useCallback( (updatedFormValues: Partial) => { setTxInfoBar(null) - updateFormValues(updatedFormValues) + return updateFormValues(updatedFormValues) }, [updateFormValues], ) @@ -153,7 +153,7 @@ const VaultUnstake = ({ rChainId, rOwmId, rFormType, isLoaded, api, market, user const activeStep = signerAddress ? getActiveStep(steps) : null const disabled = !!formStatus.step - const onBalance = useCallback((amount?: Decimal) => reset({ amount: amount ?? '' }), [reset]) + const onBalance = useCallback((amount?: Decimal) => reset({ amount: amount ?? '' }).catch(errorFallback), [reset]) return ( <> diff --git a/apps/main/src/lend/components/PageVault/VaultWithdrawRedeem/index.tsx b/apps/main/src/lend/components/PageVault/VaultWithdrawRedeem/index.tsx index 114db0a396..e76da77fc1 100644 --- a/apps/main/src/lend/components/PageVault/VaultWithdrawRedeem/index.tsx +++ b/apps/main/src/lend/components/PageVault/VaultWithdrawRedeem/index.tsx @@ -26,6 +26,7 @@ import { useReleaseChannel } from '@ui-kit/hooks/useLocalStorage' import { t } from '@ui-kit/lib/i18n' import { LargeTokenInput } from '@ui-kit/shared/ui/LargeTokenInput' import { ReleaseChannel, decimal, type Decimal } from '@ui-kit/utils' +import { errorFallback } from '@ui-kit/utils/error.util' const VaultWithdrawRedeem = ({ rChainId, @@ -62,24 +63,21 @@ const VaultWithdrawRedeem = ({ const disableWithdrawInFull = isNotReady || max !== userBalances?.vaultSharesConverted const updateFormValues = useCallback( - (updatedFormValues: Partial) => { - void setFormValues(rChainId, rFormType, isLoaded ? api : null, market, updatedFormValues) - }, + (updatedFormValues: Partial) => + setFormValues(rChainId, rFormType, isLoaded ? api : null, market, updatedFormValues), [api, isLoaded, market, rChainId, rFormType, setFormValues], ) const reset = useCallback( (updatedFormValues: Partial) => { setTxInfoBar(null) - updateFormValues(updatedFormValues) + return updateFormValues(updatedFormValues) }, [updateFormValues], ) const handleFormChange = useCallback( - (updatedFormValues: Partial) => { - reset({ ...updatedFormValues, amountError: '' }) - }, + (updatedFormValues: Partial) => reset({ ...updatedFormValues, amountError: '' }), [reset], ) @@ -215,7 +213,7 @@ const VaultWithdrawRedeem = ({ }} value={formValues.amount} onChange={(amount) => { - handleFormChange({ amount, isFullWithdraw: false }) + handleFormChange({ amount, isFullWithdraw: false }).catch(errorFallback) }} /> @@ -274,7 +272,7 @@ const VaultWithdrawRedeem = ({ handleFormChange({ isFullWithdraw, amount: '' })} + onChange={(isFullWithdraw) => handleFormChange({ isFullWithdraw, amount: '' }).catch(errorFallback)} > {t`Withdraw in full`} diff --git a/apps/main/src/lend/components/TokenLabel.tsx b/apps/main/src/lend/components/TokenLabel.tsx index 5c14627846..d14ffdc912 100644 --- a/apps/main/src/lend/components/TokenLabel.tsx +++ b/apps/main/src/lend/components/TokenLabel.tsx @@ -10,6 +10,7 @@ import TextEllipsis from '@ui/TextEllipsis' import { scanTokenPath } from '@ui/utils' import { TokenIcon } from '@ui-kit/shared/ui/TokenIcon' import { copyToClipboard } from '@ui-kit/utils' +import { errorFallback } from '@ui-kit/utils/error.util' const TokenLabel = ({ rChainId, @@ -50,7 +51,7 @@ const TokenLabel = ({ size="medium" onClick={(evt) => { evt.stopPropagation() - void copyToClipboard(address) + copyToClipboard(address).catch(errorFallback) }} > diff --git a/apps/main/src/lend/hooks/useContract.ts b/apps/main/src/lend/hooks/useContract.ts index a15cb070f5..2744181783 100644 --- a/apps/main/src/lend/hooks/useContract.ts +++ b/apps/main/src/lend/hooks/useContract.ts @@ -3,6 +3,7 @@ import { useCallback, useEffect, useState } from 'react' import networks from '@/lend/networks' import { ChainId, Provider } from '@/lend/types/lend.types' import { useWallet } from '@ui-kit/features/connect-wallet' +import { errorFallback } from '@ui-kit/utils/error.util' const useAbiGaugeTotalSupply = ( rChainId: ChainId, @@ -41,7 +42,7 @@ const useAbiGaugeTotalSupply = ( : walletProvider || new JsonRpcProvider(networks[rChainId].rpcUrl) if (jsonModuleName && contractAddress && provider) { - void (async () => setContract(await getContract(jsonModuleName, contractAddress, provider)))() + ;(async () => setContract(await getContract(jsonModuleName, contractAddress, provider)))().catch(errorFallback) } } }, [contractAddress, getContract, walletProvider, jsonModuleName, rChainId, signerRequired]) diff --git a/apps/main/src/lend/store/createLoanBorrowMoreSlice.ts b/apps/main/src/lend/store/createLoanBorrowMoreSlice.ts index 9b43d69a03..367302ed51 100644 --- a/apps/main/src/lend/store/createLoanBorrowMoreSlice.ts +++ b/apps/main/src/lend/store/createLoanBorrowMoreSlice.ts @@ -23,6 +23,7 @@ import { refetchLoanExists } from '@/llamalend/queries/loan-exists' import { Chain } from '@curvefi/prices-api' import { getUserMarketCollateralEvents } from '@curvefi/prices-api/lending' import { getLib, useWallet } from '@ui-kit/features/connect-wallet' +import { errorFallback } from '@ui-kit/utils/error.util' import { setMissingProvider } from '@ui-kit/utils/store.util' type StateKey = keyof typeof DEFAULT_STATE @@ -240,7 +241,7 @@ const createLoanBorrowMore = ( // api calls await sliceState.fetchMaxRecv(activeKey.activeKeyMax, api, market, isLeverage) await sliceState.fetchDetailInfo(activeKey.activeKey, api, market, maxSlippage, isLeverage) - void sliceState.fetchEstGasApproval(activeKey.activeKey, api, market, maxSlippage, isLeverage) + sliceState.fetchEstGasApproval(activeKey.activeKey, api, market, maxSlippage, isLeverage).catch(errorFallback) }, // steps @@ -306,12 +307,12 @@ const createLoanBorrowMore = ( ) // update user events api - void getUserMarketCollateralEvents( + getUserMarketCollateralEvents( wallet?.account?.address, networks[chainId].name as Chain, market.addresses.controller, resp.hash, - ) + ).catch(errorFallback) if (resp.activeKey === get()[sliceKey].activeKey) { if (error) { @@ -330,18 +331,18 @@ const createLoanBorrowMore = ( userAddress: wallet?.account?.address, }) if (loanExists) { - void user.fetchAll(api, market, true) + user.fetchAll(api, market, true).catch(errorFallback) invalidateAllUserBorrowDetails({ chainId: api.chainId, marketId: market.id }) } invalidateMarketDetails({ chainId: api.chainId, marketId: market.id }) - void markets.fetchAll(api, market, true) + markets.fetchAll(api, market, true).catch(errorFallback) // update formStatus sliceState.setStateByKeys({ ...DEFAULT_STATE, formStatus: { ...DEFAULT_FORM_STATUS, isApproved: true, isComplete: true }, }) - void sliceState.setFormValues(api, market, DEFAULT_FORM_VALUES, maxSlippage, isLeverage) + sliceState.setFormValues(api, market, DEFAULT_FORM_VALUES, maxSlippage, isLeverage).catch(errorFallback) return { ...resp, error } } } diff --git a/apps/main/src/lend/store/createLoanCollateralAddSlice.ts b/apps/main/src/lend/store/createLoanCollateralAddSlice.ts index a0b6fe3ccd..937573a0c4 100644 --- a/apps/main/src/lend/store/createLoanCollateralAddSlice.ts +++ b/apps/main/src/lend/store/createLoanCollateralAddSlice.ts @@ -14,6 +14,7 @@ import { refetchLoanExists } from '@/llamalend/queries/loan-exists' import { Chain } from '@curvefi/prices-api' import { getUserMarketCollateralEvents } from '@curvefi/prices-api/lending' import { useWallet } from '@ui-kit/features/connect-wallet' +import { errorFallback } from '@ui-kit/utils/error.util' import { setMissingProvider } from '@ui-kit/utils/store.util' type StateKey = keyof typeof DEFAULT_STATE @@ -126,8 +127,10 @@ const createLoanCollateralAdd = ( } // api calls - void sliceState.fetchDetailInfo(activeKey, api, market) - void sliceState.fetchEstGasApproval(activeKey, api, market) + await Promise.all([ + sliceState.fetchDetailInfo(activeKey, api, market), + sliceState.fetchEstGasApproval(activeKey, api, market), + ]) }, // step @@ -179,12 +182,12 @@ const createLoanCollateralAdd = ( ) // update user events api - void getUserMarketCollateralEvents( + getUserMarketCollateralEvents( wallet?.account?.address, networks[chainId].name as Chain, market.addresses.controller, resp.hash, - ) + ).catch(errorFallback) if (resp.activeKey === get()[sliceKey].activeKey) { if (error) { @@ -198,11 +201,11 @@ const createLoanCollateralAdd = ( userAddress: wallet?.account?.address, }) if (loanExists) { - void user.fetchAll(api, market, true) + user.fetchAll(api, market, true).catch(errorFallback) invalidateAllUserBorrowDetails({ chainId: api.chainId, marketId: market.id }) } invalidateMarketDetails({ chainId: api.chainId, marketId: market.id }) - void markets.fetchAll(api, market, true) + markets.fetchAll(api, market, true).catch(errorFallback) // update formStatus sliceState.setStateByKeys({ diff --git a/apps/main/src/lend/store/createLoanCollateralRemoveSlice.ts b/apps/main/src/lend/store/createLoanCollateralRemoveSlice.ts index 3ae72c6f3a..7780b5a389 100644 --- a/apps/main/src/lend/store/createLoanCollateralRemoveSlice.ts +++ b/apps/main/src/lend/store/createLoanCollateralRemoveSlice.ts @@ -14,6 +14,7 @@ import { refetchLoanExists } from '@/llamalend/queries/loan-exists' import { Chain } from '@curvefi/prices-api' import { getUserMarketCollateralEvents } from '@curvefi/prices-api/lending' import { useWallet } from '@ui-kit/features/connect-wallet' +import { errorFallback } from '@ui-kit/utils/error.util' import { setMissingProvider } from '@ui-kit/utils/store.util' const { cloneDeep } = lodash @@ -140,8 +141,10 @@ const createLoanCollateralRemove = ( // api calls await sliceState.fetchMaxRemovable(api, market) - void sliceState.fetchDetailInfo(activeKey, api, market) - void sliceState.fetchEstGas(activeKey, api, market) + Promise.all([ + sliceState.fetchDetailInfo(activeKey, api, market), + sliceState.fetchEstGas(activeKey, api, market), + ]).catch(errorFallback) }, // steps @@ -168,12 +171,12 @@ const createLoanCollateralRemove = ( formValues.collateral, ) // update user events api - void getUserMarketCollateralEvents( + getUserMarketCollateralEvents( wallet?.account?.address, networks[chainId].name as Chain, market.addresses.controller, resp.hash, - ) + ).catch(errorFallback) if (resp.activeKey === get()[sliceKey].activeKey) { if (error) { @@ -187,18 +190,18 @@ const createLoanCollateralRemove = ( userAddress: wallet?.account?.address, }) if (loanExists) { - void user.fetchAll(api, market, true) + user.fetchAll(api, market, true).catch(errorFallback) invalidateAllUserBorrowDetails({ chainId: api.chainId, marketId: market.id }) } invalidateMarketDetails({ chainId: api.chainId, marketId: market.id }) - void markets.fetchAll(api, market, true) + markets.fetchAll(api, market, true).catch(errorFallback) // update formStatus sliceState.setStateByKeys({ ...DEFAULT_STATE, formStatus: { ...DEFAULT_FORM_STATUS, isComplete: true }, }) - void sliceState.setFormValues(api, market, DEFAULT_FORM_VALUES) + sliceState.setFormValues(api, market, DEFAULT_FORM_VALUES).catch(errorFallback) return { ...resp, error } } } diff --git a/apps/main/src/lend/store/createLoanCreateSlice.ts b/apps/main/src/lend/store/createLoanCreateSlice.ts index 445a2bf8e1..457d265ebe 100644 --- a/apps/main/src/lend/store/createLoanCreateSlice.ts +++ b/apps/main/src/lend/store/createLoanCreateSlice.ts @@ -21,6 +21,7 @@ import { refetchLoanExists } from '@/llamalend/queries/loan-exists' import { Chain } from '@curvefi/prices-api' import { getUserMarketCollateralEvents } from '@curvefi/prices-api/lending' import { useWallet } from '@ui-kit/features/connect-wallet' +import { errorFallback } from '@ui-kit/utils/error.util' import { setMissingProvider } from '@ui-kit/utils/store.util' type StateKey = keyof typeof DEFAULT_STATE @@ -255,8 +256,10 @@ const createLoanCreate = (set: StoreApi['setState'], get: StoreApi if (isLeverage) void sliceState.fetchMaxLeverage(market) await sliceState.fetchMaxRecv(activeKeys.activeKeyMax, api, market, isLeverage) await sliceState.fetchDetailInfo(activeKeys.activeKey, api, market, maxSlippage, isLeverage) - void sliceState.fetchEstGasApproval(activeKeys.activeKey, api, market, maxSlippage, isLeverage) - void sliceState.fetchLiqRanges(activeKeys.activeKeyLiqRange, api, market, isLeverage) + Promise.all([ + sliceState.fetchEstGasApproval(activeKeys.activeKey, api, market, maxSlippage, isLeverage), + sliceState.fetchLiqRanges(activeKeys.activeKeyLiqRange, api, market, isLeverage), + ]).catch(errorFallback) }, // steps @@ -323,12 +326,12 @@ const createLoanCreate = (set: StoreApi['setState'], get: StoreApi isLeverage, ) // update user events api - void getUserMarketCollateralEvents( + getUserMarketCollateralEvents( wallet?.account?.address, networks[chainId].name as Chain, market.addresses.controller, resp.hash, - ) + ).catch(errorFallback) if (resp.activeKey === get()[sliceKey].activeKey) { if (error) { @@ -343,7 +346,7 @@ const createLoanCreate = (set: StoreApi['setState'], get: StoreApi if (loanExists) { // api calls await user.fetchAll(api, market, true) - void markets.fetchAll(api, market, true) + markets.fetchAll(api, market, true).catch(errorFallback) markets.setStateByKey('marketDetailsView', 'user') invalidateAllUserBorrowDetails({ chainId: api.chainId, marketId: market.id }) // update formStatus diff --git a/apps/main/src/lend/store/createLoanRepaySlice.ts b/apps/main/src/lend/store/createLoanRepaySlice.ts index 229b660358..60cfb12a8b 100644 --- a/apps/main/src/lend/store/createLoanRepaySlice.ts +++ b/apps/main/src/lend/store/createLoanRepaySlice.ts @@ -19,6 +19,7 @@ import { refetchLoanExists } from '@/llamalend/queries/loan-exists' import { Chain } from '@curvefi/prices-api' import { getUserMarketCollateralEvents } from '@curvefi/prices-api/lending' import { useWallet } from '@ui-kit/features/connect-wallet' +import { errorFallback } from '@ui-kit/utils/error.util' import { setMissingProvider } from '@ui-kit/utils/store.util' type StateKey = keyof typeof DEFAULT_STATE @@ -193,7 +194,7 @@ const createLoanRepaySlice = (set: StoreApi['setState'], get: StoreApi['setState'], get: StoreApi['setState'], get: StoreApi { const { formStatus, ...sliceState } = get()[sliceKey] @@ -175,12 +176,12 @@ const createLoanSelfLiquidationSlice = ( // api calls const { error, ...resp } = await loanSelfLiquidation.selfLiquidate(provider, market, maxSlippage) // update user events api - void getUserMarketCollateralEvents( + getUserMarketCollateralEvents( wallet?.account?.address, networks[chainId].name as Chain, market.addresses.controller, resp.hash, - ) + ).catch(errorFallback) if (resp) { const loanExists = await refetchLoanExists({ @@ -199,11 +200,11 @@ const createLoanSelfLiquidationSlice = ( } else { // api calls if (loanExists) { - void user.fetchAll(api, market, true) + user.fetchAll(api, market, true).catch(errorFallback) invalidateAllUserBorrowDetails({ chainId: api.chainId, marketId: market.id }) } invalidateMarketDetails({ chainId: api.chainId, marketId: market.id }) - void markets.fetchAll(api, market, true) + markets.fetchAll(api, market, true).catch(errorFallback) // update state sliceState.setStateByKey('formStatus', { ...DEFAULT_FORM_STATUS, isApproved: true, isComplete: true }) diff --git a/apps/main/src/lend/store/createVaultClaimSlice.ts b/apps/main/src/lend/store/createVaultClaimSlice.ts index f8c1082384..fae675526b 100644 --- a/apps/main/src/lend/store/createVaultClaimSlice.ts +++ b/apps/main/src/lend/store/createVaultClaimSlice.ts @@ -7,6 +7,7 @@ import apiLending from '@/lend/lib/apiLending' import type { State } from '@/lend/store/useStore' import { Api, MarketClaimable, OneWayMarketTemplate } from '@/lend/types/lend.types' import { useWallet } from '@ui-kit/features/connect-wallet' +import { errorFallback } from '@ui-kit/utils/error.util' import { setMissingProvider } from '@ui-kit/utils/store.util' type StateKey = keyof typeof DEFAULT_STATE @@ -63,10 +64,9 @@ const createVaultClaim = (set: StoreApi['setState'], get: StoreApi if (!userActiveKey || !api || !market) return const { signerAddress } = api - // api calls if (signerAddress) { - void get()[sliceKey].fetchClaimable(userActiveKey, api, market) + get()[sliceKey].fetchClaimable(userActiveKey, api, market).catch(errorFallback) } }, @@ -86,9 +86,11 @@ const createVaultClaim = (set: StoreApi['setState'], get: StoreApi if (resp.userActiveKey === userActiveKey) { // re-fetch api - void get()[sliceKey].fetchClaimable(resp.userActiveKey, api, market) - void get().user.fetchUserMarketBalances(api, market, true) - void get().markets.fetchAll(api, market, true) + Promise.all([ + get()[sliceKey].fetchClaimable(resp.userActiveKey, api, market), + get().user.fetchUserMarketBalances(api, market, true), + get().markets.fetchAll(api, market, true), + ]).catch(errorFallback) // update state const partialFormStatus: Partial = { diff --git a/apps/main/src/lend/store/createVaultDepositMintSlice.ts b/apps/main/src/lend/store/createVaultDepositMintSlice.ts index 6dfd9e7047..5885bfdb89 100644 --- a/apps/main/src/lend/store/createVaultDepositMintSlice.ts +++ b/apps/main/src/lend/store/createVaultDepositMintSlice.ts @@ -13,6 +13,7 @@ import { Api, ChainId, FutureRates, OneWayMarketTemplate } from '@/lend/types/le import { Chain } from '@curvefi/prices-api' import { getUserMarketCollateralEvents } from '@curvefi/prices-api/lending' import { useWallet } from '@ui-kit/features/connect-wallet' +import { errorFallback } from '@ui-kit/utils/error.util' import { setMissingProvider } from '@ui-kit/utils/store.util' type StateKey = keyof typeof DEFAULT_STATE @@ -132,11 +133,11 @@ const createVaultMint = ( } // api calls - void get()[sliceKey].fetchDetails(activeKey, formType, market) + get()[sliceKey].fetchDetails(activeKey, formType, market).catch(errorFallback) if (signerAddress) { await get()[sliceKey].fetchMax(rChainId, formType, market) - void get()[sliceKey].fetchEstGasApproval(activeKey, formType, api, market) + get()[sliceKey].fetchEstGasApproval(activeKey, formType, api, market).catch(errorFallback) } }, @@ -179,17 +180,19 @@ const createVaultMint = ( const { amount } = formValues const resp = await fn(activeKey, provider, market, amount) // update user events api - void getUserMarketCollateralEvents( + getUserMarketCollateralEvents( wallet?.account?.address, networks[chainId].name as Chain, market.addresses.controller, resp.hash, - ) + ).catch(errorFallback) if (resp.activeKey === get()[sliceKey].activeKey) { // re-fetch api - void get().user.fetchUserMarketBalances(api, market, true) - void get().markets.fetchAll(api, market, true) + Promise.all([ + get().user.fetchUserMarketBalances(api, market, true), + get().markets.fetchAll(api, market, true), + ]).catch(errorFallback) invalidateAllUserBorrowDetails({ chainId: api.chainId, marketId: market.id }) invalidateMarketDetails({ chainId: api.chainId, marketId: market.id }) // update state diff --git a/apps/main/src/lend/store/createVaultStakeSlice.ts b/apps/main/src/lend/store/createVaultStakeSlice.ts index da21f4d54e..66b61c2bed 100644 --- a/apps/main/src/lend/store/createVaultStakeSlice.ts +++ b/apps/main/src/lend/store/createVaultStakeSlice.ts @@ -13,6 +13,7 @@ import { Api, ChainId, OneWayMarketTemplate } from '@/lend/types/lend.types' import { Chain } from '@curvefi/prices-api' import { getUserMarketCollateralEvents } from '@curvefi/prices-api/lending' import { useWallet } from '@ui-kit/features/connect-wallet' +import { errorFallback } from '@ui-kit/utils/error.util' import { setMissingProvider } from '@ui-kit/utils/store.util' type StateKey = keyof typeof DEFAULT_STATE @@ -98,7 +99,7 @@ const createVaultStake = (set: StoreApi['setState'], get: StoreApi // api calls if (signerAddress) { - void get()[sliceKey].fetchEstGasApproval(activeKey, formType, api, market) + get()[sliceKey].fetchEstGasApproval(activeKey, formType, api, market).catch(errorFallback) } }, @@ -139,17 +140,20 @@ const createVaultStake = (set: StoreApi['setState'], get: StoreApi const { amount } = formValues const resp = await apiLending.vaultStake.stake(activeKey, provider, market, amount) // update user events api - void getUserMarketCollateralEvents( + getUserMarketCollateralEvents( wallet?.account?.address, networks[chainId].name as Chain, market.addresses.controller, resp.hash, - ) + ).catch(errorFallback) if (resp.activeKey === get()[sliceKey].activeKey) { // re-fetch api - void get().user.fetchUserMarketBalances(api, market, true) - void get().markets.fetchAll(api, market, true) + Promise.all([ + get().user.fetchUserMarketBalances(api, market, true), + get().markets.fetchAll(api, market, true), + ]).catch(errorFallback) + invalidateAllUserBorrowDetails({ chainId: api.chainId, marketId: market.id }) invalidateMarketDetails({ chainId: api.chainId, marketId: market.id }) diff --git a/apps/main/src/lend/store/createVaultUnstakeSlice.ts b/apps/main/src/lend/store/createVaultUnstakeSlice.ts index 1bf3d4da88..02a5a43888 100644 --- a/apps/main/src/lend/store/createVaultUnstakeSlice.ts +++ b/apps/main/src/lend/store/createVaultUnstakeSlice.ts @@ -13,6 +13,7 @@ import { Api, ChainId, OneWayMarketTemplate } from '@/lend/types/lend.types' import { Chain } from '@curvefi/prices-api' import { getUserMarketCollateralEvents } from '@curvefi/prices-api/lending' import { useWallet } from '@ui-kit/features/connect-wallet' +import { errorFallback } from '@ui-kit/utils/error.util' import { setMissingProvider } from '@ui-kit/utils/store.util' type StateKey = keyof typeof DEFAULT_STATE @@ -96,7 +97,7 @@ const createVaultUnstake = (set: StoreApi['setState'], get: StoreApi['setState'], get: StoreApi { - void onUpdate({ userCollateral, debt, range, userBorrowed, slippage, leverageEnabled }) + onUpdate({ userCollateral, debt, range, userBorrowed, slippage, leverageEnabled }).catch(errorFallback) }, [onUpdate, userCollateral, debt, range, userBorrowed, slippage, leverageEnabled]) } diff --git a/apps/main/src/loan/components/ChartOhlcWrapper/index.tsx b/apps/main/src/loan/components/ChartOhlcWrapper/index.tsx index abeca0e11a..638dca00d4 100644 --- a/apps/main/src/loan/components/ChartOhlcWrapper/index.tsx +++ b/apps/main/src/loan/components/ChartOhlcWrapper/index.tsx @@ -14,6 +14,7 @@ import TextCaption from '@ui/TextCaption' import { useLayoutStore } from '@ui-kit/features/layout' import { useUserProfileStore } from '@ui-kit/features/user-profile' import { t } from '@ui-kit/lib/i18n' +import { errorFallback } from '@ui-kit/utils/error.util' import { ChartOhlcWrapperProps, LlammaLiquidityCoins } from './types' const ChartOhlcWrapper = ({ rChainId, llamma, llammaId, betaBackgroundColor }: ChartOhlcWrapperProps) => { @@ -232,23 +233,25 @@ const ChartOhlcWrapper = ({ rChainId, llamma, llammaId, betaBackgroundColor }: C * the oracle pools based ohlc chart. */ const refetchPricesData = useCallback(() => { - void fetchOracleOhlcData( - rChainId, - controller, - chartInterval, - timeUnit, - chartTimeSettings.start, - chartTimeSettings.end, - ) - void fetchLlammaOhlcData( - rChainId, - llammaId, - address, - chartInterval, - timeUnit, - chartTimeSettings.start, - chartTimeSettings.end, - ) + Promise.all([ + fetchOracleOhlcData( + rChainId, + controller, + chartInterval, + timeUnit, + chartTimeSettings.start, + chartTimeSettings.end, + ), + fetchLlammaOhlcData( + rChainId, + llammaId, + address, + chartInterval, + timeUnit, + chartTimeSettings.start, + chartTimeSettings.end, + ), + ]).catch(errorFallback) }, [ fetchOracleOhlcData, rChainId, @@ -274,7 +277,7 @@ const ChartOhlcWrapper = ({ rChainId, llamma, llammaId, betaBackgroundColor }: C const endTime = subtractTimeUnit(timeOption, lastFetchEndTime) const startTime = getThreeHundredResultsAgo(timeOption, endTime) - void fetchMoreData(rChainId, controller, address, chartInterval, timeUnit, +startTime, endTime) + fetchMoreData(rChainId, controller, address, chartInterval, timeUnit, +startTime, endTime).catch(errorFallback) }, [timeOption, fetchMoreData, rChainId, controller, address, chartInterval, timeUnit], ) diff --git a/apps/main/src/loan/components/PageCrvUsdStaking/DepositWithdraw/DeployButton.tsx b/apps/main/src/loan/components/PageCrvUsdStaking/DepositWithdraw/DeployButton.tsx index e82f6adbd5..30b68c65e5 100644 --- a/apps/main/src/loan/components/PageCrvUsdStaking/DepositWithdraw/DeployButton.tsx +++ b/apps/main/src/loan/components/PageCrvUsdStaking/DepositWithdraw/DeployButton.tsx @@ -6,6 +6,7 @@ import { useScrvUsdUserBalances } from '@/loan/entities/scrvusd-userBalances' import useStore from '@/loan/store/useStore' import Button from '@ui/Button' import { t } from '@ui-kit/lib/i18n' +import { errorFallback } from '@ui-kit/utils/error.util' type DeployButtonProps = { className?: string } @@ -49,24 +50,19 @@ const DeployButton = ({ className }: DeployButtonProps) => { const handleClick = useCallback(async () => { if (stakingModule === 'deposit') { if (isInputAmountApproved) { - void deposit(inputAmount) + deposit(inputAmount).catch(errorFallback) } if (!isInputAmountApproved) { - const approved = await depositApprove(inputAmount) - if (approved) { - void deposit(inputAmount) + if (await depositApprove(inputAmount)) { + deposit(inputAmount).catch(errorFallback) } } } if (stakingModule === 'withdraw') { - if (inputAmount === userBalance.scrvUSD) { - void redeem(inputAmount) - } else { - void redeem(inputAmount) - } + redeem(inputAmount).catch(errorFallback) } - }, [stakingModule, isInputAmountApproved, deposit, inputAmount, depositApprove, redeem, userBalance]) + }, [stakingModule, isInputAmountApproved, deposit, inputAmount, depositApprove, redeem]) return ( { if (curve && inputAmount !== '0') { if (stakingModule === 'deposit') { if (isDepositApprovalReady) { - void estimateGasDeposit(inputAmount) + estimateGasDeposit(inputAmount).catch(errorFallback) } else { - void estimateGasDepositApprove(inputAmount) + estimateGasDepositApprove(inputAmount).catch(errorFallback) } previewAction('deposit', inputAmount) } else { - void estimateGasWithdraw(inputAmount) + estimateGasWithdraw(inputAmount).catch(errorFallback) previewAction('withdraw', inputAmount) } } diff --git a/apps/main/src/loan/components/PageCrvUsdStaking/index.tsx b/apps/main/src/loan/components/PageCrvUsdStaking/index.tsx index 5457d26839..12c7780e67 100644 --- a/apps/main/src/loan/components/PageCrvUsdStaking/index.tsx +++ b/apps/main/src/loan/components/PageCrvUsdStaking/index.tsx @@ -6,7 +6,7 @@ import Statistics from '@/loan/components/PageCrvUsdStaking/Statistics' import StatsBanner from '@/loan/components/PageCrvUsdStaking/StatsBanner' import UserInformation from '@/loan/components/PageCrvUsdStaking/UserInformation' import UserPosition from '@/loan/components/PageCrvUsdStaking/UserPosition' -import { useScrvUsdUserBalances } from '@/loan/entities/scrvusd-userBalances' +import { invalidateScrvUsdUserBalances, useScrvUsdUserBalances } from '@/loan/entities/scrvusd-userBalances' import useStore from '@/loan/store/useStore' import type { NetworkUrlParams } from '@/loan/types/loan.types' import { Stack, useMediaQuery } from '@mui/material' @@ -15,6 +15,7 @@ import { useConnection } from '@ui-kit/features/connect-wallet' import { useSwitch } from '@ui-kit/hooks/useSwitch' import { Sizing } from '@ui-kit/themes/design/0_primitives' import { SizesAndSpaces } from '@ui-kit/themes/design/1_sizes_spaces' +import { errorFallback } from '@ui-kit/utils/error.util' const { MaxWidth } = SizesAndSpaces @@ -33,7 +34,6 @@ const CrvUsdStaking = ({ params }: { params: NetworkUrlParams }) => { data: userScrvUsdBalance, isFetching: isUserScrvUsdBalanceFetching, isFetched: isUserScrvUsdBalanceFetched, - refetch: refetchUserScrvUsdBalance, } = useScrvUsdUserBalances({ userAddress: address }) const isUserScrvUsdBalanceZero = !address || !userScrvUsdBalance || BigNumber(userScrvUsdBalance.scrvUSD).isZero() @@ -49,22 +49,16 @@ const CrvUsdStaking = ({ params }: { params: NetworkUrlParams }) => { const columnView = useMediaQuery(`(max-width: ${columnViewBreakPoint})`) useEffect(() => { - const fetchData = async () => { - if (!lendApi || !address) return - // ensure user balances are up to date on load - void refetchUserScrvUsdBalance() - fetchExchangeRate() - fetchCrvUsdSupplies() - } - - void fetchData() - }, [lendApi, fetchExchangeRate, fetchCrvUsdSupplies, refetchUserScrvUsdBalance, address]) + if (!lendApi || !address) return + // ensure user balances are up to date on load + invalidateScrvUsdUserBalances({ userAddress: address }) + fetchExchangeRate() + fetchCrvUsdSupplies() + }, [lendApi, fetchExchangeRate, fetchCrvUsdSupplies, address]) useEffect(() => { - if (!lendApi || !chainId || !address || inputAmount === '0') return - - if (stakingModule === 'deposit') { - void checkApproval.depositApprove(inputAmount) + if (lendApi && chainId && address && inputAmount !== '0' && stakingModule === 'deposit') { + checkApproval.depositApprove(inputAmount).catch(errorFallback) } }, [checkApproval, lendApi, chainId, inputAmount, stakingModule, address]) diff --git a/apps/main/src/loan/components/PageIntegrations/Page.tsx b/apps/main/src/loan/components/PageIntegrations/Page.tsx index 58025741e2..59e612377d 100644 --- a/apps/main/src/loan/components/PageIntegrations/Page.tsx +++ b/apps/main/src/loan/components/PageIntegrations/Page.tsx @@ -9,6 +9,7 @@ import Spinner, { SpinnerWrapper } from '@ui/Spinner' import { breakpoints } from '@ui/utils/responsive' import { useParams } from '@ui-kit/hooks/router' import { Trans } from '@ui-kit/lib/i18n' +import { errorFallback } from '@ui-kit/utils/error.util' const Page = () => { const params = useParams() @@ -17,7 +18,7 @@ const Page = () => { const integrationsTags = useStore((state) => state.integrations.integrationsTags) useEffect(() => { - void init(rChainId) + init(rChainId).catch(errorFallback) }, [init, rChainId]) return ( diff --git a/apps/main/src/loan/components/PageLoanCreate/LoanFormCreate/index.tsx b/apps/main/src/loan/components/PageLoanCreate/LoanFormCreate/index.tsx index 773da5bc70..21617c0133 100644 --- a/apps/main/src/loan/components/PageLoanCreate/LoanFormCreate/index.tsx +++ b/apps/main/src/loan/components/PageLoanCreate/LoanFormCreate/index.tsx @@ -35,6 +35,7 @@ import { useTokenUsdRate } from '@ui-kit/lib/model/entities/token-usd-rate' import { LargeTokenInput } from '@ui-kit/shared/ui/LargeTokenInput' import { TokenLabel } from '@ui-kit/shared/ui/TokenLabel' import { ReleaseChannel, decimal, type Decimal } from '@ui-kit/utils' +import { errorFallback } from '@ui-kit/utils/error.util' const LoanCreate = ({ collateralAlert, @@ -86,9 +87,9 @@ const LoanCreate = ({ const { data: stablecoinUsdRate } = useTokenUsdRate({ chainId: network.chainId, tokenAddress: stablecoinAddress }) const updateFormValues = useCallback( - (updatedFormValues: FormValues) => { + async (updatedFormValues: FormValues) => { if (curve && llamma) { - void setFormValues(curve, isLeverage, llamma, updatedFormValues, maxSlippage) + await setFormValues(curve, isLeverage, llamma, updatedFormValues, maxSlippage) } }, [curve, isLeverage, llamma, maxSlippage, setFormValues], @@ -283,7 +284,7 @@ const LoanCreate = ({ const disabled = !isReady || (formStatus.isInProgress && !formStatus.error) useEffect(() => { - updateFormValues(formValues) + updateFormValues(formValues).catch(errorFallback) // eslint-disable-next-line react-hooks/exhaustive-deps }, [haveSigner]) diff --git a/apps/main/src/loan/components/PageLoanCreate/Page.tsx b/apps/main/src/loan/components/PageLoanCreate/Page.tsx index e5eb7a2754..abbdea8a02 100644 --- a/apps/main/src/loan/components/PageLoanCreate/Page.tsx +++ b/apps/main/src/loan/components/PageLoanCreate/Page.tsx @@ -41,6 +41,7 @@ import { t } from '@ui-kit/lib/i18n' import { REFRESH_INTERVAL } from '@ui-kit/lib/model' import { SizesAndSpaces } from '@ui-kit/themes/design/1_sizes_spaces' import { CRVUSD } from '@ui-kit/utils/address' +import { errorFallback } from '@ui-kit/utils/error.util' const { Spacing } = SizesAndSpaces @@ -106,13 +107,11 @@ const Page = () => { maxRecv: {}, maxRecvLeverage: {}, }) - const updatedFormValues = { ...formValues, n: formValues.n || llamma.defaultBands } - void setFormValues(curve, isLeverage, llamma, updatedFormValues, maxSlippage) - - if (curve.signerAddress) { - void fetchUserLoanWalletBalances(curve, llamma) - } + return Promise.all([ + setFormValues(curve, isLeverage, llamma, updatedFormValues, maxSlippage).catch(errorFallback), + curve.signerAddress && fetchUserLoanWalletBalances(curve, llamma).catch(errorFallback), + ]) }, [fetchUserLoanWalletBalances, formValues, maxSlippage, setFormValues, setStateByKeys], ) @@ -121,8 +120,7 @@ const Page = () => { if (isHydrated && curve) { if (llamma) { resetUserDetailsState(llamma) - fetchInitial(curve, isLeverage, llamma) - void fetchLoanDetails(curve, llamma) + Promise.all([fetchInitial(curve, isLeverage, llamma), fetchLoanDetails(curve, llamma)]).catch(errorFallback) setLoaded(true) } else if (collateralDatasMapper) { console.warn( @@ -152,7 +150,7 @@ const Page = () => { // max slippage updated useEffect(() => { if (loaded && !!curve) { - void setFormValues(curve, isLeverage, llamma, formValues, maxSlippage) + setFormValues(curve, isLeverage, llamma, formValues, maxSlippage).catch(errorFallback) } // eslint-disable-next-line react-hooks/exhaustive-deps }, [maxSlippage]) diff --git a/apps/main/src/loan/components/PageLoanCreate/types.ts b/apps/main/src/loan/components/PageLoanCreate/types.ts index 1649efab88..9a69a665f3 100644 --- a/apps/main/src/loan/components/PageLoanCreate/types.ts +++ b/apps/main/src/loan/components/PageLoanCreate/types.ts @@ -50,7 +50,7 @@ export type FormDetailInfo = { llammaId: string steps: Step[] setHealthMode: Dispatch> - updateFormValues: (updatedFormValues: FormValues) => void + updateFormValues: (updatedFormValues: FormValues) => Promise } export type FormDetailInfoLeverage = { diff --git a/apps/main/src/loan/components/PageLoanManage/CollateralDecrease/index.tsx b/apps/main/src/loan/components/PageLoanManage/CollateralDecrease/index.tsx index 9e5df8309a..722c110ff5 100644 --- a/apps/main/src/loan/components/PageLoanManage/CollateralDecrease/index.tsx +++ b/apps/main/src/loan/components/PageLoanManage/CollateralDecrease/index.tsx @@ -34,6 +34,7 @@ import { useTokenUsdRate } from '@ui-kit/lib/model/entities/token-usd-rate' import { LargeTokenInput } from '@ui-kit/shared/ui/LargeTokenInput' import { TokenLabel } from '@ui-kit/shared/ui/TokenLabel' import { decimal, type Decimal, ReleaseChannel } from '@ui-kit/utils' +import { errorFallback } from '@ui-kit/utils/error.util' interface Props extends Pick {} @@ -72,9 +73,9 @@ const CollateralDecrease = ({ curve, llamma, llammaId, rChainId }: Props) => { const { data: collateralUsdRate } = useTokenUsdRate({ chainId: network.chainId, tokenAddress: collateralAddress }) const updateFormValues = useCallback( - (updatedFormValues: FormValues) => { + async (updatedFormValues: FormValues) => { if (chainId && llamma) { - void setFormValues(chainId, llamma, updatedFormValues, maxRemovable) + await setFormValues(chainId, llamma, updatedFormValues, maxRemovable) } }, [chainId, llamma, maxRemovable, setFormValues], @@ -101,7 +102,7 @@ const CollateralDecrease = ({ curve, llamma, llammaId, rChainId }: Props) => { const updatedFormValues = { ...formValues } updatedFormValues.collateral = collateral updatedFormValues.collateralError = '' - updateFormValues(updatedFormValues) + updateFormValues(updatedFormValues).catch(errorFallback) } const onCollateralChanged = useCallback( @@ -109,7 +110,7 @@ const CollateralDecrease = ({ curve, llamma, llammaId, rChainId }: Props) => { const { formValues, formStatus } = useStore.getState().loanCollateralDecrease if ((val ?? '') === formValues.collateral) return reset(!!formStatus.error, formStatus.isComplete) - updateFormValues({ ...formValues, collateral: val ?? '', collateralError: '' }) + updateFormValues({ ...formValues, collateral: val ?? '', collateralError: '' }).catch(errorFallback) }, [reset, updateFormValues], ) diff --git a/apps/main/src/loan/components/PageLoanManage/CollateralIncrease/index.tsx b/apps/main/src/loan/components/PageLoanManage/CollateralIncrease/index.tsx index 2422808cd3..a07e0e6eff 100644 --- a/apps/main/src/loan/components/PageLoanManage/CollateralIncrease/index.tsx +++ b/apps/main/src/loan/components/PageLoanManage/CollateralIncrease/index.tsx @@ -74,9 +74,9 @@ const CollateralIncrease = ({ curve, isReady, llamma, llammaId }: Props) => { const { data: collateralUsdRate } = useTokenUsdRate({ chainId: network?.chainId, tokenAddress: collateralAddress }) const updateFormValues = useCallback( - (updatedFormValues: FormValues) => { + async (updatedFormValues: FormValues) => { if (chainId && llamma) { - void setFormValues(chainId, llamma, updatedFormValues) + await setFormValues(chainId, llamma, updatedFormValues) } }, [chainId, llamma, setFormValues], diff --git a/apps/main/src/loan/components/PageLoanManage/LoanDecrease/index.tsx b/apps/main/src/loan/components/PageLoanManage/LoanDecrease/index.tsx index b67e538478..aee3d8cf32 100644 --- a/apps/main/src/loan/components/PageLoanManage/LoanDecrease/index.tsx +++ b/apps/main/src/loan/components/PageLoanManage/LoanDecrease/index.tsx @@ -76,9 +76,9 @@ const LoanDecrease = ({ curve, llamma, llammaId, params, rChainId }: Props) => { const { userState } = userLoanDetails ?? {} const updateFormValues = useCallback( - (updatedFormValues: FormValues) => { + async (updatedFormValues: FormValues) => { if (chainId && llamma) { - void setFormValues(chainId, llamma, updatedFormValues) + await setFormValues(chainId, llamma, updatedFormValues) } }, [chainId, llamma, setFormValues], diff --git a/apps/main/src/loan/components/PageLoanManage/LoanDeleverage/index.tsx b/apps/main/src/loan/components/PageLoanManage/LoanDeleverage/index.tsx index c82264e30e..eca6090f69 100644 --- a/apps/main/src/loan/components/PageLoanManage/LoanDeleverage/index.tsx +++ b/apps/main/src/loan/components/PageLoanManage/LoanDeleverage/index.tsx @@ -50,6 +50,7 @@ import { useTokenUsdRate } from '@ui-kit/lib/model/entities/token-usd-rate' import { LargeTokenInput } from '@ui-kit/shared/ui/LargeTokenInput' import { TokenLabel } from '@ui-kit/shared/ui/TokenLabel' import { ReleaseChannel, decimal, type Decimal } from '@ui-kit/utils' +import { errorFallback } from '@ui-kit/utils/error.util' import { useThrottle } from '@ui-kit/utils/timers' // Loan Deleverage @@ -92,7 +93,7 @@ const LoanDeleverage = ({ const { data: collateralUsdRate } = useTokenUsdRate({ chainId: network.chainId, tokenAddress: collateralAddress }) const updateFormValues = useCallback( - (updatedFormValues: Partial, updatedMaxSlippage: string | null, isFullReset: boolean) => { + async (updatedFormValues: Partial, updatedMaxSlippage: string | null, isFullReset: boolean) => { setTxInfoBar(null) setConfirmHighPriceImpact(false) @@ -100,7 +101,7 @@ const LoanDeleverage = ({ setHealthMode(DEFAULT_HEALTH_MODE) } - return setFormValues( + await setFormValues( llammaId, curve, llamma, @@ -137,7 +138,7 @@ const LoanDeleverage = ({ txHash={scanTxPath(networks[rChainId], resp.hash)} onClose={() => { if (resp.loanExists) { - void updateFormValues({}, '', true) + updateFormValues({}, '', true).catch(() => errorFallback) } else { push(getCollateralListPathname(params)) } @@ -207,7 +208,7 @@ const LoanDeleverage = ({ // onMount useEffect(() => { isSubscribed.current = true - void updateFormValues(DEFAULT_FORM_VALUES, '', true) + updateFormValues(DEFAULT_FORM_VALUES, '', true).catch(errorFallback) return () => { isSubscribed.current = false @@ -217,14 +218,14 @@ const LoanDeleverage = ({ // signer changed useEffect(() => { - void updateFormValues(DEFAULT_FORM_VALUES, '', true) + updateFormValues(DEFAULT_FORM_VALUES, '', true).catch(errorFallback) // eslint-disable-next-line react-hooks/exhaustive-deps }, [curve?.signerAddress]) // update formValues useEffect(() => { if (chainId && llamma) { - void updateFormValues({}, '', false) + updateFormValues({}, '', false).catch(errorFallback) } // eslint-disable-next-line react-hooks/exhaustive-deps }, [chainId, llamma, userState?.collateral, userLoanDetails?.userIsCloseToLiquidation]) @@ -232,7 +233,7 @@ const LoanDeleverage = ({ // maxSlippage useEffect(() => { if (maxSlippage) { - void updateFormValues({}, maxSlippage, false) + updateFormValues({}, maxSlippage, false).catch(errorFallback) } // eslint-disable-next-line react-hooks/exhaustive-deps }, [maxSlippage]) @@ -240,7 +241,7 @@ const LoanDeleverage = ({ // pageVisible useEffect(() => { if (!formStatus.isInProgress) { - void updateFormValues({}, '', false) + updateFormValues({}, '', false).catch(errorFallback) } // eslint-disable-next-line react-hooks/exhaustive-deps }, [isPageVisible]) diff --git a/apps/main/src/loan/components/PageLoanManage/LoanIncrease/index.tsx b/apps/main/src/loan/components/PageLoanManage/LoanIncrease/index.tsx index cb62bfe5dd..633503f14d 100644 --- a/apps/main/src/loan/components/PageLoanManage/LoanIncrease/index.tsx +++ b/apps/main/src/loan/components/PageLoanManage/LoanIncrease/index.tsx @@ -38,6 +38,7 @@ import { useTokenUsdRate } from '@ui-kit/lib/model/entities/token-usd-rate' import { LargeTokenInput } from '@ui-kit/shared/ui/LargeTokenInput' import { TokenLabel } from '@ui-kit/shared/ui/TokenLabel' import { ReleaseChannel, decimal, type Decimal } from '@ui-kit/utils' +import { errorFallback } from '@ui-kit/utils/error.util' interface Props extends Pick {} @@ -84,7 +85,7 @@ const LoanIncrease = ({ curve, isReady, llamma, llammaId }: Props) => { const updateFormValues = useCallback( (updatedFormValues: FormValues) => { if (chainId && llamma) { - void setFormValues(chainId, llamma, updatedFormValues) + setFormValues(chainId, llamma, updatedFormValues).catch(errorFallback) } }, [chainId, llamma, setFormValues], @@ -245,7 +246,7 @@ const LoanIncrease = ({ curve, isReady, llamma, llammaId }: Props) => { // init useEffect(() => { if (isReady && chainId && llamma) { - void init(chainId, llamma) + init(chainId, llamma).catch(errorFallback) } // eslint-disable-next-line react-hooks/exhaustive-deps }, [isReady, chainId, llamma]) diff --git a/apps/main/src/loan/components/PageLoanManage/LoanLiquidate/index.tsx b/apps/main/src/loan/components/PageLoanManage/LoanLiquidate/index.tsx index 85950e562e..f530d3bb46 100644 --- a/apps/main/src/loan/components/PageLoanManage/LoanLiquidate/index.tsx +++ b/apps/main/src/loan/components/PageLoanManage/LoanLiquidate/index.tsx @@ -27,6 +27,7 @@ import { formatNumber, scanTxPath } from '@ui/utils' import { notify } from '@ui-kit/features/connect-wallet' import { useUserProfileStore } from '@ui-kit/features/user-profile' import { t, Trans } from '@ui-kit/lib/i18n' +import { errorFallback } from '@ui-kit/utils/error.util' interface Props extends Pick {} @@ -59,7 +60,7 @@ const LoanLiquidate = ({ curve, llamma, llammaId, params, rChainId }: Props) => if (chainId && llamma && (isErrorReset || isFullReset)) { setStateByKey('formStatus', { ...DEFAULT_FORM_STATUS, isApproved: formStatus.isApproved }) - void fetchTokensToLiquidate(rChainId, llamma, llammaId, maxSlippage, userWalletBalances) + fetchTokensToLiquidate(rChainId, llamma, llammaId, maxSlippage, userWalletBalances).catch(errorFallback) } }, [ @@ -170,7 +171,7 @@ const LoanLiquidate = ({ curve, llamma, llammaId, params, rChainId }: Props) => // init useEffect(() => { if (chainId && llamma && llammaId && typeof userWalletBalances?.stablecoin !== 'undefined') { - void fetchTokensToLiquidate(chainId, llamma, llammaId, maxSlippage, userWalletBalances) + fetchTokensToLiquidate(chainId, llamma, llammaId, maxSlippage, userWalletBalances).catch(errorFallback) } // eslint-disable-next-line react-hooks/exhaustive-deps }, [curve?.signerAddress, chainId, llamma, llammaId, maxSlippage, userWalletBalances?.stablecoin]) diff --git a/apps/main/src/loan/components/PageLoanManage/Page.tsx b/apps/main/src/loan/components/PageLoanManage/Page.tsx index 79df8d790e..4692665061 100644 --- a/apps/main/src/loan/components/PageLoanManage/Page.tsx +++ b/apps/main/src/loan/components/PageLoanManage/Page.tsx @@ -40,6 +40,7 @@ import { t } from '@ui-kit/lib/i18n' import { REFRESH_INTERVAL } from '@ui-kit/lib/model' import { SizesAndSpaces } from '@ui-kit/themes/design/1_sizes_spaces' import { CRVUSD } from '@ui-kit/utils/address' +import { errorFallback } from '@ui-kit/utils/error.util' const { Spacing } = SizesAndSpaces @@ -99,14 +100,14 @@ const Page = () => { useEffect(() => { if (isHydrated && curve) { if (rCollateralId && llamma) { - void (async () => { + ;(async () => { const fetchedLoanDetails = await fetchLoanDetails(curve, llamma) if (!fetchedLoanDetails.loanExists) { resetUserDetailsState(llamma) push(getLoanCreatePathname(params, rCollateralId)) } setLoaded(true) - })() + })().catch(errorFallback) } else { console.warn(`Cannot find market ${rCollateralId}, redirecting to list`, params) push(getCollateralListPathname(params)) diff --git a/apps/main/src/loan/store/createCollateralsSlice.ts b/apps/main/src/loan/store/createCollateralsSlice.ts index 1a3cbb3745..16d8ac659f 100644 --- a/apps/main/src/loan/store/createCollateralsSlice.ts +++ b/apps/main/src/loan/store/createCollateralsSlice.ts @@ -11,6 +11,7 @@ import { CollateralDataCache, CollateralDataCacheMapper, } from '@/loan/types/loan.types' +import { errorFallback } from '@ui-kit/utils/error.util' type StateKey = keyof typeof DEFAULT_STATE @@ -59,7 +60,9 @@ const createCollateralsSlice = (set: StoreApi['setState'], get: StoreApi< get()[sliceKey].setStateByActiveKey('collateralDatasMapper', chainId.toString(), collateralDatasMapper) // add to cache - void get().storeCache.setStateByActiveKey('collateralDatasMapper', chainId.toString(), collateralDatasCacheMapper) + get() + .storeCache.setStateByActiveKey('collateralDatasMapper', chainId.toString(), collateralDatasCacheMapper) + .catch(errorFallback) return { collateralDatas, collateralDatasMapper } }, diff --git a/apps/main/src/loan/store/createLoanCollateralDecreaseSlice.ts b/apps/main/src/loan/store/createLoanCollateralDecreaseSlice.ts index 1f30d97502..1c5d4742cc 100644 --- a/apps/main/src/loan/store/createLoanCollateralDecreaseSlice.ts +++ b/apps/main/src/loan/store/createLoanCollateralDecreaseSlice.ts @@ -14,6 +14,7 @@ import { loadingLRPrices } from '@/loan/utils/utilsCurvejs' import { getTokenName } from '@/loan/utils/utilsLoan' import { getUserMarketCollateralEvents } from '@curvefi/prices-api/crvusd' import { useWallet } from '@ui-kit/features/connect-wallet' +import { errorFallback } from '@ui-kit/utils/error.util' import { setMissingProvider } from '@ui-kit/utils/store.util' type StateKey = keyof typeof DEFAULT_STATE @@ -78,7 +79,7 @@ const createLoanCollateralDecrease = (set: StoreApi['setState'], get: Sto ...DEFAULT_STATE, init: (chainId: ChainId, llamma: Llamma) => { - void get()[sliceKey].fetchMaxRemovable(chainId, llamma) + get()[sliceKey].fetchMaxRemovable(chainId, llamma).catch(errorFallback) }, fetchEstGas: async (activeKey: string, chainId: ChainId, llamma: Llamma, formValues: FormValues) => { const { collateral } = formValues @@ -142,8 +143,10 @@ const createLoanCollateralDecrease = (set: StoreApi['setState'], get: Sto // fetch detail, approval, est gas, set loading if (haveCollateral) { - void get()[sliceKey].fetchDetailInfo(activeKey, chainId, llamma, cFormValues) - void get()[sliceKey].fetchEstGas(activeKey, chainId, llamma, cFormValues) + Promise.all([ + get()[sliceKey].fetchDetailInfo(activeKey, chainId, llamma, cFormValues), + get()[sliceKey].fetchEstGas(activeKey, chainId, llamma, cFormValues), + ]).catch(errorFallback) } else { get()[sliceKey].setStateByActiveKey('detailInfo', activeKey, DEFAULT_DETAIL_INFO) get()[sliceKey].setStateByActiveKey('formEstGas', activeKey, DEFAULT_FORM_EST_GAS) @@ -165,8 +168,10 @@ const createLoanCollateralDecrease = (set: StoreApi['setState'], get: Sto const removeCollateralFn = networks[chainId].api.collateralDecrease.removeCollateral const resp = await removeCollateralFn(activeKey, provider, llamma, formValues.collateral) // update user events api - void getUserMarketCollateralEvents(wallet?.account?.address, networks[chainId].id, llamma.controller, resp.hash) - void get()[sliceKey].fetchMaxRemovable(chainId, llamma) + Promise.all([ + getUserMarketCollateralEvents(wallet?.account?.address, networks[chainId].id, llamma.controller, resp.hash), + get()[sliceKey].fetchMaxRemovable(chainId, llamma), + ]).catch(errorFallback) const { loanExists } = await get().loans.fetchLoanDetails(curve, llamma) if (!loanExists) { get().loans.resetUserDetailsState(llamma) diff --git a/apps/main/src/loan/store/createLoanCollateralIncreaseSlice.ts b/apps/main/src/loan/store/createLoanCollateralIncreaseSlice.ts index 26f0dc0704..6bccfbd756 100644 --- a/apps/main/src/loan/store/createLoanCollateralIncreaseSlice.ts +++ b/apps/main/src/loan/store/createLoanCollateralIncreaseSlice.ts @@ -13,6 +13,7 @@ import { ChainId, LlamaApi, Llamma } from '@/loan/types/loan.types' import { loadingLRPrices } from '@/loan/utils/utilsCurvejs' import { getUserMarketCollateralEvents } from '@curvefi/prices-api/crvusd' import { useWallet } from '@ui-kit/features/connect-wallet' +import { errorFallback } from '@ui-kit/utils/error.util' import { setMissingProvider } from '@ui-kit/utils/store.util' type StateKey = keyof typeof DEFAULT_STATE @@ -133,8 +134,10 @@ const createLoanCollateralIncrease = (set: StoreApi['setState'], get: Sto // fetch detail, approval, est gas, set loading if (haveCollateral) { - void get()[sliceKey].fetchDetailInfo(activeKey, chainId, llamma, cFormValues) - void get()[sliceKey].fetchEstGasApproval(activeKey, chainId, llamma, cFormValues) + Promise.all([ + get()[sliceKey].fetchDetailInfo(activeKey, chainId, llamma, cFormValues), + get()[sliceKey].fetchEstGasApproval(activeKey, chainId, llamma, cFormValues), + ]).catch(errorFallback) } else { get()[sliceKey].setStateByActiveKey('detailInfo', activeKey, DEFAULT_DETAIL_INFO) get()[sliceKey].setStateByActiveKey('formEstGas', activeKey, DEFAULT_FORM_EST_GAS) @@ -165,7 +168,7 @@ const createLoanCollateralIncrease = (set: StoreApi['setState'], get: Sto }) if (!resp.error) { - void get()[sliceKey].fetchEstGasApproval(activeKey, chainId, llamma, formValues) + get()[sliceKey].fetchEstGasApproval(activeKey, chainId, llamma, formValues).catch(errorFallback) } return resp } @@ -183,7 +186,9 @@ const createLoanCollateralIncrease = (set: StoreApi['setState'], get: Sto const addCollateralFn = networks[chainId].api.collateralIncrease.addCollateral const resp = await addCollateralFn(activeKey, provider, llamma, formValues.collateral) // update user events api - void getUserMarketCollateralEvents(wallet?.account?.address, networks[chainId].id, llamma.controller, resp.hash) + getUserMarketCollateralEvents(wallet?.account?.address, networks[chainId].id, llamma.controller, resp.hash).catch( + errorFallback, + ) if (activeKey === get()[sliceKey].activeKey) { // re-fetch loan info const { loanExists } = await get().loans.fetchLoanDetails(curve, llamma) diff --git a/apps/main/src/loan/store/createLoanCreateSlice.ts b/apps/main/src/loan/store/createLoanCreateSlice.ts index 27bd4527d1..f12e187b4d 100644 --- a/apps/main/src/loan/store/createLoanCreateSlice.ts +++ b/apps/main/src/loan/store/createLoanCreateSlice.ts @@ -21,6 +21,7 @@ import { ChainId, LlamaApi, Llamma } from '@/loan/types/loan.types' import { loadingLRPrices } from '@/loan/utils/utilsCurvejs' import { getUserMarketCollateralEvents } from '@curvefi/prices-api/crvusd' import { useWallet } from '@ui-kit/features/connect-wallet' +import { errorFallback } from '@ui-kit/utils/error.util' import { setMissingProvider } from '@ui-kit/utils/store.util' type StateKey = keyof typeof DEFAULT_STATE @@ -308,7 +309,9 @@ const createLoanCreate = (set: StoreApi['setState'], get: StoreApi storedFormValues.debt !== formValues.debt || !get()[sliceKey].liqRangesMapper[activeKeyLiqRange] ) { - void get()[sliceKey].fetchLiqRanges(activeKeyLiqRange, chainId, isLeverage, llamma, clonedFormValues) + get() + [sliceKey].fetchLiqRanges(activeKeyLiqRange, chainId, isLeverage, llamma, clonedFormValues) + .catch(errorFallback) } // fetch approval and estimate gas, detail @@ -322,25 +325,16 @@ const createLoanCreate = (set: StoreApi['setState'], get: StoreApi } // fetch detail info - void get()[sliceKey].fetchDetailInfo( - activeKey, - chainId, - isLeverage, - llamma, - clonedFormValues, - signerAddress, - maxSlippage, - ) + get() + [ + sliceKey + ].fetchDetailInfo(activeKey, chainId, isLeverage, llamma, clonedFormValues, signerAddress, maxSlippage) + .catch(errorFallback) if (signerAddress && !collateralError) { - void get()[sliceKey].fetchEstGasApproval( - activeKey, - chainId, - isLeverage, - llamma, - clonedFormValues, - maxSlippage, - ) + get() + [sliceKey].fetchEstGasApproval(activeKey, chainId, isLeverage, llamma, clonedFormValues, maxSlippage) + .catch(errorFallback) } } else { if (isLeverage) { @@ -395,7 +389,9 @@ const createLoanCreate = (set: StoreApi['setState'], get: StoreApi error: resp.error, }) - void get()[sliceKey].fetchEstGasApproval(activeKey, chainId, isLeverage, llamma, formValues, maxSlippage) + get() + [sliceKey].fetchEstGasApproval(activeKey, chainId, isLeverage, llamma, formValues, maxSlippage) + .catch(errorFallback) return resp } @@ -422,7 +418,12 @@ const createLoanCreate = (set: StoreApi['setState'], get: StoreApi const createFn = networks[chainId].api.loanCreate.create const resp = await createFn(activeKey, provider, llamma, isLeverage, collateral, debt, n, maxSlippage) // update user events api - void getUserMarketCollateralEvents(wallet?.account?.address, networks[chainId].id, llamma.controller, resp.hash) + getUserMarketCollateralEvents( + wallet?.account?.address, + networks[chainId].id, + llamma.controller, + resp.hash, + ).catch(errorFallback) if (resp.activeKey === get()[sliceKey].activeKey) { get()[sliceKey].setStateByKeys({ diff --git a/apps/main/src/loan/store/createLoanDecreaseSlice.ts b/apps/main/src/loan/store/createLoanDecreaseSlice.ts index 3b814c2e68..06caa4dd82 100644 --- a/apps/main/src/loan/store/createLoanDecreaseSlice.ts +++ b/apps/main/src/loan/store/createLoanDecreaseSlice.ts @@ -13,6 +13,7 @@ import { ChainId, LlamaApi, Llamma } from '@/loan/types/loan.types' import { loadingLRPrices } from '@/loan/utils/utilsCurvejs' import { getUserMarketCollateralEvents } from '@curvefi/prices-api/crvusd' import { useWallet } from '@ui-kit/features/connect-wallet' +import { errorFallback } from '@ui-kit/utils/error.util' import { setMissingProvider } from '@ui-kit/utils/store.util' type StateKey = keyof typeof DEFAULT_STATE @@ -119,7 +120,7 @@ const createLoanDecrease = (set: StoreApi['setState'], get: StoreApi 0 @@ -155,12 +156,11 @@ const createLoanDecrease = (set: StoreApi['setState'], get: StoreApi['setState'], get: StoreApi['setState'], get: StoreApi['setState'], get: StoreApi { - void get()[sliceKey].fetchMaxRecv(chainId, llamma, DEFAULT_FORM_VALUES) + get()[sliceKey].fetchMaxRecv(chainId, llamma, DEFAULT_FORM_VALUES).catch(errorFallback) }, fetchEstGasApproval: async (activeKey: string, chainId: ChainId, llamma: Llamma, formValues: FormValues) => { const { collateral, debt } = formValues @@ -162,10 +163,10 @@ const createLoanIncrease = (set: StoreApi['setState'], get: StoreApi['setState'], get: StoreApi['setState'], get: StoreApi['setState'], get: StoreApi['setState'], get: StoreApi { @@ -139,7 +140,9 @@ const createLoanLiquidate = (set: StoreApi['setState'], get: StoreApi['setState'], get: StoreApi[' get()[sliceKey].setStateByActiveKey('detailsMapper', collateralId, fetchedLoanDetails) if (curve.signerAddress) { - void get()[sliceKey].fetchUserLoanWalletBalances(curve, llamma) - + get()[sliceKey].fetchUserLoanWalletBalances(curve, llamma).catch(errorFallback) if (loanExists) { - void get()[sliceKey].fetchUserLoanDetails(curve, llamma) + get()[sliceKey].fetchUserLoanDetails(curve, llamma).catch(errorFallback) } } diff --git a/apps/main/src/loan/store/createScrvUsdSlice.ts b/apps/main/src/loan/store/createScrvUsdSlice.ts index 2c95f8cf9d..4a7d66864b 100644 --- a/apps/main/src/loan/store/createScrvUsdSlice.ts +++ b/apps/main/src/loan/store/createScrvUsdSlice.ts @@ -13,6 +13,7 @@ import { getLib, notify, useWallet } from '@ui-kit/features/connect-wallet' import { queryClient } from '@ui-kit/lib/api/query-client' import { t } from '@ui-kit/lib/i18n' import type { TimeOption } from '@ui-kit/lib/types/scrvusd' +import { errorFallback } from '@ui-kit/utils/error.util' type StateKey = keyof typeof DEFAULT_STATE @@ -227,7 +228,7 @@ const createScrvUsdSlice = (set: StoreApi['setState'], get: StoreApi({ setConnectState(FAILURE) } } - void initLib() + initLib().catch(errorFallback) return () => abort.abort() }, [app, hydrate, isReconnecting, libKey, network, wallet, walletChainId]) diff --git a/packages/curve-ui-kit/src/hooks/useLocalStorage.ts b/packages/curve-ui-kit/src/hooks/useLocalStorage.ts index 62a79bc12e..e93479f4b1 100644 --- a/packages/curve-ui-kit/src/hooks/useLocalStorage.ts +++ b/packages/curve-ui-kit/src/hooks/useLocalStorage.ts @@ -43,6 +43,9 @@ const useLocalStorage = (key: string, initialValue: T, migration?: MigrationO /* -- Export specific hooks so that we can keep an overview of all the local storage keys used in the app -- */ export const useShowTestNets = () => useLocalStorage('showTestnets', false) +const getReleaseChannel = (): ReleaseChannel => + getFromLocalStorage('release-channel') ?? defaultReleaseChannel +export const shouldShowErrors = () => getReleaseChannel() === ReleaseChannel.Beta export const useReleaseChannel = () => useLocalStorage('release-channel', defaultReleaseChannel, { version: 1, diff --git a/packages/curve-ui-kit/src/shared/ui/ActionInfo.tsx b/packages/curve-ui-kit/src/shared/ui/ActionInfo.tsx index 8e9e48741b..e880f26af4 100644 --- a/packages/curve-ui-kit/src/shared/ui/ActionInfo.tsx +++ b/packages/curve-ui-kit/src/shared/ui/ActionInfo.tsx @@ -17,6 +17,7 @@ import { Duration } from '@ui-kit/themes/design/0_primitives' import { SizesAndSpaces } from '@ui-kit/themes/design/1_sizes_spaces' import type { TypographyVariantKey } from '@ui-kit/themes/typography' import { copyToClipboard } from '@ui-kit/utils' +import { errorFallback } from '@ui-kit/utils/error.util' import { Tooltip } from './Tooltip' import { WithSkeleton } from './WithSkeleton' @@ -109,7 +110,7 @@ const ActionInfo = ({ const [isSnackbarOpen, openSnackbar, closeSnackbar] = useSwitch(false) const copyAndShowSnackbar = useCallback(() => { - void copyToClipboard(copyValue!.trim()) + copyToClipboard(copyValue!.trim()).catch(errorFallback) openSnackbar() }, [copyValue, openSnackbar]) diff --git a/packages/curve-ui-kit/src/shared/ui/Metric.tsx b/packages/curve-ui-kit/src/shared/ui/Metric.tsx index 2c947f2a4a..59c3746807 100644 --- a/packages/curve-ui-kit/src/shared/ui/Metric.tsx +++ b/packages/curve-ui-kit/src/shared/ui/Metric.tsx @@ -17,6 +17,7 @@ import { type NumberFormatOptions, type SxProps, } from '@ui-kit/utils' +import { errorFallback } from '@ui-kit/utils/error.util' import { Duration } from '../../themes/design/0_primitives' import { WithSkeleton } from './WithSkeleton' @@ -203,7 +204,7 @@ export const Metric = ({ const [openCopyAlert, setOpenCopyAlert] = useState(false) const copyValue = useCallback(() => { - void copyToClipboard(value!.toString()) + copyToClipboard(value!.toString()).catch(errorFallback) setOpenCopyAlert(true) }, [value]) diff --git a/packages/curve-ui-kit/src/utils/error.util.ts b/packages/curve-ui-kit/src/utils/error.util.ts new file mode 100644 index 0000000000..c5d10ee4b1 --- /dev/null +++ b/packages/curve-ui-kit/src/utils/error.util.ts @@ -0,0 +1,18 @@ +import { notify } from '@ui-kit/features/connect-wallet' +import { shouldShowErrors } from '@ui-kit/hooks/useLocalStorage' + +const IGNORED_ERROR_MESSAGES = [ + 'network error', + 'Error in input stream', + 'NetworkError', + 'AbortError', + 'ChunkLoadError', +] + +export const errorFallback = (error: unknown) => { + if (!shouldShowErrors()) return + const { message = 'An unknown error occurred' } = error as Error + const { name } = error as DOMException + if (IGNORED_ERROR_MESSAGES.find((ignored) => message.startsWith(ignored) || name === ignored)) return + notify(message, 'error') +} diff --git a/packages/curve-ui-kit/src/widgets/ErrorBoundary.tsx b/packages/curve-ui-kit/src/widgets/ErrorBoundary.tsx index 383992cdda..eaa1303491 100644 --- a/packages/curve-ui-kit/src/widgets/ErrorBoundary.tsx +++ b/packages/curve-ui-kit/src/widgets/ErrorBoundary.tsx @@ -2,6 +2,7 @@ import { ReactNode } from 'react' import { CatchBoundary } from '@tanstack/react-router' import type { ErrorComponentProps } from '@tanstack/router-core' import { ErrorPage } from '@ui-kit/pages/ErrorPage' +import { errorFallback } from '@ui-kit/utils/error.util' export const ErrorBoundary = ({ children, title }: { children: ReactNode; title: string }) => ( ( )} + onCatch={errorFallback} > {children} diff --git a/packages/ui/src/Chart/CandleChart.tsx b/packages/ui/src/Chart/CandleChart.tsx index c2e8645899..d590b07472 100644 --- a/packages/ui/src/Chart/CandleChart.tsx +++ b/packages/ui/src/Chart/CandleChart.tsx @@ -153,7 +153,7 @@ const CandleChart = ({ const barsInfo = candlestickSeriesRef.current.barsInLogicalRange(logicalRange) if (barsInfo && barsInfo.barsBefore < 50) { - void debouncedFetchMoreChartData.current() + debouncedFetchMoreChartData.current() setLastTimescale(timeScale.getVisibleRange()) } }, [refetchingCapped]) From c5a935984cf7cac5e70456a7c7fead99d5451be7 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Fri, 31 Oct 2025 16:44:36 +0100 Subject: [PATCH 03/12] chore: replace void by errorCallback --- .../components/PageDashboard/components/FormVecrv.tsx | 5 +++-- .../PagePool/components/AlertSeedAmounts.tsx | 3 ++- apps/main/src/dex/hooks/usePoolTotalStaked.tsx | 2 +- apps/main/src/dex/store/createDashboardSlice.ts | 3 ++- .../DetailsMarket/components/MarketParameters.tsx | 3 ++- .../PageLoanManage/LoanBorrowMore/index.tsx | 2 +- .../components/PageLoanManage/LoanRepay/index.tsx | 2 +- .../PageLoanManage/LoanSelfLiquidation/index.tsx | 2 +- apps/main/src/lend/hooks/useAbiTotalSupply.tsx | 3 ++- apps/main/src/lend/hooks/useVaultShares.ts | 3 ++- apps/main/src/lend/store/createLoanBorrowMoreSlice.ts | 2 +- .../src/lend/store/createLoanCollateralAddSlice.ts | 2 +- apps/main/src/lend/store/createLoanCreateSlice.ts | 11 +++++++---- apps/main/src/lend/store/createLoanRepaySlice.ts | 2 +- .../src/lend/store/createLoanSelfLiquidationSlice.ts | 2 +- .../src/lend/store/createVaultDepositMintSlice.ts | 2 +- apps/main/src/lend/store/createVaultStakeSlice.ts | 2 +- 17 files changed, 30 insertions(+), 21 deletions(-) diff --git a/apps/main/src/dex/components/PageDashboard/components/FormVecrv.tsx b/apps/main/src/dex/components/PageDashboard/components/FormVecrv.tsx index 4fa1dca601..5a61a71af5 100644 --- a/apps/main/src/dex/components/PageDashboard/components/FormVecrv.tsx +++ b/apps/main/src/dex/components/PageDashboard/components/FormVecrv.tsx @@ -25,6 +25,7 @@ import { notify } from '@ui-kit/features/connect-wallet' import { t, Trans } from '@ui-kit/lib/i18n' import { DAO_ROUTES } from '@ui-kit/shared/routes' import { getInternalUrl } from '@ui-kit/shared/routes' +import { errorFallback } from '@ui-kit/utils/error.util' import { Chain } from '@ui-kit/utils/network' // TODO uncomment locker link code once it is ready @@ -95,7 +96,7 @@ const FormVecrv = () => { type: 'action', content: formStatus.formTypeCompleted ? t`Withdraw CRV Complete` : t`Withdraw CRV`, onClick: () => { - if (curve) void handleBtnClickWithdraw(activeKey, curve, lockedAmount) + if (curve) handleBtnClickWithdraw(activeKey, curve, lockedAmount).catch(errorFallback) }, }, } @@ -148,7 +149,7 @@ const FormVecrv = () => { disabled={!curve} variant="filled" onClick={() => { - if (curve) void handleBtnClickWithdraw(activeKey, curve, lockedAmount) + if (curve) handleBtnClickWithdraw(activeKey, curve, lockedAmount).catch(errorFallback) }} size="medium" > diff --git a/apps/main/src/dex/components/PagePool/components/AlertSeedAmounts.tsx b/apps/main/src/dex/components/PagePool/components/AlertSeedAmounts.tsx index 4800d999c4..ae528bd7bb 100644 --- a/apps/main/src/dex/components/PagePool/components/AlertSeedAmounts.tsx +++ b/apps/main/src/dex/components/PagePool/components/AlertSeedAmounts.tsx @@ -5,6 +5,7 @@ import { PoolData } from '@/dex/types/main.types' import AlertBox from '@ui/AlertBox' import { formatNumber } from '@ui/utils' import { t } from '@ui-kit/lib/i18n' +import { errorFallback } from '@ui-kit/utils/error.util' type Props = { seed: Seed @@ -32,7 +33,7 @@ const AlertSeedAmounts = ({ seed, poolData }: Props) => { }, []) useEffect(() => { - if (!!poolData && loaded && isSeed) void getSeedRatio(poolData) + if (!!poolData && loaded && isSeed) getSeedRatio(poolData).catch(errorFallback) // eslint-disable-next-line react-hooks/exhaustive-deps }, [poolData?.pool?.id, loaded, isSeed]) diff --git a/apps/main/src/dex/hooks/usePoolTotalStaked.tsx b/apps/main/src/dex/hooks/usePoolTotalStaked.tsx index 00eb423864..651060aa5e 100644 --- a/apps/main/src/dex/hooks/usePoolTotalStaked.tsx +++ b/apps/main/src/dex/hooks/usePoolTotalStaked.tsx @@ -73,7 +73,7 @@ const usePoolTotalStaked = (poolDataCacheOrApi: PoolDataCacheOrApi) => { ? await getContract('poolTotalSupply', address, provider) : await getContract('lpTokenTotalSupply', lpToken, provider) - if (poolContract) void getTotalSupply(poolContract, gaugeContract) + if (poolContract) getTotalSupply(poolContract, gaugeContract).catch(errorFallback) } else { updateTotalStakeValue({ totalStakedPercent: 'N/A', gaugeTotalSupply: 'N/A' }) } diff --git a/apps/main/src/dex/store/createDashboardSlice.ts b/apps/main/src/dex/store/createDashboardSlice.ts index 3b566ec6b0..487b4922b0 100644 --- a/apps/main/src/dex/store/createDashboardSlice.ts +++ b/apps/main/src/dex/store/createDashboardSlice.ts @@ -21,6 +21,7 @@ import type { IProfit } from '@curvefi/api/lib/interfaces' import { PromisePool } from '@supercharge/promise-pool' import { shortenAccount } from '@ui/utils' import { useWallet } from '@ui-kit/features/connect-wallet' +import { errorFallback } from '@ui-kit/utils/error.util' import { setMissingProvider } from '@ui-kit/utils/store.util' type StateKey = keyof typeof DEFAULT_STATE @@ -285,7 +286,7 @@ const createDashboardSlice = (_: StoreApi['setState'], get: StoreApi { - if (type === 'supply' && owm) void fetchVaultPricePerShare(rChainId, owm) + if (type === 'supply' && owm) fetchVaultPricePerShare(rChainId, owm).catch(errorFallback) // eslint-disable-next-line react-hooks/exhaustive-deps }, [type, owm]) diff --git a/apps/main/src/lend/components/PageLoanManage/LoanBorrowMore/index.tsx b/apps/main/src/lend/components/PageLoanManage/LoanBorrowMore/index.tsx index e81288026c..5e99ed603b 100644 --- a/apps/main/src/lend/components/PageLoanManage/LoanBorrowMore/index.tsx +++ b/apps/main/src/lend/components/PageLoanManage/LoanBorrowMore/index.tsx @@ -290,7 +290,7 @@ const LoanBorrowMore = ({ // form changed to leverage, reset form useEffect(() => { - if (isLoaded) void updateFormValues(DEFAULT_FORM_VALUES, '', true) + if (isLoaded) updateFormValues(DEFAULT_FORM_VALUES, '', true).catch(errorFallback) // eslint-disable-next-line react-hooks/exhaustive-deps }, [isLeverage]) diff --git a/apps/main/src/lend/components/PageLoanManage/LoanRepay/index.tsx b/apps/main/src/lend/components/PageLoanManage/LoanRepay/index.tsx index 9150652271..47c6659525 100644 --- a/apps/main/src/lend/components/PageLoanManage/LoanRepay/index.tsx +++ b/apps/main/src/lend/components/PageLoanManage/LoanRepay/index.tsx @@ -306,7 +306,7 @@ const LoanRepay = ({ }, [isLoaded]) useEffect(() => { - if (isLoaded) void updateFormValues({}, maxSlippage) + if (isLoaded) updateFormValues({}, maxSlippage).catch(errorFallback) // eslint-disable-next-line react-hooks/exhaustive-deps }, [maxSlippage]) diff --git a/apps/main/src/lend/components/PageLoanManage/LoanSelfLiquidation/index.tsx b/apps/main/src/lend/components/PageLoanManage/LoanSelfLiquidation/index.tsx index e76b6c8c35..fb43f5c6b1 100644 --- a/apps/main/src/lend/components/PageLoanManage/LoanSelfLiquidation/index.tsx +++ b/apps/main/src/lend/components/PageLoanManage/LoanSelfLiquidation/index.tsx @@ -185,7 +185,7 @@ const LoanSelfLiquidation = ({ // max slippage useEffect(() => { - if (isLoaded && api && market && maxSlippage) void fetchDetails(api, market, maxSlippage) + if (isLoaded && api && market && maxSlippage) fetchDetails(api, market, maxSlippage).catch(errorFallback) // eslint-disable-next-line react-hooks/exhaustive-deps }, [maxSlippage]) diff --git a/apps/main/src/lend/hooks/useAbiTotalSupply.tsx b/apps/main/src/lend/hooks/useAbiTotalSupply.tsx index 13650600c6..443fe09b32 100644 --- a/apps/main/src/lend/hooks/useAbiTotalSupply.tsx +++ b/apps/main/src/lend/hooks/useAbiTotalSupply.tsx @@ -6,6 +6,7 @@ import { ChainId } from '@/lend/types/lend.types' import usePageVisibleInterval from '@ui-kit/hooks/usePageVisibleInterval' import { REFRESH_INTERVAL } from '@ui-kit/lib/model' import { weiToEther } from '@ui-kit/utils' +import { errorFallback } from '@ui-kit/utils/error.util' const useAbiTotalSupply = (rChainId: ChainId, contractAddress: string | undefined) => { const contract = useContract(rChainId, false, 'totalSupply', contractAddress) @@ -23,7 +24,7 @@ const useAbiTotalSupply = (rChainId: ChainId, contractAddress: string | undefine }, []) useEffect(() => { - if (contract && isValidAddress) void getTotalSupply(contract) + if (contract && isValidAddress) getTotalSupply(contract).catch(errorFallback) }, [contract, isValidAddress, getTotalSupply]) usePageVisibleInterval(() => contract && isValidAddress && getTotalSupply(contract), REFRESH_INTERVAL['1m']) diff --git a/apps/main/src/lend/hooks/useVaultShares.ts b/apps/main/src/lend/hooks/useVaultShares.ts index 177ae84c46..370c5ea9a7 100644 --- a/apps/main/src/lend/hooks/useVaultShares.ts +++ b/apps/main/src/lend/hooks/useVaultShares.ts @@ -4,6 +4,7 @@ import useStore from '@/lend/store/useStore' import { ChainId } from '@/lend/types/lend.types' import { useTokenUsdRate } from '@ui-kit/lib/model/entities/token-usd-rate' import { formatNumber } from '@ui-kit/utils' +import { errorFallback } from '@ui-kit/utils/error.util' function formatNumberWithPrecision(value: number, precisionDigits: number) { const valueDigits = Math.max(0, Math.floor(Math.log10(value))) @@ -39,7 +40,7 @@ function useVaultShares(rChainId: ChainId, rOwmId: string, vaultShares: string | }, [pricePerShareResp, usdRate, symbol, vaultShares]) useEffect(() => { - if (market && +vaultShares > 0) void fetchVaultPricePerShare(rChainId, market) + if (market && +vaultShares > 0) fetchVaultPricePerShare(rChainId, market).catch(errorFallback) // eslint-disable-next-line react-hooks/exhaustive-deps }, [market?.id, vaultShares]) diff --git a/apps/main/src/lend/store/createLoanBorrowMoreSlice.ts b/apps/main/src/lend/store/createLoanBorrowMoreSlice.ts index 367302ed51..f6b9d339e7 100644 --- a/apps/main/src/lend/store/createLoanBorrowMoreSlice.ts +++ b/apps/main/src/lend/store/createLoanBorrowMoreSlice.ts @@ -272,7 +272,7 @@ const createLoanBorrowMore = ( isApprovedCompleted: !error, stepError: error, }) - if (!error) void sliceState.fetchEstGasApproval(activeKey, api, market, maxSlippage, isLeverage) + if (!error) sliceState.fetchEstGasApproval(activeKey, api, market, maxSlippage, isLeverage).catch(errorFallback) return { ...resp, error } } }, diff --git a/apps/main/src/lend/store/createLoanCollateralAddSlice.ts b/apps/main/src/lend/store/createLoanCollateralAddSlice.ts index 937573a0c4..ff5afaa141 100644 --- a/apps/main/src/lend/store/createLoanCollateralAddSlice.ts +++ b/apps/main/src/lend/store/createLoanCollateralAddSlice.ts @@ -154,7 +154,7 @@ const createLoanCollateralAdd = ( isApproved: !error, isInProgress: !error, }) - if (!error) void sliceState.fetchEstGasApproval(activeKey, api, market) + if (!error) sliceState.fetchEstGasApproval(activeKey, api, market).catch(errorFallback) return { ...resp, error } } }, diff --git a/apps/main/src/lend/store/createLoanCreateSlice.ts b/apps/main/src/lend/store/createLoanCreateSlice.ts index 457d265ebe..510163f746 100644 --- a/apps/main/src/lend/store/createLoanCreateSlice.ts +++ b/apps/main/src/lend/store/createLoanCreateSlice.ts @@ -253,9 +253,12 @@ const createLoanCreate = (set: StoreApi['setState'], get: StoreApi } // api calls - if (isLeverage) void sliceState.fetchMaxLeverage(market) - await sliceState.fetchMaxRecv(activeKeys.activeKeyMax, api, market, isLeverage) - await sliceState.fetchDetailInfo(activeKeys.activeKey, api, market, maxSlippage, isLeverage) + if (isLeverage) sliceState.fetchMaxLeverage(market).catch(errorFallback) + + await Promise.all([ + sliceState.fetchMaxRecv(activeKeys.activeKeyMax, api, market, isLeverage), + sliceState.fetchDetailInfo(activeKeys.activeKey, api, market, maxSlippage, isLeverage), + ]) Promise.all([ sliceState.fetchEstGasApproval(activeKeys.activeKey, api, market, maxSlippage, isLeverage), sliceState.fetchLiqRanges(activeKeys.activeKeyLiqRange, api, market, isLeverage), @@ -291,7 +294,7 @@ const createLoanCreate = (set: StoreApi['setState'], get: StoreApi isApprovedCompleted: !error, stepError: error, }) - if (!error) void sliceState.fetchEstGasApproval(activeKey, api, market, maxSlippage, isLeverage) + if (!error) sliceState.fetchEstGasApproval(activeKey, api, market, maxSlippage, isLeverage).catch(errorFallback) return { ...resp, error } } }, diff --git a/apps/main/src/lend/store/createLoanRepaySlice.ts b/apps/main/src/lend/store/createLoanRepaySlice.ts index 60cfb12a8b..2977cd7657 100644 --- a/apps/main/src/lend/store/createLoanRepaySlice.ts +++ b/apps/main/src/lend/store/createLoanRepaySlice.ts @@ -228,7 +228,7 @@ const createLoanRepaySlice = (set: StoreApi['setState'], get: StoreApi['setState'], get: StoreApi isInProgress: true, } get()[sliceKey].setStateByKey('formStatus', merge(cloneDeep(FORM_STATUS), partialFormStatus)) - if (!resp.error) void get()[sliceKey].fetchEstGasApproval(activeKey, formType, api, market) + if (!resp.error) get()[sliceKey].fetchEstGasApproval(activeKey, formType, api, market).catch(errorFallback) return resp } }, From ce960ce0231486c1b73fdcc39a7c43ac966d8578 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Fri, 31 Oct 2025 16:46:55 +0100 Subject: [PATCH 04/12] refactor: simplify ternaries --- .../PagePool/Deposit/components/FormStake.tsx | 6 +-- .../components/PageVault/VaultClaim/index.tsx | 4 +- .../PageLoanCreate/LoanFormCreate/index.tsx | 6 +-- .../CollateralDecrease/index.tsx | 6 +-- .../CollateralIncrease/index.tsx | 7 +-- .../PageLoanManage/LoanDecrease/index.tsx | 6 +-- .../PageLoanManage/LoanDeleverage/index.tsx | 44 ++++++++++--------- .../PageLoanManage/LoanIncrease/index.tsx | 6 +-- 8 files changed, 45 insertions(+), 40 deletions(-) diff --git a/apps/main/src/dex/components/PagePool/Deposit/components/FormStake.tsx b/apps/main/src/dex/components/PagePool/Deposit/components/FormStake.tsx index a873275995..66fd2b0971 100644 --- a/apps/main/src/dex/components/PagePool/Deposit/components/FormStake.tsx +++ b/apps/main/src/dex/components/PagePool/Deposit/components/FormStake.tsx @@ -210,9 +210,9 @@ const FormStake = ({ curve, poolData, poolDataCacheOrApi, routerParams, seed, us > {formStatus.error === 'lpToken-too-much' ? ( {t`Not enough LP Tokens balances.`} - ) : formStatus.error ? ( - updateFormValues({})} /> - ) : null} + ) : ( + formStatus.error && updateFormValues({})} /> + )} {txInfoBar} diff --git a/apps/main/src/lend/components/PageVault/VaultClaim/index.tsx b/apps/main/src/lend/components/PageVault/VaultClaim/index.tsx index ff42f50530..313f070c60 100644 --- a/apps/main/src/lend/components/PageVault/VaultClaim/index.tsx +++ b/apps/main/src/lend/components/PageVault/VaultClaim/index.tsx @@ -184,9 +184,9 @@ const VaultClaim = ({ isLoaded, api, market, userActiveKey }: PageContentProps) {/* actions */} - {formStatus.error ? ( + {formStatus.error && ( reset().catch(errorFallback)} /> - ) : null} + )} {txInfoBar} {api && market && ( diff --git a/apps/main/src/loan/components/PageLoanCreate/LoanFormCreate/index.tsx b/apps/main/src/loan/components/PageLoanCreate/LoanFormCreate/index.tsx index 21617c0133..40ee054726 100644 --- a/apps/main/src/loan/components/PageLoanCreate/LoanFormCreate/index.tsx +++ b/apps/main/src/loan/components/PageLoanCreate/LoanFormCreate/index.tsx @@ -456,9 +456,9 @@ const LoanCreate = ({ {t`Transaction complete`} ) : healthMode.message ? ( {healthMode.message} - ) : formStatus.error ? ( - reset(true, false)} /> - ) : null} + ) : ( + formStatus.error && reset(true, false)} /> + )} {txInfoBar} {steps && } diff --git a/apps/main/src/loan/components/PageLoanManage/CollateralDecrease/index.tsx b/apps/main/src/loan/components/PageLoanManage/CollateralDecrease/index.tsx index 722c110ff5..040cf5b9a0 100644 --- a/apps/main/src/loan/components/PageLoanManage/CollateralDecrease/index.tsx +++ b/apps/main/src/loan/components/PageLoanManage/CollateralDecrease/index.tsx @@ -326,9 +326,9 @@ const CollateralDecrease = ({ curve, llamma, llammaId, rChainId }: Props) => { {formStatus.error ? ( reset(true, false)} /> - ) : healthMode.message ? ( - {healthMode.message} - ) : null} + ) : ( + healthMode.message && {healthMode.message} + )} {txInfoBar} {steps && } diff --git a/apps/main/src/loan/components/PageLoanManage/CollateralIncrease/index.tsx b/apps/main/src/loan/components/PageLoanManage/CollateralIncrease/index.tsx index a07e0e6eff..ebe23e35db 100644 --- a/apps/main/src/loan/components/PageLoanManage/CollateralIncrease/index.tsx +++ b/apps/main/src/loan/components/PageLoanManage/CollateralIncrease/index.tsx @@ -346,9 +346,10 @@ const CollateralIncrease = ({ curve, isReady, llamma, llammaId }: Props) => { {formStatus.error ? ( reset(true, false)} /> - ) : detailInfo.healthNotFull !== healthMode.percent && healthMode.message ? ( - {healthMode.message} - ) : null} + ) : ( + detailInfo.healthNotFull !== healthMode.percent && + healthMode.message && {healthMode.message} + )} {txInfoBar} {steps && } diff --git a/apps/main/src/loan/components/PageLoanManage/LoanDecrease/index.tsx b/apps/main/src/loan/components/PageLoanManage/LoanDecrease/index.tsx index aee3d8cf32..e7ceabdfdf 100644 --- a/apps/main/src/loan/components/PageLoanManage/LoanDecrease/index.tsx +++ b/apps/main/src/loan/components/PageLoanManage/LoanDecrease/index.tsx @@ -369,9 +369,9 @@ const LoanDecrease = ({ curve, llamma, llammaId, params, rChainId }: Props) => { <> {formStatus.error ? ( reset(true, false)} /> - ) : formStatus.warning ? ( - - ) : null} + ) : ( + formStatus.warning && + )} )} {txInfoBar} diff --git a/apps/main/src/loan/components/PageLoanManage/LoanDeleverage/index.tsx b/apps/main/src/loan/components/PageLoanManage/LoanDeleverage/index.tsx index eca6090f69..faf15f6046 100644 --- a/apps/main/src/loan/components/PageLoanManage/LoanDeleverage/index.tsx +++ b/apps/main/src/loan/components/PageLoanManage/LoanDeleverage/index.tsx @@ -421,30 +421,34 @@ const LoanDeleverage = ({ updateFormValues({}, '', true)} /> ) : formStatus.warning ? ( - ) : !!llamma && + ) : ( + !!llamma && userState && !detailInfo.loading && !formValues.collateralError && +formValues.collateral > 0 && - +detailInfo.receiveStablecoin > 0 ? ( - - {formValues.isFullRepay ? ( - - ) : formStatus.warning !== 'warning-full-repayment-only' ? ( - - ) : null} - - ) : null} + +detailInfo.receiveStablecoin > 0 && ( + + {formValues.isFullRepay ? ( + + ) : ( + formStatus.warning !== 'warning-full-repayment-only' && ( + + ) + )} + + ) + )} )} {txInfoBar} diff --git a/apps/main/src/loan/components/PageLoanManage/LoanIncrease/index.tsx b/apps/main/src/loan/components/PageLoanManage/LoanIncrease/index.tsx index 633503f14d..0db4884bee 100644 --- a/apps/main/src/loan/components/PageLoanManage/LoanIncrease/index.tsx +++ b/apps/main/src/loan/components/PageLoanManage/LoanIncrease/index.tsx @@ -439,9 +439,9 @@ const LoanIncrease = ({ curve, isReady, llamma, llammaId }: Props) => { {formStatus.error ? ( reset(true, false)} /> - ) : healthMode.message ? ( - {healthMode.message} - ) : null} + ) : ( + healthMode.message && {healthMode.message} + )} {txInfoBar} {steps && } From b45598849d1a7eedc54c3a0f04adc2d218d1a9f3 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Fri, 31 Oct 2025 16:50:53 +0100 Subject: [PATCH 05/12] refactor: async instead of return --- .../src/lend/components/PageLoanManage/LoanRepay/index.tsx | 2 +- apps/main/src/lend/components/PageVault/VaultClaim/index.tsx | 4 ++-- .../src/lend/components/PageVault/VaultDepositMint/index.tsx | 4 ++-- apps/main/src/lend/components/PageVault/VaultStake/index.tsx | 4 ++-- .../main/src/lend/components/PageVault/VaultUnstake/index.tsx | 4 ++-- .../lend/components/PageVault/VaultWithdrawRedeem/index.tsx | 4 ++-- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/apps/main/src/lend/components/PageLoanManage/LoanRepay/index.tsx b/apps/main/src/lend/components/PageLoanManage/LoanRepay/index.tsx index 47c6659525..b3ab014c00 100644 --- a/apps/main/src/lend/components/PageLoanManage/LoanRepay/index.tsx +++ b/apps/main/src/lend/components/PageLoanManage/LoanRepay/index.tsx @@ -132,7 +132,7 @@ const LoanRepay = ({ txHash={scanTxPath(networks[rChainId], resp.hash)} onClose={() => { if (resp.loanExists) { - return updateFormValues(DEFAULT_FORM_VALUES, '', true) + updateFormValues(DEFAULT_FORM_VALUES, '', true).catch(errorFallback) } push(getCollateralListPathname(params)) }} diff --git a/apps/main/src/lend/components/PageVault/VaultClaim/index.tsx b/apps/main/src/lend/components/PageVault/VaultClaim/index.tsx index 313f070c60..64c1187793 100644 --- a/apps/main/src/lend/components/PageVault/VaultClaim/index.tsx +++ b/apps/main/src/lend/components/PageVault/VaultClaim/index.tsx @@ -44,9 +44,9 @@ const VaultClaim = ({ isLoaded, api, market, userActiveKey }: PageContentProps) [api, isLoaded, market, setFormValues, userActiveKey], ) - const reset = useCallback(() => { + const reset = useCallback(async () => { setTxInfoBar(null) - return updateFormValues() + await updateFormValues() }, [updateFormValues]) const handleBtnClickClaim = useCallback( diff --git a/apps/main/src/lend/components/PageVault/VaultDepositMint/index.tsx b/apps/main/src/lend/components/PageVault/VaultDepositMint/index.tsx index 8e13432133..b22dbb955d 100644 --- a/apps/main/src/lend/components/PageVault/VaultDepositMint/index.tsx +++ b/apps/main/src/lend/components/PageVault/VaultDepositMint/index.tsx @@ -60,9 +60,9 @@ const VaultDepositMint = ({ rChainId, rOwmId, rFormType, isLoaded, api, market, ) const reset = useCallback( - (updatedFormValues: Partial) => { + async (updatedFormValues: Partial) => { setTxInfoBar(null) - return updateFormValues(updatedFormValues) + await updateFormValues(updatedFormValues) }, [updateFormValues], ) diff --git a/apps/main/src/lend/components/PageVault/VaultStake/index.tsx b/apps/main/src/lend/components/PageVault/VaultStake/index.tsx index 9e5be85c3d..e3f6567d23 100644 --- a/apps/main/src/lend/components/PageVault/VaultStake/index.tsx +++ b/apps/main/src/lend/components/PageVault/VaultStake/index.tsx @@ -51,9 +51,9 @@ const VaultStake = ({ rChainId, rOwmId, rFormType, isLoaded, api, market, userAc ) const reset = useCallback( - (updatedFormValues: Partial) => { + async (updatedFormValues: Partial) => { setTxInfoBar(null) - return updateFormValues(updatedFormValues) + await updateFormValues(updatedFormValues) }, [updateFormValues], ) diff --git a/apps/main/src/lend/components/PageVault/VaultUnstake/index.tsx b/apps/main/src/lend/components/PageVault/VaultUnstake/index.tsx index c7e21bbc8a..9e889f16f2 100644 --- a/apps/main/src/lend/components/PageVault/VaultUnstake/index.tsx +++ b/apps/main/src/lend/components/PageVault/VaultUnstake/index.tsx @@ -49,9 +49,9 @@ const VaultUnstake = ({ rChainId, rOwmId, rFormType, isLoaded, api, market, user ) const reset = useCallback( - (updatedFormValues: Partial) => { + async (updatedFormValues: Partial) => { setTxInfoBar(null) - return updateFormValues(updatedFormValues) + await updateFormValues(updatedFormValues) }, [updateFormValues], ) diff --git a/apps/main/src/lend/components/PageVault/VaultWithdrawRedeem/index.tsx b/apps/main/src/lend/components/PageVault/VaultWithdrawRedeem/index.tsx index e76da77fc1..feef1d1910 100644 --- a/apps/main/src/lend/components/PageVault/VaultWithdrawRedeem/index.tsx +++ b/apps/main/src/lend/components/PageVault/VaultWithdrawRedeem/index.tsx @@ -69,9 +69,9 @@ const VaultWithdrawRedeem = ({ ) const reset = useCallback( - (updatedFormValues: Partial) => { + async (updatedFormValues: Partial) => { setTxInfoBar(null) - return updateFormValues(updatedFormValues) + await updateFormValues(updatedFormValues) }, [updateFormValues], ) From 98fc09ce24b34f9fa0e75a54e6f625043d3d47de Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Fri, 31 Oct 2025 17:01:28 +0100 Subject: [PATCH 06/12] fix: `fetchInitial` type --- apps/main/src/loan/components/PageLoanCreate/index.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/main/src/loan/components/PageLoanCreate/index.tsx b/apps/main/src/loan/components/PageLoanCreate/index.tsx index 37f0dbda16..4bd8aa0512 100644 --- a/apps/main/src/loan/components/PageLoanCreate/index.tsx +++ b/apps/main/src/loan/components/PageLoanCreate/index.tsx @@ -16,6 +16,7 @@ import { useReleaseChannel } from '@ui-kit/hooks/useLocalStorage' import { t } from '@ui-kit/lib/i18n' import { type TabOption, TabsSwitcher } from '@ui-kit/shared/ui/TabsSwitcher' import { ReleaseChannel } from '@ui-kit/utils' +import { errorFallback } from '@ui-kit/utils/error.util' /** * Callback that synchronizes the `ChartOhlc` component with the `RangeSlider` component in the new `BorrowTabContents`. @@ -42,7 +43,7 @@ const LoanCreate = ({ ...props }: PageLoanCreateProps & { loanExists: boolean | undefined - fetchInitial: (curve: LlamaApi, isLeverage: boolean, llamma: Llamma) => void + fetchInitial: (curve: LlamaApi, isLeverage: boolean, llamma: Llamma) => Promise }) => { const { curve, llamma, loanExists, params, rCollateralId, rFormType, rChainId } = props const push = useNavigate() @@ -69,7 +70,7 @@ const LoanCreate = ({ push(getLoanManagePathname(params, rCollateralId, 'loan')) } else { if (curve && llamma) { - fetchInitial(curve, formType === 'leverage', llamma) + fetchInitial(curve, formType === 'leverage', llamma).catch(errorFallback) } push(getLoanCreatePathname(params, rCollateralId, formType)) } From fe83777d7fe53d69730eb1fbf4dd12e13e6107b2 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Mon, 3 Nov 2025 09:58:52 +0100 Subject: [PATCH 07/12] fix: typecheck --- apps/main/src/loan/components/PageLoanCreate/Page.tsx | 4 ++-- packages/curve-ui-kit/src/types/window.d.ts | 2 -- packages/ui/tsconfig.json | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/apps/main/src/loan/components/PageLoanCreate/Page.tsx b/apps/main/src/loan/components/PageLoanCreate/Page.tsx index abbdea8a02..3ed6d0bba7 100644 --- a/apps/main/src/loan/components/PageLoanCreate/Page.tsx +++ b/apps/main/src/loan/components/PageLoanCreate/Page.tsx @@ -96,7 +96,7 @@ const Page = () => { }) const fetchInitial = useCallback( - (curve: LlamaApi, isLeverage: boolean, llamma: Llamma) => { + async (curve: LlamaApi, isLeverage: boolean, llamma: Llamma) => { // reset createLoan estGas, detailInfo state setStateByKeys({ formEstGas: {}, @@ -108,7 +108,7 @@ const Page = () => { maxRecvLeverage: {}, }) const updatedFormValues = { ...formValues, n: formValues.n || llamma.defaultBands } - return Promise.all([ + await Promise.all([ setFormValues(curve, isLeverage, llamma, updatedFormValues, maxSlippage).catch(errorFallback), curve.signerAddress && fetchUserLoanWalletBalances(curve, llamma).catch(errorFallback), ]) diff --git a/packages/curve-ui-kit/src/types/window.d.ts b/packages/curve-ui-kit/src/types/window.d.ts index bff3accecb..1cef4536be 100644 --- a/packages/curve-ui-kit/src/types/window.d.ts +++ b/packages/curve-ui-kit/src/types/window.d.ts @@ -15,8 +15,6 @@ declare global { interface Window { clipboardData: any ethereum: EIP1193Provider & { eip6963ProviderDetails: Eip6963Provider[] } - exodus?: EIP1193Provider - enkrypt?: { providers: { ethereum: EIP1193Provider } } binancew3w?: { ethereum?: EIP1193Provider } } } diff --git a/packages/ui/tsconfig.json b/packages/ui/tsconfig.json index 5bbb8f055d..92c1beb57b 100644 --- a/packages/ui/tsconfig.json +++ b/packages/ui/tsconfig.json @@ -11,5 +11,5 @@ "@ui-kit/*": ["../../curve-ui-kit/src/*"] } }, - "include": ["src"] + "include": ["src", "../curve-ui-kit/src/types/*.d.ts"] } From ca91a1d6e5ab615d6e343652891decb693b20ec6 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Mon, 3 Nov 2025 14:06:51 +0100 Subject: [PATCH 08/12] chore: save artifacts --- .github/workflows/ci.yaml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 5453b81191..4d19a97136 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -59,6 +59,12 @@ jobs: ELECTRON_ENABLE_LOGGING: true # send console logs to stdout in electron browser NODE_ENV: test + - uses: actions/upload-artifact@v4 + if: failure() + with: + name: cypress-rpc + path: tests/cypress/screenshots + cypress-component-rpc: name: Cypress component tests with RPC if: github.ref_name == 'main' From 8637db81b6f82936392c4c8b5bd03cdbbdda6522 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Mon, 3 Nov 2025 14:52:51 +0100 Subject: [PATCH 09/12] fix: lint and component tests --- .github/workflows/ci.yaml | 8 +++- .../PageVeCrv/components/FormLockCreate.tsx | 25 ++++++++++--- .../PageVeCrv/components/FormLockCrv.tsx | 13 +++++-- .../PageDashboard/components/TableHead.tsx | 3 +- .../components/TableSortDialog.tsx | 3 +- .../dex/components/PageDashboard/index.tsx | 5 ++- .../Deposit/components/FieldsDeposit.tsx | 6 ++- .../Deposit/components/FormDeposit.tsx | 5 ++- .../Deposit/components/FormDepositStake.tsx | 5 ++- .../dex/components/PagePool/Swap/index.tsx | 26 +++++++------ .../components/RouterSwapAlerts.tsx | 3 +- .../dex/components/PageRouterSwap/index.tsx | 26 ++++++++----- .../LoanFormCreate/components/DetailInfo.tsx | 5 ++- .../PageLoanCreate/LoanFormCreate/index.tsx | 24 +++++++----- .../PageLoanManage/LoanBorrowMore/index.tsx | 28 +++++++++----- .../PageLoanManage/LoanRepay/index.tsx | 37 ++++++++++--------- .../components/PageVault/VaultClaim/index.tsx | 2 +- .../PageVault/VaultUnstake/index.tsx | 8 ++-- .../PageVault/VaultWithdrawRedeem/index.tsx | 4 +- .../LoanFormCreate/components/DetailInfo.tsx | 5 ++- .../PageLoanCreate/LoanFormCreate/index.tsx | 2 +- .../CollateralIncrease/index.tsx | 5 ++- .../PageLoanManage/LoanDecrease/index.tsx | 7 ++-- .../src/hooks/usePageVisibleInterval.ts | 2 +- .../component/large-token-input.cy.tsx | 32 ++++++---------- .../support/helpers/ComponentTestWrapper.tsx | 6 +-- 26 files changed, 177 insertions(+), 118 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 4d19a97136..abb2dd85e3 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -62,8 +62,10 @@ jobs: - uses: actions/upload-artifact@v4 if: failure() with: - name: cypress-rpc + name: cypress-component-${{ matrix.browser }}-${{ matrix.count }} path: tests/cypress/screenshots + retention-days: 1 + if-no-files-found: error cypress-component-rpc: name: Cypress component tests with RPC @@ -94,6 +96,8 @@ jobs: with: name: cypress-rpc path: tests/cypress/screenshots + retention-days: 1 + if-no-files-found: error cypress-e2e: strategy: @@ -140,7 +144,7 @@ jobs: - uses: actions/upload-artifact@v4 if: failure() with: - name: cypress-main-${{ matrix.browser }}-${{ matrix.count }} + name: cypress-e2e-${{ matrix.browser }}-${{ matrix.count }} path: tests/cypress/screenshots retention-days: 1 if-no-files-found: error diff --git a/apps/main/src/dao/components/PageVeCrv/components/FormLockCreate.tsx b/apps/main/src/dao/components/PageVeCrv/components/FormLockCreate.tsx index 6afaa76c49..6a12618353 100644 --- a/apps/main/src/dao/components/PageVeCrv/components/FormLockCreate.tsx +++ b/apps/main/src/dao/components/PageVeCrv/components/FormLockCreate.tsx @@ -22,6 +22,7 @@ import usePageVisibleInterval from '@ui-kit/hooks/usePageVisibleInterval' import dayjs from '@ui-kit/lib/dayjs' import { t } from '@ui-kit/lib/i18n' import { REFRESH_INTERVAL } from '@ui-kit/lib/model' +import { errorFallback } from '@ui-kit/utils/error.util' import { useThrottle } from '@ui-kit/utils/timers' const FormLockCreate = ({ curve, rChainId, rFormType, vecrvInfo }: PageVecrv) => { @@ -76,7 +77,7 @@ const FormLockCreate = ({ curve, rChainId, rFormType, vecrvInfo }: PageVecrv) => days, }, false, - ) + ).catch(errorFallback) }, [currUtcDate, haveSigner, maxUtcDate, minUtcDate, rChainId, updateFormValues], ) @@ -88,7 +89,10 @@ const FormLockCreate = ({ curve, rChainId, rFormType, vecrvInfo }: PageVecrv) => if (!value || !unit) { const days = maxUtcDate.diff(currUtcDate, 'd') const calcdUtcDate = calcUnlockTime(curve, 'create', null, days) - updateFormValues({ utcDate: toCalendarDate(calcdUtcDate), utcDateError: '', days, calcdUtcDate: '' }, false) + updateFormValues( + { utcDate: toCalendarDate(calcdUtcDate), utcDateError: '', days, calcdUtcDate: '' }, + false, + ).catch(errorFallback) return maxUtcDate } @@ -96,7 +100,10 @@ const FormLockCreate = ({ curve, rChainId, rFormType, vecrvInfo }: PageVecrv) => const days = utcDate.diff(currUtcDate, 'd') const calcdUtcDate = calcUnlockTime(curve, 'create', null, days) - updateFormValues({ utcDate: toCalendarDate(calcdUtcDate), utcDateError: '', days, calcdUtcDate: '' }, false) + updateFormValues( + { utcDate: toCalendarDate(calcdUtcDate), utcDateError: '', days, calcdUtcDate: '' }, + false, + ).catch(errorFallback) return utcDate }, [currUtcDate, maxUtcDate, rChainId, updateFormValues], @@ -186,7 +193,7 @@ const FormLockCreate = ({ curve, rChainId, rFormType, vecrvInfo }: PageVecrv) => // onMount useEffect(() => { isSubscribed.current = true - updateFormValues({}, true) + updateFormValues({}, true).catch(errorFallback) return () => { isSubscribed.current = false @@ -224,7 +231,10 @@ const FormLockCreate = ({ curve, rChainId, rFormType, vecrvInfo }: PageVecrv) => haveSigner={haveSigner} formType={rFormType} vecrvInfo={vecrvInfo} - handleInpLockedAmt={useCallback((lockedAmt) => updateFormValues({ lockedAmt }, false), [updateFormValues])} + handleInpLockedAmt={useCallback( + (lockedAmt) => updateFormValues({ lockedAmt }, false).catch(errorFallback), + [updateFormValues], + )} {...formValues} /> @@ -255,7 +265,10 @@ const FormLockCreate = ({ curve, rChainId, rFormType, vecrvInfo }: PageVecrv) => {formStatus.error && ( - updateFormValues({}, false)} /> + updateFormValues({}, false).catch(errorFallback)} + /> )} {txInfoBar} diff --git a/apps/main/src/dao/components/PageVeCrv/components/FormLockCrv.tsx b/apps/main/src/dao/components/PageVeCrv/components/FormLockCrv.tsx index 1f7d91db75..5cde0cc38d 100644 --- a/apps/main/src/dao/components/PageVeCrv/components/FormLockCrv.tsx +++ b/apps/main/src/dao/components/PageVeCrv/components/FormLockCrv.tsx @@ -17,6 +17,7 @@ import { type CurveApi, isLoading, notify, useConnection } from '@ui-kit/feature import usePageVisibleInterval from '@ui-kit/hooks/usePageVisibleInterval' import { t } from '@ui-kit/lib/i18n' import { REFRESH_INTERVAL } from '@ui-kit/lib/model' +import { errorFallback } from '@ui-kit/utils/error.util' import { useThrottle } from '@ui-kit/utils/timers' const FormLockCrv = ({ curve, rChainId, rFormType, vecrvInfo }: PageVecrv) => { @@ -120,7 +121,7 @@ const FormLockCrv = ({ curve, rChainId, rFormType, vecrvInfo }: PageVecrv) => { // onMount useEffect(() => { isSubscribed.current = true - updateFormValues({}, true) + updateFormValues({}, true).catch(errorFallback) return () => { isSubscribed.current = false @@ -156,7 +157,10 @@ const FormLockCrv = ({ curve, rChainId, rFormType, vecrvInfo }: PageVecrv) => { haveSigner={haveSigner} formType={rFormType} vecrvInfo={vecrvInfo} - handleInpLockedAmt={useCallback((lockedAmt) => updateFormValues({ lockedAmt }), [updateFormValues])} + handleInpLockedAmt={useCallback( + (lockedAmt) => updateFormValues({ lockedAmt }).catch(errorFallback), + [updateFormValues], + )} {...formValues} /> @@ -173,7 +177,10 @@ const FormLockCrv = ({ curve, rChainId, rFormType, vecrvInfo }: PageVecrv) => { {formStatus.error && ( - updateFormValues({}, false)} /> + updateFormValues({}, false).catch(errorFallback)} + /> )} {txInfoBar} diff --git a/apps/main/src/dex/components/PageDashboard/components/TableHead.tsx b/apps/main/src/dex/components/PageDashboard/components/TableHead.tsx index 8e4f6681b0..7105f4b85b 100644 --- a/apps/main/src/dex/components/PageDashboard/components/TableHead.tsx +++ b/apps/main/src/dex/components/PageDashboard/components/TableHead.tsx @@ -8,12 +8,13 @@ import type { TheadSortButtonProps } from '@ui/Table/TheadSortButton' import IconTooltip from '@ui/Tooltip/TooltipIcon' import { breakpoints } from '@ui/utils' import { t } from '@ui-kit/lib/i18n' +import { errorFallback } from '@ui-kit/utils/error.util' const TableHead = ({ tableLabel }: { tableLabel: TableLabel }) => { const { isLite, isLoading, formValues, updateFormValues } = useDashboardContext() const handleBtnClickSort = (sortBy: string, sortByOrder: Order) => { - updateFormValues({ sortBy: sortBy as SORT_ID, sortByOrder: sortByOrder as Order }) + updateFormValues({ sortBy: sortBy as SORT_ID, sortByOrder: sortByOrder as Order }).catch(errorFallback) } const props: Omit, 'sortIdKey'> = { diff --git a/apps/main/src/dex/components/PageDashboard/components/TableSortDialog.tsx b/apps/main/src/dex/components/PageDashboard/components/TableSortDialog.tsx index 951eb1f86c..aec73fcb02 100644 --- a/apps/main/src/dex/components/PageDashboard/components/TableSortDialog.tsx +++ b/apps/main/src/dex/components/PageDashboard/components/TableSortDialog.tsx @@ -8,6 +8,7 @@ import OpenDialogButton from '@ui/Dialog/OpenDialogButton' import Icon from '@ui/Icon' import { Radio, RadioGroup } from '@ui/Radio' import { Chip } from '@ui/Typography' +import { errorFallback } from '@ui-kit/utils/error.util' const sortOrder = { asc: { label: 'Ascending', icon: }, @@ -29,7 +30,7 @@ const TableSortDialog = ({ className = '', tableLabel }: Props) => { const handleRadioGroupChange = (val: string) => { const [sortBy, sortByOrder] = val.split('-') - updateFormValues({ sortBy: sortBy as SortId, sortByOrder: sortByOrder as Order }) + updateFormValues({ sortBy: sortBy as SortId, sortByOrder: sortByOrder as Order }).catch(errorFallback) overlayTriggerState.close() } diff --git a/apps/main/src/dex/components/PageDashboard/index.tsx b/apps/main/src/dex/components/PageDashboard/index.tsx index 449236f431..888935db0b 100644 --- a/apps/main/src/dex/components/PageDashboard/index.tsx +++ b/apps/main/src/dex/components/PageDashboard/index.tsx @@ -25,6 +25,7 @@ import { breakpoints } from '@ui/utils' import { useLayoutStore } from '@ui-kit/features/layout' import { useNavigate } from '@ui-kit/hooks/router' import { t } from '@ui-kit/lib/i18n' +import { errorFallback } from '@ui-kit/utils/error.util' const Dashboard = ({ curve, @@ -90,14 +91,14 @@ const Dashboard = ({ // curvejs change useEffect(() => { - updateFormValues({}) + updateFormValues({}).catch(errorFallback) // eslint-disable-next-line react-hooks/exhaustive-deps }, [chainId, !pageLoaded, haveAllPools, poolsMapper]) // signerAddress useEffect(() => { if (signerAddress) { - updateFormValues({ walletAddress: signerAddress }) + updateFormValues({ walletAddress: signerAddress }).catch(errorFallback) } // eslint-disable-next-line react-hooks/exhaustive-deps }, [signerAddress]) diff --git a/apps/main/src/dex/components/PagePool/Deposit/components/FieldsDeposit.tsx b/apps/main/src/dex/components/PagePool/Deposit/components/FieldsDeposit.tsx index 7251fe665c..04ea4908cb 100644 --- a/apps/main/src/dex/components/PagePool/Deposit/components/FieldsDeposit.tsx +++ b/apps/main/src/dex/components/PagePool/Deposit/components/FieldsDeposit.tsx @@ -167,7 +167,9 @@ const FieldsDeposit = ({ isDisabled={isDisabled} isSelected={!!formValues.isBalancedAmounts} onChange={(isBalancedAmounts) => - updateFormValues({ isBalancedAmounts: isBalancedAmounts ? 'by-wallet' : false }, null, null) + updateFormValues({ isBalancedAmounts: isBalancedAmounts ? 'by-wallet' : false }, null, null).catch( + errorFallback, + ) } > {t`Add all coins in a balanced proportion`} @@ -191,7 +193,7 @@ const FieldsDeposit = ({ tokenAddress: wrapped.tokenAddresses[idx], value: '', })) - updateFormValues(cFormValues, null, null) + updateFormValues(cFormValues, null, null).catch(errorFallback) } }} > diff --git a/apps/main/src/dex/components/PagePool/Deposit/components/FormDeposit.tsx b/apps/main/src/dex/components/PagePool/Deposit/components/FormDeposit.tsx index 78752e1926..4bddf2d7eb 100644 --- a/apps/main/src/dex/components/PagePool/Deposit/components/FormDeposit.tsx +++ b/apps/main/src/dex/components/PagePool/Deposit/components/FormDeposit.tsx @@ -313,7 +313,10 @@ const FormDeposit = ({ > {formStatus.error && ( - updateFormValues({}, null, null)} /> + updateFormValues({}, null, null).catch(errorFallback)} + /> )} {txInfoBar} diff --git a/apps/main/src/dex/components/PagePool/Deposit/components/FormDepositStake.tsx b/apps/main/src/dex/components/PagePool/Deposit/components/FormDepositStake.tsx index a15188b00a..20f578145c 100644 --- a/apps/main/src/dex/components/PagePool/Deposit/components/FormDepositStake.tsx +++ b/apps/main/src/dex/components/PagePool/Deposit/components/FormDepositStake.tsx @@ -313,7 +313,10 @@ const FormDepositStake = ({ > {formStatus.error && ( - updateFormValues({}, null, null)} /> + updateFormValues({}, null, null).catch(errorFallback)} + /> )} {txInfoBar} diff --git a/apps/main/src/dex/components/PagePool/Swap/index.tsx b/apps/main/src/dex/components/PagePool/Swap/index.tsx index fa8fc57728..ead74f029e 100644 --- a/apps/main/src/dex/components/PagePool/Swap/index.tsx +++ b/apps/main/src/dex/components/PagePool/Swap/index.tsx @@ -158,7 +158,7 @@ const Swap = ({ description={`Swapped ${fromAmount} ${fromToken}.`} txHash={scanTxPath(network, resp.hash)} onClose={() => { - updateFormValues({}, null, null) + updateFormValues({}, null, null).catch(errorFallback) }} />, ) @@ -332,9 +332,9 @@ const Swap = ({ ]) // pageVisible - useEffect(() => { fetchData().catch(errorFallback) + // eslint-disable-next-line react-hooks/exhaustive-deps }, [isPageVisible]) // re-fetch data @@ -344,11 +344,13 @@ const Swap = ({ const isDisabled = seed.isSeed === null || seed.isSeed || formStatus.formProcessing const setFromAmount = useCallback( - (value?: Decimal) => updateFormValues({ isFrom: true, fromAmount: value ?? '', toAmount: '' }, null, null), + (value?: Decimal) => + updateFormValues({ isFrom: true, fromAmount: value ?? '', toAmount: '' }, null, null).catch(errorFallback), [updateFormValues], ) const setToAmount = useCallback( - (value?: Decimal) => updateFormValues({ isFrom: false, toAmount: value ?? '', fromAmount: '' }, null, null), + (value?: Decimal) => + updateFormValues({ isFrom: false, toAmount: value ?? '', fromAmount: '' }, null, null).catch(errorFallback), [updateFormValues], ) @@ -378,7 +380,7 @@ const Swap = ({ } value={formValues.fromAmount} onChange={(fromAmount) => { - updateFormValues({ isFrom: true, fromAmount, toAmount: '' }, null, null) + updateFormValues({ isFrom: true, fromAmount, toAmount: '' }, null, null).catch(errorFallback) }} /> { - updateFormValues({ isFrom: true, fromAmount: '', toAmount: '' }, true, null) + updateFormValues({ isFrom: true, fromAmount: '', toAmount: '' }, true, null).catch(errorFallback) }} /> { @@ -414,7 +416,7 @@ const Swap = ({ cFormValues.fromAmount = '' } - updateFormValues(cFormValues, null, '') + updateFormValues(cFormValues, null, '').catch(errorFallback) }} /> } @@ -493,7 +495,7 @@ const Swap = ({ cFormValues.toAddress = formValues.fromAddress cFormValues.toAmount = '' - updateFormValues(cFormValues, null, '') + updateFormValues(cFormValues, null, '').catch(errorFallback) }} size="medium" > @@ -523,7 +525,7 @@ const Swap = ({ } value={formValues.toAmount} onChange={(toAmount) => { - updateFormValues({ isFrom: false, toAmount, fromAmount: '' }, null, '') + updateFormValues({ isFrom: false, toAmount, fromAmount: '' }, null, '').catch(errorFallback) }} /> @@ -625,7 +627,7 @@ const Swap = ({ cFormValues.fromAmount = '' } - updateFormValues(cFormValues, null, '') + updateFormValues(cFormValues, null, '').catch(errorFallback) } }} > @@ -671,7 +673,7 @@ const Swap = ({ { - updateFormValues({}, null, null) + updateFormValues({}, null, null).catch(errorFallback) }} /> diff --git a/apps/main/src/dex/components/PageRouterSwap/components/RouterSwapAlerts.tsx b/apps/main/src/dex/components/PageRouterSwap/components/RouterSwapAlerts.tsx index 5775cde661..c7421c5b07 100644 --- a/apps/main/src/dex/components/PageRouterSwap/components/RouterSwapAlerts.tsx +++ b/apps/main/src/dex/components/PageRouterSwap/components/RouterSwapAlerts.tsx @@ -7,6 +7,7 @@ import type { FormStatus, FormValues, SearchedParams } from '@/dex/components/Pa import AlertBox from '@ui/AlertBox' import { t } from '@ui-kit/lib/i18n' import { useTokenUsdRate } from '@ui-kit/lib/model/entities/token-usd-rate' +import { errorFallback } from '@ui-kit/utils/error.util' const { isUndefined, isNaN } = lodash @@ -58,7 +59,7 @@ const RouterSwapAlerts = ({ - updateFormValues({})} /> + updateFormValues({}).catch(errorFallback)} /> ) } diff --git a/apps/main/src/dex/components/PageRouterSwap/index.tsx b/apps/main/src/dex/components/PageRouterSwap/index.tsx index c7d9800231..bb1dfa7eb9 100644 --- a/apps/main/src/dex/components/PageRouterSwap/index.tsx +++ b/apps/main/src/dex/components/PageRouterSwap/index.tsx @@ -184,7 +184,7 @@ const QuickSwap = ({ updateFormValues({}, false, '', true)} + onClose={() => updateFormValues({}, false, '', true).catch(errorFallback)} />, ) } @@ -315,20 +315,20 @@ const QuickSwap = ({ return () => { isSubscribed.current = false - updateFormValues({}, false, '', true) + updateFormValues({}, false, '', true).catch(errorFallback) } // eslint-disable-next-line react-hooks/exhaustive-deps }, []) // maxSlippage useEffect(() => { - if (isReady) updateFormValues({}, false, cryptoMaxSlippage) + if (isReady) updateFormValues({}, false, cryptoMaxSlippage).catch(errorFallback) // eslint-disable-next-line react-hooks/exhaustive-deps }, [cryptoMaxSlippage]) // pageVisible re-fetch data useEffect(() => { - if (isReady) fetchData() + if (isReady) fetchData().catch(errorFallback) // eslint-disable-next-line react-hooks/exhaustive-deps }, [isPageVisible]) @@ -339,9 +339,9 @@ const QuickSwap = ({ }, [curve?.chainId]) // updateForm - useEffect(() => { fetchData().catch(errorFallback) + // eslint-disable-next-line react-hooks/exhaustive-deps }, [tokensMapperStr, searchedParams.fromAddress, searchedParams.toAddress]) useEffect(() => { @@ -377,11 +377,13 @@ const QuickSwap = ({ const [releaseChannel] = useReleaseChannel() const setFromAmount = useCallback( - (fromAmount?: Decimal) => updateFormValues({ isFrom: true, fromAmount: fromAmount ?? '', toAmount: '' }), + (fromAmount?: Decimal) => + updateFormValues({ isFrom: true, fromAmount: fromAmount ?? '', toAmount: '' }).catch(errorFallback), [updateFormValues], ) const setToAmount = useCallback( - (toAmount?: Decimal) => updateFormValues({ isFrom: false, toAmount: toAmount ?? '', fromAmount: '' }), + (toAmount?: Decimal) => + updateFormValues({ isFrom: false, toAmount: toAmount ?? '', fromAmount: '' }).catch(errorFallback), [updateFormValues], ) @@ -411,14 +413,16 @@ const QuickSwap = ({ } testId="from-amount" value={isMaxLoading ? '' : formValues.fromAmount} - onChange={(fromAmount) => updateFormValues({ isFrom: true, fromAmount, toAmount: '' })} + onChange={(fromAmount) => + updateFormValues({ isFrom: true, fromAmount, toAmount: '' }).catch(errorFallback) + } /> updateFormValues({ isFrom: true, toAmount: '' }, true)} + onClick={() => updateFormValues({ isFrom: true, toAmount: '' }, true).catch(errorFallback)} /> updateFormValues({ isFrom: false, toAmount, fromAmount: '' })} + onChange={(toAmount) => + updateFormValues({ isFrom: false, toAmount, fromAmount: '' }).catch(errorFallback) + } /> { const { api, market, steps, updateFormValues } = props @@ -32,11 +33,11 @@ const DetailInfoComp = ({ isLeverage, ...props }: PageContentProps & DetailInfoC const handleLiqRangesEdit = () => { const showEditLiqRange = !isEditLiqRange setStateByKey('isEditLiqRange', showEditLiqRange) - updateFormValues(formValues) + updateFormValues(formValues).catch(errorFallback) } const handleSelLiqRange = (n: number) => { - updateFormValues({ ...formValues, n }) + updateFormValues({ ...formValues, n }).catch(errorFallback) } const additionalProps: DetailInfoCompAdditionalProps = { diff --git a/apps/main/src/lend/components/PageLoanCreate/LoanFormCreate/index.tsx b/apps/main/src/lend/components/PageLoanCreate/LoanFormCreate/index.tsx index e1f487fcaa..733210f69c 100644 --- a/apps/main/src/lend/components/PageLoanCreate/LoanFormCreate/index.tsx +++ b/apps/main/src/lend/components/PageLoanCreate/LoanFormCreate/index.tsx @@ -36,6 +36,7 @@ import { useNavigate } from '@ui-kit/hooks/router' import usePageVisibleInterval from '@ui-kit/hooks/usePageVisibleInterval' import { t } from '@ui-kit/lib/i18n' import { REFRESH_INTERVAL } from '@ui-kit/lib/model' +import { errorFallback } from '@ui-kit/utils/error.util' import { useThrottle } from '@ui-kit/utils/timers' const LoanCreate = ({ @@ -263,7 +264,7 @@ const LoanCreate = ({ !formStatus.step && !formStatus.error && !isConfirming && - updateFormValues({}), + updateFormValues({}).catch(errorFallback), REFRESH_INTERVAL['10s'], ) @@ -307,21 +308,24 @@ const LoanCreate = ({ // signerAddress, maxSlippage state change useEffect(() => { - if (isLoaded) updateFormValues({}) + if (isLoaded) updateFormValues({}).catch(errorFallback) // eslint-disable-next-line react-hooks/exhaustive-deps }, [maxSlippage, isAdvancedMode]) useEffect(() => { if (isLoaded) { resetState() - updateFormValues({}) + updateFormValues({}).catch(errorFallback) } // eslint-disable-next-line react-hooks/exhaustive-deps }, [isLoaded]) const disabled = !!formStatus.step - const setUserBorrowed = useCallback((userBorrowed: string) => updateFormValues({ userBorrowed }), [updateFormValues]) + const setUserBorrowed = useCallback( + (userBorrowed: string) => updateFormValues({ userBorrowed }).catch(errorFallback), + [updateFormValues], + ) return ( <> @@ -338,10 +342,12 @@ const LoanCreate = ({ tokenSymbol={collateral_token?.symbol} tokenBalance={userBalances?.collateral} handleInpChange={useCallback( - (userCollateral: string) => updateFormValues({ userCollateral }), + (userCollateral: string) => updateFormValues({ userCollateral }).catch(errorFallback), [updateFormValues], )} - handleMaxClick={() => updateFormValues({ userCollateral: userBalances?.collateral ?? '' })} + handleMaxClick={() => + updateFormValues({ userCollateral: userBalances?.collateral ?? '' }).catch(errorFallback) + } /> {isLeverage && ( @@ -357,7 +363,7 @@ const LoanCreate = ({ tokenSymbol={borrowed_token?.symbol} tokenBalance={userBalances?.borrowed} handleInpChange={setUserBorrowed} - handleMaxClick={() => updateFormValues({ userBorrowed: userBalances?.borrowed ?? '' })} + handleMaxClick={() => updateFormValues({ userBorrowed: userBalances?.borrowed ?? '' }).catch(errorFallback)} /> )} @@ -372,10 +378,10 @@ const LoanCreate = ({ tokenAddress={borrowed_token?.address} tokenSymbol={borrowed_token?.symbol} maxRecv={maxRecv} - handleInpChange={useCallback((debt) => updateFormValues({ debt }), [updateFormValues])} + handleInpChange={useCallback((debt) => updateFormValues({ debt }).catch(errorFallback), [updateFormValues])} handleMaxClick={async () => { const debt = await refetchMaxRecv(market, isLeverage) - updateFormValues({ debt }) + updateFormValues({ debt }).catch(errorFallback) }} /> diff --git a/apps/main/src/lend/components/PageLoanManage/LoanBorrowMore/index.tsx b/apps/main/src/lend/components/PageLoanManage/LoanBorrowMore/index.tsx index 5e99ed603b..c0839fc84e 100644 --- a/apps/main/src/lend/components/PageLoanManage/LoanBorrowMore/index.tsx +++ b/apps/main/src/lend/components/PageLoanManage/LoanBorrowMore/index.tsx @@ -123,7 +123,7 @@ const LoanBorrowMore = ({ updateFormValues({}, '', true, true)} + onClose={() => updateFormValues({}, '', true, true).catch(errorFallback)} />, ) } @@ -276,7 +276,7 @@ const LoanBorrowMore = ({ !formStatus.step && !formStatus.error && !isConfirming && - updateFormValues({}), + updateFormValues({}).catch(errorFallback), REFRESH_INTERVAL['10s'], ) @@ -351,7 +351,10 @@ const LoanBorrowMore = ({ setHealthMode, } - const setUserBorrowed = useCallback((userBorrowed: string) => updateFormValues({ userBorrowed }), [updateFormValues]) + const setUserBorrowed = useCallback( + (userBorrowed: string) => updateFormValues({ userBorrowed }).catch(errorFallback), + [updateFormValues], + ) const network = networks[rChainId] return ( @@ -371,8 +374,13 @@ const LoanBorrowMore = ({ tokenAddress={market?.collateral_token?.address} tokenSymbol={market?.collateral_token?.symbol} tokenBalance={userBalances?.collateral} - handleInpChange={useCallback((userCollateral) => updateFormValues({ userCollateral }), [updateFormValues])} - handleMaxClick={() => updateFormValues({ userCollateral: userBalances?.collateral ?? '' })} + handleInpChange={useCallback( + (userCollateral) => updateFormValues({ userCollateral }).catch(errorFallback), + [updateFormValues], + )} + handleMaxClick={() => + updateFormValues({ userCollateral: userBalances?.collateral ?? '' }).catch(errorFallback) + } /> {isLeverage && ( @@ -388,7 +396,9 @@ const LoanBorrowMore = ({ tokenSymbol={market?.borrowed_token?.symbol} tokenBalance={userBalances?.borrowed} handleInpChange={setUserBorrowed} - handleMaxClick={() => updateFormValues({ userBorrowed: userBalances?.borrowed ?? '' })} + handleMaxClick={() => + updateFormValues({ userBorrowed: userBalances?.borrowed ?? '' }).catch(errorFallback) + } /> )} @@ -405,10 +415,10 @@ const LoanBorrowMore = ({ tokenAddress={market?.borrowed_token?.address} tokenSymbol={market?.borrowed_token?.symbol} maxRecv={maxRecv} - handleInpChange={useCallback((debt) => updateFormValues({ debt }), [updateFormValues])} + handleInpChange={useCallback((debt) => updateFormValues({ debt }).catch(errorFallback), [updateFormValues])} handleMaxClick={async () => { const debt = await refetchMaxRecv(market, isLeverage) - updateFormValues({ debt }) + updateFormValues({ debt }).catch(errorFallback) }} /> @@ -429,7 +439,7 @@ const LoanBorrowMore = ({ updateFormValues({})} + handleBtnClose={() => updateFormValues({}).catch(errorFallback)} /> )} {steps && } diff --git a/apps/main/src/lend/components/PageLoanManage/LoanRepay/index.tsx b/apps/main/src/lend/components/PageLoanManage/LoanRepay/index.tsx index b3ab014c00..2899122595 100644 --- a/apps/main/src/lend/components/PageLoanManage/LoanRepay/index.tsx +++ b/apps/main/src/lend/components/PageLoanManage/LoanRepay/index.tsx @@ -293,7 +293,7 @@ const LoanRepay = ({ !formStatus.step && !formStatus.error && !isConfirming && - updateFormValues({}) + updateFormValues({}).catch(errorFallback) ) }, REFRESH_INTERVAL['10s']) @@ -367,11 +367,11 @@ const LoanRepay = ({ const network = networks[rChainId] const setUserCollateral = useCallback( - (userCollateral: string) => updateFormValues({ userCollateral, isFullRepay: false }), + (userCollateral: string) => updateFormValues({ userCollateral, isFullRepay: false }).catch(errorFallback), [updateFormValues], ) const setStateCollateral = useCallback( - (stateCollateral: string) => updateFormValues({ stateCollateral, isFullRepay: false }), + (stateCollateral: string) => updateFormValues({ stateCollateral, isFullRepay: false }).catch(errorFallback), [updateFormValues], ) @@ -394,7 +394,9 @@ const LoanRepay = ({ tokenBalance={userState?.collateral} handleInpChange={setStateCollateral} handleMaxClick={() => - updateFormValues({ stateCollateral: userState?.collateral ?? '', isFullRepay: false }) + updateFormValues({ stateCollateral: userState?.collateral ?? '', isFullRepay: false }).catch( + errorFallback, + ) } /> @@ -418,7 +420,9 @@ const LoanRepay = ({ tokenBalance={userBalances?.collateral} handleInpChange={setUserCollateral} handleMaxClick={() => - updateFormValues({ userCollateral: userBalances?.collateral ?? '', isFullRepay: false }) + updateFormValues({ userCollateral: userBalances?.collateral ?? '', isFullRepay: false }).catch( + errorFallback, + ) } /> )} @@ -438,29 +442,29 @@ const LoanRepay = ({ handleInpChange={useCallback( (userBorrowed) => { if (hasExpectedBorrowed) { - updateFormValues({ userBorrowed, isFullRepay: false }) + updateFormValues({ userBorrowed, isFullRepay: false }).catch(errorFallback) return } if (!hasExpectedBorrowed && userState?.borrowed != null && borrowedTokenDecimals) { const totalRepay = sum([userState.borrowed, userBorrowed], borrowedTokenDecimals) const isFullRepay = isGreaterThanOrEqualTo(totalRepay, userState.debt, borrowedTokenDecimals) - updateFormValues({ userBorrowed, isFullRepay }) + updateFormValues({ userBorrowed, isFullRepay }).catch(errorFallback) return } - updateFormValues({ userBorrowed, isFullRepay: false }) + updateFormValues({ userBorrowed, isFullRepay: false }).catch(errorFallback) }, [borrowedTokenDecimals, hasExpectedBorrowed, updateFormValues, userState?.borrowed, userState?.debt], )} handleMaxClick={async () => { if (+userBalances.borrowed === 0) { - updateFormValues({ userBorrowed: '', isFullRepay: false }) + updateFormValues({ userBorrowed: '', isFullRepay: false }).catch(errorFallback) return } if (expectedBorrowed) { - updateFormValues({ userBorrowed: userBalances.borrowed, isFullRepay: false }) + updateFormValues({ userBorrowed: userBalances.borrowed, isFullRepay: false }).catch(errorFallback) return } @@ -473,14 +477,11 @@ const LoanRepay = ({ const amountNeededWithInterestRate = amountNeeded + getPercentage(amountNeeded, 1n) if (isGreaterThan(amountNeededWithInterestRate, userBalances.borrowed, borrowedTokenDecimals)) { - updateFormValues({ userBorrowed: userBalances.borrowed, isFullRepay: false }) + updateFormValues({ userBorrowed: userBalances.borrowed, isFullRepay: false }).catch(errorFallback) return } - - updateFormValues({ userBorrowed: '', isFullRepay: true }) - return } - updateFormValues({ userBorrowed: '', isFullRepay: false }) + updateFormValues({ userBorrowed: '', isFullRepay: false }).catch(errorFallback) }} /> @@ -495,9 +496,9 @@ const LoanRepay = ({ isSelected={detailInfoLeverage?.repayIsFull || formValues.isFullRepay} onChange={(isFullRepay) => { if (isFullRepay) { - updateFormValues({ ...DEFAULT_FORM_VALUES, isFullRepay }) + updateFormValues({ ...DEFAULT_FORM_VALUES, isFullRepay }).catch(errorFallback) } else { - updateFormValues({ ...DEFAULT_FORM_VALUES }) + updateFormValues({ ...DEFAULT_FORM_VALUES }).catch(errorFallback) } }} > @@ -537,7 +538,7 @@ const LoanRepay = ({ updateFormValues({})} + handleBtnClose={() => updateFormValues({}).catch(errorFallback)} /> ) : null} {steps && } diff --git a/apps/main/src/lend/components/PageVault/VaultClaim/index.tsx b/apps/main/src/lend/components/PageVault/VaultClaim/index.tsx index 64c1187793..8c7218ee1c 100644 --- a/apps/main/src/lend/components/PageVault/VaultClaim/index.tsx +++ b/apps/main/src/lend/components/PageVault/VaultClaim/index.tsx @@ -136,7 +136,7 @@ const VaultClaim = ({ isLoaded, api, market, userActiveKey }: PageContentProps) }, [resetState]) useEffect(() => { - if (isLoaded) updateFormValues() + if (isLoaded) updateFormValues().catch(errorFallback) // eslint-disable-next-line react-hooks/exhaustive-deps }, [isLoaded]) diff --git a/apps/main/src/lend/components/PageVault/VaultUnstake/index.tsx b/apps/main/src/lend/components/PageVault/VaultUnstake/index.tsx index 9e889f16f2..54e7c774b1 100644 --- a/apps/main/src/lend/components/PageVault/VaultUnstake/index.tsx +++ b/apps/main/src/lend/components/PageVault/VaultUnstake/index.tsx @@ -57,7 +57,7 @@ const VaultUnstake = ({ rChainId, rOwmId, rFormType, isLoaded, api, market, user ) const handleInpAmountChange = (amount: string) => { - reset({ amount }) + reset({ amount }).catch(errorFallback) } const handleBtnClickUnstake = useCallback( @@ -80,7 +80,9 @@ const VaultUnstake = ({ rChainId, rOwmId, rFormType, isLoaded, api, market, user if (isSubscribed.current && resp && resp.hash && resp.activeKey === activeKey && !resp.error) { const txMessage = t`Transaction completed.` const txHash = scanTxPath(networks[chainId], resp.hash) - setTxInfoBar( reset({})} />) + setTxInfoBar( + reset({}).catch(errorFallback)} />, + ) } if (resp?.error) setTxInfoBar(null) notification?.dismiss() @@ -138,7 +140,7 @@ const VaultUnstake = ({ rChainId, rOwmId, rFormType, isLoaded, api, market, user }, [resetState]) useEffect(() => { - if (isLoaded) updateFormValues({}) + if (isLoaded) updateFormValues({}).catch(errorFallback) // eslint-disable-next-line react-hooks/exhaustive-deps }, [isLoaded]) diff --git a/apps/main/src/lend/components/PageVault/VaultWithdrawRedeem/index.tsx b/apps/main/src/lend/components/PageVault/VaultWithdrawRedeem/index.tsx index feef1d1910..6630e8bb6c 100644 --- a/apps/main/src/lend/components/PageVault/VaultWithdrawRedeem/index.tsx +++ b/apps/main/src/lend/components/PageVault/VaultWithdrawRedeem/index.tsx @@ -110,7 +110,7 @@ const VaultWithdrawRedeem = ({ reset({})} + onClose={() => reset({}).catch(errorFallback)} />, ) } @@ -172,7 +172,7 @@ const VaultWithdrawRedeem = ({ }, [resetState]) useEffect(() => { - if (isLoaded) updateFormValues({}) + if (isLoaded) updateFormValues({}).catch(errorFallback) // eslint-disable-next-line react-hooks/exhaustive-deps }, [isLoaded]) diff --git a/apps/main/src/loan/components/PageLoanCreate/LoanFormCreate/components/DetailInfo.tsx b/apps/main/src/loan/components/PageLoanCreate/LoanFormCreate/components/DetailInfo.tsx index e91db6f69c..1dbf680c09 100644 --- a/apps/main/src/loan/components/PageLoanCreate/LoanFormCreate/components/DetailInfo.tsx +++ b/apps/main/src/loan/components/PageLoanCreate/LoanFormCreate/components/DetailInfo.tsx @@ -9,6 +9,7 @@ import { getActiveStep } from '@ui/Stepper/helpers' import { FORMAT_OPTIONS, formatNumber } from '@ui/utils' import { t } from '@ui-kit/lib/i18n' import { useTokenUsdRate } from '@ui-kit/lib/model/entities/token-usd-rate' +import { errorFallback } from '@ui-kit/utils/error.util' const DetailInfoComp = (props: FormDetailInfo) => { const { activeKeyLiqRange, formValues, isLeverage, isReady, llamma, haveSigner, steps, updateFormValues } = props @@ -31,11 +32,11 @@ const DetailInfoComp = (props: FormDetailInfo) => { const handleLiqRangesEdit = () => { const showEditLiqRange = !isEditLiqRange setStateByKey('isEditLiqRange', showEditLiqRange) - updateFormValues(formValues) + updateFormValues(formValues).catch(errorFallback) } const handleSelLiqRange = (n: number) => { - updateFormValues({ ...formValues, n }) + updateFormValues({ ...formValues, n }).catch(errorFallback) } const loanToValueRatio = useMemo(() => { diff --git a/apps/main/src/loan/components/PageLoanCreate/LoanFormCreate/index.tsx b/apps/main/src/loan/components/PageLoanCreate/LoanFormCreate/index.tsx index 40ee054726..eaf29432a5 100644 --- a/apps/main/src/loan/components/PageLoanCreate/LoanFormCreate/index.tsx +++ b/apps/main/src/loan/components/PageLoanCreate/LoanFormCreate/index.tsx @@ -118,7 +118,7 @@ const LoanCreate = ({ [name]: value, collateralError: '', debtError: '', - }) + }).catch(errorFallback) }, [formStatus, reset, updateFormValues], ) diff --git a/apps/main/src/loan/components/PageLoanManage/CollateralIncrease/index.tsx b/apps/main/src/loan/components/PageLoanManage/CollateralIncrease/index.tsx index ebe23e35db..b2d948a0d7 100644 --- a/apps/main/src/loan/components/PageLoanManage/CollateralIncrease/index.tsx +++ b/apps/main/src/loan/components/PageLoanManage/CollateralIncrease/index.tsx @@ -35,6 +35,7 @@ import { useTokenUsdRate } from '@ui-kit/lib/model/entities/token-usd-rate' import { LargeTokenInput } from '@ui-kit/shared/ui/LargeTokenInput' import { TokenLabel } from '@ui-kit/shared/ui/TokenLabel' import { decimal, type Decimal, ReleaseChannel } from '@ui-kit/utils' +import { errorFallback } from '@ui-kit/utils/error.util' interface Props extends Pick {} @@ -103,7 +104,7 @@ const CollateralIncrease = ({ curve, isReady, llamma, llammaId }: Props) => { const updatedFormValues = { ...formValues } updatedFormValues.collateral = collateral updatedFormValues.collateralError = '' - updateFormValues(updatedFormValues) + updateFormValues(updatedFormValues).catch(errorFallback) } const onCollateralChanged = useCallback( @@ -111,7 +112,7 @@ const CollateralIncrease = ({ curve, isReady, llamma, llammaId }: Props) => { const { formStatus, formValues } = useStore.getState().loanCollateralIncrease if (formValues.collateral === (val ?? '')) return reset(!!formStatus.error, formStatus.isComplete) - updateFormValues({ ...formValues, collateral: val ?? '', collateralError: '' }) + updateFormValues({ ...formValues, collateral: val ?? '', collateralError: '' }).catch(errorFallback) }, [reset, updateFormValues], ) diff --git a/apps/main/src/loan/components/PageLoanManage/LoanDecrease/index.tsx b/apps/main/src/loan/components/PageLoanManage/LoanDecrease/index.tsx index e7ceabdfdf..34e6492b21 100644 --- a/apps/main/src/loan/components/PageLoanManage/LoanDecrease/index.tsx +++ b/apps/main/src/loan/components/PageLoanManage/LoanDecrease/index.tsx @@ -36,6 +36,7 @@ import { useTokenUsdRate } from '@ui-kit/lib/model/entities/token-usd-rate' import { LargeTokenInput } from '@ui-kit/shared/ui/LargeTokenInput' import { TokenLabel } from '@ui-kit/shared/ui/TokenLabel' import { ReleaseChannel, decimal, type Decimal } from '@ui-kit/utils' +import { errorFallback } from '@ui-kit/utils/error.util' interface Props extends Pick {} @@ -104,7 +105,7 @@ const LoanDecrease = ({ curve, llamma, llammaId, params, rChainId }: Props) => { const updatedFormValues = { ...formValues } updatedFormValues.debt = debt updatedFormValues.debtError = '' - updateFormValues(updatedFormValues) + updateFormValues(updatedFormValues).catch(errorFallback) } const onDebtChanged = useCallback( @@ -116,7 +117,7 @@ const LoanDecrease = ({ curve, llamma, llammaId, params, rChainId }: Props) => { debt, debtError: '', isFullRepay: decimal(userWalletBalances.stablecoin) == value, - }) + }).catch(errorFallback) }, [formStatus.error, formStatus.isComplete, reset, updateFormValues, userWalletBalances.stablecoin], ) @@ -127,7 +128,7 @@ const LoanDecrease = ({ curve, llamma, llammaId, params, rChainId }: Props) => { updatedFormValues.debt = '' updatedFormValues.debtError = '' updatedFormValues.isFullRepay = isFullRepay - updateFormValues(updatedFormValues) + updateFormValues(updatedFormValues).catch(errorFallback) } const handleBtnClickPay = useCallback( diff --git a/packages/curve-ui-kit/src/hooks/usePageVisibleInterval.ts b/packages/curve-ui-kit/src/hooks/usePageVisibleInterval.ts index 45c0baf972..23ab1a611b 100644 --- a/packages/curve-ui-kit/src/hooks/usePageVisibleInterval.ts +++ b/packages/curve-ui-kit/src/hooks/usePageVisibleInterval.ts @@ -2,7 +2,7 @@ import { useEffect, useEffectEvent } from 'react' import { useLayoutStore } from '@ui-kit/features/layout' import { setTimeoutInterval } from '@ui-kit/utils/timers' -type CallbackFunction = () => unknown +type CallbackFunction = () => unknown | Promise /** * A hook that runs a callback function at specified intervals, but only when the page is visible. diff --git a/tests/cypress/component/large-token-input.cy.tsx b/tests/cypress/component/large-token-input.cy.tsx index b76742d66c..8fd881b8c6 100644 --- a/tests/cypress/component/large-token-input.cy.tsx +++ b/tests/cypress/component/large-token-input.cy.tsx @@ -4,27 +4,15 @@ import { LargeTokenInput } from '@ui-kit/shared/ui/LargeTokenInput' import type { Decimal } from '@ui-kit/utils' function TestComponent() { - const [balance, setBalance] = useState(undefined) - - // This value is different from balance, as it's not being overwritten by user input and is debounced uniquely. + // This value is different from the input value, it is debounced in the component const [balanceDebounced, setBalanceDebounced] = useState(undefined) - return ( - <> - { - setBalance(newBalance) - setBalanceDebounced(newBalance) - }} - /> + setBalanceDebounced(newBalance)} /> -
- Debounced balance value: {balanceDebounced} -
- +
+ Debounced balance value: {balanceDebounced} +
) } @@ -34,13 +22,17 @@ describe('LargeTokenInput', () => { cy.mount() cy.get('input').should('have.value', '') cy.get('[data-testid="debounced-balance"]').should('have.text', '') - cy.get('input').click().type('5').blur() + cy.get('input').click() + cy.get('input').type('5') + cy.get('input').blur() cy.get('input').should('have.value', '5') cy.get('[data-testid="debounced-balance"]').should('have.text', '') - cy.get('input').click().type('.') + cy.get('input').click() + cy.get('input').type('.') cy.get('input').should('have.value', '.') cy.get('[data-testid="debounced-balance"]').should('have.text', '') - cy.get('input').click().type('5') + cy.get('input').click() + cy.get('input').type('5') cy.get('input').should('have.value', '.5') cy.get('[data-testid="debounced-balance"]').should('have.text', '.5') }) diff --git a/tests/cypress/support/helpers/ComponentTestWrapper.tsx b/tests/cypress/support/helpers/ComponentTestWrapper.tsx index 8cb6bdf0f6..faa6669429 100644 --- a/tests/cypress/support/helpers/ComponentTestWrapper.tsx +++ b/tests/cypress/support/helpers/ComponentTestWrapper.tsx @@ -1,4 +1,4 @@ -import { type ReactElement } from 'react' +import { type ReactNode } from 'react' import { WagmiProvider, type ResolvedRegister } from 'wagmi' import { createMemoryHistory, createRootRoute, createRouter, RouterProvider } from '@tanstack/react-router' import { persister, queryClient, QueryProvider } from '@ui-kit/lib/api' @@ -9,7 +9,7 @@ export type Config = ResolvedRegister['config'] type Props = { config?: Config - children: ReactElement + children: ReactNode autoConnect?: boolean } @@ -25,7 +25,7 @@ export function ComponentTestWrapper({ config, children, autoConnect }: Props) { // Create a minimal router for testing environment const router = createRouter({ routeTree: createRootRoute({ - component: () => children, + component: () => <>{children}, }), history: createMemoryHistory({ initialEntries: ['/'], From a0818693d09c1368bf2efb98a7cf59951a3bace1 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Mon, 3 Nov 2025 15:11:09 +0100 Subject: [PATCH 10/12] chore: self-review --- .../PagePool/Deposit/components/FormStake.tsx | 20 +++++++++++++------ .../PageLoanManage/LoanRepay/index.tsx | 6 +++--- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/apps/main/src/dex/components/PagePool/Deposit/components/FormStake.tsx b/apps/main/src/dex/components/PagePool/Deposit/components/FormStake.tsx index 66fd2b0971..5a36b7b8e5 100644 --- a/apps/main/src/dex/components/PagePool/Deposit/components/FormStake.tsx +++ b/apps/main/src/dex/components/PagePool/Deposit/components/FormStake.tsx @@ -48,9 +48,9 @@ const FormStake = ({ curve, poolData, poolDataCacheOrApi, routerParams, seed, us const haveSigner = !!signerAddress const updateFormValues = useCallback( - (updatedFormValues: Partial) => { + async (updatedFormValues: Partial) => { setTxInfoBar(null) - setFormValues( + await setFormValues( 'STAKE', curve, poolDataCacheOrApi.pool.id, @@ -59,7 +59,7 @@ const FormStake = ({ curve, poolData, poolDataCacheOrApi, routerParams, seed, us null, seed.isSeed, '', - ).catch(errorFallback) + ) }, [curve, poolData, poolDataCacheOrApi.pool.id, seed.isSeed, setFormValues], ) @@ -151,7 +151,7 @@ const FormStake = ({ curve, poolData, poolDataCacheOrApi, routerParams, seed, us // curve state change useEffect(() => { if (chainId && poolId) { - updateFormValues({}) + updateFormValues({}).catch(errorFallback) } // eslint-disable-next-line react-hooks/exhaustive-deps }, [chainId, poolId, signerAddress, seed.isSeed]) @@ -179,7 +179,10 @@ const FormStake = ({ curve, poolData, poolDataCacheOrApi, routerParams, seed, us balanceLoading={balancesLoading} hasError={haveSigner ? new BigNumber(formValues.lpToken).isGreaterThan(balLpToken as string) : false} haveSigner={haveSigner} - handleAmountChange={useCallback((lpToken) => updateFormValues({ lpToken }), [updateFormValues])} + handleAmountChange={useCallback( + (lpToken) => updateFormValues({ lpToken }).catch(errorFallback), + [updateFormValues], + )} disabled={disableForm} /> @@ -211,7 +214,12 @@ const FormStake = ({ curve, poolData, poolDataCacheOrApi, routerParams, seed, us {formStatus.error === 'lpToken-too-much' ? ( {t`Not enough LP Tokens balances.`} ) : ( - formStatus.error && updateFormValues({})} /> + formStatus.error && ( + updateFormValues({}).catch(errorFallback)} + /> + ) )} {txInfoBar} diff --git a/apps/main/src/lend/components/PageLoanManage/LoanRepay/index.tsx b/apps/main/src/lend/components/PageLoanManage/LoanRepay/index.tsx index 2899122595..c72cf9abce 100644 --- a/apps/main/src/lend/components/PageLoanManage/LoanRepay/index.tsx +++ b/apps/main/src/lend/components/PageLoanManage/LoanRepay/index.tsx @@ -131,10 +131,10 @@ const LoanRepay = ({ description={txMessage} txHash={scanTxPath(networks[rChainId], resp.hash)} onClose={() => { - if (resp.loanExists) { - updateFormValues(DEFAULT_FORM_VALUES, '', true).catch(errorFallback) + updateFormValues(DEFAULT_FORM_VALUES, '', true).catch(errorFallback) + if (!resp.loanExists) { + push(getCollateralListPathname(params)) } - push(getCollateralListPathname(params)) }} />, ) From 404701daa762ecb9c7f18dfbea5e684d803afe1c Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Mon, 3 Nov 2025 16:37:33 +0100 Subject: [PATCH 11/12] chore: job name --- .github/workflows/ci.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index abb2dd85e3..89cdd5f129 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -108,7 +108,7 @@ jobs: include: - browser: chrome count: 2 - name: Cypress in ${{ matrix.browser }} ${{ matrix.count }} + name: Cypress e2e tests in ${{ matrix.browser }} ${{ matrix.count }} timeout-minutes: 15 runs-on: ubuntu-latest steps: From 93e8c05664d612e10e3245e368be415dc1312d54 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Tue, 4 Nov 2025 15:22:57 +0100 Subject: [PATCH 12/12] chore: only show async errors on preview urls for now --- .../PageLoanManage/LoanDeleverage/index.tsx | 12 +++++------- .../main/src/loan/components/PageLoanManage/Page.tsx | 5 +++-- packages/curve-ui-kit/src/hooks/useLocalStorage.ts | 3 ++- packages/curve-ui-kit/src/utils/error.util.ts | 1 + packages/curve-ui-kit/src/utils/timers.ts | 4 ++++ 5 files changed, 15 insertions(+), 10 deletions(-) diff --git a/apps/main/src/loan/components/PageLoanManage/LoanDeleverage/index.tsx b/apps/main/src/loan/components/PageLoanManage/LoanDeleverage/index.tsx index 19b7cb7bfb..28a1421949 100644 --- a/apps/main/src/loan/components/PageLoanManage/LoanDeleverage/index.tsx +++ b/apps/main/src/loan/components/PageLoanManage/LoanDeleverage/index.tsx @@ -137,13 +137,11 @@ const LoanDeleverage = ({ { - if (resp.loanExists) { - updateFormValues({}, '', true).catch(() => errorFallback) - } else { - push(getCollateralListPathname(params)) - } - }} + onClose={() => + resp.loanExists + ? updateFormValues({}, '', true).catch(errorFallback) + : push(getCollateralListPathname(params)) + } />, ) } diff --git a/apps/main/src/loan/components/PageLoanManage/Page.tsx b/apps/main/src/loan/components/PageLoanManage/Page.tsx index 4692665061..a467b3fed1 100644 --- a/apps/main/src/loan/components/PageLoanManage/Page.tsx +++ b/apps/main/src/loan/components/PageLoanManage/Page.tsx @@ -102,11 +102,12 @@ const Page = () => { if (rCollateralId && llamma) { ;(async () => { const fetchedLoanDetails = await fetchLoanDetails(curve, llamma) - if (!fetchedLoanDetails.loanExists) { + if (fetchedLoanDetails.loanExists) { + setLoaded(true) + } else { resetUserDetailsState(llamma) push(getLoanCreatePathname(params, rCollateralId)) } - setLoaded(true) })().catch(errorFallback) } else { console.warn(`Cannot find market ${rCollateralId}, redirecting to list`, params) diff --git a/packages/curve-ui-kit/src/hooks/useLocalStorage.ts b/packages/curve-ui-kit/src/hooks/useLocalStorage.ts index e93479f4b1..bcc5ee583e 100644 --- a/packages/curve-ui-kit/src/hooks/useLocalStorage.ts +++ b/packages/curve-ui-kit/src/hooks/useLocalStorage.ts @@ -45,7 +45,8 @@ export const useShowTestNets = () => useLocalStorage('showTestnets', fa const getReleaseChannel = (): ReleaseChannel => getFromLocalStorage('release-channel') ?? defaultReleaseChannel -export const shouldShowErrors = () => getReleaseChannel() === ReleaseChannel.Beta +export const shouldShowErrors = () => + getReleaseChannel() === ReleaseChannel.Beta && defaultReleaseChannel === ReleaseChannel.Beta export const useReleaseChannel = () => useLocalStorage('release-channel', defaultReleaseChannel, { version: 1, diff --git a/packages/curve-ui-kit/src/utils/error.util.ts b/packages/curve-ui-kit/src/utils/error.util.ts index c5d10ee4b1..59352db51a 100644 --- a/packages/curve-ui-kit/src/utils/error.util.ts +++ b/packages/curve-ui-kit/src/utils/error.util.ts @@ -10,6 +10,7 @@ const IGNORED_ERROR_MESSAGES = [ ] export const errorFallback = (error: unknown) => { + console.error(error) if (!shouldShowErrors()) return const { message = 'An unknown error occurred' } = error as Error const { name } = error as DOMException diff --git a/packages/curve-ui-kit/src/utils/timers.ts b/packages/curve-ui-kit/src/utils/timers.ts index 88d9cc4d02..e0fc3c35fc 100644 --- a/packages/curve-ui-kit/src/utils/timers.ts +++ b/packages/curve-ui-kit/src/utils/timers.ts @@ -32,5 +32,9 @@ export function setTimeoutInterval(callback: () => unknown, delay: number): () = } } +/** + * Throttles a function using lodash throttle and memoizes it with useMemo. + * Important: the passed function should be stable between renders (e.g., static or wrapped in useCallback). + */ export const useThrottle = any>(f: T, duration = Duration.FormThrottle) => useMemo(() => throttle(f, duration), [f, duration])