diff --git a/.env.app b/.env.app index 9d0b29fa44b..9ff7327cc3e 100644 --- a/.env.app +++ b/.env.app @@ -43,7 +43,6 @@ REACT_APP_POLYGON_NODE_URL=https://daemon.polygon.shapeshift.com REACT_APP_GNOSIS_NODE_URL=https://daemon.gnosis.shapeshift.com REACT_APP_ARBITRUM_NODE_URL=https://daemon.arbitrum.shapeshift.com REACT_APP_ARBITRUM_NOVA_NODE_URL=https://daemon.arbitrum-nova.shapeshift.com -REACT_APP_COSMOS_NODE_URL=https://daemon.cosmos.shapeshift.com REACT_APP_THORCHAIN_NODE_URL=https://daemon.thorchain.shapeshift.com # thorchain diff --git a/.env.dev b/.env.dev index 749a6ec95ee..3a12a474173 100644 --- a/.env.dev +++ b/.env.dev @@ -38,15 +38,14 @@ REACT_APP_UNCHAINED_THORCHAIN_HTTP_URL=https://dev-api.thorchain.shapeshift.com REACT_APP_UNCHAINED_THORCHAIN_WS_URL=wss://dev-api.thorchain.shapeshift.com # nodes -REACT_APP_ETHEREUM_NODE_URL=https://dev-daemon.ethereum.shapeshift.com +REACT_APP_ETHEREUM_NODE_URL=https://dev-nownodes.shapeshift.com/ethereum REACT_APP_AVALANCHE_NODE_URL=https://dev-daemon.avalanche.shapeshift.com/ext/bc/C/rpc REACT_APP_OPTIMISM_NODE_URL=https://dev-daemon.optimism.shapeshift.com -REACT_APP_BNBSMARTCHAIN_NODE_URL=https://dev-daemon.bnbsmartchain.shapeshift.com -REACT_APP_POLYGON_NODE_URL=https://dev-daemon.polygon.shapeshift.com +REACT_APP_BNBSMARTCHAIN_NODE_URL=https://dev-nownodes.shapeshift.com/bnbsmartchain +REACT_APP_POLYGON_NODE_URL=https://dev-nownodes.shapeshift.com/polygon REACT_APP_GNOSIS_NODE_URL=https://dev-daemon.gnosis.shapeshift.com -REACT_APP_ARBITRUM_NODE_URL=https://dev-daemon.arbitrum.shapeshift.com +REACT_APP_ARBITRUM_NODE_URL=https://dev-nownodes.shapeshift.com/arbitrum REACT_APP_ARBITRUM_NOVA_NODE_URL=https://dev-daemon.arbitrum-nova.shapeshift.com -REACT_APP_COSMOS_NODE_URL=https://dev-daemon.cosmos.shapeshift.com REACT_APP_THORCHAIN_NODE_URL=https://dev-daemon.thorchain.shapeshift.com # thorchain diff --git a/.env.develop b/.env.develop index b9d96367b41..d63945fe34f 100644 --- a/.env.develop +++ b/.env.develop @@ -36,15 +36,14 @@ REACT_APP_UNCHAINED_THORCHAIN_HTTP_URL=https://dev-api.thorchain.shapeshift.com REACT_APP_UNCHAINED_THORCHAIN_WS_URL=wss://dev-api.thorchain.shapeshift.com # nodes -REACT_APP_ETHEREUM_NODE_URL=https://dev-daemon.ethereum.shapeshift.com +REACT_APP_ETHEREUM_NODE_URL=https://dev-nownodes.shapeshift.com/ethereum REACT_APP_AVALANCHE_NODE_URL=https://dev-daemon.avalanche.shapeshift.com/ext/bc/C/rpc REACT_APP_OPTIMISM_NODE_URL=https://dev-daemon.optimism.shapeshift.com -REACT_APP_BNBSMARTCHAIN_NODE_URL=https://dev-daemon.bnbsmartchain.shapeshift.com -REACT_APP_POLYGON_NODE_URL=https://dev-daemon.polygon.shapeshift.com +REACT_APP_BNBSMARTCHAIN_NODE_URL=https://dev-nownodes.shapeshift.com/bnbsmartchain +REACT_APP_POLYGON_NODE_URL=https://dev-nownodes.shapeshift.com/polygon REACT_APP_GNOSIS_NODE_URL=https://dev-daemon.gnosis.shapeshift.com -REACT_APP_ARBITRUM_NODE_URL=https://dev-daemon.arbitrum.shapeshift.com +REACT_APP_ARBITRUM_NODE_URL=https://dev-nownodes.shapeshift.com/arbitrum REACT_APP_ARBITRUM_NOVA_NODE_URL=https://dev-daemon.arbitrum-nova.shapeshift.com -REACT_APP_COSMOS_NODE_URL=https://dev-daemon.cosmos.shapeshift.com REACT_APP_THORCHAIN_NODE_URL=https://dev-daemon.thorchain.shapeshift.com # thorchain diff --git a/.env.e2e b/.env.e2e index 417fb7771e8..392d978bbb7 100644 --- a/.env.e2e +++ b/.env.e2e @@ -32,16 +32,15 @@ REACT_APP_UNCHAINED_THORCHAIN_HTTP_URL=https://dev-api.thorchain.shapeshift.com REACT_APP_UNCHAINED_THORCHAIN_WS_URL=wss://dev-api.thorchain.shapeshift.com # nodes -REACT_APP_ETHEREUM_NODE_URL=http://localhost:8080 +REACT_APP_ETHEREUM_NODE_URL=https://dev-nownodes.shapeshift.com/ethereum REACT_APP_AVALANCHE_NODE_URL=https://dev-daemon.avalanche.shapeshift.com/ext/bc/C/rpc REACT_APP_OPTIMISM_NODE_URL=https://dev-daemon.optimism.shapeshift.com -REACT_APP_BNBSMARTCHAIN_NODE_URL=https://dev-daemon.bnbsmartchain.shapeshift.com -REACT_APP_POLYGON_NODE_URL=https://dev-daemon.polygon.shapeshift.com +REACT_APP_BNBSMARTCHAIN_NODE_URL=https://dev-nownodes.shapeshift.com/bnbsmartchain +REACT_APP_POLYGON_NODE_URL=https://dev-nownodes.shapeshift.com/polygon REACT_APP_GNOSIS_NODE_URL=https://dev-daemon.gnosis.shapeshift.com -REACT_APP_ARBITRUM_NODE_URL=https://dev-daemon.arbitrum.shapeshift.com +REACT_APP_ARBITRUM_NODE_URL=https://dev-nownodes.shapeshift.com/arbitrum REACT_APP_ARBITRUM_NOVA_NODE_URL=https://dev-daemon.arbitrum-nova.shapeshift.com -REACT_APP_COSMOS_NODE_URL=https://dev-daemon.cosmos.shapeshift.com -REACT_APP_THORCHAIN_NODE_URL=https://dev-daemon.thorchain.shapeshift.com/lcd +REACT_APP_THORCHAIN_NODE_URL=https://dev-daemon.thorchain.shapeshift.com # thorchain REACT_APP_MIDGARD_URL=https://dev-indexer.thorchain.shapeshift.com/v2 diff --git a/.env.private b/.env.private index eb29f4eb91e..54ae279ce13 100644 --- a/.env.private +++ b/.env.private @@ -41,7 +41,6 @@ REACT_APP_POLYGON_NODE_URL=https://daemon.polygon.shapeshift.com REACT_APP_GNOSIS_NODE_URL=https://daemon.gnosis.shapeshift.com REACT_APP_ARBITRUM_NODE_URL=https://daemon.arbitrum.shapeshift.com REACT_APP_ARBITRUM_NOVA_NODE_URL=https://daemon.arbitrum-nova.shapeshift.com -REACT_APP_COSMOS_NODE_URL=https://daemon.cosmos.shapeshift.com REACT_APP_THORCHAIN_NODE_URL=https://daemon.thorchain.shapeshift.com # thorchain diff --git a/react-app-rewired/headers/csps/chains/cosmos.ts b/react-app-rewired/headers/csps/chains/cosmos.ts index 1aff2647c44..5055f34d84d 100644 --- a/react-app-rewired/headers/csps/chains/cosmos.ts +++ b/react-app-rewired/headers/csps/chains/cosmos.ts @@ -4,7 +4,6 @@ export const csp: Csp = { 'connect-src': [ process.env.REACT_APP_UNCHAINED_COSMOS_HTTP_URL!, process.env.REACT_APP_UNCHAINED_COSMOS_WS_URL!, - process.env.REACT_APP_COSMOS_NODE_URL!, ], 'img-src': [ 'https://raw.githubusercontent.com/cosmostation/', diff --git a/src/components/Modals/Send/hooks/useFormSend/useFormSend.test.tsx b/src/components/Modals/Send/hooks/useFormSend/useFormSend.test.tsx index 7684df201ee..5123f56da1e 100644 --- a/src/components/Modals/Send/hooks/useFormSend/useFormSend.test.tsx +++ b/src/components/Modals/Send/hooks/useFormSend/useFormSend.test.tsx @@ -170,6 +170,7 @@ describe.each([ wallet: { supportsOfflineSigning: vi.fn().mockReturnValue(true), ethSupportsEIP1559: vi.fn().mockReturnValue(walletSupportsEIP1559), + getVendor: vi.fn().mockReturnValue('Native'), }, }, }) as unknown as IWalletContext, @@ -230,6 +231,7 @@ describe.each([ wallet: { supportsOfflineSigning: vi.fn().mockReturnValue(true), ethSupportsEIP1559: vi.fn().mockReturnValue(walletSupportsEIP1559), + getVendor: vi.fn().mockReturnValue('Native'), }, }, }) as unknown as IWalletContext, @@ -296,6 +298,7 @@ describe.each([ supportsOfflineSigning: vi.fn().mockReturnValue(false), supportsBroadcast: vi.fn().mockReturnValue(true), ethSupportsEIP1559: vi.fn().mockReturnValue(walletSupportsEIP1559), + getVendor: vi.fn().mockReturnValue('Native'), }, }, }) as unknown as IWalletContext, @@ -351,6 +354,7 @@ describe.each([ supportsOfflineSigning: vi.fn().mockReturnValue(false), supportsBroadcast: vi.fn().mockReturnValue(true), ethSupportsEIP1559: vi.fn().mockReturnValue(walletSupportsEIP1559), + getVendor: vi.fn().mockReturnValue('Native'), } as unknown as HDWallet const toaster = vi.fn() as unknown as CreateToastFnReturn const signAndBroadcastTransaction = vi.fn().mockResolvedValue('txid') diff --git a/src/components/Modals/Send/utils.ts b/src/components/Modals/Send/utils.ts index 80b8425e6e2..f37d468753f 100644 --- a/src/components/Modals/Send/utils.ts +++ b/src/components/Modals/Send/utils.ts @@ -18,7 +18,7 @@ import { checkIsSnapInstalled, } from 'hooks/useIsSnapInstalled/useIsSnapInstalled' import { bn, bnOrZero } from 'lib/bignumber/bignumber' -import { assertGetChainAdapter, tokenOrUndefined } from 'lib/utils' +import { assertGetChainAdapter, isKeepKeyHDWallet, tokenOrUndefined } from 'lib/utils' import { assertGetCosmosSdkChainAdapter } from 'lib/utils/cosmosSdk' import { assertGetEvmChainAdapter, getSupportedEvmChainIds } from 'lib/utils/evm' import { assertGetUtxoChainAdapter } from 'lib/utils/utxo' @@ -141,6 +141,7 @@ export const handleSend = async ({ chainSpecific: { gasPrice, gasLimit, maxFeePerGas, maxPriorityFeePerGas }, } = fees const shouldUseEIP1559Fees = + !isKeepKeyHDWallet(wallet) && (await wallet.ethSupportsEIP1559()) && maxFeePerGas !== undefined && maxPriorityFeePerGas !== undefined diff --git a/src/components/MultiHopTrade/components/MultiHopTradeConfirm/hooks/useApprovalTx.tsx b/src/components/MultiHopTrade/components/MultiHopTradeConfirm/hooks/useApprovalTx.tsx index a0fdc73f505..b81a8f79fc7 100644 --- a/src/components/MultiHopTrade/components/MultiHopTradeConfirm/hooks/useApprovalTx.tsx +++ b/src/components/MultiHopTrade/components/MultiHopTradeConfirm/hooks/useApprovalTx.tsx @@ -5,6 +5,7 @@ import type { TradeQuoteStep } from '@shapeshiftoss/swapper' import { useEffect, useState } from 'react' import { usePoll } from 'hooks/usePoll/usePoll' import { useWallet } from 'hooks/useWallet/useWallet' +import { isKeepKeyHDWallet } from 'lib/utils' import { assertGetEvmChainAdapter } from 'lib/utils/evm' import { selectHopSellAccountId } from 'state/slices/tradeQuoteSlice/selectors' import { useAppSelector } from 'state/store' @@ -38,7 +39,7 @@ export const useApprovalTx = ( // This accidentally works since all EVM chains share the same address, so there's no need // to call adapter.getAddress() later down the call stack const from = fromAccountId(sellAssetAccountId).account - const supportsEIP1559 = await wallet.ethSupportsEIP1559() + const supportsEIP1559 = !isKeepKeyHDWallet(wallet) && (await wallet.ethSupportsEIP1559()) const { buildCustomTxInput, networkFeeCryptoBaseUnit } = await getApprovalTxData({ tradeQuoteStep, diff --git a/src/components/MultiHopTrade/components/MultiHopTradeConfirm/hooks/useTradeExecution.tsx b/src/components/MultiHopTrade/components/MultiHopTradeConfirm/hooks/useTradeExecution.tsx index 0802e85acf6..a7d218bdb89 100644 --- a/src/components/MultiHopTrade/components/MultiHopTradeConfirm/hooks/useTradeExecution.tsx +++ b/src/components/MultiHopTrade/components/MultiHopTradeConfirm/hooks/useTradeExecution.tsx @@ -13,7 +13,7 @@ import { useErrorHandler } from 'hooks/useErrorToast/useErrorToast' import { useWallet } from 'hooks/useWallet/useWallet' import { MixPanelEvent } from 'lib/mixpanel/types' import { TradeExecution } from 'lib/swapper/tradeExecution' -import { assertUnreachable } from 'lib/utils' +import { assertUnreachable, isKeepKeyHDWallet } from 'lib/utils' import { assertGetCosmosSdkChainAdapter } from 'lib/utils/cosmosSdk' import { assertGetEvmChainAdapter, signAndBroadcast } from 'lib/utils/evm' import { assertGetUtxoChainAdapter } from 'lib/utils/utxo' @@ -203,7 +203,8 @@ export const useTradeExecution = (hopIndex: number) => { case CHAIN_NAMESPACE.Evm: { const adapter = assertGetEvmChainAdapter(stepSellAssetChainId) const from = await adapter.getAddress({ accountNumber, wallet }) - const supportsEIP1559 = supportsETH(wallet) && (await wallet.ethSupportsEIP1559()) + const supportsEIP1559 = + !isKeepKeyHDWallet(wallet) && supportsETH(wallet) && (await wallet.ethSupportsEIP1559()) const output = await execution.execEvmTransaction({ swapperName, diff --git a/src/components/MultiHopTrade/components/TradeInput/components/TradeQuotes/TradeQuote.tsx b/src/components/MultiHopTrade/components/TradeInput/components/TradeQuotes/TradeQuote.tsx index 0917a2f7074..01911997dd7 100644 --- a/src/components/MultiHopTrade/components/TradeInput/components/TradeQuotes/TradeQuote.tsx +++ b/src/components/MultiHopTrade/components/TradeInput/components/TradeQuotes/TradeQuote.tsx @@ -66,9 +66,11 @@ export const TradeQuoteLoaded: FC = ({ const sellAsset = useAppSelector(selectInputSellAsset) const { isTradingActive: isTradingActiveOnBuyPool } = useIsTradingActive({ assetId: buyAsset.assetId, + enabled: true, }) const { isTradingActive: isTradingActiveOnSellPool } = useIsTradingActive({ assetId: sellAsset.assetId, + enabled: true, }) const isTradingActive = Boolean(isTradingActiveOnBuyPool && isTradingActiveOnSellPool) diff --git a/src/components/MultiHopTrade/hooks/useGetTradeQuotes/getTradeQuoteArgs.ts b/src/components/MultiHopTrade/hooks/useGetTradeQuotes/getTradeQuoteArgs.ts index 4f57a8b6144..c659f79f897 100644 --- a/src/components/MultiHopTrade/hooks/useGetTradeQuotes/getTradeQuoteArgs.ts +++ b/src/components/MultiHopTrade/hooks/useGetTradeQuotes/getTradeQuoteArgs.ts @@ -6,7 +6,7 @@ import type { GetTradeQuoteInput } from '@shapeshiftoss/swapper' import type { Asset, UtxoAccountType } from '@shapeshiftoss/types' import type { TradeQuoteInputCommonArgs } from 'components/MultiHopTrade/types' import { toBaseUnit } from 'lib/math' -import { assertUnreachable } from 'lib/utils' +import { assertUnreachable, isKeepKeyHDWallet } from 'lib/utils' import { assertGetCosmosSdkChainAdapter } from 'lib/utils/cosmosSdk' import { assertGetEvmChainAdapter } from 'lib/utils/evm' import { assertGetUtxoChainAdapter } from 'lib/utils/utxo' @@ -65,7 +65,8 @@ export const getTradeQuoteArgs = async ({ switch (chainNamespace) { case CHAIN_NAMESPACE.Evm: { - const supportsEIP1559 = supportsETH(wallet) && (await wallet.ethSupportsEIP1559()) + const supportsEIP1559 = + !isKeepKeyHDWallet(wallet) && supportsETH(wallet) && (await wallet.ethSupportsEIP1559()) const sellAssetChainAdapter = assertGetEvmChainAdapter(sellAsset.chainId) const sendAddress = await sellAssetChainAdapter.getAddress({ accountNumber: sellAccountNumber, diff --git a/src/config.ts b/src/config.ts index 7ba107acfd6..64c5a0f4047 100644 --- a/src/config.ts +++ b/src/config.ts @@ -110,9 +110,6 @@ const validators = { REACT_APP_COWSWAP_BASE_URL: url({ default: 'https://api.cow.fi', }), - REACT_APP_COSMOS_NODE_URL: url({ - default: 'https://dev-daemon.cosmos.shapeshift.com', - }), REACT_APP_ONRAMPER_WIDGET_URL: url(), REACT_APP_ONRAMPER_API_URL: url(), REACT_APP_ONRAMPER_API_KEY: str(), diff --git a/src/features/defi/providers/fox-farming/hooks/useFoxFarming.ts b/src/features/defi/providers/fox-farming/hooks/useFoxFarming.ts index 2bfb66c8dc2..62731789f85 100644 --- a/src/features/defi/providers/fox-farming/hooks/useFoxFarming.ts +++ b/src/features/defi/providers/fox-farming/hooks/useFoxFarming.ts @@ -9,7 +9,7 @@ import { encodeFunctionData, getAddress } from 'viem' import { useFoxEth } from 'context/FoxEthProvider/FoxEthProvider' import { useWallet } from 'hooks/useWallet/useWallet' import { toBaseUnit } from 'lib/math' -import { isValidAccountNumber } from 'lib/utils' +import { isKeepKeyHDWallet, isValidAccountNumber } from 'lib/utils' import { assertGetEvmChainAdapter, buildAndBroadcast, @@ -220,7 +220,8 @@ export const useFoxFarming = ( from: userAddress, to: contractAddress, value: '0', - supportsEIP1559: supportsETH(wallet) && (await wallet.ethSupportsEIP1559()), + supportsEIP1559: + !isKeepKeyHDWallet(wallet) && supportsETH(wallet) && (await wallet.ethSupportsEIP1559()), }) }, [adapter, contractAddress, foxFarmingContract, wallet], 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 5c1f0711ff2..c03c81581bd 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,6 +540,7 @@ export const Confirm: React.FC = ({ accountId, onNext }) => { const { isTradingActive, refetch: refetchIsTradingActive } = useIsTradingActive({ assetId, + enabled: !!assetId, }) const handleDeposit = useCallback(async () => { 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 8352c46b2b3..9b8043cb63c 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,6 +130,7 @@ export const ThorchainSaversOverview: React.FC = ({ const { isTradingActive, isLoading: isTradingActiveLoading } = useIsTradingActive({ assetId, + enabled: !!assetId, }) useEffect(() => { 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 e8acee7aa75..a4dfdfaf5b6 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,6 +594,7 @@ export const Confirm: React.FC = ({ accountId, onNext }) => { const { isTradingActive, refetch: refetchIsTradingActive } = useIsTradingActive({ assetId, + enabled: !!assetId, }) const handleConfirm = useCallback(async () => { diff --git a/src/hooks/useIsSmartContractAddress/useIsSmartContractAddress.ts b/src/hooks/useIsSmartContractAddress/useIsSmartContractAddress.ts index 2e00279dbb5..a03949046c7 100644 --- a/src/hooks/useIsSmartContractAddress/useIsSmartContractAddress.ts +++ b/src/hooks/useIsSmartContractAddress/useIsSmartContractAddress.ts @@ -1,5 +1,6 @@ import { useQuery } from '@tanstack/react-query' import { useMemo } from 'react' +import { isAddress } from 'viem' import { isSmartContractAddress } from 'lib/address/utils' export const useIsSmartContractAddress = (address: string) => { @@ -13,7 +14,7 @@ export const useIsSmartContractAddress = (address: string) => { }, ], queryFn: () => isSmartContractAddress(userAddress), - enabled: Boolean(userAddress.length), + enabled: Boolean(userAddress.length && isAddress(address)), }) return query diff --git a/src/lib/investor/investor-foxy/api/api.ts b/src/lib/investor/investor-foxy/api/api.ts index 65295dc5284..eb45b5d9d55 100644 --- a/src/lib/investor/investor-foxy/api/api.ts +++ b/src/lib/investor/investor-foxy/api/api.ts @@ -14,6 +14,7 @@ import { ethers } from 'ethers' import { toLower } from 'lodash' import { bn, bnOrZero } from 'lib/bignumber/bignumber' import { MAX_ALLOWANCE } from 'lib/investor/constants' +import { isKeepKeyHDWallet } from 'lib/utils' import { DefiType } from 'state/slices/opportunitiesSlice/types' import { erc20Abi } from '../abi/erc20-abi' @@ -128,6 +129,7 @@ export class FoxyApi { chainSpecific: { gasPrice, gasLimit, maxFeePerGas, maxPriorityFeePerGas }, } = payload.estimatedFees.fast const shouldUseEIP1559Fees = + !isKeepKeyHDWallet(wallet) && (await wallet.ethSupportsEIP1559()) && maxFeePerGas !== undefined && maxPriorityFeePerGas !== undefined diff --git a/src/lib/utils/evm.ts b/src/lib/utils/evm.ts index 2483e03949e..726b6719e92 100644 --- a/src/lib/utils/evm.ts +++ b/src/lib/utils/evm.ts @@ -20,7 +20,7 @@ import { encodeFunctionData, getAddress } from 'viem' import { getChainAdapterManager } from 'context/PluginProvider/chainAdapterSingleton' import { bn, bnOrZero } from 'lib/bignumber/bignumber' -import { getSupportedChainIdsByChainNamespace } from '.' +import { getSupportedChainIdsByChainNamespace, isKeepKeyHDWallet } from '.' type GetApproveContractDataArgs = { approvalAmountCryptoBaseUnit: string @@ -96,7 +96,8 @@ export const getFeesWithWallet = async (args: GetFeesWithWalletArgs): Promise { +}: EstimateFeesInput & { enabled: boolean; disableRefetch?: boolean }) => { const asset = useAppSelector(state => selectAssetById(state, estimateFeesInput.assetId)) const assetMarketData = useAppSelector(state => selectMarketDataById(state, estimateFeesInput.assetId), @@ -49,9 +49,13 @@ export const useGetEstimatedFeesQuery = ({ staleTime: 30_000, queryFn, enabled: enabled && Boolean(estimateFeesInput.to && estimateFeesInput.accountId && asset), - // Ensures fees are refetched at an interval, including when the app is in the background - refetchIntervalInBackground: true, - refetchInterval: 5000, + ...(enabled + ? { + // Ensures fees are refetched at an interval, including when the app is in the background + refetchIntervalInBackground: true, + refetchInterval: 5000, + } + : {}), }) return getEstimatedFeesQuery diff --git a/src/pages/ThorChainLP/AvailablePools.tsx b/src/pages/ThorChainLP/AvailablePools.tsx index ac6b25c07fc..e045ab3f720 100644 --- a/src/pages/ThorChainLP/AvailablePools.tsx +++ b/src/pages/ThorChainLP/AvailablePools.tsx @@ -53,6 +53,7 @@ const PoolButton = ({ pool }: PoolButtonProps) => { const { isTradingActive, isLoading: isTradingActiveLoading } = useIsTradingActive({ assetId: pool?.assetId, + enabled: !!pool, }) const handlePoolClick = useCallback(() => { diff --git a/src/pages/ThorChainLP/Pool/Pool.tsx b/src/pages/ThorChainLP/Pool/Pool.tsx index 85338f18c1b..05b1f18c15f 100644 --- a/src/pages/ThorChainLP/Pool/Pool.tsx +++ b/src/pages/ThorChainLP/Pool/Pool.tsx @@ -104,6 +104,7 @@ export const Pool = () => { const { isTradingActive, isLoading: isTradingActiveLoading } = useIsTradingActive({ assetId: foundPool?.assetId, + enabled: !!foundPool, }) const poolAssetIds = useMemo(() => { @@ -125,6 +126,11 @@ export const Pool = () => { ) }, [foundPool?.opportunityId, history]) + const handleTradeClick = useCallback(() => { + if (!foundPool) return + history.push(`/trade/${foundPool?.assetId}`) + }, [foundPool, history]) + const runeMarketData = useAppSelector(state => selectMarketDataById(state, thorchainAssetId)) const assetMarketData = useAppSelector(state => selectMarketDataById(state, foundPool?.assetId ?? ''), @@ -214,7 +220,12 @@ export const Pool = () => { {translate('pools.addLiquidity')} - diff --git a/src/pages/ThorChainLP/components/AddLiquitity/AddLiquidityInput.tsx b/src/pages/ThorChainLP/components/AddLiquitity/AddLiquidityInput.tsx index 1fd6e365279..2d3f438cc8f 100644 --- a/src/pages/ThorChainLP/components/AddLiquitity/AddLiquidityInput.tsx +++ b/src/pages/ThorChainLP/components/AddLiquitity/AddLiquidityInput.tsx @@ -37,6 +37,7 @@ import { TradeAssetInput } from 'components/MultiHopTrade/components/TradeAssetI import { Row } from 'components/Row/Row' import { SlideTransition } from 'components/SlideTransition' import { useBrowserRouter } from 'hooks/useBrowserRouter/useBrowserRouter' +import { useIsSmartContractAddress } from 'hooks/useIsSmartContractAddress/useIsSmartContractAddress' import { useIsSnapInstalled } from 'hooks/useIsSnapInstalled/useIsSnapInstalled' import { useModal } from 'hooks/useModal/useModal' import { useWallet } from 'hooks/useWallet/useWallet' @@ -162,6 +163,9 @@ export const AddLiquidityInput: React.FC = ({ opportunityId ?? defaultOpportunityId, ) + const { data: isSmartContractAccountAddress, isLoading: isSmartContractAccountAddressLoading } = + useIsSmartContractAddress(poolAssetAccountAddress ?? '') + useEffect(() => { if (!(opportunityId || defaultOpportunityId)) return @@ -428,6 +432,7 @@ export const AddLiquidityInput: React.FC = ({ const { isTradingActive, isLoading: isTradingActiveLoading } = useIsTradingActive({ assetId: poolAsset?.assetId, + enabled: !!poolAsset, }) const poolAccountId = useMemo( @@ -1147,13 +1152,16 @@ export const AddLiquidityInput: React.FC = ({ // Order matters here. Since we're dealing with two assets potentially, we want to show the most relevant error message possible i.e // 1. Asset unsupported by wallet // 2. pool halted - // 3. pool asset balance - // 4. pool asset fee balance, since gas would usually be more expensive on the pool asset fee side vs. RUNE side - // 5. RUNE balance - // 6. RUNE fee balance + // 3. smart contract deposits disabled + // 4. pool asset balance + // 5. pool asset fee balance, since gas would usually be more expensive on the pool asset fee side vs. RUNE side + // 6. RUNE balance + // 7. RUNE fee balance // Not enough *pool* asset, but possibly enough *fee* asset if (!walletSupportsOpportunity) return translate('common.unsupportedNetwork') if (isTradingActive === false) return translate('common.poolHalted') + if (isSmartContractAccountAddress === true) + return translate('trade.errors.smartContractWalletNotSupported') if (poolAsset && notEnoughPoolAssetError) return translate('common.insufficientFunds') // Not enough *fee* asset if (poolAssetFeeAsset && notEnoughFeeAssetError) @@ -1170,6 +1178,7 @@ export const AddLiquidityInput: React.FC = ({ return null }, [ + isSmartContractAccountAddress, isTradingActive, notEnoughFeeAssetError, notEnoughPoolAssetError, @@ -1295,6 +1304,7 @@ export const AddLiquidityInput: React.FC = ({ isVotingPowerLoading || isInboundAddressesDataLoading || isTradingActiveLoading || + isSmartContractAccountAddressLoading || isAllowanceDataLoading || isApprovalTxPending || isSweepNeededLoading || diff --git a/src/pages/ThorChainLP/components/ReusableLpConfirm.tsx b/src/pages/ThorChainLP/components/ReusableLpConfirm.tsx index 9edaeb523a5..7b1378552b8 100644 --- a/src/pages/ThorChainLP/components/ReusableLpConfirm.tsx +++ b/src/pages/ThorChainLP/components/ReusableLpConfirm.tsx @@ -17,6 +17,7 @@ import type { Asset } from '@shapeshiftoss/types' import React, { useMemo } from 'react' import { FaPlus } from 'react-icons/fa' import { useTranslate } from 'react-polyglot' +import { useIsTradingActive } from 'react-queries/hooks/useIsTradingActive' import { Amount } from 'components/Amount/Amount' import { AssetIcon } from 'components/AssetIcon' import { Row } from 'components/Row/Row' @@ -180,6 +181,17 @@ export const ReusableLpConfirm: React.FC = ({ pool, ]) + const { isTradingActive, isLoading: isTradingActiveLoading } = useIsTradingActive({ + assetId: pool?.assetId, + enabled: !!pool, + }) + + const confirmCopy = useMemo(() => { + if (isTradingActive === false) return translate('common.poolHalted') + + return translate('pools.confirmAndDeposit') + }, [isTradingActive, translate]) + if (!(pool && asset && baseAsset)) return null return ( @@ -279,8 +291,15 @@ export const ReusableLpConfirm: React.FC = ({ bg='background.surface.raised.accent' borderBottomRadius='xl' > - diff --git a/src/pages/ThorChainLP/components/ReusableLpStatus/TransactionRow.tsx b/src/pages/ThorChainLP/components/ReusableLpStatus/TransactionRow.tsx index f8e6096b42d..c1f033ac801 100644 --- a/src/pages/ThorChainLP/components/ReusableLpStatus/TransactionRow.tsx +++ b/src/pages/ThorChainLP/components/ReusableLpStatus/TransactionRow.tsx @@ -107,6 +107,7 @@ export const TransactionRow: React.FC = ({ isLoading: isTradingActiveLoading, } = useIsTradingActive({ assetId: poolAssetId, + enabled: !txId, }) const runeAccountId = accountIdsByChainId[thorchainChainId] @@ -368,7 +369,7 @@ export const TransactionRow: React.FC = ({ memo: estimateFeesArgs?.memo ?? '', accountId: estimateFeesArgs?.accountId ?? '', contractAddress: estimateFeesArgs?.contractAddress ?? '', - enabled: !!estimateFeesArgs, + enabled: !!estimateFeesArgs && !txId, }) const estimatedFeeDataCryptoPrecision = useMemo(() => { diff --git a/src/react-queries/hooks/useIsTradingActive.ts b/src/react-queries/hooks/useIsTradingActive.ts index 8dd319aac4d..f1431a48703 100644 --- a/src/react-queries/hooks/useIsTradingActive.ts +++ b/src/react-queries/hooks/useIsTradingActive.ts @@ -9,7 +9,13 @@ import { selectInboundAddressData, selectIsTradingActive } from 'react-queries/s import type { InboundAddressResponse } from 'lib/swapper/swappers/ThorchainSwapper/types' import { thorchainBlockTimeMs } from 'lib/utils/thorchain/constants' -export const useIsTradingActive = ({ assetId }: { assetId: AssetId | undefined }) => { +export const useIsTradingActive = ({ + assetId, + enabled, +}: { + assetId: AssetId | undefined + enabled: boolean +}) => { const [ { data: inboundAddressesData, @@ -25,9 +31,13 @@ export const useIsTradingActive = ({ assetId }: { assetId: AssetId | undefined } staleTime: 0, // Never store queries in cache since we always want fresh data gcTime: 0, - refetchOnWindowFocus: true, - refetchOnMount: true, - refetchInterval: 60_000, + ...(enabled + ? { + refetchInterval: 60_000, + refetchOnWindowFocus: true, + refetchOnMount: true, + } + : {}), select: (data: Result) => selectInboundAddressData(data, assetId), }, @@ -39,7 +49,7 @@ export const useIsTradingActive = ({ assetId }: { assetId: AssetId | undefined } }) const isTradingActive = useMemo(() => { - if (isMimirLoading || !mimir) return + if (isMimirLoading || !mimir || !assetId) return return selectIsTradingActive({ assetId, diff --git a/src/react-queries/index.ts b/src/react-queries/index.ts index e1d8d2a515c..abfc841f71a 100644 --- a/src/react-queries/index.ts +++ b/src/react-queries/index.ts @@ -14,7 +14,7 @@ import type { } from 'lib/swapper/swappers/ThorchainSwapper/types' import { assetIdToPoolAssetId } from 'lib/swapper/swappers/ThorchainSwapper/utils/poolAssetHelpers/poolAssetHelpers' import { thorService } from 'lib/swapper/swappers/ThorchainSwapper/utils/thorService' -import { isToken } from 'lib/utils' +import { isKeepKeyHDWallet, isToken } from 'lib/utils' import { assertGetEvmChainAdapter, buildAndBroadcast, @@ -98,7 +98,8 @@ const mutations = createMutationKeys('mutations', { value: '0', data: approvalCalldata, from, - supportsEIP1559: supportsETH(wallet) && (await wallet.ethSupportsEIP1559()), + supportsEIP1559: + !isKeepKeyHDWallet(wallet) && supportsETH(wallet) && (await wallet.ethSupportsEIP1559()), }) const buildCustomTxInput = { diff --git a/src/state/slices/opportunitiesSlice/resolvers/uniV2/index.ts b/src/state/slices/opportunitiesSlice/resolvers/uniV2/index.ts index ad23ea4c40c..962d6c4ac2a 100644 --- a/src/state/slices/opportunitiesSlice/resolvers/uniV2/index.ts +++ b/src/state/slices/opportunitiesSlice/resolvers/uniV2/index.ts @@ -35,10 +35,9 @@ import type { } from '../types' import { calculateAPRFromToken0 } from './utils' -const ethersProvider = getEthersProvider() - let _blockNumber: number | null = null const getBlockNumber = async () => { + const ethersProvider = getEthersProvider() if (_blockNumber) return _blockNumber const blockNumber = await ethersProvider.getBlockNumber() _blockNumber = blockNumber