From 271aae08239d248cc43f814cabb93be66150cc66 Mon Sep 17 00:00:00 2001
From: gomes <17035424+gomesalexandre@users.noreply.github.com>
Date: Wed, 7 Feb 2024 15:06:57 +0100
Subject: [PATCH 01/33] wip: wip
---
src/assets/translations/en/main.json | 2 ++
src/pages/ThorChainLP/AvailablePools.tsx | 18 +++++++----
src/pages/ThorChainLP/Pool/Pool.tsx | 25 ++++++++++++++--
.../AddLiquitity/AddLiquidityInput.tsx | 30 +++++++++++++++----
.../ReusableLpStatus/TransactionRow.tsx | 25 +++++++++++++++-
src/react-queries/index.ts | 14 ++++++++-
6 files changed, 98 insertions(+), 16 deletions(-)
diff --git a/src/assets/translations/en/main.json b/src/assets/translations/en/main.json
index a4a784c28c3..d337d2a3207 100644
--- a/src/assets/translations/en/main.json
+++ b/src/assets/translations/en/main.json
@@ -127,6 +127,8 @@
"yourBalance": "Your balance",
"signTransaction": "Sign transaction",
"halted": "Halted",
+ "poolHalted": "Pool Halted",
+ "available": "Available",
"carousel": {
"next": "Next",
"prev": "Previous",
diff --git a/src/pages/ThorChainLP/AvailablePools.tsx b/src/pages/ThorChainLP/AvailablePools.tsx
index 0cf0d1f32a9..2b64a4ed9c8 100644
--- a/src/pages/ThorChainLP/AvailablePools.tsx
+++ b/src/pages/ThorChainLP/AvailablePools.tsx
@@ -51,7 +51,7 @@ type PoolButtonProps = {
const PoolButton = ({ pool }: PoolButtonProps) => {
const history = useHistory()
- const { data: isTradingActive } = useQuery(
+ const { data: isTradingActive, isLoading: isTradingActiveLoading } = useQuery(
reactQueries.common.isTradingActive({
assetId: pool.assetId,
swapperName: SwapperName.Thorchain,
@@ -106,11 +106,17 @@ const PoolButton = ({ pool }: PoolButtonProps) => {
- {isTradingActive === false && (
-
-
-
- )}
+
+ {isTradingActive === false ? (
+
+
+
+ ) : (
+
+
+
+ )}
+
diff --git a/src/pages/ThorChainLP/Pool/Pool.tsx b/src/pages/ThorChainLP/Pool/Pool.tsx
index 543fcd351d7..30aaf20c597 100644
--- a/src/pages/ThorChainLP/Pool/Pool.tsx
+++ b/src/pages/ThorChainLP/Pool/Pool.tsx
@@ -10,9 +10,11 @@ import {
Heading,
IconButton,
Stack,
+ Tooltip,
} from '@chakra-ui/react'
import type { AccountId, AssetId } from '@shapeshiftoss/caip'
import { thorchainAssetId } from '@shapeshiftoss/caip'
+import { SwapperName } from '@shapeshiftoss/swapper'
import { useQuery } from '@tanstack/react-query'
import type { Property } from 'csstype'
import React, { useCallback, useMemo } from 'react'
@@ -100,6 +102,13 @@ export const Pool = () => {
return parsedPools.find(pool => pool.opportunityId === routeOpportunityId)
}, [params, parsedPools])
+ const { data: isTradingActive, isLoading: isTradingActiveLoading } = useQuery(
+ reactQueries.common.isTradingActive({
+ assetId: foundPool?.assetId,
+ swapperName: SwapperName.Thorchain,
+ }),
+ )
+
const poolAssetIds = useMemo(() => {
if (!foundPool) return []
@@ -186,9 +195,19 @@ export const Pool = () => {
>
-
+
+
+
diff --git a/src/pages/ThorChainLP/components/AddLiquitity/AddLiquidityInput.tsx b/src/pages/ThorChainLP/components/AddLiquitity/AddLiquidityInput.tsx
index c23f4b61d06..721fe3b3b1a 100644
--- a/src/pages/ThorChainLP/components/AddLiquitity/AddLiquidityInput.tsx
+++ b/src/pages/ThorChainLP/components/AddLiquitity/AddLiquidityInput.tsx
@@ -18,6 +18,7 @@ import {
} from '@chakra-ui/react'
import type { AccountId, AssetId, ChainId } from '@shapeshiftoss/caip'
import { fromAssetId, thorchainAssetId, thorchainChainId } from '@shapeshiftoss/caip'
+import { SwapperName } from '@shapeshiftoss/swapper'
import type { Asset, KnownChainIds, MarketData } from '@shapeshiftoss/types'
import { TxStatus } from '@shapeshiftoss/unchained-client'
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
@@ -183,6 +184,13 @@ export const AddLiquidityInput: React.FC = ({
const [poolAsset, setPoolAsset] = useState(foundPoolAsset)
+ const { data: isTradingActive, isLoading: isTradingActiveLoading } = useQuery(
+ reactQueries.common.isTradingActive({
+ assetId: poolAsset?.assetId,
+ swapperName: SwapperName.Thorchain,
+ }),
+ )
+
useEffect(() => {
if (!(poolAsset && parsedPools)) return
// We only want to run this effect in the standalone AddLiquidity page
@@ -730,7 +738,12 @@ export const AddLiquidityInput: React.FC = ({
useEffect(() => {
;(async () => {
- if (!actualRuneCryptoLiquidityAmount || !actualAssetCryptoLiquidityAmount || !poolAsset)
+ if (
+ !actualRuneCryptoLiquidityAmount ||
+ !actualAssetCryptoLiquidityAmount ||
+ !poolAsset ||
+ isTradingActive === false
+ )
return
const runeAmountCryptoThorPrecision = convertPrecision({
@@ -775,6 +788,7 @@ export const AddLiquidityInput: React.FC = ({
isAsymAssetSide,
isAsymRuneSide,
virtualRuneFiatLiquidityAmount,
+ isTradingActive,
])
useEffect(() => {
@@ -955,6 +969,7 @@ export const AddLiquidityInput: React.FC = ({
= ({
const errorCopy = useMemo(() => {
// Order matters here. Since we're dealing with two assets potentially, we want to show the most relevant error message possible i.e
- // 1 pool asset balance
- // 2. pool asset fee balance, since gas would usually be more expensive on the pool asset fee side vs. RUNE side
- // 3. RUNE balance
- // 4. RUNE fee balance
+ // 1. pool halted
+ // 2. pool asset balance
+ // 3. pool asset fee balance, since gas would usually be more expensive on the pool asset fee side vs. RUNE side
+ // 4. RUNE balance
+ // 5. RUNE fee balance
// Not enough *pool* asset, but possibly enough *fee* asset
+ if (isTradingActive === false) return translate('common.poolHalted')
if (poolAsset && notEnoughPoolAssetError) return translate('common.insufficientFunds')
// Not enough *fee* asset
if (poolAssetFeeAsset && notEnoughFeeAssetError)
@@ -1041,6 +1058,7 @@ export const AddLiquidityInput: React.FC = ({
return null
}, [
+ isTradingActive,
notEnoughFeeAssetError,
notEnoughPoolAssetError,
notEnoughRuneError,
@@ -1142,6 +1160,7 @@ export const AddLiquidityInput: React.FC = ({
size='lg'
colorScheme={errorCopy ? 'red' : 'blue'}
isDisabled={
+ isTradingActive === false ||
!confirmedQuote ||
isVotingPowerLoading ||
!hasEnoughAssetBalance ||
@@ -1163,6 +1182,7 @@ export const AddLiquidityInput: React.FC = ({
isAllowanceDataLoading ||
isApprovalTxPending ||
isSweepNeededLoading ||
+ isTradingActiveLoading ||
isEstimatedPoolAssetFeesDataLoading
}
onClick={handleSubmit}
diff --git a/src/pages/ThorChainLP/components/ReusableLpStatus/TransactionRow.tsx b/src/pages/ThorChainLP/components/ReusableLpStatus/TransactionRow.tsx
index c9c6d4ef02d..744f865b003 100644
--- a/src/pages/ThorChainLP/components/ReusableLpStatus/TransactionRow.tsx
+++ b/src/pages/ThorChainLP/components/ReusableLpStatus/TransactionRow.tsx
@@ -23,6 +23,7 @@ import {
type FeeDataEstimate,
FeeDataKey,
} from '@shapeshiftoss/chain-adapters'
+import { SwapperName } from '@shapeshiftoss/swapper'
import type { KnownChainIds } from '@shapeshiftoss/types'
import { TxStatus } from '@shapeshiftoss/unchained-client'
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
@@ -99,6 +100,18 @@ export const TransactionRow: React.FC = ({
const [txId, setTxId] = useState(null)
const wallet = useWallet().state.wallet
+ const {
+ data: isTradingActive,
+ isLoading: isTradingActiveLoading,
+ isRefetching: isTradingActiveRefetching,
+ refetch: refetchIsTradingActive,
+ } = useQuery(
+ reactQueries.common.isTradingActive({
+ assetId: poolAssetId,
+ swapperName: SwapperName.Thorchain,
+ }),
+ )
+
const runeAccountId = accountIdsByChainId[thorchainChainId]
const poolAssetAccountId =
accountIdsByChainId[poolAsset?.assetId ? fromAssetId(poolAsset.assetId).chainId : '']
@@ -376,6 +389,10 @@ export const TransactionRow: React.FC = ({
return
return (async () => {
+ // Refetch the trading active state JIT to ensure the pool didn't just become halted
+ const { data: isTradingActiveData } = await refetchIsTradingActive()
+ if (!isTradingActiveData) return
+
const accountId = isRuneTx ? runeAccountId : poolAssetAccountId
if (!accountId) throw new Error(`No accountId found for asset ${asset.assetId}`)
const { account } = fromAccountId(accountId)
@@ -614,7 +631,13 @@ export const TransactionRow: React.FC = ({
size='lg'
colorScheme='blue'
onClick={handleSignTx}
- isLoading={status === TxStatus.Pending || isInboundAddressLoading}
+ isDisabled={isTradingActive === false}
+ isLoading={
+ status === TxStatus.Pending ||
+ isInboundAddressLoading ||
+ isTradingActiveLoading ||
+ isTradingActiveRefetching
+ }
>
{translate('common.signTransaction')}
diff --git a/src/react-queries/index.ts b/src/react-queries/index.ts
index 3464826f121..dec38da7542 100644
--- a/src/react-queries/index.ts
+++ b/src/react-queries/index.ts
@@ -65,16 +65,28 @@ const common = createQueryKeys('common', {
from &&
getSupportedEvmChainIds().includes(fromAssetId(assetId).chainId as KnownChainIds),
}),
- isTradingActive: ({ assetId, swapperName }: { assetId: AssetId; swapperName: SwapperName }) => ({
+ isTradingActive: ({
+ assetId,
+ swapperName,
+ }: {
+ assetId: AssetId | undefined
+ swapperName: SwapperName
+ }) => ({
queryKey: ['isTradingActive', assetId, swapperName],
queryFn: async () => {
+ if (!assetId) throw new Error('assetId is required')
+
const maybeIsTradingActive = await isTradingActive(assetId, swapperName)
// Do not return things in a monadic way so that we can leverage native react-query error-handling
if (maybeIsTradingActive.isErr()) throw maybeIsTradingActive.unwrapErr()
return maybeIsTradingActive.unwrap()
},
+ enabled: Boolean(assetId),
+ // Go stale instantly
staleTime: 0,
+ // Never store queries in cache since we always want fresh data
+ gcTime: 0,
refetchOnWindowFocus: true,
refetchOnMount: true,
refetchInterval: 60_000,
From 66beabb8be80801f7b9041a0dbb7c08e0c5b6410 Mon Sep 17 00:00:00 2001
From: gomes <17035424+gomesalexandre@users.noreply.github.com>
Date: Wed, 7 Feb 2024 15:35:33 +0100
Subject: [PATCH 02/33] feat: throw on pool just halted at sign step so we
don't infinitely spin
---
.../components/ReusableLpStatus/TransactionRow.tsx | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/src/pages/ThorChainLP/components/ReusableLpStatus/TransactionRow.tsx b/src/pages/ThorChainLP/components/ReusableLpStatus/TransactionRow.tsx
index 744f865b003..e3ddf2cfea6 100644
--- a/src/pages/ThorChainLP/components/ReusableLpStatus/TransactionRow.tsx
+++ b/src/pages/ThorChainLP/components/ReusableLpStatus/TransactionRow.tsx
@@ -391,7 +391,7 @@ export const TransactionRow: React.FC = ({
return (async () => {
// Refetch the trading active state JIT to ensure the pool didn't just become halted
const { data: isTradingActiveData } = await refetchIsTradingActive()
- if (!isTradingActiveData) return
+ if (!isTradingActiveData) throw new Error('Pool Halted')
const accountId = isRuneTx ? runeAccountId : poolAssetAccountId
if (!accountId) throw new Error(`No accountId found for asset ${asset.assetId}`)
@@ -570,6 +570,7 @@ export const TransactionRow: React.FC = ({
wallet,
isRuneTx,
inboundAddressData,
+ refetchIsTradingActive,
runeAccountId,
poolAssetAccountId,
amountCryptoPrecision,
@@ -583,6 +584,12 @@ export const TransactionRow: React.FC = ({
const txIdLink = useMemo(() => `${asset?.explorerTxLink}${txId}`, [asset?.explorerTxLink, txId])
+ const confirmTranslation = useMemo(() => {
+ if (isTradingActive === false) return translate('common.poolHalted')
+
+ return translate('common.signTransaction')
+ }, [isTradingActive, translate])
+
if (!asset) return null
return (
@@ -629,7 +636,7 @@ export const TransactionRow: React.FC = ({
From 67b2af8feba5eacfb5b8867cd16a86b22176701f Mon Sep 17 00:00:00 2001
From: gomes <17035424+gomesalexandre@users.noreply.github.com>
Date: Thu, 8 Feb 2024 17:44:43 +0100
Subject: [PATCH 03/33] feat: improve thorchain savers JIT halted checks
---
.../Deposit/components/Confirm.tsx | 32 ++++++++++-------
.../Overview/ThorchainSaversOverview.tsx | 14 ++++----
.../Withdraw/components/Confirm.tsx | 34 ++++++++++++-------
src/state/apis/swapper/swapperApi.ts | 3 +-
4 files changed, 50 insertions(+), 33 deletions(-)
diff --git a/src/features/defi/providers/thorchain-savers/components/ThorchainSaversManager/Deposit/components/Confirm.tsx b/src/features/defi/providers/thorchain-savers/components/ThorchainSaversManager/Deposit/components/Confirm.tsx
index eb9678104b4..44973c4729b 100644
--- a/src/features/defi/providers/thorchain-savers/components/ThorchainSaversManager/Deposit/components/Confirm.tsx
+++ b/src/features/defi/providers/thorchain-savers/components/ThorchainSaversManager/Deposit/components/Confirm.tsx
@@ -15,6 +15,7 @@ import type { BuildCustomTxInput } from '@shapeshiftoss/chain-adapters/src/evm/t
import { supportsETH } from '@shapeshiftoss/hdwallet-core'
import { SwapperName } from '@shapeshiftoss/swapper'
import type { Asset, KnownChainIds } from '@shapeshiftoss/types'
+import { useQuery } from '@tanstack/react-query'
import { getConfig } from 'config'
import { getOrCreateContractByType } from 'contracts/contractManager'
import { ContractType } from 'contracts/types'
@@ -28,6 +29,7 @@ import type {
import { DefiStep } from 'features/defi/contexts/DefiManagerProvider/DefiCommon'
import { useCallback, useContext, useEffect, useMemo, useState } from 'react'
import { useTranslate } from 'react-polyglot'
+import { reactQueries } from 'react-queries'
import { encodeFunctionData, getAddress } from 'viem'
import { Amount } from 'components/Amount/Amount'
import { AssetIcon } from 'components/AssetIcon'
@@ -58,7 +60,6 @@ import {
import { fromThorBaseUnit, getThorchainFromAddress, toThorBaseUnit } from 'lib/utils/thorchain'
import { BASE_BPS_POINTS } from 'lib/utils/thorchain/constants'
import { getInboundAddressDataForChain } from 'lib/utils/thorchain/getInboundAddressDataForChain'
-import { swapperApi } from 'state/apis/swapper/swapperApi'
import {
getMaybeThorchainSaversDepositQuote,
getThorchainSaversPosition,
@@ -75,7 +76,7 @@ import {
selectPortfolioCryptoBalanceBaseUnitByFilter,
selectSelectedCurrency,
} from 'state/slices/selectors'
-import { store, useAppDispatch, useAppSelector } from 'state/store'
+import { store, useAppSelector } from 'state/store'
import { ThorchainSaversDepositActionType } from '../DepositCommon'
import { DepositContext } from '../DepositContext'
@@ -96,7 +97,6 @@ export const Confirm: React.FC = ({ accountId, onNext }) => {
null,
)
const [daysToBreakEven, setDaysToBreakEven] = useState(null)
- const appDispatch = useAppDispatch()
const translate = useTranslate()
const mixpanel = getMixPanel()
// TODO: Allow user to set fee priority
@@ -540,6 +540,13 @@ export const Confirm: React.FC = ({ accountId, onNext }) => {
})()
}, [accountId, accountMetadata, accountType, assetId, bip44Params, chainAdapter, wallet])
+ const { data: isTradingActive, refetch: refetchIsTradingActive } = useQuery(
+ reactQueries.common.isTradingActive({
+ assetId,
+ swapperName: SwapperName.Thorchain,
+ }),
+ )
+
const handleDeposit = useCallback(async () => {
if (!contextDispatch || !bip44Params || !accountId || !assetId) return
try {
@@ -561,15 +568,15 @@ export const Confirm: React.FC = ({ accountId, onNext }) => {
contextDispatch({ type: ThorchainSaversDepositActionType.SET_LOADING, payload: true })
- const { getIsTradingActive } = swapperApi.endpoints
- const { data: isTradingActive } = await appDispatch(
- getIsTradingActive.initiate({
- assetId,
- swapperName: SwapperName.Thorchain,
- }),
- )
+ // Was the pool active when it was fetched at the time of the component mount
+ if (isTradingActive === false) {
+ throw new Error(`THORChain pool halted for assetId: ${assetId}`)
+ }
+
+ // Refetch the trading active state JIT to ensure the pool didn't just become halted
+ const { data: isTradingActiveData } = await refetchIsTradingActive()
- if (!isTradingActive) {
+ if (!isTradingActiveData) {
throw new Error(`THORChain pool halted for assetId: ${assetId}`)
}
@@ -633,7 +640,8 @@ export const Confirm: React.FC = ({ accountId, onNext }) => {
chainAdapter,
state?.deposit.cryptoAmount,
state?.deposit.fiatAmount,
- appDispatch,
+ isTradingActive,
+ refetchIsTradingActive,
protocolFeeCryptoBaseUnit,
maybeFromUTXOAccountAddress,
onNext,
diff --git a/src/features/defi/providers/thorchain-savers/components/ThorchainSaversManager/Overview/ThorchainSaversOverview.tsx b/src/features/defi/providers/thorchain-savers/components/ThorchainSaversManager/Overview/ThorchainSaversOverview.tsx
index ca2ca5afb38..cac00a066ab 100644
--- a/src/features/defi/providers/thorchain-savers/components/ThorchainSaversManager/Overview/ThorchainSaversOverview.tsx
+++ b/src/features/defi/providers/thorchain-savers/components/ThorchainSaversManager/Overview/ThorchainSaversOverview.tsx
@@ -17,6 +17,7 @@ import { toAssetId } from '@shapeshiftoss/caip'
import { SwapperName } from '@shapeshiftoss/swapper'
import type { Asset } from '@shapeshiftoss/types'
import { TxStatus } from '@shapeshiftoss/unchained-client'
+import { useQuery } from '@tanstack/react-query'
import BigNumber from 'bignumber.js'
import type { DefiButtonProps } from 'features/defi/components/DefiActionButtons'
import { Overview } from 'features/defi/components/Overview/Overview'
@@ -28,6 +29,7 @@ import { DefiAction } from 'features/defi/contexts/DefiManagerProvider/DefiCommo
import { useCallback, useEffect, useMemo, useState } from 'react'
import { FaTwitter } from 'react-icons/fa'
import { useTranslate } from 'react-polyglot'
+import { reactQueries } from 'react-queries'
import type { AccountDropdownProps } from 'components/AccountDropdown/AccountDropdown'
import { Amount } from 'components/Amount/Amount'
import { CircularProgress } from 'components/CircularProgress/CircularProgress'
@@ -36,7 +38,6 @@ import { Text } from 'components/Text'
import { useBrowserRouter } from 'hooks/useBrowserRouter/useBrowserRouter'
import { bnOrZero } from 'lib/bignumber/bignumber'
import { fromBaseUnit, toBaseUnit } from 'lib/math'
-import { useGetIsTradingActiveQuery } from 'state/apis/swapper/swapperApi'
import type { ThorchainSaversStakingSpecificMetadata } from 'state/slices/opportunitiesSlice/resolvers/thorchainsavers/types'
import {
getMaybeThorchainSaversDepositQuote,
@@ -129,11 +130,12 @@ export const ThorchainSaversOverview: React.FC = ({
[accountId, defaultAccountId, highestBalanceAccountId],
)
- const { data: isTradingActive, isFetching: isTradingActiveQueryPending } =
- useGetIsTradingActiveQuery({
+ const { data: isTradingActive, isLoading: isTradingActiveLoading } = useQuery(
+ reactQueries.common.isTradingActive({
assetId,
swapperName: SwapperName.Thorchain,
- })
+ }),
+ )
useEffect(() => {
if (!maybeAccountId) return
@@ -272,7 +274,7 @@ export const ThorchainSaversOverview: React.FC = ({
isFull: opportunityMetadata?.isFull || isHardCapReached,
hasPendingTxs,
hasPendingQueries,
- isHalted: !isTradingActive,
+ isHalted: isTradingActive === false,
})
}, [
earnOpportunityData,
@@ -355,7 +357,7 @@ export const ThorchainSaversOverview: React.FC = ({
const handleThorchainSaversEmptyClick = useCallback(() => setHideEmptyState(true), [])
- if (!earnOpportunityData || isTradingActiveQueryPending) {
+ if (!earnOpportunityData || isTradingActiveLoading) {
return (
diff --git a/src/features/defi/providers/thorchain-savers/components/ThorchainSaversManager/Withdraw/components/Confirm.tsx b/src/features/defi/providers/thorchain-savers/components/ThorchainSaversManager/Withdraw/components/Confirm.tsx
index 524ec484c59..c0af1afcd7c 100644
--- a/src/features/defi/providers/thorchain-savers/components/ThorchainSaversManager/Withdraw/components/Confirm.tsx
+++ b/src/features/defi/providers/thorchain-savers/components/ThorchainSaversManager/Withdraw/components/Confirm.tsx
@@ -16,6 +16,7 @@ import { FeeDataKey } from '@shapeshiftoss/chain-adapters'
import type { BuildCustomTxInput } from '@shapeshiftoss/chain-adapters/src/evm/types'
import { supportsETH } from '@shapeshiftoss/hdwallet-core'
import { SwapperName } from '@shapeshiftoss/swapper'
+import { useQuery } from '@tanstack/react-query'
import { getConfig } from 'config'
import { getOrCreateContractByType } from 'contracts/contractManager'
import { ContractType } from 'contracts/types'
@@ -29,6 +30,7 @@ import type {
import { DefiStep } from 'features/defi/contexts/DefiManagerProvider/DefiCommon'
import { useCallback, useContext, useEffect, useMemo, useState } from 'react'
import { useTranslate } from 'react-polyglot'
+import { reactQueries } from 'react-queries'
import { encodeFunctionData, getAddress } from 'viem'
import { Amount } from 'components/Amount/Amount'
import { AssetIcon } from 'components/AssetIcon'
@@ -58,7 +60,6 @@ import {
import { fromThorBaseUnit, toThorBaseUnit } from 'lib/utils/thorchain'
import { BASE_BPS_POINTS } from 'lib/utils/thorchain/constants'
import { getInboundAddressDataForChain } from 'lib/utils/thorchain/getInboundAddressDataForChain'
-import { swapperApi } from 'state/apis/swapper/swapperApi'
import {
getThorchainSaversPosition,
getThorchainSaversWithdrawQuote,
@@ -79,7 +80,7 @@ import {
selectPortfolioCryptoBalanceBaseUnitByFilter,
selectSelectedCurrency,
} from 'state/slices/selectors'
-import { useAppDispatch, useAppSelector } from 'state/store'
+import { useAppSelector } from 'state/store'
import { ThorchainSaversWithdrawActionType } from '../WithdrawCommon'
import { WithdrawContext } from '../WithdrawContext'
@@ -98,7 +99,6 @@ export const Confirm: React.FC = ({ accountId, onNext }) => {
null,
)
const { state, dispatch: contextDispatch } = useContext(WithdrawContext)
- const appDispatch = useAppDispatch()
const translate = useTranslate()
const mixpanel = getMixPanel()
const { query } = useBrowserRouter()
@@ -594,6 +594,13 @@ export const Confirm: React.FC = ({ accountId, onNext }) => {
return txId
}, [getWithdrawInput, wallet])
+ const { data: isTradingActive, refetch: refetchIsTradingActive } = useQuery(
+ reactQueries.common.isTradingActive({
+ assetId,
+ swapperName: SwapperName.Thorchain,
+ }),
+ )
+
const handleConfirm = useCallback(async () => {
if (!contextDispatch || !bip44Params || !accountId || !assetId || !opportunityData) return
try {
@@ -625,15 +632,15 @@ export const Confirm: React.FC = ({ accountId, onNext }) => {
return
}
- const { getIsTradingActive } = swapperApi.endpoints
- const { data: isTradingActive } = await appDispatch(
- getIsTradingActive.initiate({
- assetId,
- swapperName: SwapperName.Thorchain,
- }),
- )
+ // Was the pool active when it was fetched at the time of the component mount
+ if (isTradingActive === false) {
+ throw new Error(`THORChain pool halted for assetId: ${assetId}`)
+ }
+
+ // Refetch the trading active state JIT to ensure the pool didn't just become halted
+ const { data: isTradingActiveData } = await refetchIsTradingActive()
- if (!isTradingActive) {
+ if (!isTradingActiveData) {
throw new Error(`THORChain pool halted for assetId: ${assetId}`)
}
@@ -701,8 +708,8 @@ export const Confirm: React.FC = ({ accountId, onNext }) => {
state?.withdraw.cryptoAmount,
state?.withdraw.fiatAmount,
expiry,
- appDispatch,
- getWithdrawInput,
+ isTradingActive,
+ refetchIsTradingActive,
dustAmountCryptoBaseUnit,
protocolFeeCryptoBaseUnit,
onNext,
@@ -710,6 +717,7 @@ export const Confirm: React.FC = ({ accountId, onNext }) => {
toast,
translate,
isTokenWithdraw,
+ getWithdrawInput,
handleMultiTxSend,
handleCustomTx,
])
diff --git a/src/state/apis/swapper/swapperApi.ts b/src/state/apis/swapper/swapperApi.ts
index 426db3c8897..a4f292cfc15 100644
--- a/src/state/apis/swapper/swapperApi.ts
+++ b/src/state/apis/swapper/swapperApi.ts
@@ -244,5 +244,4 @@ export const swapperApi = swapperApiBase.injectEndpoints({
}),
})
-export const { useGetTradeQuoteQuery, useGetSupportedAssetsQuery, useGetIsTradingActiveQuery } =
- swapperApi
+export const { useGetTradeQuoteQuery, useGetSupportedAssetsQuery } = swapperApi
From 0e0e9e551ba19cb23a2b664326cfd4210603b162 Mon Sep 17 00:00:00 2001
From: gomes <17035424+gomesalexandre@users.noreply.github.com>
Date: Thu, 8 Feb 2024 23:18:30 +0100
Subject: [PATCH 04/33] feat: handle @lukemorales/query-key-factory shenanigans
---
.../Deposit/components/Confirm.tsx | 15 ++++++++++++---
.../Overview/ThorchainSaversOverview.tsx | 15 ++++++++++++---
.../Withdraw/components/Confirm.tsx | 15 ++++++++++++---
src/pages/ThorChainLP/AvailablePools.tsx | 14 +++++++++++---
src/pages/ThorChainLP/Pool/Pool.tsx | 15 ++++++++++++---
.../components/AddLiquitity/AddLiquidityInput.tsx | 15 ++++++++++++---
.../ReusableLpStatus/TransactionRow.tsx | 15 ++++++++++++---
src/react-queries/index.ts | 8 --------
8 files changed, 83 insertions(+), 29 deletions(-)
diff --git a/src/features/defi/providers/thorchain-savers/components/ThorchainSaversManager/Deposit/components/Confirm.tsx b/src/features/defi/providers/thorchain-savers/components/ThorchainSaversManager/Deposit/components/Confirm.tsx
index 44973c4729b..ed2203d3027 100644
--- a/src/features/defi/providers/thorchain-savers/components/ThorchainSaversManager/Deposit/components/Confirm.tsx
+++ b/src/features/defi/providers/thorchain-savers/components/ThorchainSaversManager/Deposit/components/Confirm.tsx
@@ -540,12 +540,21 @@ export const Confirm: React.FC = ({ accountId, onNext }) => {
})()
}, [accountId, accountMetadata, accountType, assetId, bip44Params, chainAdapter, wallet])
- const { data: isTradingActive, refetch: refetchIsTradingActive } = useQuery(
- reactQueries.common.isTradingActive({
+ const { data: isTradingActive, refetch: refetchIsTradingActive } = useQuery({
+ ...reactQueries.common.isTradingActive({
assetId,
swapperName: SwapperName.Thorchain,
}),
- )
+ // @lukemorales/query-key-factory only returns queryFn and queryKey - all others will be ignored in the returned object
+ enabled: Boolean(assetId),
+ // Go stale instantly
+ staleTime: 0,
+ // Never store queries in cache since we always want fresh data
+ gcTime: 0,
+ refetchOnWindowFocus: true,
+ refetchOnMount: true,
+ refetchInterval: 60_000,
+ })
const handleDeposit = useCallback(async () => {
if (!contextDispatch || !bip44Params || !accountId || !assetId) return
diff --git a/src/features/defi/providers/thorchain-savers/components/ThorchainSaversManager/Overview/ThorchainSaversOverview.tsx b/src/features/defi/providers/thorchain-savers/components/ThorchainSaversManager/Overview/ThorchainSaversOverview.tsx
index cac00a066ab..cf1698ca25d 100644
--- a/src/features/defi/providers/thorchain-savers/components/ThorchainSaversManager/Overview/ThorchainSaversOverview.tsx
+++ b/src/features/defi/providers/thorchain-savers/components/ThorchainSaversManager/Overview/ThorchainSaversOverview.tsx
@@ -130,12 +130,21 @@ export const ThorchainSaversOverview: React.FC = ({
[accountId, defaultAccountId, highestBalanceAccountId],
)
- const { data: isTradingActive, isLoading: isTradingActiveLoading } = useQuery(
- reactQueries.common.isTradingActive({
+ const { data: isTradingActive, isLoading: isTradingActiveLoading } = useQuery({
+ ...reactQueries.common.isTradingActive({
assetId,
swapperName: SwapperName.Thorchain,
}),
- )
+ // @lukemorales/query-key-factory only returns queryFn and queryKey - all others will be ignored in the returned object
+ enabled: Boolean(assetId),
+ // Go stale instantly
+ staleTime: 0,
+ // Never store queries in cache since we always want fresh data
+ gcTime: 0,
+ refetchOnWindowFocus: true,
+ refetchOnMount: true,
+ refetchInterval: 60_000,
+ })
useEffect(() => {
if (!maybeAccountId) return
diff --git a/src/features/defi/providers/thorchain-savers/components/ThorchainSaversManager/Withdraw/components/Confirm.tsx b/src/features/defi/providers/thorchain-savers/components/ThorchainSaversManager/Withdraw/components/Confirm.tsx
index c0af1afcd7c..7ac32132920 100644
--- a/src/features/defi/providers/thorchain-savers/components/ThorchainSaversManager/Withdraw/components/Confirm.tsx
+++ b/src/features/defi/providers/thorchain-savers/components/ThorchainSaversManager/Withdraw/components/Confirm.tsx
@@ -594,12 +594,21 @@ export const Confirm: React.FC = ({ accountId, onNext }) => {
return txId
}, [getWithdrawInput, wallet])
- const { data: isTradingActive, refetch: refetchIsTradingActive } = useQuery(
- reactQueries.common.isTradingActive({
+ const { data: isTradingActive, refetch: refetchIsTradingActive } = useQuery({
+ ...reactQueries.common.isTradingActive({
assetId,
swapperName: SwapperName.Thorchain,
}),
- )
+ // @lukemorales/query-key-factory only returns queryFn and queryKey - all others will be ignored in the returned object
+ enabled: Boolean(assetId),
+ // Go stale instantly
+ staleTime: 0,
+ // Never store queries in cache since we always want fresh data
+ gcTime: 0,
+ refetchOnWindowFocus: true,
+ refetchOnMount: true,
+ refetchInterval: 60_000,
+ })
const handleConfirm = useCallback(async () => {
if (!contextDispatch || !bip44Params || !accountId || !assetId || !opportunityData) return
diff --git a/src/pages/ThorChainLP/AvailablePools.tsx b/src/pages/ThorChainLP/AvailablePools.tsx
index 2b64a4ed9c8..f6a379abe97 100644
--- a/src/pages/ThorChainLP/AvailablePools.tsx
+++ b/src/pages/ThorChainLP/AvailablePools.tsx
@@ -51,12 +51,20 @@ type PoolButtonProps = {
const PoolButton = ({ pool }: PoolButtonProps) => {
const history = useHistory()
- const { data: isTradingActive, isLoading: isTradingActiveLoading } = useQuery(
- reactQueries.common.isTradingActive({
+ const { data: isTradingActive, isLoading: isTradingActiveLoading } = useQuery({
+ ...reactQueries.common.isTradingActive({
assetId: pool.assetId,
swapperName: SwapperName.Thorchain,
}),
- )
+ // @lukemorales/query-key-factory only returns queryFn and queryKey - all others will be ignored in the returned object
+ // Go stale instantly
+ staleTime: 0,
+ // Never store queries in cache since we always want fresh data
+ gcTime: 0,
+ refetchOnWindowFocus: true,
+ refetchOnMount: true,
+ refetchInterval: 60_000,
+ })
const handlePoolClick = useCallback(() => {
const { opportunityId } = pool
diff --git a/src/pages/ThorChainLP/Pool/Pool.tsx b/src/pages/ThorChainLP/Pool/Pool.tsx
index 30aaf20c597..7850ce6d594 100644
--- a/src/pages/ThorChainLP/Pool/Pool.tsx
+++ b/src/pages/ThorChainLP/Pool/Pool.tsx
@@ -102,12 +102,21 @@ export const Pool = () => {
return parsedPools.find(pool => pool.opportunityId === routeOpportunityId)
}, [params, parsedPools])
- const { data: isTradingActive, isLoading: isTradingActiveLoading } = useQuery(
- reactQueries.common.isTradingActive({
+ const { data: isTradingActive, isLoading: isTradingActiveLoading } = useQuery({
+ ...reactQueries.common.isTradingActive({
assetId: foundPool?.assetId,
swapperName: SwapperName.Thorchain,
}),
- )
+ // @lukemorales/query-key-factory only returns queryFn and queryKey - all others will be ignored in the returned object
+ enabled: Boolean(foundPool?.assetId),
+ // Go stale instantly
+ staleTime: 0,
+ // Never store queries in cache since we always want fresh data
+ gcTime: 0,
+ refetchOnWindowFocus: true,
+ refetchOnMount: true,
+ refetchInterval: 60_000,
+ })
const poolAssetIds = useMemo(() => {
if (!foundPool) return []
diff --git a/src/pages/ThorChainLP/components/AddLiquitity/AddLiquidityInput.tsx b/src/pages/ThorChainLP/components/AddLiquitity/AddLiquidityInput.tsx
index 721fe3b3b1a..525d7191edb 100644
--- a/src/pages/ThorChainLP/components/AddLiquitity/AddLiquidityInput.tsx
+++ b/src/pages/ThorChainLP/components/AddLiquitity/AddLiquidityInput.tsx
@@ -184,12 +184,21 @@ export const AddLiquidityInput: React.FC = ({
const [poolAsset, setPoolAsset] = useState(foundPoolAsset)
- const { data: isTradingActive, isLoading: isTradingActiveLoading } = useQuery(
- reactQueries.common.isTradingActive({
+ const { data: isTradingActive, isLoading: isTradingActiveLoading } = useQuery({
+ ...reactQueries.common.isTradingActive({
assetId: poolAsset?.assetId,
swapperName: SwapperName.Thorchain,
}),
- )
+ // @lukemorales/query-key-factory only returns queryFn and queryKey - all others will be ignored in the returned object
+ enabled: Boolean(poolAsset?.assetId),
+ // Go stale instantly
+ staleTime: 0,
+ // Never store queries in cache since we always want fresh data
+ gcTime: 0,
+ refetchOnWindowFocus: true,
+ refetchOnMount: true,
+ refetchInterval: 60_000,
+ })
useEffect(() => {
if (!(poolAsset && parsedPools)) return
diff --git a/src/pages/ThorChainLP/components/ReusableLpStatus/TransactionRow.tsx b/src/pages/ThorChainLP/components/ReusableLpStatus/TransactionRow.tsx
index e3ddf2cfea6..2091aa1f4a7 100644
--- a/src/pages/ThorChainLP/components/ReusableLpStatus/TransactionRow.tsx
+++ b/src/pages/ThorChainLP/components/ReusableLpStatus/TransactionRow.tsx
@@ -105,12 +105,21 @@ export const TransactionRow: React.FC = ({
isLoading: isTradingActiveLoading,
isRefetching: isTradingActiveRefetching,
refetch: refetchIsTradingActive,
- } = useQuery(
- reactQueries.common.isTradingActive({
+ } = useQuery({
+ ...reactQueries.common.isTradingActive({
assetId: poolAssetId,
swapperName: SwapperName.Thorchain,
}),
- )
+ // @lukemorales/query-key-factory only returns queryFn and queryKey - all others will be ignored in the returned object
+ enabled: Boolean(poolAssetId),
+ // Go stale instantly
+ staleTime: 0,
+ // Never store queries in cache since we always want fresh data
+ gcTime: 0,
+ refetchOnWindowFocus: true,
+ refetchOnMount: true,
+ refetchInterval: 60_000,
+ })
const runeAccountId = accountIdsByChainId[thorchainChainId]
const poolAssetAccountId =
diff --git a/src/react-queries/index.ts b/src/react-queries/index.ts
index dec38da7542..27acd90d49c 100644
--- a/src/react-queries/index.ts
+++ b/src/react-queries/index.ts
@@ -82,14 +82,6 @@ const common = createQueryKeys('common', {
if (maybeIsTradingActive.isErr()) throw maybeIsTradingActive.unwrapErr()
return maybeIsTradingActive.unwrap()
},
- enabled: Boolean(assetId),
- // Go stale instantly
- staleTime: 0,
- // Never store queries in cache since we always want fresh data
- gcTime: 0,
- refetchOnWindowFocus: true,
- refetchOnMount: true,
- refetchInterval: 60_000,
}),
})
From 10997b2de743dac2285659caa542b77178387d34 Mon Sep 17 00:00:00 2001
From: gomes <17035424+gomesalexandre@users.noreply.github.com>
Date: Thu, 8 Feb 2024 23:55:37 +0100
Subject: [PATCH 05/33] feat: remove swapperApi's getIsTradingActive
---
.../hooks/useIsTradingActive.tsx | 80 ++++++++-----------
src/react-queries/index.ts | 3 +-
src/state/apis/swapper/swapperApi.ts | 44 +++-------
3 files changed, 45 insertions(+), 82 deletions(-)
diff --git a/src/components/MultiHopTrade/hooks/useIsTradingActive.tsx b/src/components/MultiHopTrade/hooks/useIsTradingActive.tsx
index 123e08ca80d..ebd76c0f5d3 100644
--- a/src/components/MultiHopTrade/hooks/useIsTradingActive.tsx
+++ b/src/components/MultiHopTrade/hooks/useIsTradingActive.tsx
@@ -1,71 +1,57 @@
-import { useEffect, useState } from 'react'
+import { useQuery } from '@tanstack/react-query'
+import { reactQueries } from 'react-queries'
import type { ThorEvmTradeQuote } from 'lib/swapper/swappers/ThorchainSwapper/getThorTradeQuote/getTradeQuote'
import { TradeType } from 'lib/swapper/swappers/ThorchainSwapper/utils/longTailHelpers'
-import { swapperApi } from 'state/apis/swapper/swapperApi'
import { selectInputBuyAsset, selectInputSellAsset } from 'state/slices/tradeInputSlice/selectors'
import { selectActiveQuote, selectActiveSwapperName } from 'state/slices/tradeQuoteSlice/selectors'
-import { useAppDispatch, useAppSelector } from 'state/store'
+import { useAppSelector } from 'state/store'
export const useIsTradingActive = () => {
const activeQuote = useAppSelector(selectActiveQuote)
const tradeType = (activeQuote as ThorEvmTradeQuote)?.tradeType
- const [isTradingActiveOnSellPool, setIsTradingActiveOnSellPool] = useState(false)
- const [isTradingActiveOnBuyPool, setIsTradingActiveOnBuyPool] = useState(false)
-
- const dispatch = useAppDispatch()
-
const buyAssetId = useAppSelector(selectInputBuyAsset).assetId
const sellAssetId = useAppSelector(selectInputSellAsset).assetId
- const { getIsTradingActive } = swapperApi.endpoints
const swapperName = useAppSelector(selectActiveSwapperName)
- useEffect(() => {
- ;(async () => {
- const isTradingActiveOnSellPoolResult =
- sellAssetId &&
- swapperName &&
- (
- await dispatch(
- getIsTradingActive.initiate({
- assetId: sellAssetId,
- swapperName,
- }),
- )
- ).data
-
- setIsTradingActiveOnSellPool(!!isTradingActiveOnSellPoolResult)
- })()
- }, [dispatch, getIsTradingActive, sellAssetId, swapperName])
-
- useEffect(() => {
- ;(async () => {
- const isTradingActiveOnBuyPoolResult =
- buyAssetId &&
- swapperName &&
- (
- await dispatch(
- getIsTradingActive.initiate({
- assetId: buyAssetId,
- swapperName,
- }),
- )
- ).data
-
- setIsTradingActiveOnBuyPool(!!isTradingActiveOnBuyPoolResult)
- })()
- }, [buyAssetId, dispatch, getIsTradingActive, swapperName])
+ const { data: isTradingActiveOnSellPool } = useQuery({
+ ...reactQueries.common.isTradingActive({
+ assetId: sellAssetId,
+ swapperName,
+ }),
+ // @lukemorales/query-key-factory only returns queryFn and queryKey - all others will be ignored in the returned object
+ // Go stale instantly
+ staleTime: 0,
+ // Never store queries in cache since we always want fresh data
+ gcTime: 0,
+ refetchOnWindowFocus: true,
+ refetchOnMount: true,
+ refetchInterval: 60_000,
+ })
+
+ const { data: isTradingActiveOnBuyPool } = useQuery({
+ ...reactQueries.common.isTradingActive({
+ assetId: buyAssetId,
+ swapperName,
+ }),
+ // @lukemorales/query-key-factory only returns queryFn and queryKey - all others will be ignored in the returned object
+ // Go stale instantly
+ // Never store queries in cache since we always want fresh data
+ refetchOnWindowFocus: true,
+ refetchOnMount: true,
+ refetchInterval: 60_000,
+ })
return {
isTradingActiveOnSellPool:
tradeType === TradeType.L1ToL1 || tradeType === TradeType.L1ToLongTail
- ? isTradingActiveOnSellPool
+ ? Boolean(isTradingActiveOnSellPool)
: true,
isTradingActiveOnBuyPool:
tradeType === TradeType.L1ToL1 || tradeType === TradeType.LongTailToL1
- ? isTradingActiveOnBuyPool
+ ? Boolean(isTradingActiveOnBuyPool)
: true,
- isTradingActive: isTradingActiveOnSellPool && isTradingActiveOnBuyPool,
+ isTradingActive: Boolean(isTradingActiveOnSellPool && isTradingActiveOnBuyPool),
}
}
diff --git a/src/react-queries/index.ts b/src/react-queries/index.ts
index 27acd90d49c..2ce0a6eab33 100644
--- a/src/react-queries/index.ts
+++ b/src/react-queries/index.ts
@@ -70,11 +70,12 @@ const common = createQueryKeys('common', {
swapperName,
}: {
assetId: AssetId | undefined
- swapperName: SwapperName
+ swapperName: SwapperName | undefined
}) => ({
queryKey: ['isTradingActive', assetId, swapperName],
queryFn: async () => {
if (!assetId) throw new Error('assetId is required')
+ if (!swapperName) throw new Error('swapperName is required')
const maybeIsTradingActive = await isTradingActive(assetId, swapperName)
diff --git a/src/state/apis/swapper/swapperApi.ts b/src/state/apis/swapper/swapperApi.ts
index a4f292cfc15..9d490f5c549 100644
--- a/src/state/apis/swapper/swapperApi.ts
+++ b/src/state/apis/swapper/swapperApi.ts
@@ -1,7 +1,8 @@
import { createApi } from '@reduxjs/toolkit/dist/query/react'
import type { ChainId } from '@shapeshiftoss/caip'
import { type AssetId, fromAssetId } from '@shapeshiftoss/caip'
-import type { SwapperName } from '@shapeshiftoss/swapper'
+import { reactQueries } from 'react-queries'
+import { queryClient } from 'context/QueryClientProvider/queryClient'
import {
getSupportedBuyAssetIds,
getSupportedSellAssetIds,
@@ -21,36 +22,15 @@ import { selectFeatureFlags } from 'state/slices/preferencesSlice/selectors'
import { selectInputSellAsset } from 'state/slices/tradeInputSlice/selectors'
import { BASE_RTK_CREATE_API_CONFIG } from '../const'
-import { apiErrorHandler } from '../utils'
-import { isTradingActive } from './helpers'
import { validateTradeQuote } from './helpers/validateTradeQuote'
-const getIsTradingActiveErrorHandler = apiErrorHandler(
- 'getIsTradingActiveApi: error getting trading status',
-)
-
export const GET_TRADE_QUOTE_POLLING_INTERVAL = 20_000
export const swapperApiBase = createApi({
...BASE_RTK_CREATE_API_CONFIG,
reducerPath: 'swapperApi',
keepUnusedDataFor: Number.MAX_SAFE_INTEGER, // never clear, we will manage this
tagTypes: ['TradeQuote'],
- endpoints: build => ({
- getIsTradingActive: build.query<
- boolean,
- { assetId: AssetId | undefined; swapperName: SwapperName }
- >({
- queryFn: async ({ assetId, swapperName }) => {
- const maybeIsTradingActive = await isTradingActive(assetId, swapperName)
- if (maybeIsTradingActive.isErr()) {
- return getIsTradingActiveErrorHandler(maybeIsTradingActive.unwrapErr())
- }
- return {
- data: maybeIsTradingActive.unwrap(),
- }
- },
- }),
- }),
+ endpoints: () => ({}),
})
export const swapperApi = swapperApiBase.injectEndpoints({
@@ -128,17 +108,13 @@ export const swapperApi = swapperApiBase.injectEndpoints({
return { isTradingActiveOnSellPool: false, isTradingActiveOnBuyPool: false }
}
- const [{ data: isTradingActiveOnSellPool }, { data: isTradingActiveOnBuyPool }] =
- await Promise.all(
- [sellAsset.assetId, buyAsset.assetId].map(assetId => {
- return dispatch(
- swapperApiBase.endpoints.getIsTradingActive.initiate({
- assetId,
- swapperName,
- }),
- )
- }),
- )
+ const [isTradingActiveOnSellPool, isTradingActiveOnBuyPool] = await Promise.all(
+ [sellAsset.assetId, buyAsset.assetId].map(assetId => {
+ return queryClient.fetchQuery(
+ reactQueries.common.isTradingActive({ assetId, swapperName }),
+ )
+ }),
+ )
return {
isTradingActiveOnSellPool:
tradeType === TradeType.LongTailToL1 || isTradingActiveOnSellPool,
From 2fad5f81adf31406ece47cc16a4601c1b5e39e95 Mon Sep 17 00:00:00 2001
From: gomes <17035424+gomesalexandre@users.noreply.github.com>
Date: Fri, 9 Feb 2024 00:02:10 +0100
Subject: [PATCH 06/33] feat: safety
---
src/components/MultiHopTrade/hooks/useIsTradingActive.tsx | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/components/MultiHopTrade/hooks/useIsTradingActive.tsx b/src/components/MultiHopTrade/hooks/useIsTradingActive.tsx
index ebd76c0f5d3..5aee74fd996 100644
--- a/src/components/MultiHopTrade/hooks/useIsTradingActive.tsx
+++ b/src/components/MultiHopTrade/hooks/useIsTradingActive.tsx
@@ -20,6 +20,7 @@ export const useIsTradingActive = () => {
assetId: sellAssetId,
swapperName,
}),
+ enabled: !!swapperName,
// @lukemorales/query-key-factory only returns queryFn and queryKey - all others will be ignored in the returned object
// Go stale instantly
staleTime: 0,
@@ -35,6 +36,7 @@ export const useIsTradingActive = () => {
assetId: buyAssetId,
swapperName,
}),
+ enabled: !!swapperName,
// @lukemorales/query-key-factory only returns queryFn and queryKey - all others will be ignored in the returned object
// Go stale instantly
// Never store queries in cache since we always want fresh data
From b1380a8790ad60bb418efcd14136718f3f3fa889 Mon Sep 17 00:00:00 2001
From: gomes <17035424+gomesalexandre@users.noreply.github.com>
Date: Fri, 9 Feb 2024 00:15:29 +0100
Subject: [PATCH 07/33] [skip ci] wip: query-key-factory shenanigans
---
.../components/AddLiquitity/AddLiquidityInput.tsx | 8 ++++++++
src/react-queries/index.ts | 5 -----
2 files changed, 8 insertions(+), 5 deletions(-)
diff --git a/src/pages/ThorChainLP/components/AddLiquitity/AddLiquidityInput.tsx b/src/pages/ThorChainLP/components/AddLiquitity/AddLiquidityInput.tsx
index 525d7191edb..119d5d1b66c 100644
--- a/src/pages/ThorChainLP/components/AddLiquitity/AddLiquidityInput.tsx
+++ b/src/pages/ThorChainLP/components/AddLiquitity/AddLiquidityInput.tsx
@@ -458,6 +458,14 @@ export const AddLiquidityInput: React.FC = ({
inboundAddressData?.router,
poolAssetAccountAddress,
),
+ enabled: Boolean(
+ poolAsset?.assetId &&
+ inboundAddressData?.router &&
+ poolAssetAccountAddress &&
+ getSupportedEvmChainIds().includes(
+ fromAssetId(poolAsset?.assetId).chainId as KnownChainIds,
+ ),
+ ),
})
const isApprovalRequired = useMemo(() => {
diff --git a/src/react-queries/index.ts b/src/react-queries/index.ts
index 2ce0a6eab33..7224f58b2b3 100644
--- a/src/react-queries/index.ts
+++ b/src/react-queries/index.ts
@@ -59,11 +59,6 @@ const common = createQueryKeys('common', {
return allowanceOnChainCryptoBaseUnit
},
- enabled:
- assetId &&
- spender &&
- from &&
- getSupportedEvmChainIds().includes(fromAssetId(assetId).chainId as KnownChainIds),
}),
isTradingActive: ({
assetId,
From a1019fdb08c193f0da0568f7c340c772aaef5a1e Mon Sep 17 00:00:00 2001
From: gomes <17035424+gomesalexandre@users.noreply.github.com>
Date: Fri, 9 Feb 2024 09:46:16 +0100
Subject: [PATCH 08/33] [skip ci] feat: swapData query
---
src/pages/ThorChainLP/AvailablePools.tsx | 2 ++
src/pages/ThorChainLP/Pool/Pool.tsx | 9 +++++++++
src/pages/ThorChainLP/Position/Position.tsx | 9 +++++++++
src/react-queries/index.ts | 3 ---
4 files changed, 20 insertions(+), 3 deletions(-)
diff --git a/src/pages/ThorChainLP/AvailablePools.tsx b/src/pages/ThorChainLP/AvailablePools.tsx
index f6a379abe97..48e5e643ed8 100644
--- a/src/pages/ThorChainLP/AvailablePools.tsx
+++ b/src/pages/ThorChainLP/AvailablePools.tsx
@@ -89,6 +89,8 @@ const PoolButton = ({ pool }: PoolButtonProps) => {
const { data: volume7D, isLoading: isVolume7DLoading } = useQuery({
...reactQueries.midgard.swapsData(pool.assetId, '7d'),
+ // @lukemorales/query-key-factory only returns queryFn and queryKey - all others will be ignored in the returned object
+ staleTime: Infinity,
select: data => getVolume(runeMarketData.price, data),
})
diff --git a/src/pages/ThorChainLP/Pool/Pool.tsx b/src/pages/ThorChainLP/Pool/Pool.tsx
index 7850ce6d594..693213f6e60 100644
--- a/src/pages/ThorChainLP/Pool/Pool.tsx
+++ b/src/pages/ThorChainLP/Pool/Pool.tsx
@@ -144,15 +144,24 @@ export const Pool = () => {
const { data: volume24h } = useQuery({
...reactQueries.midgard.swapsData(foundPool?.assetId, '24h'),
+ // @lukemorales/query-key-factory only returns queryFn and queryKey - all others will be ignored in the returned object
+ staleTime: Infinity,
+ enabled: !!foundPool?.assetId,
select: data => getVolume(runeMarketData.price, data),
})
const { data: swapDataPrevious24h } = useQuery({
...reactQueries.midgard.swapsData(foundPool?.assetId, 'previous24h'),
+ // @lukemorales/query-key-factory only returns queryFn and queryKey - all others will be ignored in the returned object
+ staleTime: Infinity,
+ enabled: !!foundPool?.assetId,
})
const { data: swapData24h } = useQuery({
...reactQueries.midgard.swapsData(foundPool?.assetId, '24h'),
+ // @lukemorales/query-key-factory only returns queryFn and queryKey - all others will be ignored in the returned object
+ staleTime: Infinity,
+ enabled: !!foundPool?.assetId,
})
const fees24h = useMemo(() => {
diff --git a/src/pages/ThorChainLP/Position/Position.tsx b/src/pages/ThorChainLP/Position/Position.tsx
index b23680e2c45..4cb058ad5f3 100644
--- a/src/pages/ThorChainLP/Position/Position.tsx
+++ b/src/pages/ThorChainLP/Position/Position.tsx
@@ -177,10 +177,16 @@ export const Position = () => {
const { data: swapDataPrevious24h } = useQuery({
...reactQueries.midgard.swapsData(foundPool?.assetId, 'previous24h'),
+ // @lukemorales/query-key-factory only returns queryFn and queryKey - all others will be ignored in the returned object
+ staleTime: Infinity,
+ enabled: !!foundPool?.assetId,
})
const { data: swapData24h } = useQuery({
...reactQueries.midgard.swapsData(foundPool?.assetId, '24h'),
+ // @lukemorales/query-key-factory only returns queryFn and queryKey - all others will be ignored in the returned object
+ staleTime: Infinity,
+ enabled: !!foundPool?.assetId,
})
const fees24h = useMemo(() => {
@@ -192,6 +198,9 @@ export const Position = () => {
const { data: volume24h } = useQuery({
...reactQueries.midgard.swapsData(foundPool?.assetId, '24h'),
select: data => getVolume(runeMarketData.price, data),
+ // @lukemorales/query-key-factory only returns queryFn and queryKey - all others will be ignored in the returned object
+ staleTime: Infinity,
+ enabled: !!foundPool?.assetId,
})
const swap24hChange = useMemo(() => {
diff --git a/src/react-queries/index.ts b/src/react-queries/index.ts
index 7224f58b2b3..98f14e5e3d4 100644
--- a/src/react-queries/index.ts
+++ b/src/react-queries/index.ts
@@ -148,9 +148,6 @@ const mutations = createMutationKeys('mutations', {
// Feature-agnostic, abstracts away midgard endpoints
const midgard = createQueryKeys('midgard', {
swapsData: (assetId: AssetId | undefined, timeframe: '24h' | 'previous24h' | '7d') => ({
- // We may or may not want to revisit this, but this will prevent overfetching for now
- staleTime: Infinity,
- enabled: !!assetId,
queryKey: ['midgardSwapsData', assetId ?? '', timeframe],
queryFn: async () => {
if (!assetId) throw new Error('assetId is required')
From 7fd16135f0ec1e4631e42a8078ff1305ab1fadcb Mon Sep 17 00:00:00 2001
From: gomes <17035424+gomesalexandre@users.noreply.github.com>
Date: Fri, 9 Feb 2024 09:49:09 +0100
Subject: [PATCH 09/33] [skip ci] feat: midgard.poolData query
---
src/pages/ThorChainLP/queries/hooks/useUserLpData.ts | 6 +++++-
src/react-queries/index.ts | 3 ---
2 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/src/pages/ThorChainLP/queries/hooks/useUserLpData.ts b/src/pages/ThorChainLP/queries/hooks/useUserLpData.ts
index 024b6be2ae9..bcb23118570 100644
--- a/src/pages/ThorChainLP/queries/hooks/useUserLpData.ts
+++ b/src/pages/ThorChainLP/queries/hooks/useUserLpData.ts
@@ -37,6 +37,9 @@ export const useUserLpData = ({
const { data: midgardPoolData } = useQuery({
...reactQueries.midgard.poolData(assetId),
+ // @lukemorales/query-key-factory only returns queryFn and queryKey - all others will be ignored in the returned object
+ // 60 seconds staleTime since this is used to get the current position value
+ staleTime: 60_000,
})
const selectLiquidityPositionsData = (
@@ -104,7 +107,8 @@ export const useUserLpData = ({
const liquidityPoolPositionData = useQuery({
...reactQueries.thorchainLp.userLpData(assetId),
- staleTime: Infinity,
+ // 60 seconds staleTime since this is used to get the current position value
+ staleTime: 60_000,
queryFn: async ({ queryKey }) => {
const [, , , { assetId }] = queryKey
diff --git a/src/react-queries/index.ts b/src/react-queries/index.ts
index 98f14e5e3d4..b1b0b07e7f8 100644
--- a/src/react-queries/index.ts
+++ b/src/react-queries/index.ts
@@ -184,9 +184,6 @@ const midgard = createQueryKeys('midgard', {
},
}),
poolData: (assetId: AssetId | undefined) => ({
- // We may or may not want to revisit this, but this will prevent overfetching for now
- staleTime: Infinity,
- enabled: !!assetId,
queryKey: ['midgardPoolData', assetId],
queryFn: async () => {
if (!assetId) throw new Error('assetId is required')
From 2a0d339b432bc2a065ceac792e18777bbbc412a1 Mon Sep 17 00:00:00 2001
From: gomes <17035424+gomesalexandre@users.noreply.github.com>
Date: Fri, 9 Feb 2024 09:51:46 +0100
Subject: [PATCH 10/33] feat: midgard.poolsData and use 5mn staleTime
---
src/pages/ThorChainLP/queries/hooks/usePools.ts | 3 +++
src/react-queries/index.ts | 2 --
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/src/pages/ThorChainLP/queries/hooks/usePools.ts b/src/pages/ThorChainLP/queries/hooks/usePools.ts
index 34d9b219907..9a5066e4ed7 100644
--- a/src/pages/ThorChainLP/queries/hooks/usePools.ts
+++ b/src/pages/ThorChainLP/queries/hooks/usePools.ts
@@ -79,6 +79,9 @@ export const usePools = (excludeVirtualPools?: boolean) => {
)
const pools = useQuery({
...reactQueries.midgard.poolsData(),
+ // @lukemorales/query-key-factory only returns queryFn and queryKey - all others will be ignored in the returned object
+ // 5 minutes, since this is related to pools data, not user data - we can afford to have this stale for longer
+ staleTime: 60_000 * 5,
// Parses pools with 3 "positions" per pool:
// - RUNE asym
// - Asset asym
diff --git a/src/react-queries/index.ts b/src/react-queries/index.ts
index b1b0b07e7f8..32eef6a3c1c 100644
--- a/src/react-queries/index.ts
+++ b/src/react-queries/index.ts
@@ -196,8 +196,6 @@ const midgard = createQueryKeys('midgard', {
},
}),
poolsData: () => ({
- // We may or may not want to revisit this, but this will prevent overfetching for now
- staleTime: Infinity,
queryKey: ['midgardPoolsData'],
queryFn: async () => {
const { data: poolsData } = await axios.get(
From 041aca3c3e62cd0cfa6d88369dd3256ba0765036 Mon Sep 17 00:00:00 2001
From: gomes <17035424+gomesalexandre@users.noreply.github.com>
Date: Fri, 9 Feb 2024 09:54:04 +0100
Subject: [PATCH 11/33] feat: thornode.poolData
---
src/pages/ThorChainLP/queries/hooks/useUserLpData.ts | 10 ++++++++--
src/react-queries/index.ts | 3 ---
2 files changed, 8 insertions(+), 5 deletions(-)
diff --git a/src/pages/ThorChainLP/queries/hooks/useUserLpData.ts b/src/pages/ThorChainLP/queries/hooks/useUserLpData.ts
index bcb23118570..e3acba0d1bf 100644
--- a/src/pages/ThorChainLP/queries/hooks/useUserLpData.ts
+++ b/src/pages/ThorChainLP/queries/hooks/useUserLpData.ts
@@ -33,13 +33,19 @@ export const useUserLpData = ({
const { data: thornodePoolData } = useQuery({
...reactQueries.thornode.poolData(assetId),
+ // @lukemorales/query-key-factory only returns queryFn and queryKey - all others will be ignored in the returned object
+ // 0 seconds garbage collect and stale times since this is used to get the current position value, we want this to always be cached-then-fresh
+ staleTime: 0,
+ gcTime: 0,
+ enabled: !!assetId,
})
const { data: midgardPoolData } = useQuery({
...reactQueries.midgard.poolData(assetId),
// @lukemorales/query-key-factory only returns queryFn and queryKey - all others will be ignored in the returned object
- // 60 seconds staleTime since this is used to get the current position value
- staleTime: 60_000,
+ // 0 seconds garbage collect and stale times since this is used to get the current position value, we want this to always be cached-then-fresh
+ staleTime: 0,
+ gcTime: 0,
})
const selectLiquidityPositionsData = (
diff --git a/src/react-queries/index.ts b/src/react-queries/index.ts
index 32eef6a3c1c..51940a5ba90 100644
--- a/src/react-queries/index.ts
+++ b/src/react-queries/index.ts
@@ -209,9 +209,6 @@ const midgard = createQueryKeys('midgard', {
// Feature-agnostic, abstracts away THORNode endpoints
const thornode = createQueryKeys('thornode', {
poolData: (assetId: AssetId | undefined) => ({
- // We may or may not want to revisit this, but this will prevent overfetching for now
- staleTime: Infinity,
- enabled: !!assetId,
queryKey: ['thornodePoolData', assetId],
queryFn: async () => {
if (!assetId) throw new Error('assetId is required')
From 93334a161950b5147d735586bc00ee1bf2f7ebe9 Mon Sep 17 00:00:00 2001
From: gomes <17035424+gomesalexandre@users.noreply.github.com>
Date: Fri, 9 Feb 2024 10:35:45 +0100
Subject: [PATCH 12/33] feat: thornode.poolsData
---
src/pages/Lending/hooks/useLendingSupportedAssets/index.ts | 3 +++
src/pages/ThorChainLP/queries/hooks/useAllUserLpData.ts | 3 +++
src/react-queries/index.ts | 3 ---
.../opportunitiesSlice/resolvers/thorchainsavers/index.ts | 6 ++++++
4 files changed, 12 insertions(+), 3 deletions(-)
diff --git a/src/pages/Lending/hooks/useLendingSupportedAssets/index.ts b/src/pages/Lending/hooks/useLendingSupportedAssets/index.ts
index 04c706957c4..ba2e91645c5 100644
--- a/src/pages/Lending/hooks/useLendingSupportedAssets/index.ts
+++ b/src/pages/Lending/hooks/useLendingSupportedAssets/index.ts
@@ -23,6 +23,9 @@ export const useLendingSupportedAssets = ({ type }: { type: 'collateral' | 'borr
const { data: availablePools } = useQuery({
...reactQueries.thornode.poolsData(),
+ // @lukemorales/query-key-factory only returns queryFn and queryKey - all others will be ignored in the returned object
+ // Infinity staleTime as we handle halted state JIT
+ staleTime: Infinity,
select: pools => pools.filter(pool => pool.status === 'Available'),
})
diff --git a/src/pages/ThorChainLP/queries/hooks/useAllUserLpData.ts b/src/pages/ThorChainLP/queries/hooks/useAllUserLpData.ts
index 717fde3c143..a19f4340bd6 100644
--- a/src/pages/ThorChainLP/queries/hooks/useAllUserLpData.ts
+++ b/src/pages/ThorChainLP/queries/hooks/useAllUserLpData.ts
@@ -35,6 +35,9 @@ export const useAllUserLpData = ({
const { data: availableThornodePools, isSuccess: isAvailableThornodePoolsDataLoaded } = useQuery({
...reactQueries.thornode.poolsData(),
+ // @lukemorales/query-key-factory only returns queryFn and queryKey - all others will be ignored in the returned object
+ // Infinity staleTime as we handle halted state JIT
+ staleTime: Infinity,
select: pools => pools.filter(pool => pool.status === 'Available'),
})
diff --git a/src/react-queries/index.ts b/src/react-queries/index.ts
index 51940a5ba90..00c1db5517e 100644
--- a/src/react-queries/index.ts
+++ b/src/react-queries/index.ts
@@ -222,9 +222,6 @@ const thornode = createQueryKeys('thornode', {
}),
poolsData: () => ({
queryKey: ['thornodePoolsData'],
- // Typically 60 second staleTime to handle pools going to live/halt states
- // This may not be required in your specific consumption, override if needed
- staleTime: 60_000,
queryFn: async () => {
const daemonUrl = getConfig().REACT_APP_THORCHAIN_NODE_URL
const poolResponse = await thorService.get(
diff --git a/src/state/slices/opportunitiesSlice/resolvers/thorchainsavers/index.ts b/src/state/slices/opportunitiesSlice/resolvers/thorchainsavers/index.ts
index be4b938339b..31afbebf211 100644
--- a/src/state/slices/opportunitiesSlice/resolvers/thorchainsavers/index.ts
+++ b/src/state/slices/opportunitiesSlice/resolvers/thorchainsavers/index.ts
@@ -34,6 +34,9 @@ export const thorchainSaversOpportunityIdsResolver = async (): Promise<{
}> => {
const thorchainPools = await queryClient.fetchQuery({
...reactQueries.thornode.poolsData(),
+ // @lukemorales/query-key-factory only returns queryFn and queryKey - all others will be ignored in the returned object
+ // Infinity staleTime as we handle halted state JIT
+ staleTime: Infinity,
})
if (!thorchainPools.length) {
@@ -92,6 +95,9 @@ export const thorchainSaversStakingOpportunitiesMetadataResolver = async ({
const thorchainPools = await queryClient.fetchQuery({
...reactQueries.thornode.poolsData(),
+ // @lukemorales/query-key-factory only returns queryFn and queryKey - all others will be ignored in the returned object
+ // Infinity staleTime as we handle halted state JIT
+ staleTime: Infinity,
})
if (!thorchainPools.length) {
From 9b4f215d005db1194565a3d91f0d8da707d5ab53 Mon Sep 17 00:00:00 2001
From: gomes <17035424+gomesalexandre@users.noreply.github.com>
Date: Fri, 9 Feb 2024 10:37:38 +0100
Subject: [PATCH 13/33] feat: thornode.mimir
---
src/pages/Lending/hooks/useRepaymentLockData.tsx | 11 +++++++++--
src/react-queries/index.ts | 7 -------
2 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/src/pages/Lending/hooks/useRepaymentLockData.tsx b/src/pages/Lending/hooks/useRepaymentLockData.tsx
index 7906b658585..dc867cd55cd 100644
--- a/src/pages/Lending/hooks/useRepaymentLockData.tsx
+++ b/src/pages/Lending/hooks/useRepaymentLockData.tsx
@@ -2,8 +2,8 @@ import type { AccountId, AssetId } from '@shapeshiftoss/caip'
import type { QueryObserverOptions } from '@tanstack/react-query'
import { useQuery } from '@tanstack/react-query'
import { useMemo } from 'react'
-import { reactQueries, thorchainBlockTimeSeconds } from 'react-queries'
-import { bnOrZero } from 'lib/bignumber/bignumber'
+import { reactQueries } from 'react-queries'
+import { bn, bnOrZero } from 'lib/bignumber/bignumber'
import { thorchainLendingPositionQueryFn } from './useLendingPositionData'
@@ -12,6 +12,10 @@ type UseLendingPositionDataProps = {
assetId?: AssetId
}
+// Current blocktime as per https://thorchain.network/stats
+export const thorchainBlockTimeSeconds = '6.1'
+
+const thorchainBlockTimeMs = bn(thorchainBlockTimeSeconds).times(1000).toNumber()
export const useRepaymentLockData = ({
accountId,
assetId,
@@ -44,6 +48,9 @@ export const useRepaymentLockData = ({
const repaymentLockData = useQuery({
...reactQueries.thornode.mimir(),
+ // @lukemorales/query-key-factory only returns queryFn and queryKey - all others will be ignored in the returned object
+ // We use the mimir query to get the repayment maturity block, so need to mark it stale at the end of each THOR block
+ staleTime: thorchainBlockTimeMs,
select: mimirData => {
if (!mimirData || !blockHeight) return null
diff --git a/src/react-queries/index.ts b/src/react-queries/index.ts
index 00c1db5517e..0a0b4731805 100644
--- a/src/react-queries/index.ts
+++ b/src/react-queries/index.ts
@@ -7,7 +7,6 @@ import type { SwapperName } from '@shapeshiftoss/swapper'
import type { KnownChainIds } from '@shapeshiftoss/types'
import axios from 'axios'
import { getConfig } from 'config'
-import { bn } from 'lib/bignumber/bignumber'
import type {
MidgardPoolResponse,
ThornodePoolResponse,
@@ -29,10 +28,6 @@ import type { MidgardSwapHistoryResponse } from 'lib/utils/thorchain/lp/types'
import { thorchainLp } from 'pages/ThorChainLP/queries/queries'
import { isTradingActive } from 'state/apis/swapper/helpers'
-// Current blocktime as per https://thorchain.network/stats
-export const thorchainBlockTimeSeconds = '6.1'
-const thorchainBlockTimeMs = bn(thorchainBlockTimeSeconds).times(1000).toNumber()
-
const common = createQueryKeys('common', {
allowanceCryptoBaseUnit: (
assetId: AssetId | undefined,
@@ -237,8 +232,6 @@ const thornode = createQueryKeys('thornode', {
}),
mimir: () => {
return {
- // We use the mimir query to get the repayment maturity block, so need to mark it stale at the end of each THOR block
- staleTime: thorchainBlockTimeMs,
queryKey: ['thorchainMimir'],
queryFn: async () => {
const daemonUrl = getConfig().REACT_APP_THORCHAIN_NODE_URL
From 0325f7cbb2881e0f776abeb260ad33e2162fbbe1 Mon Sep 17 00:00:00 2001
From: gomes <17035424+gomesalexandre@users.noreply.github.com>
Date: Fri, 9 Feb 2024 10:38:51 +0100
Subject: [PATCH 14/33] feat: thornode.block
---
src/pages/Lending/hooks/useRepaymentLockData.tsx | 3 +++
src/react-queries/index.ts | 2 --
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/src/pages/Lending/hooks/useRepaymentLockData.tsx b/src/pages/Lending/hooks/useRepaymentLockData.tsx
index dc867cd55cd..d1cf0368cf6 100644
--- a/src/pages/Lending/hooks/useRepaymentLockData.tsx
+++ b/src/pages/Lending/hooks/useRepaymentLockData.tsx
@@ -24,6 +24,9 @@ export const useRepaymentLockData = ({
enabled = true,
}: UseLendingPositionDataProps & QueryObserverOptions) => {
const { data: blockHeight } = useQuery({
+ // @lukemorales/query-key-factory only returns queryFn and queryKey - all others will be ignored in the returned object
+ // We use the block query to get the current height, so we obviously need to mark it stale at the end of each THOR block
+ staleTime: thorchainBlockTimeMs,
...reactQueries.thornode.block(),
select: block => block.header.height,
enabled,
diff --git a/src/react-queries/index.ts b/src/react-queries/index.ts
index 0a0b4731805..0b9cb741061 100644
--- a/src/react-queries/index.ts
+++ b/src/react-queries/index.ts
@@ -245,8 +245,6 @@ const thornode = createQueryKeys('thornode', {
},
block: () => {
return {
- // Mark blockHeight query as stale at the end of each THOR block
- staleTime: thorchainBlockTimeMs,
queryKey: ['thorchainBlockHeight'],
queryFn: async () => {
const daemonUrl = getConfig().REACT_APP_THORCHAIN_NODE_URL
From 60a2ee00045bb20ef80a45cac322c603211d0f0e Mon Sep 17 00:00:00 2001
From: gomes <17035424+gomesalexandre@users.noreply.github.com>
Date: Fri, 9 Feb 2024 10:52:25 +0100
Subject: [PATCH 15/33] feat: thornode.inboundAddress
---
.../components/ReusableLpStatus/TransactionRow.tsx | 5 +++++
src/react-queries/index.ts | 1 -
2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/src/pages/ThorChainLP/components/ReusableLpStatus/TransactionRow.tsx b/src/pages/ThorChainLP/components/ReusableLpStatus/TransactionRow.tsx
index 2091aa1f4a7..26a218bc8ba 100644
--- a/src/pages/ThorChainLP/components/ReusableLpStatus/TransactionRow.tsx
+++ b/src/pages/ThorChainLP/components/ReusableLpStatus/TransactionRow.tsx
@@ -260,6 +260,11 @@ export const TransactionRow: React.FC = ({
const { data: inboundAddressData, isLoading: isInboundAddressLoading } = useQuery({
...reactQueries.thornode.inboundAddress(assetId),
enabled: !!assetId,
+ // @lukemorales/query-key-factory only returns queryFn and queryKey - all others will be ignored in the returned object
+ // We technically don't care about going stale immediately here - halted checks are done JIT at signing time in case the pool went
+ // halted by the time the user clicked the confirm button
+ // But we still have some sane 60s stale time rather than 0 for paranoia's sake, as a balance of safety and not overfetching
+ staleTime: 60_000,
select: data => data?.unwrap(),
})
diff --git a/src/react-queries/index.ts b/src/react-queries/index.ts
index 0b9cb741061..74c027f8976 100644
--- a/src/react-queries/index.ts
+++ b/src/react-queries/index.ts
@@ -257,7 +257,6 @@ const thornode = createQueryKeys('thornode', {
},
inboundAddress: (assetId: AssetId | undefined) => {
return {
- staleTime: 60_000, // 60 seconds to handle pools going to/from live/halt states
queryKey: ['thorchainInboundAddress', assetId],
queryFn: async () => {
if (!assetId) throw new Error('assetId is required')
From 2439281e1da045ee985b8dcc6ce9bf4dcb546243 Mon Sep 17 00:00:00 2001
From: gomes <17035424+gomesalexandre@users.noreply.github.com>
Date: Fri, 9 Feb 2024 11:01:08 +0100
Subject: [PATCH 16/33] feat: thorchainLp.earnings
---
src/pages/ThorChainLP/YourPositions.tsx | 4 ++++
src/pages/ThorChainLP/queries/queries.ts | 3 ---
2 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/src/pages/ThorChainLP/YourPositions.tsx b/src/pages/ThorChainLP/YourPositions.tsx
index 25e1f76edc3..a4d8f6d5491 100644
--- a/src/pages/ThorChainLP/YourPositions.tsx
+++ b/src/pages/ThorChainLP/YourPositions.tsx
@@ -92,6 +92,10 @@ const PositionButton = ({
const { data: earnings, isLoading: isEarningsLoading } = useQuery({
...reactQueries.thorchainLp.earnings(userPoolData.dateFirstAdded),
+ // @lukemorales/query-key-factory only returns queryFn and queryKey - all others will be ignored in the returned object
+ // No staleTime, meaning cache-then-fresh (or fresh if now > garbage collection time)
+ // That ensures new active listeners always get fresh earnings data
+ staleTime: 0,
select: data => {
if (!data) return null
const poolAssetId = assetIdToPoolAssetId({ assetId })
diff --git a/src/pages/ThorChainLP/queries/queries.ts b/src/pages/ThorChainLP/queries/queries.ts
index 685780081a8..da6c7cd11ad 100644
--- a/src/pages/ThorChainLP/queries/queries.ts
+++ b/src/pages/ThorChainLP/queries/queries.ts
@@ -54,9 +54,6 @@ export const liquidityMembers = () => ({
export const thorchainLp = createQueryKeys('thorchainLp', {
earnings: (from: string | undefined) => ({
- enabled: Boolean(from),
- // We may or may not want to revisit this, but this will prevent overfetching for now
- staleTime: Infinity,
queryKey: ['thorchainearnings', from],
queryFn: () => {
if (!from) throw new Error('from is required')
From cbbfbbb6e20a962f707132d7e1a824a0a9f3d34d Mon Sep 17 00:00:00 2001
From: gomes <17035424+gomesalexandre@users.noreply.github.com>
Date: Fri, 9 Feb 2024 11:01:40 +0100
Subject: [PATCH 17/33] feat: thorchainLp.tvl24hChange
---
src/pages/ThorChainLP/Position/Position.tsx | 1 +
src/pages/ThorChainLP/queries/queries.ts | 1 -
2 files changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/pages/ThorChainLP/Position/Position.tsx b/src/pages/ThorChainLP/Position/Position.tsx
index 4cb058ad5f3..a14424a03ee 100644
--- a/src/pages/ThorChainLP/Position/Position.tsx
+++ b/src/pages/ThorChainLP/Position/Position.tsx
@@ -216,6 +216,7 @@ export const Position = () => {
const { data: tvl24hChange } = useQuery({
...reactQueries.thorchainLp.tvl24hChange(foundPool?.assetId),
+ enabled: !!foundPool?.assetId,
})
const { data: allTimeVolume } = useQuery({
diff --git a/src/pages/ThorChainLP/queries/queries.ts b/src/pages/ThorChainLP/queries/queries.ts
index da6c7cd11ad..20e5441506d 100644
--- a/src/pages/ThorChainLP/queries/queries.ts
+++ b/src/pages/ThorChainLP/queries/queries.ts
@@ -66,7 +66,6 @@ export const thorchainLp = createQueryKeys('thorchainLp', {
if (!assetId) throw new Error('assetId is required')
return get24hTvlChangePercentage(assetId)
},
- enabled: !!assetId,
}),
allTimeVolume: (assetId: AssetId | undefined, runePrice: string) => ({
queryKey: ['thorchainAllTimeVolume', assetId],
From dbf0818346821ded339330c6931a33ba555ca3ea Mon Sep 17 00:00:00 2001
From: gomes <17035424+gomesalexandre@users.noreply.github.com>
Date: Fri, 9 Feb 2024 11:02:35 +0100
Subject: [PATCH 18/33] feat: thorchainLp.allTimeVolume
---
src/pages/ThorChainLP/Position/Position.tsx | 2 ++
src/pages/ThorChainLP/queries/queries.ts | 1 -
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/pages/ThorChainLP/Position/Position.tsx b/src/pages/ThorChainLP/Position/Position.tsx
index a14424a03ee..84211013c0d 100644
--- a/src/pages/ThorChainLP/Position/Position.tsx
+++ b/src/pages/ThorChainLP/Position/Position.tsx
@@ -29,6 +29,7 @@ import { AssetIcon } from 'components/AssetIcon'
import { DynamicComponent } from 'components/DynamicComponent'
import { Main } from 'components/Layout/Main'
import { RawText, Text } from 'components/Text'
+import { bnOrZero } from 'lib/bignumber/bignumber'
import { assetIdToPoolAssetId } from 'lib/swapper/swappers/ThorchainSwapper/utils/poolAssetHelpers/poolAssetHelpers'
import {
calculateEarnings,
@@ -221,6 +222,7 @@ export const Position = () => {
const { data: allTimeVolume } = useQuery({
...reactQueries.thorchainLp.allTimeVolume(foundPool?.assetId, runeMarketData.price),
+ enabled: Boolean(!!foundPool?.assetId && !!bnOrZero(runeMarketData.price).gt(0)),
})
const { data: thornodePoolData } = useQuery({
diff --git a/src/pages/ThorChainLP/queries/queries.ts b/src/pages/ThorChainLP/queries/queries.ts
index 20e5441506d..0f9afab3ec6 100644
--- a/src/pages/ThorChainLP/queries/queries.ts
+++ b/src/pages/ThorChainLP/queries/queries.ts
@@ -73,7 +73,6 @@ export const thorchainLp = createQueryKeys('thorchainLp', {
if (!assetId) throw new Error('assetId is required')
return getAllTimeVolume(assetId, runePrice)
},
- enabled: !!assetId && !!runePrice,
}),
liquidityMembers,
liquidityMember,
From 92b73b1f3e7312e94df32d2faa139f0b116eec9e Mon Sep 17 00:00:00 2001
From: gomes <17035424+gomesalexandre@users.noreply.github.com>
Date: Fri, 9 Feb 2024 11:06:14 +0100
Subject: [PATCH 19/33] feat: thorchainLp.liquidityProviderPosition
---
src/pages/ThorChainLP/queries/queries.ts | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/src/pages/ThorChainLP/queries/queries.ts b/src/pages/ThorChainLP/queries/queries.ts
index 0f9afab3ec6..ccd69f1e74c 100644
--- a/src/pages/ThorChainLP/queries/queries.ts
+++ b/src/pages/ThorChainLP/queries/queries.ts
@@ -87,10 +87,6 @@ export const thorchainLp = createQueryKeys('thorchainLp', {
assetId: AssetId
}) => {
return {
- // Since this isn't a query per se but rather a fetching util deriving from multiple queries, we want data to be considered stale immediately
- // Note however that the two underlying liquidityMember and liquidityMembers queries in this query *have* an Infinity staleTime themselves
- staleTime: 0,
- enabled: !!accountId && !!assetId,
queryKey: ['thorchainLiquidityProviderPosition', { accountId, assetId }],
queryFn: async () => {
const accountPosition = await (async () => {
@@ -139,9 +135,13 @@ export const getThorchainLpPosition = async ({
}) => {
if (!opportunityId) throw new Error('opportunityId is required')
- const lpPositions = await queryClient.fetchQuery(
- thorchainLp.liquidityProviderPosition({ accountId, assetId: poolAssetId }),
- )
+ const lpPositions = await queryClient.fetchQuery({
+ ...thorchainLp.liquidityProviderPosition({ accountId, assetId: poolAssetId }),
+ // @lukemorales/query-key-factory only returns queryFn and queryKey - all others will be ignored in the returned object
+ // Since this isn't a query per se but rather a fetching util deriving from multiple queries, we want data to be considered stale immediately
+ // Note however that the two underlying liquidityMember and liquidityMembers queries in this query *have* an Infinity staleTime themselves
+ staleTime: 0,
+ })
if (!lpPositions) return null
From 6c2be01af9344a75d40d767f35a60d69a2486f62 Mon Sep 17 00:00:00 2001
From: gomes <17035424+gomesalexandre@users.noreply.github.com>
Date: Fri, 9 Feb 2024 11:08:18 +0100
Subject: [PATCH 20/33] feat: commentary
---
src/pages/ThorChainLP/queries/queries.ts | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/src/pages/ThorChainLP/queries/queries.ts b/src/pages/ThorChainLP/queries/queries.ts
index ccd69f1e74c..878dccb9a8d 100644
--- a/src/pages/ThorChainLP/queries/queries.ts
+++ b/src/pages/ThorChainLP/queries/queries.ts
@@ -16,6 +16,8 @@ import {
} from 'lib/utils/thorchain/lp/types'
import { isUtxoChainId } from 'state/slices/portfolioSlice/utils'
+// Note: since this isn't consumes as part of reactQueries queries, but directly as a regular function call within this file,
+// the additional property on top of queryKey and queryFn (i.e staleTime) *is* working
const liquidityMember = (address: string) => ({
queryKey: ['thorchainLiquidityMember', { address }] as [string, { address: string }],
// Don't forget to invalidate me alongside thorchainUserLpData if you want to refresh the data
@@ -39,6 +41,8 @@ const liquidityMember = (address: string) => ({
},
})
+// Note: since this isn't consumes as part of reactQueries queries, but directly as a regular function call within this file,
+// the additional property on top of queryKey and queryFn (i.e staleTime) *is* working
export const liquidityMembers = () => ({
queryKey: ['thorchainLiquidityMembers'] as [string],
// Don't forget to invalidate me alongside thorchainUserLpData if you want to refresh the data
From ad8137d9b39de03371072b8b28a7a07c05b60285 Mon Sep 17 00:00:00 2001
From: gomes <17035424+gomesalexandre@users.noreply.github.com>
Date: Fri, 9 Feb 2024 12:06:41 +0100
Subject: [PATCH 21/33] wip: closer to network queries
---
.../hooks/useIsTradingActive.tsx | 94 ++++++++++++++-----
src/lib/utils/thorchain/constants.ts | 6 ++
.../Lending/hooks/useRepaymentLockData.tsx | 7 +-
src/pages/ThorChainLP/AvailablePools.tsx | 29 ++++--
src/pages/ThorChainLP/Pool/Pool.tsx | 35 +++++--
.../AddLiquitity/AddLiquidityInput.tsx | 73 ++++++++------
.../ReusableLpStatus/TransactionRow.tsx | 46 +++++----
src/react-queries/index.ts | 44 ++++-----
src/react-queries/selectors/index.ts | 57 +++++++++++
src/state/apis/swapper/helpers.test.ts | 22 ++++-
src/state/apis/swapper/helpers.ts | 49 ----------
11 files changed, 287 insertions(+), 175 deletions(-)
create mode 100644 src/react-queries/selectors/index.ts
delete mode 100644 src/state/apis/swapper/helpers.ts
diff --git a/src/components/MultiHopTrade/hooks/useIsTradingActive.tsx b/src/components/MultiHopTrade/hooks/useIsTradingActive.tsx
index 5aee74fd996..a23bfb019bd 100644
--- a/src/components/MultiHopTrade/hooks/useIsTradingActive.tsx
+++ b/src/components/MultiHopTrade/hooks/useIsTradingActive.tsx
@@ -1,7 +1,10 @@
import { useQuery } from '@tanstack/react-query'
+import { useMemo } from 'react'
import { reactQueries } from 'react-queries'
+import { selectInboundAddressData, selectIsTradingActive } from 'react-queries/selectors'
import type { ThorEvmTradeQuote } from 'lib/swapper/swappers/ThorchainSwapper/getThorTradeQuote/getTradeQuote'
import { TradeType } from 'lib/swapper/swappers/ThorchainSwapper/utils/longTailHelpers'
+import { thorchainBlockTimeMs } from 'lib/utils/thorchain/constants'
import { selectInputBuyAsset, selectInputSellAsset } from 'state/slices/tradeInputSlice/selectors'
import { selectActiveQuote, selectActiveSwapperName } from 'state/slices/tradeQuoteSlice/selectors'
import { useAppSelector } from 'state/store'
@@ -15,35 +18,78 @@ export const useIsTradingActive = () => {
const swapperName = useAppSelector(selectActiveSwapperName)
- const { data: isTradingActiveOnSellPool } = useQuery({
- ...reactQueries.common.isTradingActive({
- assetId: sellAssetId,
- swapperName,
- }),
+ const { data: sellAssetInboundAddressData, isLoading: isSellAssetInboundAddressLoading } =
+ useQuery({
+ ...reactQueries.thornode.inboundAddresses(),
+ // @lukemorales/query-key-factory only returns queryFn and queryKey - all others will be ignored in the returned object
+ // Go stale instantly
+ staleTime: 0,
+ // Never store queries in cache since we always want fresh data
+ gcTime: 0,
+ refetchOnWindowFocus: true,
+ refetchOnMount: true,
+ refetchInterval: 60_000,
+ select: data => selectInboundAddressData(data, sellAssetId),
+ enabled: Boolean(sellAssetId),
+ })
+
+ const { data: buyAssetInboundAddressData, isLoading: isBuyAssetInboundAddressLoading } = useQuery(
+ {
+ ...reactQueries.thornode.inboundAddresses(),
+ // @lukemorales/query-key-factory only returns queryFn and queryKey - all others will be ignored in the returned object
+ // Go stale instantly
+ staleTime: 0,
+ // Never store queries in cache since we always want fresh data
+ gcTime: 0,
+ refetchOnWindowFocus: true,
+ refetchOnMount: true,
+ refetchInterval: 60_000,
+ select: data => selectInboundAddressData(data, buyAssetId),
+ enabled: Boolean(buyAssetId),
+ },
+ )
+
+ const { data: mimir, isLoading: isMimirLoading } = useQuery({
+ ...reactQueries.thornode.mimir(),
+ staleTime: thorchainBlockTimeMs,
enabled: !!swapperName,
- // @lukemorales/query-key-factory only returns queryFn and queryKey - all others will be ignored in the returned object
- // Go stale instantly
- staleTime: 0,
- // Never store queries in cache since we always want fresh data
- gcTime: 0,
- refetchOnWindowFocus: true,
- refetchOnMount: true,
- refetchInterval: 60_000,
})
- const { data: isTradingActiveOnBuyPool } = useQuery({
- ...reactQueries.common.isTradingActive({
+ const isTradingActiveOnSellPool = useMemo(() => {
+ if (isSellAssetInboundAddressLoading || isMimirLoading || !mimir || !swapperName) return
+
+ return selectIsTradingActive({
+ assetId: sellAssetId,
+ inboundAddressResponse: sellAssetInboundAddressData,
+ swapperName,
+ mimir,
+ })
+ }, [
+ isSellAssetInboundAddressLoading,
+ isMimirLoading,
+ sellAssetId,
+ sellAssetInboundAddressData,
+ swapperName,
+ mimir,
+ ])
+
+ const isTradingActiveOnBuyPool = useMemo(() => {
+ if (isBuyAssetInboundAddressLoading || isMimirLoading || !mimir || !swapperName) return
+
+ return selectIsTradingActive({
assetId: buyAssetId,
+ inboundAddressResponse: buyAssetInboundAddressData,
swapperName,
- }),
- enabled: !!swapperName,
- // @lukemorales/query-key-factory only returns queryFn and queryKey - all others will be ignored in the returned object
- // Go stale instantly
- // Never store queries in cache since we always want fresh data
- refetchOnWindowFocus: true,
- refetchOnMount: true,
- refetchInterval: 60_000,
- })
+ mimir,
+ })
+ }, [
+ isBuyAssetInboundAddressLoading,
+ isMimirLoading,
+ buyAssetId,
+ buyAssetInboundAddressData,
+ swapperName,
+ mimir,
+ ])
return {
isTradingActiveOnSellPool:
diff --git a/src/lib/utils/thorchain/constants.ts b/src/lib/utils/thorchain/constants.ts
index eef232916e3..9a1d36a77f1 100644
--- a/src/lib/utils/thorchain/constants.ts
+++ b/src/lib/utils/thorchain/constants.ts
@@ -1,4 +1,10 @@
+import { bn } from 'lib/bignumber/bignumber'
+
export const THOR_PRECISION = 8
export const BASE_BPS_POINTS = '10000'
export const THORCHAIN_AFFILIATE_NAME = 'ss'
export const THORCHAIN_POOL_MODULE_ADDRESS = 'thor1g98cy3n9mmjrpn0sxmn63lztelera37n8n67c0'
+
+// Current blocktime as per https://thorchain.network/stats
+export const thorchainBlockTimeSeconds = '6.1'
+export const thorchainBlockTimeMs = bn(thorchainBlockTimeSeconds).times(1000).toNumber()
diff --git a/src/pages/Lending/hooks/useRepaymentLockData.tsx b/src/pages/Lending/hooks/useRepaymentLockData.tsx
index d1cf0368cf6..75fdc7dc2af 100644
--- a/src/pages/Lending/hooks/useRepaymentLockData.tsx
+++ b/src/pages/Lending/hooks/useRepaymentLockData.tsx
@@ -3,7 +3,8 @@ import type { QueryObserverOptions } from '@tanstack/react-query'
import { useQuery } from '@tanstack/react-query'
import { useMemo } from 'react'
import { reactQueries } from 'react-queries'
-import { bn, bnOrZero } from 'lib/bignumber/bignumber'
+import { bnOrZero } from 'lib/bignumber/bignumber'
+import { thorchainBlockTimeMs, thorchainBlockTimeSeconds } from 'lib/utils/thorchain/constants'
import { thorchainLendingPositionQueryFn } from './useLendingPositionData'
@@ -12,10 +13,6 @@ type UseLendingPositionDataProps = {
assetId?: AssetId
}
-// Current blocktime as per https://thorchain.network/stats
-export const thorchainBlockTimeSeconds = '6.1'
-
-const thorchainBlockTimeMs = bn(thorchainBlockTimeSeconds).times(1000).toNumber()
export const useRepaymentLockData = ({
accountId,
assetId,
diff --git a/src/pages/ThorChainLP/AvailablePools.tsx b/src/pages/ThorChainLP/AvailablePools.tsx
index 48e5e643ed8..c6b3d02ce76 100644
--- a/src/pages/ThorChainLP/AvailablePools.tsx
+++ b/src/pages/ThorChainLP/AvailablePools.tsx
@@ -5,10 +5,12 @@ import { SwapperName } from '@shapeshiftoss/swapper'
import { useQuery } from '@tanstack/react-query'
import { useCallback, useMemo } from 'react'
import { reactQueries } from 'react-queries'
+import { selectInboundAddressData, selectIsTradingActive } from 'react-queries/selectors'
import { generatePath, useHistory } from 'react-router'
import { Amount } from 'components/Amount/Amount'
import { Main } from 'components/Layout/Main'
import { RawText, Text } from 'components/Text'
+import { thorchainBlockTimeMs } from 'lib/utils/thorchain/constants'
import { calculateTVL, getVolume } from 'lib/utils/thorchain/lp'
import { selectMarketDataById } from 'state/slices/marketDataSlice/selectors'
import { useAppSelector } from 'state/store'
@@ -51,12 +53,8 @@ type PoolButtonProps = {
const PoolButton = ({ pool }: PoolButtonProps) => {
const history = useHistory()
- const { data: isTradingActive, isLoading: isTradingActiveLoading } = useQuery({
- ...reactQueries.common.isTradingActive({
- assetId: pool.assetId,
- swapperName: SwapperName.Thorchain,
- }),
- // @lukemorales/query-key-factory only returns queryFn and queryKey - all others will be ignored in the returned object
+ const { data: inboundAddressesData, isLoading: isInboundAddressesDataLoading } = useQuery({
+ ...reactQueries.thornode.inboundAddresses(),
// Go stale instantly
staleTime: 0,
// Never store queries in cache since we always want fresh data
@@ -64,8 +62,25 @@ const PoolButton = ({ pool }: PoolButtonProps) => {
refetchOnWindowFocus: true,
refetchOnMount: true,
refetchInterval: 60_000,
+ select: data => selectInboundAddressData(data, pool?.assetId),
+ })
+
+ const { data: mimir, isLoading: isMimirLoading } = useQuery({
+ ...reactQueries.thornode.mimir(),
+ staleTime: thorchainBlockTimeMs,
})
+ const isTradingActive = useMemo(() => {
+ if (isMimirLoading || !mimir) return
+
+ return selectIsTradingActive({
+ assetId: pool?.assetId,
+ inboundAddressResponse: inboundAddressesData,
+ swapperName: SwapperName.Thorchain,
+ mimir,
+ })
+ }, [inboundAddressesData, isMimirLoading, mimir, pool?.assetId])
+
const handlePoolClick = useCallback(() => {
const { opportunityId } = pool
history.push(generatePath('/pools/poolAccount/:opportunityId', { opportunityId }))
@@ -116,7 +131,7 @@ const PoolButton = ({ pool }: PoolButtonProps) => {
-
+
{isTradingActive === false ? (
diff --git a/src/pages/ThorChainLP/Pool/Pool.tsx b/src/pages/ThorChainLP/Pool/Pool.tsx
index 693213f6e60..ca3eb188e8d 100644
--- a/src/pages/ThorChainLP/Pool/Pool.tsx
+++ b/src/pages/ThorChainLP/Pool/Pool.tsx
@@ -21,9 +21,11 @@ import React, { useCallback, useMemo } from 'react'
import { FaPlus } from 'react-icons/fa6'
import { useTranslate } from 'react-polyglot'
import { reactQueries } from 'react-queries'
+import { selectInboundAddressData, selectIsTradingActive } from 'react-queries/selectors'
import { generatePath, matchPath, useHistory, useParams, useRouteMatch } from 'react-router'
import { SwapIcon } from 'components/Icons/SwapIcon'
import { Main } from 'components/Layout/Main'
+import { thorchainBlockTimeMs } from 'lib/utils/thorchain/constants'
import {
calculateTVL,
get24hSwapChangePercentage,
@@ -102,13 +104,9 @@ export const Pool = () => {
return parsedPools.find(pool => pool.opportunityId === routeOpportunityId)
}, [params, parsedPools])
- const { data: isTradingActive, isLoading: isTradingActiveLoading } = useQuery({
- ...reactQueries.common.isTradingActive({
- assetId: foundPool?.assetId,
- swapperName: SwapperName.Thorchain,
- }),
- // @lukemorales/query-key-factory only returns queryFn and queryKey - all others will be ignored in the returned object
- enabled: Boolean(foundPool?.assetId),
+ const { data: inboundAddressesData, isLoading: isInboundAddressesDataLoading } = useQuery({
+ ...reactQueries.thornode.inboundAddresses(),
+ enabled: !!foundPool,
// Go stale instantly
staleTime: 0,
// Never store queries in cache since we always want fresh data
@@ -116,8 +114,25 @@ export const Pool = () => {
refetchOnWindowFocus: true,
refetchOnMount: true,
refetchInterval: 60_000,
+ select: data => selectInboundAddressData(data, foundPool?.assetId),
+ })
+
+ const { data: mimir, isLoading: isMimirLoading } = useQuery({
+ ...reactQueries.thornode.mimir(),
+ staleTime: thorchainBlockTimeMs,
})
+ const isTradingActive = useMemo(() => {
+ if (isMimirLoading || !mimir) return
+
+ return selectIsTradingActive({
+ assetId: foundPool?.assetId,
+ inboundAddressResponse: inboundAddressesData,
+ swapperName: SwapperName.Thorchain,
+ mimir,
+ })
+ }, [foundPool?.assetId, inboundAddressesData, isMimirLoading, mimir])
+
const poolAssetIds = useMemo(() => {
if (!foundPool) return []
@@ -215,11 +230,13 @@ export const Pool = () => {