diff --git a/src/hooks/useRouteAssetId/useRouteAssetId.ts b/src/hooks/useRouteAssetId/useRouteAssetId.ts
index 75a9a546947..6de96bdd64d 100644
--- a/src/hooks/useRouteAssetId/useRouteAssetId.ts
+++ b/src/hooks/useRouteAssetId/useRouteAssetId.ts
@@ -1,6 +1,5 @@
import type { AccountId, AssetId, ChainNamespace, ChainReference } from '@shapeshiftoss/caip'
import { toChainId } from '@shapeshiftoss/caip'
-import { getFoxPageRouteAssetId } from 'plugins/foxPage/utils/getFoxPageRouteAssetId'
import { useMemo } from 'react'
import { matchPath, useLocation } from 'react-router'
import { getChainAdapterManager } from 'context/PluginProvider/chainAdapterSingleton'
@@ -65,9 +64,8 @@ export const useRouteAssetId = () => {
const assetId = useMemo(() => {
const routeAssetId = getRouteAssetId(location.pathname)
- const foxPageRouteAssetId = getFoxPageRouteAssetId(location.pathname)
- return decodeURIComponent(routeAssetId ?? foxPageRouteAssetId)
+ return decodeURIComponent(routeAssetId ?? '')
}, [location.pathname])
return assetId
diff --git a/src/plugins/activePlugins.ts b/src/plugins/activePlugins.ts
index 16dbae9b245..41db6fa3932 100644
--- a/src/plugins/activePlugins.ts
+++ b/src/plugins/activePlugins.ts
@@ -8,7 +8,6 @@ import bnbsmartchain from 'plugins/bnbsmartchain'
import cosmos from 'plugins/cosmos'
import dogecoin from 'plugins/dogecoin'
import ethereum from 'plugins/ethereum'
-import foxPage from 'plugins/foxPage'
import gnosis from 'plugins/gnosis'
import litecoin from 'plugins/litecoin'
import mobile from 'plugins/mobile'
@@ -24,7 +23,6 @@ export const activePlugins = [
dogecoin,
litecoin,
ethereum,
- foxPage,
polygon,
gnosis,
avalanche,
diff --git a/src/plugins/foxPage/FoxCommon.ts b/src/plugins/foxPage/FoxCommon.ts
deleted file mode 100644
index 78487b98a8d..00000000000
--- a/src/plugins/foxPage/FoxCommon.ts
+++ /dev/null
@@ -1,67 +0,0 @@
-import type { DefiType } from 'state/slices/opportunitiesSlice/types'
-
-import type { TradeOpportunitiesBucket } from './components/TradeOpportunities'
-
-export const TrimmedDescriptionLength = 191
-
-export enum OpportunityTypes {
- LiquidityPool = 'liquidityPools',
- Farming = 'farming',
- BorrowingAndLending = 'borrowingAndLending',
-}
-
-export type ExternalOpportunity = {
- name: string | undefined
- type?: DefiType
- apy?: string | null
- link?: string
- icons?: string[] | undefined
- isLoaded?: boolean
- isDisabled?: boolean
- contractAddress?: string
- provider?: string
- highestBalanceAccountAddress?: string
-}
-
-export type OpportunitiesBucket = {
- type: OpportunityTypes | DefiType
- title: string
- opportunities: ExternalOpportunity[]
-}
-
-export const foxTradeOpportunitiesBuckets: TradeOpportunitiesBucket[] = [
- {
- title: 'plugins.foxPage.dex',
- opportunities: [
- {
- link: 'https://app.uniswap.org/#/swap?inputCurrency=ETH&outputCurrency=0xc770eefad204b5180df6a14ee197d99d808ee52d&chain=mainnet',
- icon: 'uniswap.png',
- },
- {
- link: 'https://app.thorswap.finance/swap/ETH.ETH_ETH.FOX-0XC770EEFAD204B5180DF6A14EE197D99D808EE52D',
- icon: 'thorswap.png',
- },
- ],
- },
- {
- title: 'plugins.foxPage.centralized',
- opportunities: [
- {
- link: 'https://www.coinbase.com/price/fox-token',
- icon: 'coinbase.png',
- },
- ],
- },
-]
-
-export const foxyTradeOpportunitiesBuckets: TradeOpportunitiesBucket[] = [
- {
- title: 'plugins.foxPage.dex',
- opportunities: [
- {
- link: 'https://elasticswap.org/',
- icon: 'elasticswap.png',
- },
- ],
- },
-]
diff --git a/src/plugins/foxPage/components/AssetActions.tsx b/src/plugins/foxPage/components/AssetActions.tsx
deleted file mode 100644
index b253bcdd143..00000000000
--- a/src/plugins/foxPage/components/AssetActions.tsx
+++ /dev/null
@@ -1,212 +0,0 @@
-import { ExternalLinkIcon } from '@chakra-ui/icons'
-import {
- Box,
- Button,
- Card,
- CardBody,
- Link,
- Skeleton,
- SkeletonText,
- Stack,
- Tab,
- TabList,
- TabPanel,
- TabPanels,
- Tabs,
- Text as CText,
-} from '@chakra-ui/react'
-import type { AssetId } from '@shapeshiftoss/caip'
-import { foxAssetId } from '@shapeshiftoss/caip'
-import { supportsETH } from '@shapeshiftoss/hdwallet-core/dist/wallet'
-import isEqual from 'lodash/isEqual'
-import qs from 'qs'
-import { useCallback, useMemo } from 'react'
-import { useTranslate } from 'react-polyglot'
-import { useHistory, useLocation } from 'react-router'
-import { AssetIcon } from 'components/AssetIcon'
-import { MultiHopTrade } from 'components/MultiHopTrade/MultiHopTrade'
-import { Text } from 'components/Text/Text'
-import { WalletActions } from 'context/WalletProvider/actions'
-import { useModal } from 'hooks/useModal/useModal'
-import { useWallet } from 'hooks/useWallet/useWallet'
-import { foxyAddresses } from 'lib/investor/investor-foxy'
-import { getMixPanel } from 'lib/mixpanel/mixPanelSingleton'
-import { MixPanelEvents } from 'lib/mixpanel/types'
-import { DefiProvider } from 'state/slices/opportunitiesSlice/types'
-import { trimWithEndEllipsis } from 'state/slices/portfolioSlice/utils'
-import { selectAccountIdsByAssetId, selectAssetById } from 'state/slices/selectors'
-import { useAppSelector } from 'state/store'
-
-import { TrimmedDescriptionLength } from '../FoxCommon'
-
-type FoxTabProps = {
- assetId: AssetId
-}
-
-const BuyFoxCoinbaseUrl = 'https://www.coinbase.com/price/fox-token'
-const TradeFoxyElasticSwapUrl = `https://elasticswap.org/#/swap`
-
-const externalLinkIcon =
-
-export const AssetActions: React.FC = ({ assetId }) => {
- const translate = useTranslate()
- const location = useLocation()
- const history = useHistory()
- const asset = useAppSelector(state => selectAssetById(state, assetId))
- if (!asset) throw new Error(`Asset not found for AssetId ${assetId}`)
- const { description } = asset || {}
- const trimmedDescription = trimWithEndEllipsis(description, TrimmedDescriptionLength)
- const isFoxAsset = assetId === foxAssetId
-
- const filter = useMemo(() => ({ assetId }), [assetId])
- const accountIds = useAppSelector(state => selectAccountIdsByAssetId(state, filter), isEqual)
- const accountId = accountIds?.[0]
-
- const {
- state: { isConnected, isDemoWallet, wallet },
- dispatch,
- } = useWallet()
- const receive = useModal('receive')
-
- const walletSupportsETH = useMemo(() => Boolean(wallet && supportsETH(wallet)), [wallet])
-
- const handleWalletModalOpen = useCallback(
- () => dispatch({ type: WalletActions.SET_WALLET_MODAL, payload: true }),
- [dispatch],
- )
- const handleReceiveClick = useCallback(
- () =>
- !isDemoWallet && isConnected && walletSupportsETH
- ? receive.open({ asset, accountId })
- : handleWalletModalOpen(),
- [
- accountId,
- asset,
- handleWalletModalOpen,
- isConnected,
- isDemoWallet,
- receive,
- walletSupportsETH,
- ],
- )
-
- const receiveButtonTranslation = useMemo(
- () => (!isDemoWallet && walletSupportsETH ? 'plugins.foxPage.receive' : 'common.connectWallet'),
- [isDemoWallet, walletSupportsETH],
- )
-
- const onGetAssetClick = useCallback(() => {
- history.push({
- pathname: location.pathname,
- search: qs.stringify({
- provider: DefiProvider.ShapeShift,
- chainId: asset.chainId,
- assetNamespace: 'erc20',
- contractAddress: foxyAddresses[0].foxy,
- assetReference: foxyAddresses[0].staking,
- rewardId: foxyAddresses[0].foxy,
- modal: 'overview',
- }),
- state: { background: location },
- })
- }, [asset.chainId, history, location])
-
- const handleCoinbaseButtonClick = useCallback(
- () => getMixPanel()?.track(MixPanelEvents.Click, { element: 'Coinbase Button' }),
- [],
- )
-
- return (
-
-
-
-
-
- {translate('plugins.foxPage.getAsset', {
- assetSymbol: asset.symbol,
- })}
-
-
- {translate('plugins.foxPage.trade')}
-
-
-
-
-
-
-
-
-
- {trimmedDescription}
-
-
-
- {!isFoxAsset && (
-
- )}
- {isFoxAsset && (
-
- )}
-
-
-
-
-
-
- {isFoxAsset ? : null}
- {!isFoxAsset && (
-
-
-
- {translate('plugins.foxPage.tradingUnavailable', {
- assetSymbol: asset.symbol,
- })}
-
-
-
-
- )}
-
-
-
-
-
- )
-}
diff --git a/src/plugins/foxPage/components/BondProtocolCta.tsx b/src/plugins/foxPage/components/BondProtocolCta.tsx
deleted file mode 100644
index 5dbe0b7c6de..00000000000
--- a/src/plugins/foxPage/components/BondProtocolCta.tsx
+++ /dev/null
@@ -1,35 +0,0 @@
-import { Button, Card, CardBody, CardHeader, Heading, Link } from '@chakra-ui/react'
-import { useCallback } from 'react'
-import { useTranslate } from 'react-polyglot'
-import { Text } from 'components/Text'
-import { getMixPanel } from 'lib/mixpanel/mixPanelSingleton'
-import { MixPanelEvents } from 'lib/mixpanel/types'
-
-export const BondProtocolCta = () => {
- const translate = useTranslate()
-
- const handleClick = useCallback(() => {
- getMixPanel()?.track(MixPanelEvents.Click, { element: 'BondProtocol Button' })
- }, [])
- return (
-
-
-
-
-
-
-
-
-
-
-
- )
-}
diff --git a/src/plugins/foxPage/components/DappBack.tsx b/src/plugins/foxPage/components/DappBack.tsx
deleted file mode 100644
index 5ebe6dcc26b..00000000000
--- a/src/plugins/foxPage/components/DappBack.tsx
+++ /dev/null
@@ -1,38 +0,0 @@
-import { Button, Card, CardBody, CardHeader, Heading, Link } from '@chakra-ui/react'
-import { useCallback } from 'react'
-import { useTranslate } from 'react-polyglot'
-import { Text } from 'components/Text'
-import { useFeatureFlag } from 'hooks/useFeatureFlag/useFeatureFlag'
-import { getMixPanel } from 'lib/mixpanel/mixPanelSingleton'
-import { MixPanelEvents } from 'lib/mixpanel/types'
-
-export const DappBack = () => {
- const translate = useTranslate()
- const isFoxBondCTAEnabled = useFeatureFlag('FoxBondCTA')
-
- const handleClick = useCallback(() => {
- getMixPanel()?.track(MixPanelEvents.Click, { element: 'Dappback Button' })
- }, [])
- if (!isFoxBondCTAEnabled) return null
- return (
-
-
-
-
-
-
-
-
-
-
-
- )
-}
diff --git a/src/plugins/foxPage/components/FoxChart.tsx b/src/plugins/foxPage/components/FoxChart.tsx
deleted file mode 100644
index a67d20bdbc9..00000000000
--- a/src/plugins/foxPage/components/FoxChart.tsx
+++ /dev/null
@@ -1,91 +0,0 @@
-import {
- Box,
- Card,
- CardBody,
- CardFooter,
- Stat,
- StatArrow,
- StatNumber,
- Text,
-} from '@chakra-ui/react'
-import type { HistoryTimeframe } from '@shapeshiftoss/types'
-import { useState } from 'react'
-import NumberFormat from 'react-number-format'
-import { useTranslate } from 'react-polyglot'
-import { TimeControls } from 'components/Graph/TimeControls'
-import { PriceChart } from 'components/PriceChart/PriceChart'
-import { RawText } from 'components/Text/Text'
-import { useLocaleFormatter } from 'hooks/useLocaleFormatter/useLocaleFormatter'
-import { useTimeframeChange } from 'hooks/useTimeframeChange/useTimeframeChange'
-import { selectChartTimeframe, selectMarketDataById } from 'state/slices/selectors'
-import { useAppSelector } from 'state/store'
-
-type FoxChartProps = {
- assetId: string
-}
-
-const timeControlsButtonGroupProps = {
- display: 'flex',
- width: 'full',
- justifyContent: 'space-between',
-}
-
-export const FoxChart: React.FC = ({ assetId }) => {
- const userChartTimeframe = useAppSelector(selectChartTimeframe)
- const [timeframe, setTimeframe] = useState(userChartTimeframe)
- const handleTimeframeChange = useTimeframeChange(setTimeframe)
- const [percentChange, setPercentChange] = useState(0)
- const {
- number: { toFiat },
- } = useLocaleFormatter()
- const translate = useTranslate()
- const marketData = useAppSelector(state => selectMarketDataById(state, assetId))
- const { price } = marketData || {}
- const assetPrice = toFiat(price) ?? 0
-
- return (
-
-
-
-
- {translate('plugins.foxPage.currentPrice')}
-
-
-
-
-
- 0 ? 'green.500' : 'red.500'}
- >
- 0 ? 'increase' : 'decrease'} />
- {isFinite(percentChange) && {percentChange}%}
-
-
-
-
-
-
-
-
-
- )
-}
diff --git a/src/plugins/foxPage/components/FoxTab.tsx b/src/plugins/foxPage/components/FoxTab.tsx
deleted file mode 100644
index e9a8c8c9b8d..00000000000
--- a/src/plugins/foxPage/components/FoxTab.tsx
+++ /dev/null
@@ -1,87 +0,0 @@
-import type { ResponsiveValue, TabProps } from '@chakra-ui/react'
-import { Card, CardBody, Flex, SkeletonText, Tab, useColorModeValue } from '@chakra-ui/react'
-import type { Property } from 'csstype'
-import { useMemo } from 'react'
-import { Amount } from 'components/Amount/Amount'
-import { AssetIcon } from 'components/AssetIcon'
-
-type FoxTabProps = {
- assetIcon: string
- assetSymbol: string
- fiatAmount: string
- cryptoAmount: string
- onClick?: () => void
-} & TabProps
-
-const tabFocus = { borderWidth: '0' }
-const tabBorderWidth = { base: 0, md: '1px' }
-const cardBodyPx = { base: 6, md: 4 }
-const cardFlexDirection: ResponsiveValue = { base: 'row', md: 'column' }
-const flexMb = { base: 0, md: 6 }
-const flexMr = { base: 2, md: 0 }
-
-export const FoxTab: React.FC = ({
- assetIcon,
- assetSymbol,
- fiatAmount,
- cryptoAmount,
- onClick,
- ...props
-}) => {
- const bgHover = useColorModeValue('gray.100', 'gray.750')
-
- const tabSelected = useMemo(
- () => ({
- bg: { base: 'none', md: bgHover },
- borderColor: 'primary',
- borderWidth: { base: 0, md: '2px' },
- }),
- [bgHover],
- )
-
- const tabHover = useMemo(
- () => ({ textDecoration: 'none', bg: { base: 'none', md: bgHover } }),
- [bgHover],
- )
-
- return (
-
-
-
-
-
-
-
-
-
-
-
-
-
- )
-}
diff --git a/src/plugins/foxPage/components/Governance.tsx b/src/plugins/foxPage/components/Governance.tsx
deleted file mode 100644
index 4dd3427fcfd..00000000000
--- a/src/plugins/foxPage/components/Governance.tsx
+++ /dev/null
@@ -1,93 +0,0 @@
-import {
- Badge,
- Box,
- Card,
- CardBody,
- CardHeader,
- Flex,
- Link,
- Progress,
- Skeleton,
- Text as CText,
- useColorModeValue,
-} from '@chakra-ui/react'
-import { getConfig } from 'config'
-import { Amount } from 'components/Amount/Amount'
-import { Text } from 'components/Text/Text'
-import { bnOrZero } from 'lib/bignumber/bignumber'
-
-import { useGetGovernanceData } from '../hooks/getGovernanceData'
-
-const BOARDROOM_APP_BASE_URL = getConfig().REACT_APP_BOARDROOM_APP_BASE_URL
-const SNAPSHOT_BASE_URL = getConfig().REACT_APP_SNAPSHOT_BASE_URL
-
-export const Governance = () => {
- const linkColor = useColorModeValue('blue.500', 'blue.200')
- const governanceData = useGetGovernanceData()
-
- return (
-
-
-
-
-
-
-
-
-
-
-
- {governanceData?.data.map((proposal, i) => (
-
-
-
- {proposal.title}
-
- {proposal.choices.map((choice, i) => (
-
-
- {choice}
-
-
-
-
-
-
-
-
-
-
- ))}
-
-
- ))}
-
-
- )
-}
diff --git a/src/plugins/foxPage/components/Layout.tsx b/src/plugins/foxPage/components/Layout.tsx
deleted file mode 100644
index 5e269d41d80..00000000000
--- a/src/plugins/foxPage/components/Layout.tsx
+++ /dev/null
@@ -1,53 +0,0 @@
-import { Box, Container, Text, useColorModeValue } from '@chakra-ui/react'
-import type { ReactNode } from 'react'
-import foxPageBg from 'assets/foxpage-bg.png'
-import { AssetIcon } from 'components/AssetIcon'
-
-type FoxLayoutProps = {
- children: ReactNode
- icon: string
- title: string
- description: string
-}
-
-const boxPy = { base: 8, md: 12 }
-const boxMb = { base: 0, md: 4 }
-const boxPx = { base: 0, md: 8 }
-const boxDisplay = { base: 'none', md: 'block' }
-const boxMinHeight = { base: '285px', sm: '235px', md: '190px' }
-const containerPx = { base: 0, md: 16 }
-
-export const Layout = ({ children, icon, title, description }: FoxLayoutProps) => {
- const descriptionColor = useColorModeValue('gray.750', 'whiteAlpha.700')
-
- return (
- <>
-
-
-
-
-
- {title}
-
- {description}
-
-
-
-
- {children}
-
- >
- )
-}
diff --git a/src/plugins/foxPage/components/MainOpportunity.tsx b/src/plugins/foxPage/components/MainOpportunity.tsx
deleted file mode 100644
index 833f644c721..00000000000
--- a/src/plugins/foxPage/components/MainOpportunity.tsx
+++ /dev/null
@@ -1,158 +0,0 @@
-import type { ResponsiveValue } from '@chakra-ui/react'
-import {
- Box,
- Button,
- Card,
- CardBody,
- CardHeader,
- Flex,
- Skeleton,
- Text as CText,
- useColorModeValue,
-} from '@chakra-ui/react'
-import type { ToAssetIdArgs } from '@shapeshiftoss/caip'
-import { ethChainId } from '@shapeshiftoss/caip'
-import { supportsETH } from '@shapeshiftoss/hdwallet-core/dist/wallet'
-import type { Property } from 'csstype'
-import { useMemo } from 'react'
-import { Amount } from 'components/Amount/Amount'
-import { AssetIcon } from 'components/AssetIcon'
-import type { TextPropTypes } from 'components/Text/Text'
-import { Text } from 'components/Text/Text'
-import { useWallet } from 'hooks/useWallet/useWallet'
-import { bnOrZero } from 'lib/bignumber/bignumber'
-import { foxyAddresses } from 'lib/investor/investor-foxy'
-import { toOpportunityId } from 'state/slices/opportunitiesSlice/utils'
-import {
- selectAggregatedEarnUserStakingOpportunityByStakingId,
- selectAssetById,
-} from 'state/slices/selectors'
-import { useAppSelector } from 'state/store'
-
-type MainOpportunityProps = {
- apy: string
- assetId: string
- balance: string
- isLoaded: boolean
- onClick: () => void
- tvl: string
-}
-
-const flexDirectionRow: ResponsiveValue = { base: 'column', md: 'row' }
-const flexDirectionColumn: ResponsiveValue = { base: 'row', md: 'column' }
-const alignItemsFlexStart = { base: 'center', md: 'flex-start' }
-
-export const MainOpportunity = ({
- apy,
- assetId,
- tvl,
- balance,
- onClick,
- isLoaded,
-}: MainOpportunityProps) => {
- const {
- state: { wallet, isDemoWallet },
- } = useWallet()
- const greenColor = useColorModeValue('green.600', 'green.400')
- const selectedAsset = useAppSelector(state => selectAssetById(state, assetId))
- if (!selectedAsset) throw new Error(`Asset not found for AssetId ${assetId}`)
-
- const toAssetIdParts: ToAssetIdArgs = {
- assetNamespace: 'erc20',
- assetReference: foxyAddresses[0].staking,
- chainId: ethChainId,
- }
-
- const opportunityId = toOpportunityId(toAssetIdParts)
- const opportunityDataFilter = useMemo(() => {
- return {
- stakingId: opportunityId,
- }
- }, [opportunityId])
-
- const foxyEarnOpportunityData = useAppSelector(state =>
- opportunityDataFilter
- ? selectAggregatedEarnUserStakingOpportunityByStakingId(state, opportunityDataFilter)
- : undefined,
- )
- const hasActiveStaking = bnOrZero(foxyEarnOpportunityData?.stakedAmountCryptoBaseUnit).gt(0)
-
- const opportunityButtonTranslation = useMemo(() => {
- if (isDemoWallet || !wallet || !supportsETH(wallet)) return 'common.connectWallet'
- if (hasActiveStaking) return 'plugins.foxPage.manage'
- return 'plugins.foxPage.getStarted'
- }, [isDemoWallet, wallet, hasActiveStaking])
-
- const isOpportunityButtonReady = useMemo(
- () => Boolean(isDemoWallet || (wallet && !supportsETH(wallet)) || foxyEarnOpportunityData),
- [isDemoWallet, wallet, foxyEarnOpportunityData],
- )
-
- const mainStakingTitleTranslation: TextPropTypes['translation'] = useMemo(
- () => [
- 'plugins.foxPage.mainStakingTitle',
- {
- assetSymbol: selectedAsset.symbol,
- },
- ],
- [selectedAsset.symbol],
- )
-
- return (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {balance}
-
-
-
-
-
-
-
-
-
-
- )
-}
diff --git a/src/plugins/foxPage/components/OtherOpportunities/FoxOtherOpportunityPanel.tsx b/src/plugins/foxPage/components/OtherOpportunities/FoxOtherOpportunityPanel.tsx
deleted file mode 100644
index 31dcbf61764..00000000000
--- a/src/plugins/foxPage/components/OtherOpportunities/FoxOtherOpportunityPanel.tsx
+++ /dev/null
@@ -1,65 +0,0 @@
-import {
- AccordionButton,
- AccordionIcon,
- AccordionItem,
- AccordionPanel,
- Badge,
- Box,
- Flex,
- useColorModeValue,
-} from '@chakra-ui/react'
-import { useMemo } from 'react'
-import { useTranslate } from 'react-polyglot'
-import type { DefiType } from 'state/slices/opportunitiesSlice/types'
-
-import type { ExternalOpportunity, OpportunityTypes } from '../../FoxCommon'
-import { FoxOtherOpportunityPanelRow } from './FoxOtherOpportunityPanelRow'
-
-type FoxOtherOpportunityPanelProps = {
- opportunities: ExternalOpportunity[]
- title: string
- type: OpportunityTypes | DefiType
-}
-
-const accordionItemLast = { borderBottomWidth: 0 }
-
-export const FoxOtherOpportunityPanel: React.FC = ({
- opportunities,
- title,
-}) => {
- const translate = useTranslate()
- const borderColor = useColorModeValue('gray.150', 'gray.700')
-
- const renderRows = useMemo(() => {
- return opportunities?.map((opportunity, index) => (
-
- ))
- }, [opportunities])
-
- return (
-
-
-
- {translate(title)}
-
-
-
- {opportunities.length}
-
-
-
-
-
- {renderRows}
-
-
- )
-}
diff --git a/src/plugins/foxPage/components/OtherOpportunities/FoxOtherOpportunityPanelRow.tsx b/src/plugins/foxPage/components/OtherOpportunities/FoxOtherOpportunityPanelRow.tsx
deleted file mode 100644
index f9fa2893fef..00000000000
--- a/src/plugins/foxPage/components/OtherOpportunities/FoxOtherOpportunityPanelRow.tsx
+++ /dev/null
@@ -1,218 +0,0 @@
-import { ExternalLinkIcon } from '@chakra-ui/icons'
-import type { ResponsiveValue } from '@chakra-ui/react'
-import {
- Box,
- Button,
- Flex,
- Link,
- Skeleton,
- Text as CText,
- useColorModeValue,
-} from '@chakra-ui/react'
-import { ASSET_NAMESPACE, ethChainId, fromAssetId } from '@shapeshiftoss/caip'
-import { supportsETH } from '@shapeshiftoss/hdwallet-core'
-import type { Property } from 'csstype'
-import qs from 'qs'
-import { useCallback, useMemo } from 'react'
-import { useHistory, useLocation } from 'react-router'
-import { Amount } from 'components/Amount/Amount'
-import { AssetIcon } from 'components/AssetIcon'
-import { Text } from 'components/Text/Text'
-import { WalletActions } from 'context/WalletProvider/actions'
-import { useWallet } from 'hooks/useWallet/useWallet'
-import { bnOrZero } from 'lib/bignumber/bignumber'
-import { trackOpportunityEvent } from 'lib/mixpanel/helpers'
-import { MixPanelEvents } from 'lib/mixpanel/types'
-import { DefiProvider, DefiType } from 'state/slices/opportunitiesSlice/types'
-import { toOpportunityId } from 'state/slices/opportunitiesSlice/utils'
-import {
- selectAggregatedEarnUserLpOpportunity,
- selectAggregatedEarnUserStakingOpportunityByStakingId,
- selectAssets,
-} from 'state/slices/selectors'
-import { useAppSelector } from 'state/store'
-
-import type { ExternalOpportunity } from '../../FoxCommon'
-
-type FoxOtherOpportunityPanelRowProps = {
- opportunity: ExternalOpportunity
-}
-
-const flexWidth = { base: 'auto', md: '40%' }
-const assetIconBoxSize = { base: 6, md: 8 }
-const apyTextAlign: ResponsiveValue = { base: 'right', md: 'center' }
-const opportunityButtonDisplay = { base: 'none', md: 'block' }
-
-export const FoxOtherOpportunityPanelRow: React.FC = ({
- opportunity,
-}) => {
- const {
- state: { isDemoWallet, wallet },
- dispatch,
- } = useWallet()
- const assets = useAppSelector(selectAssets)
- const opportunityId = useMemo(
- () =>
- opportunity.contractAddress &&
- toOpportunityId({
- assetReference: opportunity.contractAddress,
- assetNamespace: 'erc20',
- chainId: ethChainId,
- }),
- [opportunity.contractAddress],
- )
-
- const earnOpportunity = useAppSelector(state => {
- if (!opportunityId) return
-
- return opportunity.type === DefiType.LiquidityPool
- ? selectAggregatedEarnUserLpOpportunity(state, {
- assetId: opportunityId,
- lpId: opportunityId,
- })
- : selectAggregatedEarnUserStakingOpportunityByStakingId(state, {
- stakingId: opportunityId,
- })
- })
-
- const hoverOpportunityBg = useColorModeValue('gray.100', 'gray.750')
- const greenColor = useColorModeValue('green.600', 'green.400')
- const hasActivePosition = bnOrZero(earnOpportunity?.cryptoAmountBaseUnit).gt(0) ?? false
- const history = useHistory()
- const location = useLocation()
- const wrapperLinkProps = useMemo(
- () => (earnOpportunity ? {} : { as: Link, isExternal: true, href: opportunity.link }),
- [earnOpportunity, opportunity.link],
- )
-
- const handleClick = useCallback(() => {
- if (opportunity.link) {
- window.open(opportunity.link)
- return
- }
-
- if (isDemoWallet || !wallet || !supportsETH(wallet)) {
- dispatch({ type: WalletActions.SET_WALLET_MODAL, payload: true })
- return
- }
-
- if (earnOpportunity) {
- const { chainId, contractAddress, rewardAddress } = earnOpportunity
- trackOpportunityEvent(
- MixPanelEvents.ClickOpportunity,
- {
- opportunity: earnOpportunity,
- element: 'Table Row',
- },
- assets,
- )
- history.push({
- pathname: location.pathname,
- search: qs.stringify({
- type: earnOpportunity.type,
- provider:
- opportunity.type === DefiType.LiquidityPool
- ? DefiProvider.UniV2
- : DefiProvider.EthFoxStaking,
- chainId,
- contractAddress,
- assetNamespace: ASSET_NAMESPACE.erc20,
- assetReference: earnOpportunity.underlyingAssetId
- ? fromAssetId(earnOpportunity.underlyingAssetId).assetReference
- : undefined,
- highestBalanceAccountAddress: opportunity.highestBalanceAccountAddress,
- rewardId: rewardAddress,
- modal: 'overview',
- }),
- state: { background: location },
- })
- return
- }
- }, [
- opportunity.link,
- opportunity.type,
- opportunity.highestBalanceAccountAddress,
- isDemoWallet,
- wallet,
- earnOpportunity,
- dispatch,
- assets,
- history,
- location,
- ])
-
- const opportunityButtonTranslation = useMemo(() => {
- if (opportunity.link) return 'plugins.foxPage.getStarted'
- if (isDemoWallet || !wallet || !supportsETH(wallet)) return 'common.connectWallet'
-
- return hasActivePosition ? 'plugins.foxPage.manage' : 'plugins.foxPage.getStarted'
- }, [isDemoWallet, opportunity.link, hasActivePosition, wallet])
-
- const isOpportunityButtonReady = useMemo(
- () => Boolean(isDemoWallet || (wallet && !supportsETH(wallet)) || earnOpportunity),
- [isDemoWallet, wallet, earnOpportunity],
- )
-
- const hoverStyle = useMemo(
- () => ({ bg: hoverOpportunityBg, textDecoration: 'none' }),
- [hoverOpportunityBg],
- )
-
- if (!opportunity) return null
-
- return (
-
-
- {opportunity.icons?.map((iconSrc, i, icons) => (
-
- ))}
-
- {opportunity.name}
-
-
-
-
-
-
- {opportunity.apy ? : '--'}
-
-
-
-
-
- {earnOpportunity ? (
-
- ) : (
-
- )}
-
-
-
- )
-}
diff --git a/src/plugins/foxPage/components/OtherOpportunities/OtherOpportunities.tsx b/src/plugins/foxPage/components/OtherOpportunities/OtherOpportunities.tsx
deleted file mode 100644
index d3a486aee1b..00000000000
--- a/src/plugins/foxPage/components/OtherOpportunities/OtherOpportunities.tsx
+++ /dev/null
@@ -1,51 +0,0 @@
-import { Accordion, Card, CardHeader, Flex } from '@chakra-ui/react'
-import type { OpportunitiesBucket } from 'plugins/foxPage/FoxCommon'
-import { useMemo } from 'react'
-import { Text } from 'components/Text/Text'
-
-import { FoxOtherOpportunityPanel } from './FoxOtherOpportunityPanel'
-
-type OtherOpportunitiesProps = {
- title: string
- description: string
- opportunities: OpportunitiesBucket[]
-}
-
-const defaultIndex = [0]
-
-export const OtherOpportunities: React.FC = ({
- title,
- description,
- opportunities,
-}) => {
- const renderRows = useMemo(() => {
- return opportunities.map(opportunitiesBucket => {
- const { opportunities } = opportunitiesBucket
- if (!opportunities.length || opportunities.every(opportunity => opportunity.isDisabled))
- return null
-
- return (
-
- )
- })
- }, [opportunities])
-
- return (
-
-
-
-
-
-
-
-
- {renderRows}
-
-
- )
-}
diff --git a/src/plugins/foxPage/components/Total.tsx b/src/plugins/foxPage/components/Total.tsx
deleted file mode 100644
index e564fce1aa3..00000000000
--- a/src/plugins/foxPage/components/Total.tsx
+++ /dev/null
@@ -1,54 +0,0 @@
-import type { ResponsiveValue } from '@chakra-ui/react'
-import { Flex, SkeletonText, Text } from '@chakra-ui/react'
-import type { Property } from 'csstype'
-import { useTranslate } from 'react-polyglot'
-import { Amount } from 'components/Amount/Amount'
-import { AssetIcon } from 'components/AssetIcon'
-
-type TotalProps = {
- icons: string[]
- fiatAmount: string
-}
-
-const flexDirection: ResponsiveValue = { base: 'row-reverse', md: 'column' }
-const alignItems = { base: 'center', md: 'flex-start' }
-const justifyContent = { base: 'space-between', md: 'flex-start' }
-const flexMb = { base: 0, md: 6 }
-
-export const Total = ({ icons, fiatAmount }: TotalProps) => {
- const translate = useTranslate()
-
- return (
-
-
- {icons.map((icon, index) => (
- 0 ? '-3.5' : 0}
- />
- ))}
-
-
-
- {translate('plugins.foxPage.totalFoxValue')}
-
-
-
-
- )
-}
diff --git a/src/plugins/foxPage/components/TradeOpportunities.tsx b/src/plugins/foxPage/components/TradeOpportunities.tsx
deleted file mode 100644
index 135befe59fe..00000000000
--- a/src/plugins/foxPage/components/TradeOpportunities.tsx
+++ /dev/null
@@ -1,50 +0,0 @@
-import { Box, Card, CardBody, CardHeader, Flex, Image, Link, Text as CText } from '@chakra-ui/react'
-import { useTranslate } from 'react-polyglot'
-import { Text } from 'components/Text/Text'
-
-type TradeOpportunity = {
- link: string
- icon: string
-}
-
-export type TradeOpportunitiesBucket = {
- title: string
- opportunities: TradeOpportunity[]
-}
-
-type TradeOpportunitiesProps = {
- opportunities: TradeOpportunitiesBucket[]
-}
-
-export const TradeOpportunities: React.FC = ({ opportunities }) => {
- const translate = useTranslate()
-
- return (
-
-
-
- {translate('plugins.foxPage.availableToTradeOn')}
-
-
-
- {opportunities.map((bucket, index) => (
-
-
-
- {bucket.opportunities.map((opportunity, index) => (
-
-
-
- ))}
-
-
- ))}
-
-
- )
-}
diff --git a/src/plugins/foxPage/foxPage.tsx b/src/plugins/foxPage/foxPage.tsx
deleted file mode 100644
index a42a24d8ff2..00000000000
--- a/src/plugins/foxPage/foxPage.tsx
+++ /dev/null
@@ -1,357 +0,0 @@
-import { ChevronDownIcon } from '@chakra-ui/icons'
-import type { StackDirection } from '@chakra-ui/react'
-import {
- Box,
- Button,
- Menu,
- MenuButton,
- MenuItem,
- MenuList,
- SimpleGrid,
- Stack,
- TabList,
- TabPanel,
- TabPanels,
- Tabs,
- useColorModeValue,
- useMediaQuery,
-} from '@chakra-ui/react'
-import type { AssetId, ToAssetIdArgs } from '@shapeshiftoss/caip'
-import { ethChainId, foxAssetId, foxyAssetId } from '@shapeshiftoss/caip'
-import { supportsETH } from '@shapeshiftoss/hdwallet-core'
-import qs from 'qs'
-import { useCallback, useMemo } from 'react'
-import { useTranslate } from 'react-polyglot'
-import { useHistory, useLocation } from 'react-router'
-import { AssetMarketData } from 'components/AssetHeader/AssetMarketData'
-import { SEO } from 'components/Layout/Seo'
-import { WalletActions } from 'context/WalletProvider/actions'
-import { useRouteAssetId } from 'hooks/useRouteAssetId/useRouteAssetId'
-import { useWallet } from 'hooks/useWallet/useWallet'
-import { bn, bnOrZero } from 'lib/bignumber/bignumber'
-import { foxyAddresses } from 'lib/investor/investor-foxy'
-import { trackOpportunityEvent } from 'lib/mixpanel/helpers'
-import { getMixPanel } from 'lib/mixpanel/mixPanelSingleton'
-import { MixPanelEvents } from 'lib/mixpanel/types'
-import { useGetFoxyAprQuery } from 'state/apis/foxy/foxyApi'
-import { useGetAssetDescriptionQuery } from 'state/slices/assetsSlice/assetsSlice'
-import { DefiProvider } from 'state/slices/opportunitiesSlice/types'
-import { toOpportunityId } from 'state/slices/opportunitiesSlice/utils'
-import {
- selectAggregatedEarnUserStakingOpportunityByStakingId,
- selectAssetById,
- selectAssets,
- selectPortfolioCryptoPrecisionBalanceByFilter,
- selectPortfolioUserCurrencyBalanceByAssetId,
- selectSelectedLocale,
-} from 'state/slices/selectors'
-import { useAppSelector } from 'state/store'
-import { breakpoints } from 'theme/theme'
-
-import { AssetActions } from './components/AssetActions'
-import { BondProtocolCta } from './components/BondProtocolCta'
-import { DappBack } from './components/DappBack'
-import { FoxChart } from './components/FoxChart'
-import { FoxTab } from './components/FoxTab'
-import { Governance } from './components/Governance'
-import { Layout } from './components/Layout'
-import { MainOpportunity } from './components/MainOpportunity'
-import { OtherOpportunities } from './components/OtherOpportunities/OtherOpportunities'
-import { Total } from './components/Total'
-import type { TradeOpportunitiesBucket } from './components/TradeOpportunities'
-import { TradeOpportunities } from './components/TradeOpportunities'
-import { foxTradeOpportunitiesBuckets, foxyTradeOpportunitiesBuckets } from './FoxCommon'
-import { useOtherOpportunities } from './hooks/useOtherOpportunities'
-
-const gridTemplateColumns = { base: 'repeat(1, 1fr)', lg: 'repeat(3, 1fr)' }
-const boxMxProps = { base: 4, md: 0 }
-const tabPanelDirectionProps: StackDirection = { base: 'column', xl: 'row' }
-const stackMaxWidthProps = { base: 'full', lg: 'sm' }
-
-export enum FoxPageRoutes {
- Fox = '/fox/fox',
- Foxy = '/fox/foxy',
-}
-
-const assetsRoutes: Record = {
- [foxAssetId]: FoxPageRoutes.Fox,
- [foxyAssetId]: FoxPageRoutes.Foxy,
-}
-
-const assetsTradeOpportunitiesBuckets: Record = {
- [foxAssetId]: foxTradeOpportunitiesBuckets,
- [foxyAssetId]: foxyTradeOpportunitiesBuckets,
-}
-
-const chevronDownIcon =
-
-export const FoxPage = () => {
- const {
- state: { wallet },
- dispatch,
- } = useWallet()
- const translate = useTranslate()
- const history = useHistory()
- const location = useLocation()
- const mixpanel = getMixPanel()
-
- const activeAssetId = useRouteAssetId()
- const allAssets = useAppSelector(selectAssets)
- // TODO(gomes): Use useRouteAssetId and selectAssetById programmatically
- const assetFox = useAppSelector(state => selectAssetById(state, foxAssetId))
- const assetFoxy = useAppSelector(state => selectAssetById(state, foxyAssetId))
- if (!assetFox) throw new Error(`Asset not found for AssetId ${foxAssetId}`)
- if (!assetFoxy) throw new Error(`Asset not found for AssetId ${foxyAssetId}`)
-
- const otherOpportunities = useOtherOpportunities(activeAssetId)
-
- const assets = useMemo(() => [assetFox, assetFoxy], [assetFox, assetFoxy])
-
- const selectedAssetIndex = useMemo(
- () => assets.findIndex(asset => asset?.assetId === activeAssetId),
- [activeAssetId, assets],
- )
-
- const selectedAsset = assets[selectedAssetIndex]
-
- const foxFilter = useMemo(() => ({ assetId: foxAssetId }), [])
- const foxyFilter = useMemo(() => ({ assetId: foxyAssetId }), [])
- const fiatBalanceFox =
- useAppSelector(s => selectPortfolioUserCurrencyBalanceByAssetId(s, foxFilter)) ?? '0'
- const fiatBalanceFoxy =
- useAppSelector(s => selectPortfolioUserCurrencyBalanceByAssetId(s, foxyFilter)) ?? '0'
- const cryptoHumanBalanceFox =
- useAppSelector(s => selectPortfolioCryptoPrecisionBalanceByFilter(s, foxFilter)) ?? '0'
- const cryptoHumanBalanceFoxy =
- useAppSelector(s => selectPortfolioCryptoPrecisionBalanceByFilter(s, foxyFilter)) ?? '0'
-
- const fiatBalances = useMemo(
- () => [fiatBalanceFox, fiatBalanceFoxy],
- [fiatBalanceFox, fiatBalanceFoxy],
- )
-
- const cryptoHumanBalances = useMemo(
- () => [cryptoHumanBalanceFox, cryptoHumanBalanceFoxy],
- [cryptoHumanBalanceFox, cryptoHumanBalanceFoxy],
- )
-
- const { data: foxyAprData, isLoading: isFoxyAprLoading } = useGetFoxyAprQuery()
-
- const totalFiatBalance = bnOrZero(fiatBalanceFox).plus(bnOrZero(fiatBalanceFoxy)).toString()
-
- const [isLargerThanMd] = useMediaQuery(`(min-width: ${breakpoints['md']})`, { ssr: false })
- const mobileTabBg = useColorModeValue('gray.100', 'gray.750')
- const description =
- selectedAsset.assetId === foxAssetId
- ? translate('plugins.foxPage.foxDescription') // FOX has a custom description, other assets can use the asset-service one
- : selectedAsset.description
-
- const selectedLocale = useAppSelector(selectSelectedLocale)
- // TODO(gomes): Export a similar RTK select() query, consumed to determine wallet + staking balance loaded
- const getAssetDescriptionQuery = useGetAssetDescriptionQuery({
- assetId: selectedAsset.assetId,
- selectedLocale,
- })
- const isAssetDescriptionLoaded = !getAssetDescriptionQuery.isLoading
-
- const toAssetIdParts: ToAssetIdArgs = {
- assetNamespace: 'erc20',
- assetReference: foxyAddresses[0].staking,
- chainId: ethChainId,
- }
-
- const opportunityId = toOpportunityId(toAssetIdParts)
- const opportunityDataFilter = useMemo(() => {
- return {
- stakingId: opportunityId,
- }
- }, [opportunityId])
-
- const foxyEarnOpportunityData = useAppSelector(state =>
- opportunityDataFilter
- ? selectAggregatedEarnUserStakingOpportunityByStakingId(state, opportunityDataFilter)
- : undefined,
- )
-
- const totalIcons = useMemo(() => [assetFox.icon, assetFoxy.icon], [assetFox, assetFoxy])
-
- const handleTabClick = useCallback(
- (assetId: AssetId, assetName: string) => {
- if (assetId === activeAssetId) {
- return
- }
- mixpanel?.track(MixPanelEvents.Click, { element: `${assetName} toggle` })
- history.push(assetsRoutes[assetId])
- },
- [activeAssetId, history, mixpanel],
- )
-
- const handleOpportunityClick = useCallback(() => {
- if (!foxyEarnOpportunityData) return
- if (!wallet || !supportsETH(wallet)) {
- dispatch({ type: WalletActions.SET_WALLET_MODAL, payload: true })
- return
- }
-
- trackOpportunityEvent(
- MixPanelEvents.ClickOpportunity,
- {
- opportunity: foxyEarnOpportunityData,
- element: 'Fox Page Row',
- },
- allAssets,
- )
-
- history.push({
- pathname: location.pathname,
- search: qs.stringify({
- provider: DefiProvider.ShapeShift,
- chainId: assetFoxy.chainId,
- assetNamespace: 'erc20',
- contractAddress: foxyAddresses[0].foxy,
- assetReference: foxyAddresses[0].staking,
- rewardId: foxyAddresses[0].foxy,
- modal: 'overview',
- }),
- state: { background: location },
- })
- }, [allAssets, assetFoxy.chainId, dispatch, foxyEarnOpportunityData, history, location, wallet])
-
- const mdFoxTabs = useMemo(
- () =>
- assets.map((asset, index) => (
- handleTabClick(asset.assetId, asset.name)}
- />
- )),
- [assets, cryptoHumanBalances, fiatBalances, handleTabClick],
- )
-
- const smFoxTabs = useMemo(
- () =>
- assets.map((asset, index) => (
- // eslint-disable-next-line react-memo/require-usememo
-
- )),
- [assets, cryptoHumanBalances, fiatBalances, handleTabClick],
- )
-
- if (!isAssetDescriptionLoaded || !activeAssetId) return null
- if (wallet && supportsETH(wallet) && !foxyEarnOpportunityData) return null
-
- return (
-
-
-
-
-
-
- {isLargerThanMd && mdFoxTabs}
- {!isLargerThanMd && (
-
-
-
- )}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- )
-}
diff --git a/src/plugins/foxPage/hooks/getGovernanceData.test.ts b/src/plugins/foxPage/hooks/getGovernanceData.test.ts
deleted file mode 100644
index 6e922c1765d..00000000000
--- a/src/plugins/foxPage/hooks/getGovernanceData.test.ts
+++ /dev/null
@@ -1,129 +0,0 @@
-import type { BoardroomGovernanceResult } from './getGovernanceData'
-import { parseGovernanceData } from './getGovernanceData'
-
-const EMPTY_RESULTS_PROPOSAL: BoardroomGovernanceResult = {
- refId: 'refId1',
- title: 'Proposal 1',
- currentState: 'active',
- choices: ['YES', 'NO'],
- indexedResult: [],
-}
-const PARTIAL_RESULTS_PROPOSAL: BoardroomGovernanceResult = {
- refId: 'refId2',
- title: 'Proposal 2',
- currentState: 'active',
- choices: ['YES', 'NO'],
- indexedResult: [
- {
- total: 362512.22,
- choice: 0,
- },
- ],
-}
-
-const ALL_RESULTS_PROPOSAL: BoardroomGovernanceResult = {
- refId: 'refId3',
- title: 'Proposal 3',
- currentState: 'closed',
- choices: ['Yes (For)', 'No (Against)'],
- indexedResult: [
- {
- total: 4122544.5,
- choice: 0,
- },
- {
- total: 200,
- choice: 1,
- },
- ],
-}
-
-const INACTIVE_PROPOSAL: BoardroomGovernanceResult = {
- refId: 'refId4',
- title: 'Proposal 4',
- currentState: 'closed',
- choices: ['For', 'Against'],
- indexedResult: [
- {
- total: 5876468,
- choice: 0,
- },
- ],
-}
-
-const INACTIVE_PROPOSAL_TWO: BoardroomGovernanceResult = {
- refId: 'refId5',
- title: 'Proposal 5',
- currentState: 'closed',
- choices: ['For', 'Against'],
- indexedResult: [
- {
- total: 5876468,
- choice: 0,
- },
- ],
-}
-
-describe('parseGovernanceData', () => {
- const ZERO_RESULT = {
- absolute: '0',
- percent: '0',
- }
- it('populates and zeros out boardroom response with no results', () => {
- const data = [EMPTY_RESULTS_PROPOSAL]
- const parsedData = parseGovernanceData(data)
- expect(parsedData).toHaveLength(1)
- expect(parsedData[0].results).toHaveLength(2)
- expect(parsedData[0].results[0]).toMatchObject(ZERO_RESULT)
- expect(parsedData[0].results[1]).toMatchObject(ZERO_RESULT)
- })
- it('populates and zeros out the missing result items of a boardroom response with partial results', () => {
- const data = [PARTIAL_RESULTS_PROPOSAL]
- const parsedData = parseGovernanceData(data)
- expect(parsedData).toHaveLength(1)
- expect(parsedData[0].results).toHaveLength(2)
- expect(parsedData[0].results[0]).toMatchObject({
- absolute: '362512.22',
- percent: '1',
- })
- expect(parsedData[0].results[1]).toMatchObject(ZERO_RESULT)
- })
- it('parses a boardroom response with results for all choices', () => {
- const data = [ALL_RESULTS_PROPOSAL]
- const parsedData = parseGovernanceData(data)
- expect(parsedData).toHaveLength(1)
- expect(parsedData[0].results).toHaveLength(2)
- expect(parsedData[0].results[0]).toMatchObject({
- absolute: '4122544.5',
- percent: '0.99995148862608391085',
- })
- expect(parsedData[0].results[1]).toMatchObject({
- absolute: '200',
- percent: '0.00004851137391608915',
- })
- })
- it('builds a parsed response with the latest inactive proposal if all inactive', () => {
- const data = [INACTIVE_PROPOSAL, INACTIVE_PROPOSAL_TWO, ALL_RESULTS_PROPOSAL]
- const parsedData = parseGovernanceData(data)
- expect(parsedData).toHaveLength(1)
- expect(parsedData[0].results).toHaveLength(2)
- expect(parsedData[0].refId).toEqual(INACTIVE_PROPOSAL.refId)
- expect(parsedData[0].results[0]).toMatchObject({
- absolute: '5876468',
- percent: '1',
- })
- })
- it('builds a parsed response with all active proposals', () => {
- const data = [EMPTY_RESULTS_PROPOSAL, PARTIAL_RESULTS_PROPOSAL]
- const parsedData = parseGovernanceData(data)
- expect(parsedData).toHaveLength(2)
- expect(parsedData[0].results).toHaveLength(2)
- expect(parsedData[0].refId).toEqual(EMPTY_RESULTS_PROPOSAL.refId)
- expect(parsedData[1].refId).toEqual(PARTIAL_RESULTS_PROPOSAL.refId)
- expect(parsedData[0].results[0]).toMatchObject(ZERO_RESULT)
- expect(parsedData[1].results[0]).toMatchObject({
- absolute: '362512.22',
- percent: '1',
- })
- })
-})
diff --git a/src/plugins/foxPage/hooks/getGovernanceData.ts b/src/plugins/foxPage/hooks/getGovernanceData.ts
deleted file mode 100644
index a3197865cb8..00000000000
--- a/src/plugins/foxPage/hooks/getGovernanceData.ts
+++ /dev/null
@@ -1,78 +0,0 @@
-import axios from 'axios'
-import { getConfig } from 'config'
-import { useEffect, useState } from 'react'
-import { bnOrZero } from 'lib/bignumber/bignumber'
-
-// Non-exhaustive typings. We do not want to keep this a 1/1 mapping to an external API
-export type BoardroomGovernanceResult = {
- currentState: string
- title: string
- choices: string[]
- indexedResult: { total: number; choice: number }[]
- refId: string
-}
-
-export type ParsedBoardroomGovernanceResult = {
- refId: string
- title: string
- choices: string[]
- results: {
- absolute: string
- percent: string
- }[]
-}
-
-const BOARDROOM_API_BASE_URL = getConfig().REACT_APP_BOARDROOM_API_BASE_URL
-
-export const parseGovernanceData = (
- governanceData: BoardroomGovernanceResult[],
-): ParsedBoardroomGovernanceResult[] => {
- const activeProposals = governanceData.filter(data => data.currentState === 'active')
- const proposals = activeProposals.length ? activeProposals : [governanceData[0]]
-
- return proposals.map(({ title, choices, indexedResult, refId }) => {
- const totalResults = indexedResult.reduce((acc, currentResult) => {
- acc = acc.plus(currentResult.total)
- return acc
- }, bnOrZero('0'))
-
- return {
- refId,
- title,
- choices,
- results: choices.map((_, i) => ({
- absolute: bnOrZero(indexedResult[i]?.total).toString(),
- percent: indexedResult[i]
- ? bnOrZero(indexedResult[i].total).div(totalResults).toString()
- : '0',
- })),
- }
- })
-}
-
-export const useGetGovernanceData = () => {
- const [data, setData] = useState>([])
- const [error, setError] = useState()
- const [loaded, setLoaded] = useState(false)
-
- useEffect(() => {
- const loadGovernanceData = async () => {
- try {
- const response = await axios.get<{ data: BoardroomGovernanceResult[] }>(
- `${BOARDROOM_API_BASE_URL}proposals`,
- )
- const governanceData = response?.data?.data
- const parsedGovernanceData = parseGovernanceData(governanceData)
- setData(parsedGovernanceData)
- } catch (e) {
- setError(e)
- } finally {
- setLoaded(true)
- }
- }
-
- loadGovernanceData()
- }, [])
-
- return { data, error, loaded }
-}
diff --git a/src/plugins/foxPage/hooks/useOtherOpportunities.ts b/src/plugins/foxPage/hooks/useOtherOpportunities.ts
deleted file mode 100644
index d2bccee0834..00000000000
--- a/src/plugins/foxPage/hooks/useOtherOpportunities.ts
+++ /dev/null
@@ -1,154 +0,0 @@
-import type { AssetId } from '@shapeshiftoss/caip'
-import { foxAssetId, foxyAssetId, fromAccountId, fromAssetId } from '@shapeshiftoss/caip'
-import { useMemo } from 'react'
-import { bnOrZero } from 'lib/bignumber/bignumber'
-import { foxyAddresses } from 'lib/investor/investor-foxy'
-import { foxEthLpAssetId, foxEthStakingAssetIdV8 } from 'state/slices/opportunitiesSlice/constants'
-import type { StakingId } from 'state/slices/opportunitiesSlice/types'
-import { DefiType } from 'state/slices/opportunitiesSlice/types'
-import {
- selectAggregatedEarnUserLpOpportunity,
- selectHighestBalanceAccountIdByLpId,
- selectHighestBalanceAccountIdByStakingId,
- selectLpOpportunitiesById,
- selectStakingOpportunitiesById,
-} from 'state/slices/selectors'
-import { useAppSelector } from 'state/store'
-
-import type { OpportunitiesBucket } from '../FoxCommon'
-import { OpportunityTypes } from '../FoxCommon'
-
-export const useOtherOpportunities = (assetId: AssetId) => {
- const highestFarmingBalanceAccountIdFilter = useMemo(
- () => ({
- stakingId: foxEthStakingAssetIdV8 as StakingId,
- }),
- [],
- )
- const highestFarmingBalanceAccountId = useAppSelector(state =>
- selectHighestBalanceAccountIdByStakingId(state, highestFarmingBalanceAccountIdFilter),
- )
-
- const lpOpportunitiesById = useAppSelector(selectLpOpportunitiesById)
-
- const defaultLpOpportunityData = useMemo(
- () => lpOpportunitiesById[foxEthLpAssetId],
- [lpOpportunitiesById],
- )
- const lpOpportunityId = foxEthLpAssetId
- const highestBalanceLpAccountIdFilter = useMemo(
- () => ({ lpId: lpOpportunityId }),
- [lpOpportunityId],
- )
- const highestBalanceLpAccountId = useAppSelector(state =>
- selectHighestBalanceAccountIdByLpId(state, highestBalanceLpAccountIdFilter),
- )
-
- const foxEthLpOpportunityFilter = useMemo(
- () => ({
- lpId: foxEthLpAssetId,
- assetId: foxEthLpAssetId,
- }),
- [],
- )
- const foxEthLpOpportunity = useAppSelector(state =>
- selectAggregatedEarnUserLpOpportunity(state, foxEthLpOpportunityFilter),
- )
-
- const stakingOpportunities = useAppSelector(selectStakingOpportunitiesById)
-
- const foxFarmingOpportunityMetadata = useMemo(
- () => stakingOpportunities[foxEthStakingAssetIdV8 as StakingId],
- [stakingOpportunities],
- )
-
- const otherOpportunities = useMemo(() => {
- const opportunities: Record = {
- [foxAssetId]: [
- {
- type: DefiType.Staking,
- title: 'plugins.foxPage.farming',
- opportunities: [
- ...(foxFarmingOpportunityMetadata
- ? [
- {
- ...foxFarmingOpportunityMetadata,
- apy: Boolean(defaultLpOpportunityData && foxFarmingOpportunityMetadata)
- ? bnOrZero(foxFarmingOpportunityMetadata?.apy)
- .plus(defaultLpOpportunityData?.apy ?? 0)
- .toString()
- : undefined,
- contractAddress: fromAssetId(foxFarmingOpportunityMetadata.assetId)
- .assetReference,
- highestBalanceAccountAddress:
- highestFarmingBalanceAccountId &&
- fromAccountId(highestFarmingBalanceAccountId).account,
- },
- ]
- : []),
- ],
- },
- {
- type: DefiType.LiquidityPool,
- title: 'plugins.foxPage.liquidityPools',
- opportunities: [
- ...(foxEthLpOpportunity
- ? [
- {
- ...foxEthLpOpportunity,
- type: DefiType.LiquidityPool,
- contractAddress: fromAssetId(foxEthLpAssetId).assetReference,
- highestBalanceAccountAddress:
- highestBalanceLpAccountId && fromAccountId(highestBalanceLpAccountId).account,
- },
- ]
- : []),
- ],
- },
- {
- type: OpportunityTypes.BorrowingAndLending,
- title: 'plugins.foxPage.borrowingAndLending',
- opportunities: [
- {
- name: 'FOX',
- isLoaded: true,
- apy: null,
- link: 'https://app.rari.capital/fuse/pool/79',
- icons: ['https://assets.coincap.io/assets/icons/256/fox.png'],
- isDisabled: true,
- },
- ],
- },
- ],
- [foxyAssetId]: [
- {
- type: OpportunityTypes.LiquidityPool,
- title: 'plugins.foxPage.liquidityPools',
- opportunities: [
- {
- name: 'ElasticSwap',
- contractAddress: foxyAddresses[0].staking,
- isLoaded: true, // No network request here
- apy: null,
- link: 'https://elasticswap.org/#/liquidity',
- icons: [
- 'https://raw.githubusercontent.com/shapeshift/lib/main/packages/asset-service/src/generateAssetData/ethereum/icons/foxy-icon.png',
- ],
- },
- ],
- },
- ],
- }
-
- return opportunities[assetId]
- }, [
- assetId,
- defaultLpOpportunityData,
- foxFarmingOpportunityMetadata,
- foxEthLpOpportunity,
- highestBalanceLpAccountId,
- highestFarmingBalanceAccountId,
- ])
-
- return otherOpportunities
-}
diff --git a/src/plugins/foxPage/images/binance.png b/src/plugins/foxPage/images/binance.png
deleted file mode 100644
index 95148ff7ec5..00000000000
Binary files a/src/plugins/foxPage/images/binance.png and /dev/null differ
diff --git a/src/plugins/foxPage/images/coinbase.png b/src/plugins/foxPage/images/coinbase.png
deleted file mode 100644
index 931b11d2e92..00000000000
Binary files a/src/plugins/foxPage/images/coinbase.png and /dev/null differ
diff --git a/src/plugins/foxPage/images/elasticswap.png b/src/plugins/foxPage/images/elasticswap.png
deleted file mode 100644
index efa7d195cb5..00000000000
Binary files a/src/plugins/foxPage/images/elasticswap.png and /dev/null differ
diff --git a/src/plugins/foxPage/images/thorswap.png b/src/plugins/foxPage/images/thorswap.png
deleted file mode 100644
index dd0f00bba04..00000000000
Binary files a/src/plugins/foxPage/images/thorswap.png and /dev/null differ
diff --git a/src/plugins/foxPage/images/uniswap.png b/src/plugins/foxPage/images/uniswap.png
deleted file mode 100644
index 50c6dc8ae8d..00000000000
Binary files a/src/plugins/foxPage/images/uniswap.png and /dev/null differ
diff --git a/src/plugins/foxPage/index.tsx b/src/plugins/foxPage/index.tsx
deleted file mode 100644
index 3b9776b9061..00000000000
--- a/src/plugins/foxPage/index.tsx
+++ /dev/null
@@ -1,40 +0,0 @@
-import { type Plugins } from 'plugins/types'
-import { RouteCategory } from 'Routes/helpers'
-import { FoxIcon } from 'components/Icons/FoxIcon'
-
-import { FoxPage } from './foxPage'
-
-// eslint-disable-next-line import/no-default-export
-export default function register(): Plugins {
- return [
- [
- 'foxPage',
- {
- name: 'foxPage',
- icon: ,
- routes: [
- {
- path: '/fox',
- label: 'navBar.foxToken',
- main: () => ,
- icon: ,
- category: RouteCategory.Explore,
- hide: true,
- routes: [
- {
- path: '/fox',
- label: 'navBar.foxToken',
- main: () => ,
- },
- {
- path: '/foxy',
- label: 'navBar.foxToken',
- main: () => ,
- },
- ],
- },
- ],
- },
- ],
- ]
-}
diff --git a/src/plugins/foxPage/utils/getFoxPageRouteAssetId.ts b/src/plugins/foxPage/utils/getFoxPageRouteAssetId.ts
deleted file mode 100644
index 4ad3be90b1d..00000000000
--- a/src/plugins/foxPage/utils/getFoxPageRouteAssetId.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-import { foxAssetId, foxyAssetId } from '@shapeshiftoss/caip'
-import { matchPath } from 'react-router'
-
-const FOX_PAGE_DEFAULT_ASSET = 'fox'
-
-export const getFoxPageRouteAssetId = (pathname: string) => {
- const foxPageAssetIdPathMatch = matchPath<{ foxAsset?: 'fox' | 'foxy' }>(pathname, {
- path: '/fox/:foxAsset?',
- })
-
- const foxAsset = foxPageAssetIdPathMatch?.params?.foxAsset ?? FOX_PAGE_DEFAULT_ASSET
-
- return foxAsset === 'fox' ? foxAssetId : foxyAssetId
-}