Skip to content

Commit

Permalink
Merge branch 'feat_improve_thorchain_lending_status_polling' into fea…
Browse files Browse the repository at this point in the history
…t_improve_thorchain_status_reliability
  • Loading branch information
gomesalexandre committed Nov 21, 2023
2 parents a16d87a + 3567e5a commit 54a9c50
Show file tree
Hide file tree
Showing 12 changed files with 68 additions and 59 deletions.
2 changes: 1 addition & 1 deletion src/context/TransactionsProvider/TransactionsProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { useSelector } from 'react-redux'
import { getChainAdapterManager } from 'context/PluginProvider/chainAdapterSingleton'
import { useWallet } from 'hooks/useWallet/useWallet'
import { isSome } from 'lib/utils'
import { waitForThorchainUpdate } from 'lib/utils/thorchain'
import { nftApi } from 'state/apis/nft/nftApi'
import { assets as assetsSlice } from 'state/slices/assetsSlice/assetsSlice'
import { makeNftAssetsFromTxs } from 'state/slices/assetsSlice/utils'
Expand All @@ -18,7 +19,6 @@ import type { IdleStakingSpecificMetadata } from 'state/slices/opportunitiesSlic
import {
isSupportedThorchainSaversAssetId,
isSupportedThorchainSaversChainId,
waitForThorchainUpdate,
} from 'state/slices/opportunitiesSlice/resolvers/thorchainsavers/utils'
import { fetchAllOpportunitiesUserDataByAccountId } from 'state/slices/opportunitiesSlice/thunks'
import { DefiProvider, DefiType } from 'state/slices/opportunitiesSlice/types'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ import { bn, bnOrZero } from 'lib/bignumber/bignumber'
import { trackOpportunityEvent } from 'lib/mixpanel/helpers'
import { getMixPanel } from 'lib/mixpanel/mixPanelSingleton'
import { MixPanelEvents } from 'lib/mixpanel/types'
import { waitForThorchainUpdate } from 'lib/utils/thorchain'
import { opportunitiesApi } from 'state/slices/opportunitiesSlice/opportunitiesApiSlice'
import { waitForThorchainUpdate } from 'state/slices/opportunitiesSlice/resolvers/thorchainsavers/utils'
import {
selectAssetById,
selectAssets,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ import { bn, bnOrZero } from 'lib/bignumber/bignumber'
import { trackOpportunityEvent } from 'lib/mixpanel/helpers'
import { getMixPanel } from 'lib/mixpanel/mixPanelSingleton'
import { MixPanelEvents } from 'lib/mixpanel/types'
import { waitForThorchainUpdate } from 'lib/utils/thorchain'
import { opportunitiesApi } from 'state/slices/opportunitiesSlice/opportunitiesApiSlice'
import { waitForThorchainUpdate } from 'state/slices/opportunitiesSlice/resolvers/thorchainsavers/utils'
import {
selectAssetById,
selectAssets,
Expand Down
28 changes: 27 additions & 1 deletion src/lib/utils/thorchain/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import type { AccountId } from '@shapeshiftoss/caip'
import { TxStatus } from '@shapeshiftoss/unchained-client'
import type { QueryClient } from '@tanstack/react-query'
import { queryClient } from 'context/QueryClientProvider/queryClient'
import type { Asset } from 'lib/asset-service'
import { bnOrZero } from 'lib/bignumber/bignumber'
import { fromBaseUnit, toBaseUnit } from 'lib/math'
import { poll } from 'lib/poll/poll'
import {
type EstimatedFeesQueryKey,
queryFn as getEstimatedFeesQueryFn,
Expand All @@ -11,7 +14,10 @@ import type { IsSweepNeededQueryKey } from 'pages/Lending/hooks/useIsSweepNeeded
import { queryFn as isSweepNeededQueryFn } from 'pages/Lending/hooks/useIsSweepNeededQuery'
import { selectPortfolioCryptoBalanceBaseUnitByFilter } from 'state/slices/common-selectors'
import type { ThorchainSaversWithdrawQuoteResponseSuccess } from 'state/slices/opportunitiesSlice/resolvers/thorchainsavers/types'
import { fromThorBaseUnit } from 'state/slices/opportunitiesSlice/resolvers/thorchainsavers/utils'
import {
fromThorBaseUnit,
getThorchainTransactionStatus,
} from 'state/slices/opportunitiesSlice/resolvers/thorchainsavers/utils'
import { isUtxoChainId } from 'state/slices/portfolioSlice/utils'
import { selectMarketDataById } from 'state/slices/selectors'
import { store } from 'state/store'
Expand All @@ -23,6 +29,26 @@ import {
queryFn as getThorchainSaversWithdrawQuoteQueryFn,
} from './hooks/useGetThorchainSaversWithdrawQuoteQuery'

export const waitForThorchainUpdate = ({
txHash,
queryClient,
skipOutbound,
}: {
txHash: string
queryClient?: QueryClient
skipOutbound?: boolean
}) =>
poll({
fn: () => {
// Invalidate some react-queries everytime we poll - since status detection is currently suboptimal
queryClient?.invalidateQueries({ queryKey: ['thorchainLendingPosition'], exact: false })
return getThorchainTransactionStatus(txHash, skipOutbound)
},
validate: status => Boolean(status && status === TxStatus.Confirmed),
interval: 60000,
maxAttempts: 20,
})

// TODO(gomes): this will work for UTXO but is invalid for tokens since they use diff. denoms
// the current workaround is to not do fee deduction for non-UTXO chains,
// but for consistency, we should for native EVM assets, and ensure this is a no-op for tokens
Expand Down
38 changes: 21 additions & 17 deletions src/pages/Lending/Pool/components/Borrow/Borrow.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { AccountId, AssetId } from '@shapeshiftoss/caip'
import { AnimatePresence } from 'framer-motion'
import { lazy, memo, useCallback, useState } from 'react'
import { lazy, memo, Suspense, useCallback, useState } from 'react'
import { MemoryRouter, Route, Switch, useLocation } from 'react-router'
import { useRouteAssetId } from 'hooks/useRouteAssetId/useRouteAssetId'
import type { Asset } from 'lib/asset-service'
Expand All @@ -22,6 +22,8 @@ const BorrowConfirm = lazy(() =>

const BorrowEntries = [BorrowRoutePaths.Input, BorrowRoutePaths.Confirm]

const suspenseFallback = <div>Loading...</div>

type BorrowProps = {
collateralAccountId: AccountId
borrowAccountId: AccountId
Expand Down Expand Up @@ -161,22 +163,24 @@ const BorrowRoutes = memo(
return (
<AnimatePresence exitBeforeEnter initial={false}>
<Switch location={location}>
<Route
key={BorrowRoutePaths.Input}
path={BorrowRoutePaths.Input}
render={renderBorrowInput}
/>
<Route
key={BorrowRoutePaths.Sweep}
path={BorrowRoutePaths.Sweep}
render={renderBorrowSweep}
/>

<Route
key={BorrowRoutePaths.Confirm}
path={BorrowRoutePaths.Confirm}
render={renderBorrowConfirm}
/>
<Suspense fallback={suspenseFallback}>
<Route
key={BorrowRoutePaths.Input}
path={BorrowRoutePaths.Input}
render={renderBorrowInput}
/>
<Route
key={BorrowRoutePaths.Sweep}
path={BorrowRoutePaths.Sweep}
render={renderBorrowSweep}
/>

<Route
key={BorrowRoutePaths.Confirm}
path={BorrowRoutePaths.Confirm}
render={renderBorrowConfirm}
/>
</Suspense>
</Switch>
</AnimatePresence>
)
Expand Down
9 changes: 3 additions & 6 deletions src/pages/Lending/Pool/components/Borrow/BorrowConfirm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,12 @@ import { getSupportedEvmChainIds } from 'hooks/useEvm/useEvm'
import { useWallet } from 'hooks/useWallet/useWallet'
import type { Asset } from 'lib/asset-service'
import { bnOrZero } from 'lib/bignumber/bignumber'
import { waitForThorchainUpdate } from 'lib/utils/thorchain'
import { useLendingPositionData } from 'pages/Lending/hooks/useLendingPositionData'
import { useLendingQuoteOpenQuery } from 'pages/Lending/hooks/useLendingQuoteQuery'
import { useQuoteEstimatedFeesQuery } from 'pages/Lending/hooks/useQuoteEstimatedFees'
import { getThorchainLendingPosition } from 'state/slices/opportunitiesSlice/resolvers/thorchainLending/utils'
import {
getThorchainFromAddress,
waitForThorchainUpdate,
} from 'state/slices/opportunitiesSlice/resolvers/thorchainsavers/utils'
import { getThorchainFromAddress } from 'state/slices/opportunitiesSlice/resolvers/thorchainsavers/utils'
import {
selectAssetById,
selectMarketDataById,
Expand Down Expand Up @@ -91,8 +89,7 @@ export const BorrowConfirm = ({

setIsLoanOpenPending(true)
;(async () => {
// TODO(gomes): we might want to change heuristics here - this takes forever to be truthy, while the loan open itself is reflected way earlier, at least for ETH
await waitForThorchainUpdate({ txHash, queryClient }).promise
await waitForThorchainUpdate({ txHash, queryClient, skipOutbound: true }).promise
setIsLoanOpenPending(false)
await refetchLendingPositionData()
})()
Expand Down
3 changes: 2 additions & 1 deletion src/pages/Lending/Pool/components/Borrow/BorrowInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -405,7 +405,8 @@ export const BorrowInput = ({
isSweepNeededLoading
}
isDisabled={Boolean(
isLendingQuoteError ||
bnOrZero(depositAmountCryptoPrecision).isZero() ||
isLendingQuoteError ||
isLendingQuoteLoading ||
quoteErrorTranslation ||
isEstimatedFeesDataError ||
Expand Down
5 changes: 2 additions & 3 deletions src/pages/Lending/Pool/components/Repay/RepayConfirm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,10 @@ import { getSupportedEvmChainIds } from 'hooks/useEvm/useEvm'
import { useWallet } from 'hooks/useWallet/useWallet'
import type { Asset } from 'lib/asset-service'
import { bnOrZero } from 'lib/bignumber/bignumber'
import { waitForThorchainUpdate } from 'lib/utils/thorchain'
import { useLendingQuoteCloseQuery } from 'pages/Lending/hooks/useLendingCloseQuery'
import { useLendingPositionData } from 'pages/Lending/hooks/useLendingPositionData'
import { useQuoteEstimatedFeesQuery } from 'pages/Lending/hooks/useQuoteEstimatedFees'
import { waitForThorchainUpdate } from 'state/slices/opportunitiesSlice/resolvers/thorchainsavers/utils'
import {
selectAssetById,
selectMarketDataById,
Expand Down Expand Up @@ -79,8 +79,7 @@ export const RepayConfirm = ({

setIsLoanClosePending(true)
;(async () => {
// TODO(gomes): we might want to change heuristics here - this takes forever to be truthy, while the loan open itself is reflected way earlier, at least for ETH
await waitForThorchainUpdate({ txHash, queryClient }).promise
await waitForThorchainUpdate({ txHash, queryClient, skipOutbound: true }).promise
setIsLoanClosePending(false)
await refetchLendingPositionData()
})()
Expand Down
10 changes: 5 additions & 5 deletions src/pages/Lending/hooks/useLendingCloseQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,11 @@ export const useLendingQuoteCloseQuery = ({
return repaymentPercentBn.plus('1').toNumber()
}, [_repaymentPercent])

const { data: lendingPositionData } = useLendingPositionData({
assetId: _collateralAssetId,
accountId: _collateralAccountId,
})

const lendingQuoteCloseQueryKey = useDebounce(
() => [
'lendingQuoteCloseQuery',
Expand Down Expand Up @@ -161,11 +166,6 @@ export const useLendingQuoteCloseQuery = ({
selectMarketDataById(state, collateralAssetId),
)

const { data: lendingPositionData } = useLendingPositionData({
assetId: collateralAssetId,
accountId: collateralAccountId,
})

const userCurrencyToUsdRate = useAppSelector(selectUserCurrencyToUsdRate)

const debtBalanceUserCurrency = useMemo(() => {
Expand Down
5 changes: 4 additions & 1 deletion src/pages/Lending/hooks/useLendingPositionData.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export const useLendingPositionData = ({ accountId, assetId }: UseLendingPositio

const lendingPositionData = useQuery({
// 2 minutes before the data is considered stale, meaning firing this query will trigger queryFn
staleTime: 120_000,
staleTime: 60_000,
queryKey: lendingPositionQueryKey,
queryFn: async ({ queryKey }) => {
const [, { accountId, assetId }] = queryKey
Expand All @@ -44,6 +44,9 @@ export const useLendingPositionData = ({ accountId, assetId }: UseLendingPositio
}
},
enabled: Boolean(accountId && assetId && poolAssetMarketData.price !== '0'),
refetchOnMount: true,
refetchInterval: 60_000,
refetchIntervalInBackground: true,
})

return lendingPositionData
Expand Down
1 change: 1 addition & 0 deletions src/pages/Lending/hooks/useQuoteEstimatedFees.ts
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ export const useQuoteEstimatedFeesQuery = ({
return { estimatedFees, txFeeFiat, txFeeCryptoBaseUnit: estimatedFees.fast.txFee }
},
enabled: Boolean(asset && (lendingQuoteData || lendingQuoteCloseData)),
retry: false,
})

return useQuoteEstimatedFeesQuery
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,13 @@ import type { HDWallet } from '@shapeshiftoss/hdwallet-core'
import { TxStatus } from '@shapeshiftoss/unchained-client'
import type { Result } from '@sniptt/monads'
import { Err, Ok } from '@sniptt/monads'
import type { QueryClient } from '@tanstack/react-query'
import axios from 'axios'
import { getConfig } from 'config'
import memoize from 'lodash/memoize'
import { getChainAdapterManager } from 'context/PluginProvider/chainAdapterSingleton'
import type { Asset } from 'lib/asset-service'
import type { BN } from 'lib/bignumber/bignumber'
import { BigNumber, bn, bnOrZero } from 'lib/bignumber/bignumber'
import { poll } from 'lib/poll/poll'
import type {
ThornodePoolResponse,
ThornodeStatusResponse,
Expand Down Expand Up @@ -344,26 +342,6 @@ export const isSupportedThorchainSaversAssetId = (assetId: AssetId) =>
export const isSupportedThorchainSaversChainId = (chainId: ChainId) =>
SUPPORTED_THORCHAIN_SAVERS_CHAIN_IDS.includes(chainId)

export const waitForThorchainUpdate = ({
txHash,
queryClient,
skipOutbound,
}: {
txHash: string
queryClient?: QueryClient
skipOutbound?: boolean
}) =>
poll({
fn: () => {
// Invalidate some react-queries everytime we poll - since status detection is currently suboptimal
queryClient?.invalidateQueries({ queryKey: ['thorchainLendingPosition'], exact: false })
return getThorchainTransactionStatus(txHash, skipOutbound)
},
validate: status => Boolean(status && status === TxStatus.Confirmed),
interval: 60000,
maxAttempts: 20,
})

export const makeDaysToBreakEven = ({
expectedAmountOutThorBaseUnit,
amountCryptoBaseUnit,
Expand Down

0 comments on commit 54a9c50

Please sign in to comment.