Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7ebd35fbfd | ||
|
|
4c88cfd99f | ||
|
|
373b147997 |
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "mars-v2-frontend",
|
||||
"version": "2.0.6",
|
||||
"version": "2.0.5",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"build": "yarn validate-env && next build",
|
||||
|
||||
@@ -7,12 +7,15 @@ import { resolveHLSStrategies } from 'utils/resolvers'
|
||||
|
||||
export default async function getHLSStakingAssets() {
|
||||
const stakingAssetDenoms = getStakingAssets().map((asset) => asset.denom)
|
||||
console.log('stakingAssetDenoms', stakingAssetDenoms)
|
||||
const assetParams = await getAssetParams()
|
||||
console.log('assetParams', assetParams)
|
||||
const HLSAssets = assetParams
|
||||
.filter((asset) => stakingAssetDenoms.includes(asset.denom))
|
||||
.filter((asset) => asset.credit_manager.hls)
|
||||
console.log('HLSAssets', HLSAssets)
|
||||
const strategies = resolveHLSStrategies('coin', HLSAssets)
|
||||
|
||||
console.log('strategies', strategies)
|
||||
const client = await getParamsQueryClient()
|
||||
const depositCaps$ = strategies.map((strategy) =>
|
||||
client.totalDeposit({ denom: strategy.denoms.deposit }),
|
||||
|
||||
@@ -37,7 +37,7 @@ import {
|
||||
|
||||
export default function AccountDetailsController() {
|
||||
const address = useStore((s) => s.address)
|
||||
const currentAppSection = useStore((s) => s.currentAppSection)
|
||||
const isHLS = useStore((s) => s.isHLS)
|
||||
const { data: accounts, isLoading } = useAccounts('default', address)
|
||||
const { data: accountIds } = useAccountIds(address, false)
|
||||
const accountId = useAccountId()
|
||||
@@ -46,7 +46,7 @@ export default function AccountDetailsController() {
|
||||
const focusComponent = useStore((s) => s.focusComponent)
|
||||
const isOwnAccount = accountId && accountIds?.includes(accountId)
|
||||
|
||||
if (!address || focusComponent || !isOwnAccount || currentAppSection !== 'app') return null
|
||||
if (!address || focusComponent || !isOwnAccount || isHLS) return null
|
||||
|
||||
if ((isLoading && accountId && !focusComponent) || !account) return <Skeleton />
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import classNames from 'classnames'
|
||||
import { useEffect, useMemo, useState } from 'react'
|
||||
import { useLocation } from 'react-router-dom'
|
||||
import { useEffect, useMemo } from 'react'
|
||||
|
||||
import { DEFAULT_SETTINGS } from 'constants/defaultSettings'
|
||||
import { LocalStorageKeys } from 'constants/localStorageKeys'
|
||||
@@ -13,41 +13,13 @@ export default function Background() {
|
||||
LocalStorageKeys.REDUCE_MOTION,
|
||||
DEFAULT_SETTINGS.reduceMotion,
|
||||
)
|
||||
const [backgroundClasses, setBackgroundClasses] = useState<string[]>([
|
||||
'bg-body',
|
||||
'bg-orb-primary',
|
||||
'bg-orb-secondary',
|
||||
'bg-orb-tertiary',
|
||||
])
|
||||
const { pathname } = useLocation()
|
||||
const page = getPage(pathname)
|
||||
const currentAppSection = useMemo(() => {
|
||||
switch (page.split('-')[0]) {
|
||||
case 'hls':
|
||||
setBackgroundClasses([
|
||||
'bg-body-hls',
|
||||
'bg-orb-primary-hls',
|
||||
'bg-orb-secondary-hls',
|
||||
'bg-orb-tertiary-hls',
|
||||
])
|
||||
return 'hls'
|
||||
case 'stats':
|
||||
setBackgroundClasses([
|
||||
'bg-body',
|
||||
'bg-orb-primary-stats',
|
||||
'bg-orb-secondary-stats',
|
||||
'bg-orb-tertiary-stats',
|
||||
])
|
||||
return 'stats'
|
||||
default:
|
||||
setBackgroundClasses(['bg-body', 'bg-orb-primary', 'bg-orb-secondary', 'bg-orb-tertiary'])
|
||||
return 'app'
|
||||
}
|
||||
}, [page])
|
||||
const isHLS = useMemo(() => page.split('-')[0] === 'hls', [page])
|
||||
|
||||
useEffect(() => {
|
||||
useStore.setState({ currentAppSection })
|
||||
}, [currentAppSection])
|
||||
useStore.setState({ isHLS })
|
||||
}, [isHLS])
|
||||
|
||||
return (
|
||||
<div
|
||||
@@ -55,7 +27,7 @@ export default function Background() {
|
||||
'fixed inset-0',
|
||||
'w-full h-full',
|
||||
'overflow-hidden pointer-events-none background ',
|
||||
backgroundClasses[0],
|
||||
isHLS ? 'bg-body-hls' : 'bg-body',
|
||||
!reduceMotion && 'transition-bg duration-1000 delay-300',
|
||||
)}
|
||||
>
|
||||
@@ -67,7 +39,7 @@ export default function Background() {
|
||||
'max-h-[500px] max-w-[500px]',
|
||||
'left-[-10vw] top-[-10vw]',
|
||||
'blur-orb-primary',
|
||||
backgroundClasses[1],
|
||||
isHLS ? ' bg-orb-primary-hls' : 'bg-orb-primary',
|
||||
'translate-x-0 translate-y-0 rounded-full opacity-20',
|
||||
!reduceMotion && 'animate-[float_120s_ease-in-out_infinite_2s]',
|
||||
!reduceMotion && 'transition-bg duration-1000 delay-300',
|
||||
@@ -81,7 +53,7 @@ export default function Background() {
|
||||
'max-h-[1000px] max-w-[1000px]',
|
||||
'bottom-[-20vw] right-[-10vw]',
|
||||
'blur-orb-secondary',
|
||||
backgroundClasses[2],
|
||||
isHLS ? ' bg-orb-secondary-hls' : 'bg-orb-secondary',
|
||||
'translate-x-0 translate-y-0 rounded-full opacity-30',
|
||||
!reduceMotion && 'transition-bg duration-1000 delay-300',
|
||||
)}
|
||||
@@ -94,7 +66,7 @@ export default function Background() {
|
||||
'max-h-[600px] max-w-[600px]',
|
||||
'right-[-4vw] top-[-10vw]',
|
||||
'blur-orb-tertiary ',
|
||||
backgroundClasses[3],
|
||||
isHLS ? ' bg-orb-tertiary-hls' : 'bg-orb-tertiary',
|
||||
'translate-x-0 translate-y-0 rounded-full opacity-20',
|
||||
!reduceMotion && 'animate-[float_180s_ease-in_infinite]',
|
||||
!reduceMotion && 'transition-bg duration-1000 delay-300',
|
||||
|
||||
@@ -1,117 +0,0 @@
|
||||
import classNames from 'classnames'
|
||||
import moment from 'moment'
|
||||
import {
|
||||
Area,
|
||||
AreaChart,
|
||||
CartesianGrid,
|
||||
ResponsiveContainer,
|
||||
Tooltip,
|
||||
XAxis,
|
||||
YAxis,
|
||||
} from 'recharts'
|
||||
|
||||
import Text from 'components/Text'
|
||||
import { DEFAULT_SETTINGS } from 'constants/defaultSettings'
|
||||
import { LocalStorageKeys } from 'constants/localStorageKeys'
|
||||
import useLocalStorage from 'hooks/useLocalStorage'
|
||||
import { formatValue } from 'utils/formatters'
|
||||
|
||||
interface Props {
|
||||
data: ChartData
|
||||
height?: number
|
||||
}
|
||||
|
||||
export default function ChartBody(props: Props) {
|
||||
const [reduceMotion] = useLocalStorage<boolean>(
|
||||
LocalStorageKeys.REDUCE_MOTION,
|
||||
DEFAULT_SETTINGS.reduceMotion,
|
||||
)
|
||||
const height = props.height ?? 400
|
||||
|
||||
return (
|
||||
<div className={`-ml-6 h-[${height}px] w-full`}>
|
||||
<ResponsiveContainer width='100%' height='100%'>
|
||||
<AreaChart
|
||||
data={props.data}
|
||||
margin={{
|
||||
top: 0,
|
||||
right: 0,
|
||||
left: 0,
|
||||
bottom: 0,
|
||||
}}
|
||||
>
|
||||
<defs>
|
||||
<linearGradient id='chartGradient' x1='0' y1='0' x2='0' y2='1'>
|
||||
<stop offset='0%' stopColor={'#AB47BC'} stopOpacity={0.3} />
|
||||
<stop offset='100%' stopColor={'#AB47BC'} stopOpacity={0.02} />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<CartesianGrid
|
||||
horizontal={false}
|
||||
stroke='rgba(255,255,255,0.1)'
|
||||
strokeDasharray='6 3'
|
||||
syncWithTicks={true}
|
||||
/>
|
||||
<XAxis
|
||||
stroke='rgba(255, 255, 255, 0.4)'
|
||||
tickFormatter={(value) => {
|
||||
return moment(value).format('DD MMM')
|
||||
}}
|
||||
padding={{ left: 10, right: 20 }}
|
||||
axisLine={false}
|
||||
tickLine={false}
|
||||
fontSize={12}
|
||||
dataKey='date'
|
||||
dy={10}
|
||||
/>
|
||||
<YAxis
|
||||
axisLine={false}
|
||||
tickLine={false}
|
||||
fontSize={12}
|
||||
stroke='rgba(255, 255, 255, 0.4)'
|
||||
tickFormatter={(value) => {
|
||||
return formatValue(value, {
|
||||
minDecimals: 0,
|
||||
maxDecimals: 0,
|
||||
prefix: '$',
|
||||
abbreviated: true,
|
||||
})
|
||||
}}
|
||||
/>
|
||||
<Tooltip
|
||||
cursor={false}
|
||||
isAnimationActive={!reduceMotion}
|
||||
wrapperStyle={{ outline: 'none' }}
|
||||
content={({ payload, label }) => {
|
||||
if (payload && payload.length) {
|
||||
const value = Number(payload[0].value) ?? 0
|
||||
return (
|
||||
<div
|
||||
className={classNames(
|
||||
'max-w-[320px] rounded-lg px-4 py-2 isolate bg-black/5 backdrop-blur',
|
||||
'before:content-[" "] before:absolute before:inset-0 before:-z-1 before:rounded-sm before:p-[1px] before:border-glas',
|
||||
)}
|
||||
>
|
||||
<Text size='sm' className='text-white/60'>
|
||||
{moment(label).format('DD MMM YYYY')}
|
||||
</Text>
|
||||
<Text size='sm'>
|
||||
{formatValue(value, { minDecimals: 0, maxDecimals: 0, prefix: '$' })}
|
||||
</Text>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<Area
|
||||
type='monotone'
|
||||
dataKey='value'
|
||||
stroke='#AB47BC'
|
||||
fill='url(#chartGradient)'
|
||||
isAnimationActive={!reduceMotion}
|
||||
/>
|
||||
</AreaChart>
|
||||
</ResponsiveContainer>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -1,93 +0,0 @@
|
||||
import moment from 'moment'
|
||||
import { Area, AreaChart, CartesianGrid, ResponsiveContainer, XAxis, YAxis } from 'recharts'
|
||||
import classNames from 'classnames'
|
||||
|
||||
import { DEFAULT_SETTINGS } from 'constants/defaultSettings'
|
||||
import { LocalStorageKeys } from 'constants/localStorageKeys'
|
||||
import useLocalStorage from 'hooks/useLocalStorage'
|
||||
|
||||
interface Props {
|
||||
height?: number
|
||||
}
|
||||
|
||||
function createLoadingData() {
|
||||
const data = []
|
||||
const dataValues = [0, 20, 40, 30, 60, 50, 100]
|
||||
const startDate = moment().subtract(7, 'days')
|
||||
const endDate = moment()
|
||||
const days = endDate.diff(startDate, 'days')
|
||||
for (let i = 0; i < days; i++) {
|
||||
const date = moment(startDate).add(i, 'days')
|
||||
data.push({
|
||||
date: date.format('YYYY-MM-DD'),
|
||||
value: dataValues[i],
|
||||
})
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
export default function Chart(props: Props) {
|
||||
const [reduceMotion] = useLocalStorage<boolean>(
|
||||
LocalStorageKeys.REDUCE_MOTION,
|
||||
DEFAULT_SETTINGS.reduceMotion,
|
||||
)
|
||||
const height = props.height ?? 400
|
||||
const loadingData = createLoadingData()
|
||||
|
||||
return (
|
||||
<div className={classNames(`-ml-6 h-[${height}px] w-full`, !reduceMotion && 'animate-pulse')}>
|
||||
<ResponsiveContainer width='100%' height='100%'>
|
||||
<AreaChart
|
||||
data={loadingData}
|
||||
margin={{
|
||||
top: 0,
|
||||
right: 0,
|
||||
left: 0,
|
||||
bottom: 0,
|
||||
}}
|
||||
>
|
||||
<defs>
|
||||
<linearGradient id='chartGradient' x1='0' y1='0' x2='0' y2='1'>
|
||||
<stop offset='0%' stopColor={'#FFF'} stopOpacity={0.3} />
|
||||
<stop offset='100%' stopColor={'#FFF'} stopOpacity={0.02} />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<CartesianGrid
|
||||
horizontal={false}
|
||||
stroke='rgba(255,255,255,0.2)'
|
||||
strokeDasharray='6 3'
|
||||
syncWithTicks={true}
|
||||
/>
|
||||
<XAxis
|
||||
stroke='rgba(255, 255, 255, 0.3)'
|
||||
tickFormatter={() => {
|
||||
return '...'
|
||||
}}
|
||||
padding={{ left: 10, right: 20 }}
|
||||
axisLine={false}
|
||||
tickLine={false}
|
||||
fontSize={12}
|
||||
dataKey='date'
|
||||
dy={10}
|
||||
/>
|
||||
<YAxis
|
||||
axisLine={false}
|
||||
tickLine={false}
|
||||
fontSize={12}
|
||||
stroke='rgba(255, 255, 255, 0.5)'
|
||||
tickFormatter={() => {
|
||||
return '...'
|
||||
}}
|
||||
/>
|
||||
<Area
|
||||
type='monotone'
|
||||
dataKey='value'
|
||||
stroke='rgba(255, 255, 255, 0.3)'
|
||||
fill='url(#chartGradient)'
|
||||
isAnimationActive={!reduceMotion}
|
||||
/>
|
||||
</AreaChart>
|
||||
</ResponsiveContainer>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
import Card from 'components/Card'
|
||||
import ChartBody from 'components/Chart/ChartBody'
|
||||
import ChartLoading from 'components/Chart/ChartLoading'
|
||||
|
||||
interface Props {
|
||||
data: ChartData | null
|
||||
title: string
|
||||
}
|
||||
|
||||
export default function Chart(props: Props) {
|
||||
return (
|
||||
<Card className='w-full' title={props.title} contentClassName='p-4 pr-0'>
|
||||
{props.data === null ? <ChartLoading /> : <ChartBody data={props.data} />}
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -18,7 +18,6 @@ interface Props {
|
||||
isApproximation?: boolean
|
||||
parentheses?: boolean
|
||||
showZero?: boolean
|
||||
abbreviated?: boolean
|
||||
}
|
||||
|
||||
export default function DisplayCurrency(props: Props) {
|
||||
@@ -71,7 +70,7 @@ export default function DisplayCurrency(props: Props) {
|
||||
options={{
|
||||
minDecimals: isUSD ? 2 : 0,
|
||||
maxDecimals: 2,
|
||||
abbreviated: props.abbreviated ?? true,
|
||||
abbreviated: true,
|
||||
prefix,
|
||||
suffix,
|
||||
}}
|
||||
|
||||
@@ -7,7 +7,7 @@ interface Props {
|
||||
|
||||
export default function Divider(props: Props) {
|
||||
if (props.orientation === 'vertical') {
|
||||
return <div className={classNames(props.className, 'h-full w-[1px] bg-white/10')}></div>
|
||||
return <div className={classNames('h-full w-[1px] bg-white/10', props.className)}></div>
|
||||
}
|
||||
return <div className={classNames('h-[1px] w-full bg-white/10', props.className)}></div>
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@ const underlineClasses =
|
||||
interface Props {
|
||||
tabs: Tab[]
|
||||
activeTabIdx: number
|
||||
className?: string
|
||||
}
|
||||
|
||||
export default function Tab(props: Props) {
|
||||
@@ -18,7 +17,7 @@ export default function Tab(props: Props) {
|
||||
const { address } = useParams()
|
||||
|
||||
return (
|
||||
<div className={classNames(props.className, 'relative w-full')}>
|
||||
<div className='relative w-full'>
|
||||
{props.tabs.map((tab, index) => (
|
||||
<NavLink
|
||||
key={tab.page}
|
||||
|
||||
@@ -10,18 +10,16 @@ import Settings from 'components/Settings'
|
||||
import Wallet from 'components/Wallet'
|
||||
import useAccountId from 'hooks/useAccountId'
|
||||
import useStore from 'store'
|
||||
import { ENABLE_HLS, ENABLE_PERPS } from 'utils/constants'
|
||||
import { WalletID } from 'types/enums/wallet'
|
||||
import { ENABLE_HLS } from 'utils/constants'
|
||||
import { getGovernanceUrl } from 'utils/helpers'
|
||||
|
||||
export const menuTree = (walletId: WalletID): MenuTreeEntry[] => [
|
||||
{ pages: ['trade'], label: 'Trade' },
|
||||
...(ENABLE_PERPS ? [{ pages: ['perps'] as Page[], label: 'Perps' }] : []),
|
||||
{ pages: ['lend', 'farm'], label: 'Earn' },
|
||||
{ pages: ['borrow'], label: 'Borrow' },
|
||||
...(ENABLE_HLS ? [{ pages: ['hls-staking'] as Page[], label: 'High Leverage' }] : []),
|
||||
{ pages: ['portfolio'], label: 'Portfolio' },
|
||||
{ pages: ['stats'], label: 'Statistics' },
|
||||
{ pages: ['governance'], label: 'Governance', externalUrl: getGovernanceUrl(walletId) },
|
||||
]
|
||||
|
||||
@@ -29,7 +27,7 @@ export default function DesktopHeader() {
|
||||
const address = useStore((s) => s.address)
|
||||
const focusComponent = useStore((s) => s.focusComponent)
|
||||
const isOracleStale = useStore((s) => s.isOracleStale)
|
||||
const currentAppSection = useStore((s) => s.currentAppSection)
|
||||
const isHLS = useStore((s) => s.isHLS)
|
||||
const accountId = useAccountId()
|
||||
|
||||
function handleCloseFocusMode() {
|
||||
@@ -64,7 +62,7 @@ export default function DesktopHeader() {
|
||||
<div className='flex gap-4'>
|
||||
{isOracleStale && <OracleResyncButton />}
|
||||
{accountId && <RewardsCenter />}
|
||||
{address && currentAppSection === 'app' && <AccountMenu />}
|
||||
{address && !isHLS && <AccountMenu />}
|
||||
<Wallet />
|
||||
<Settings />
|
||||
</div>
|
||||
|
||||
@@ -32,13 +32,13 @@ function IntroBackground(props: { bg: Props['bg'] }) {
|
||||
|
||||
export default function Intro(props: Props) {
|
||||
const showTutorial = useStore((s) => s.tutorial)
|
||||
const currentAppSection = useStore((s) => s.currentAppSection)
|
||||
const isHLS = useStore((s) => s.isHLS)
|
||||
if (!showTutorial) return null
|
||||
return (
|
||||
<Card
|
||||
className={classNames(
|
||||
'relative w-full p-8 bg-cover h-55',
|
||||
currentAppSection === 'hls' ? 'bg-intro-hls' : 'bg-intro',
|
||||
isHLS ? 'bg-intro-hls' : 'bg-intro',
|
||||
)}
|
||||
contentClassName='flex w-full h-full flex-col justify-between'
|
||||
>
|
||||
|
||||
@@ -68,9 +68,7 @@ export default function MarketDetails({ row, type }: Props) {
|
||||
title: 'Oracle Price',
|
||||
},
|
||||
{
|
||||
amount: totalBorrowed.isZero()
|
||||
? 0
|
||||
: totalBorrowed.dividedBy(marketDepositAmount).multipliedBy(100).toNumber(),
|
||||
amount: totalBorrowed.dividedBy(marketDepositAmount).multipliedBy(100).toNumber(),
|
||||
options: { minDecimals: 2, maxDecimals: 2, suffix: '%' },
|
||||
title: 'Utilization Rate',
|
||||
},
|
||||
@@ -99,9 +97,7 @@ export default function MarketDetails({ row, type }: Props) {
|
||||
title: 'Oracle Price',
|
||||
},
|
||||
{
|
||||
amount: totalBorrowed.isZero()
|
||||
? 0
|
||||
: totalBorrowed.dividedBy(marketDepositAmount).multipliedBy(100).toNumber(),
|
||||
amount: totalBorrowed.dividedBy(marketDepositAmount).multipliedBy(100).toNumber(),
|
||||
options: { minDecimals: 2, maxDecimals: 2, suffix: '%' },
|
||||
title: 'Utilization Rate',
|
||||
},
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
import Button from 'components/Button'
|
||||
|
||||
const LEVERAGE_PRESETS = [1, 2, 3, 5, 10]
|
||||
|
||||
export function LeverageButtons() {
|
||||
return (
|
||||
<div className='flex justify-between'>
|
||||
{LEVERAGE_PRESETS.map((leverage) => (
|
||||
<Button key={leverage} color='tertiary' className='w-12'>
|
||||
{leverage}x
|
||||
</Button>
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
import Divider from 'components/Divider'
|
||||
import Text from 'components/Text'
|
||||
|
||||
export function Or() {
|
||||
return (
|
||||
<div className='flex items-center gap-2'>
|
||||
<Divider />
|
||||
<Text size='xs' className='text-white/40'>
|
||||
OR
|
||||
</Text>
|
||||
<Divider />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
import { useState } from 'react'
|
||||
|
||||
import Button from 'components/Button'
|
||||
import Card from 'components/Card'
|
||||
import { ChevronDown } from 'components/Icons'
|
||||
import { LeverageButtons } from 'components/Perps/Module/LeverageButtons'
|
||||
import { Or } from 'components/Perps/Module/Or'
|
||||
import { SelectLongShort } from 'components/Perps/Module/SelectLongShort'
|
||||
import RangeInput from 'components/RangeInput'
|
||||
import { Spacer } from 'components/Spacer'
|
||||
import Text from 'components/Text'
|
||||
import AssetAmountInput from 'components/Trade/TradeModule/SwapForm/AssetAmountInput'
|
||||
import OrderTypeSelector from 'components/Trade/TradeModule/SwapForm/OrderTypeSelector'
|
||||
import { AvailableOrderType } from 'components/Trade/TradeModule/SwapForm/OrderTypeSelector/types'
|
||||
import { ASSETS } from 'constants/assets'
|
||||
import { BN_ZERO } from 'constants/math'
|
||||
|
||||
export function PerpsModule() {
|
||||
const [selectedOrderType, setSelectedOrderType] = useState<AvailableOrderType>('Market')
|
||||
const [selectedOrderDirection, setSelectedOrderDirection] = useState<OrderDirection>('long')
|
||||
|
||||
return (
|
||||
<Card
|
||||
contentClassName='px-4 gap-5 flex flex-col'
|
||||
title={
|
||||
<div className='flex justify-between bg-white/10 py-4 pl-4 pr-2 items-center'>
|
||||
<Text>
|
||||
ETH<span className='text-white/60'>/USD</span>
|
||||
</Text>
|
||||
<Button color='quaternary' variant='transparent' rightIcon={<ChevronDown />}>
|
||||
All Markets
|
||||
</Button>
|
||||
</div>
|
||||
}
|
||||
className='mb-4'
|
||||
>
|
||||
<OrderTypeSelector selected={selectedOrderType} onChange={setSelectedOrderType} />
|
||||
<SelectLongShort
|
||||
direction={selectedOrderDirection}
|
||||
onChangeDirection={setSelectedOrderDirection}
|
||||
/>
|
||||
<AssetAmountInput
|
||||
label='Amount'
|
||||
max={BN_ZERO}
|
||||
amount={BN_ZERO}
|
||||
setAmount={() => {}}
|
||||
asset={ASSETS[0]}
|
||||
maxButtonLabel='Max:'
|
||||
disabled={false}
|
||||
/>
|
||||
<Or />
|
||||
<Text size='sm'>Position Leverage</Text>
|
||||
<RangeInput max={0} value={0} onChange={() => {}} />
|
||||
<LeverageButtons />
|
||||
<Spacer />
|
||||
<Button>{selectedOrderDirection} ETH</Button>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
import classNames from 'classnames'
|
||||
|
||||
import Text from 'components/Text'
|
||||
|
||||
interface Props {
|
||||
direction: OrderDirection
|
||||
onChangeDirection: (direction: OrderDirection) => void
|
||||
}
|
||||
|
||||
export function SelectLongShort(props: Props) {
|
||||
return (
|
||||
<div className='flex bg-black/20 rounded-sm'>
|
||||
<Direction
|
||||
onClick={() => props.onChangeDirection('long')}
|
||||
direction='long'
|
||||
isActive={props.direction === 'long'}
|
||||
/>
|
||||
<Direction
|
||||
onClick={() => props.onChangeDirection('short')}
|
||||
direction='short'
|
||||
isActive={props.direction === 'short'}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
interface DirectionProps {
|
||||
direction: 'long' | 'short'
|
||||
isActive: boolean
|
||||
onClick: () => void
|
||||
}
|
||||
function Direction(props: DirectionProps) {
|
||||
return (
|
||||
<button
|
||||
className={classNames(
|
||||
'px-4 py-3 rounded-sm flex-1',
|
||||
borderColors[props.direction],
|
||||
props.isActive && 'border bg-white/10',
|
||||
)}
|
||||
onClick={props.onClick}
|
||||
>
|
||||
<Text
|
||||
className={classNames(
|
||||
'text-center capitalize',
|
||||
props.isActive ? directionColors[props.direction] : 'text-white/20',
|
||||
)}
|
||||
>
|
||||
{props.direction}
|
||||
</Text>
|
||||
</button>
|
||||
)
|
||||
}
|
||||
|
||||
const directionColors = {
|
||||
long: 'text-success',
|
||||
short: 'text-error',
|
||||
}
|
||||
|
||||
const borderColors = {
|
||||
long: 'border-success',
|
||||
short: 'border-error',
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
import React from 'react'
|
||||
|
||||
import TradeChart from 'components/Trade/TradeChart'
|
||||
import { ASSETS } from 'constants/assets'
|
||||
|
||||
export function PerpsChart() {
|
||||
return (
|
||||
<div className='h-full'>
|
||||
<TradeChart buyAsset={ASSETS[0]} sellAsset={ASSETS[1]} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
import React, { useMemo } from 'react'
|
||||
|
||||
import Card from 'components/Card'
|
||||
import Divider from 'components/Divider'
|
||||
import Text from 'components/Text'
|
||||
|
||||
export function PerpsInfo() {
|
||||
const items = useMemo(
|
||||
() => [
|
||||
<Text key='item1'>$6,735</Text>,
|
||||
<InfoItem key='item2' label='Label' item={<Text size='sm'>Value</Text>} />,
|
||||
<InfoItem key='item3' label='Label' item={<Text size='sm'>Value</Text>} />,
|
||||
<InfoItem key='item4' label='Label' item={<Text size='sm'>Value</Text>} />,
|
||||
<InfoItem key='item5' label='Label' item={<Text size='sm'>Value</Text>} />,
|
||||
],
|
||||
[],
|
||||
)
|
||||
|
||||
return (
|
||||
<Card contentClassName='bg-white/10 py-3.5 px-4'>
|
||||
<div className='flex gap-4 items-center'>
|
||||
{items.map((item, index) => (
|
||||
<React.Fragment key={index}>
|
||||
{item}
|
||||
{index !== items.length - 1 && <Divider orientation='vertical' className='h-9' />}
|
||||
</React.Fragment>
|
||||
))}
|
||||
</div>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
|
||||
interface InfoItemProps {
|
||||
item: React.ReactNode
|
||||
label: string
|
||||
}
|
||||
|
||||
function InfoItem(props: InfoItemProps) {
|
||||
return (
|
||||
<div className='flex flex-col gap-1'>
|
||||
<Text size='xs' className='text-white/40'>
|
||||
{props.label}
|
||||
</Text>
|
||||
{props.item}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
import AccountDetailsCard from 'components/Trade/AccountDetailsCard'
|
||||
|
||||
export function PerpsPositions() {
|
||||
return <AccountDetailsCard />
|
||||
}
|
||||
@@ -81,8 +81,6 @@ export default function RewardsCenter() {
|
||||
}
|
||||
}, [accountId, claimTx])
|
||||
|
||||
if (totalRewardsCoin.amount.isZero()) return null
|
||||
|
||||
return (
|
||||
<div className={'relative'}>
|
||||
<Button
|
||||
|
||||
@@ -1,18 +1,16 @@
|
||||
import { Navigate, Outlet, Route, Routes as RoutesWrapper } from 'react-router-dom'
|
||||
|
||||
import Layout from 'pages/_layout'
|
||||
import BorrowPage from 'pages/BorrowPage'
|
||||
import FarmPage from 'pages/FarmPage'
|
||||
import HLSFarmPage from 'pages/HLSFarmPage'
|
||||
import HLSStakingPage from 'pages/HLSStakingPage'
|
||||
import LendPage from 'pages/LendPage'
|
||||
import MobilePage from 'pages/MobilePage'
|
||||
import PerpsPage from 'pages/PerpsPage'
|
||||
import PortfolioAccountPage from 'pages/PortfolioAccountPage'
|
||||
import PortfolioPage from 'pages/PortfolioPage'
|
||||
import StatsPage from 'pages/StatsPage'
|
||||
import TradePage from 'pages/TradePage'
|
||||
import Layout from 'pages/_layout'
|
||||
import { ENABLE_HLS, ENABLE_PERPS } from 'utils/constants'
|
||||
import { ENABLE_HLS } from 'utils/constants'
|
||||
|
||||
export default function Routes() {
|
||||
return (
|
||||
@@ -25,7 +23,6 @@ export default function Routes() {
|
||||
}
|
||||
>
|
||||
<Route path='/trade' element={<TradePage />} />
|
||||
{ENABLE_PERPS && <Route path='/perps' element={<PerpsPage />} />}
|
||||
<Route path='/farm' element={<FarmPage />} />
|
||||
<Route path='/lend' element={<LendPage />} />
|
||||
<Route path='/borrow' element={<BorrowPage />} />
|
||||
@@ -33,24 +30,15 @@ export default function Routes() {
|
||||
<Route path='/mobile' element={<MobilePage />} />
|
||||
{ENABLE_HLS && <Route path='/hls-staking' element={<HLSStakingPage />} />}
|
||||
{ENABLE_HLS && <Route path='/hls-farm' element={<HLSFarmPage />} />}
|
||||
<Route path='/stats' element={<StatsPage />} />
|
||||
<Route path='/stats-farm' element={<StatsPage />} />
|
||||
<Route path='/stats-lend-borrow' element={<StatsPage />} />
|
||||
<Route path='/stats-additional' element={<StatsPage />} />
|
||||
<Route path='/' element={<TradePage />} />
|
||||
<Route path='/wallets/:address'>
|
||||
<Route path='trade' element={<TradePage />} />
|
||||
{ENABLE_PERPS && <Route path='perps' element={<PerpsPage />} />}
|
||||
<Route path='farm' element={<FarmPage />} />
|
||||
<Route path='lend' element={<LendPage />} />
|
||||
<Route path='borrow' element={<BorrowPage />} />
|
||||
<Route path='portfolio' element={<PortfolioPage />} />
|
||||
{ENABLE_HLS && <Route path='hls-staking' element={<HLSStakingPage />} />}
|
||||
{ENABLE_HLS && <Route path='hls-farm' element={<HLSFarmPage />} />}
|
||||
<Route path='stats' element={<StatsPage />} />
|
||||
<Route path='stats-farm' element={<StatsPage />} />
|
||||
<Route path='stats-lend-borrow' element={<StatsPage />} />
|
||||
<Route path='stats-additional' element={<StatsPage />} />
|
||||
<Route path='portfolio/:accountId'>
|
||||
<Route path='' element={<PortfolioAccountPage />} />
|
||||
</Route>
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
export function Spacer() {
|
||||
return <div className='h-full w-full flex-1' />
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
import { useMemo } from 'react'
|
||||
|
||||
import DisplayCurrency from 'components/DisplayCurrency'
|
||||
import { FormattedNumber } from 'components/FormattedNumber'
|
||||
import StatsCardsSkeleton from 'components/Stats/StatsCardsSkeleton'
|
||||
import { ORACLE_DENOM } from 'constants/oracle'
|
||||
import { BNCoin } from 'types/classes/BNCoin'
|
||||
import { DEFAULT_ADDITIONAL_STATS } from 'utils/constants'
|
||||
|
||||
export default function StatsAdditional() {
|
||||
const stats = useMemo(() => {
|
||||
const totalTvl = new BNCoin({ denom: ORACLE_DENOM, amount: '121345123.67' })
|
||||
const totalAccounts = 52134
|
||||
const totalFees = new BNCoin({ denom: ORACLE_DENOM, amount: '321230.34' })
|
||||
return [
|
||||
{
|
||||
head: DEFAULT_ADDITIONAL_STATS[0].head,
|
||||
title: <DisplayCurrency className='text-xl' coin={totalTvl} abbreviated={false} />,
|
||||
sub: DEFAULT_ADDITIONAL_STATS[0].sub,
|
||||
},
|
||||
{
|
||||
head: DEFAULT_ADDITIONAL_STATS[1].head,
|
||||
title: (
|
||||
<FormattedNumber
|
||||
className='text-xl'
|
||||
amount={totalAccounts}
|
||||
options={{ maxDecimals: 0, minDecimals: 0, abbreviated: false }}
|
||||
/>
|
||||
),
|
||||
sub: DEFAULT_ADDITIONAL_STATS[1].sub,
|
||||
},
|
||||
{
|
||||
head: DEFAULT_ADDITIONAL_STATS[2].head,
|
||||
title: <DisplayCurrency className='text-xl' coin={totalFees} abbreviated={false} />,
|
||||
sub: DEFAULT_ADDITIONAL_STATS[2].sub,
|
||||
},
|
||||
]
|
||||
}, [])
|
||||
|
||||
return <StatsCardsSkeleton stats={stats} />
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
import React from 'react'
|
||||
|
||||
import Card from 'components/Card'
|
||||
import Loading from 'components/Loading'
|
||||
import Text from 'components/Text'
|
||||
import TitleAndSubCell from 'components/TitleAndSubCell'
|
||||
import { DEFAULT_ADDITIONAL_STATS } from 'utils/constants'
|
||||
|
||||
interface Props {
|
||||
stats?: Stat[]
|
||||
}
|
||||
|
||||
interface Stat {
|
||||
head: string
|
||||
title: React.ReactNode | null
|
||||
sub: string
|
||||
}
|
||||
|
||||
export default function StatsCardsSkeleton(props: Props) {
|
||||
const stats = props.stats || DEFAULT_ADDITIONAL_STATS
|
||||
|
||||
return (
|
||||
<div className='grid w-full grid-cols-3 gap-4'>
|
||||
{stats.map((stat) => (
|
||||
<Card key={stat.sub} className='p-6 bg-white/5 flex-grow-1'>
|
||||
<Text size='sm' className='mb-2 text-white/60'>
|
||||
{stat.head}
|
||||
</Text>
|
||||
<TitleAndSubCell
|
||||
title={stat.title || <Loading className='w-20 h-6 mx-auto mb-2' />}
|
||||
sub={stat.sub}
|
||||
className='mb-1'
|
||||
/>
|
||||
</Card>
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
export default function StatsFarm() {
|
||||
return <div className='flex-1'>Stats Farm</div>
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
export default function StatsLendAndBorrow() {
|
||||
return <div className='flex-1'>Stats Lend & Borrow</div>
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
import { useEffect, useState } from 'react'
|
||||
|
||||
import Chart from 'components/Chart'
|
||||
|
||||
export default function StatsTrading() {
|
||||
const [totalSwapVolume, setTotalSwapVolume] = useState<ChartData | null>(null)
|
||||
|
||||
useEffect(() => {
|
||||
setTimeout(() => {
|
||||
setTotalSwapVolume([
|
||||
{
|
||||
date: '2023-11-15',
|
||||
value: 2501271,
|
||||
},
|
||||
{
|
||||
date: '2023-11-16',
|
||||
value: 2804718,
|
||||
},
|
||||
{
|
||||
date: '2023-11-17',
|
||||
value: 4901520,
|
||||
},
|
||||
{
|
||||
date: '2023-11-18',
|
||||
value: 6500000,
|
||||
},
|
||||
{
|
||||
date: '2023-11-19',
|
||||
value: 7486720,
|
||||
},
|
||||
{
|
||||
date: '2023-11-20',
|
||||
value: 8412721,
|
||||
},
|
||||
{
|
||||
date: '2023-11-21',
|
||||
value: 10432321,
|
||||
},
|
||||
])
|
||||
}, 6000)
|
||||
})
|
||||
|
||||
return <Chart title='Total Swap Volume' data={totalSwapVolume} />
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
import { useEffect, useMemo, useRef } from 'react'
|
||||
|
||||
import Card from 'components/Card'
|
||||
import { disabledFeatures, enabledFeatures, overrides } from 'components/Trade/TradeChart/constants'
|
||||
import { DataFeed, PAIR_SEPARATOR } from 'components/Trade/TradeChart/DataFeed'
|
||||
import { disabledFeatures, enabledFeatures, overrides } from 'components/Trade/TradeChart/constants'
|
||||
import useStore from 'store'
|
||||
import {
|
||||
ChartingLibraryWidgetOptions,
|
||||
@@ -102,7 +102,7 @@ export const TVChartContainer = (props: Props) => {
|
||||
}, [props.buyAsset.denom, props.sellAsset.denom])
|
||||
|
||||
return (
|
||||
<Card title='Trading Chart' contentClassName='px-0.5 pb-0.5 h-full' className='h-full'>
|
||||
<Card title='Trading Chart' contentClassName='px-0.5 pb-0.5 h-full'>
|
||||
<div ref={chartContainerRef} className='h-full overflow-hidden rounded-b-base' />
|
||||
</Card>
|
||||
)
|
||||
|
||||
@@ -16,7 +16,7 @@ export default function OrderTypeSelector(props: Props) {
|
||||
const { selected, onChange } = props
|
||||
|
||||
return (
|
||||
<div className='flex flex-row pt-4'>
|
||||
<div className='flex flex-row flex-1 px-3 pt-4'>
|
||||
{ORDER_TYPE_TABS.map((tab) => {
|
||||
const isSelected = tab.type === selected
|
||||
const classes = classNames(
|
||||
|
||||
@@ -27,7 +27,7 @@ import { useUpdatedAccount } from 'hooks/useUpdatedAccount'
|
||||
import useStore from 'store'
|
||||
import { BNCoin } from 'types/classes/BNCoin'
|
||||
import { byDenom } from 'utils/array'
|
||||
import { defaultFee, ENABLE_AUTO_REPAY } from 'utils/constants'
|
||||
import { defaultFee } from 'utils/constants'
|
||||
import { getCapLeftWithBuffer } from 'utils/generic'
|
||||
import { asyncThrottle, BN } from 'utils/helpers'
|
||||
|
||||
@@ -50,9 +50,7 @@ export default function SwapForm(props: Props) {
|
||||
const isBorrowEnabled = !!marketAssets.find(byDenom(sellAsset.denom))?.borrowEnabled
|
||||
const isRepayable = !!account?.debts.find(byDenom(buyAsset.denom))
|
||||
const [isMarginChecked, setMarginChecked] = useToggle(isBorrowEnabled ? useMargin : false)
|
||||
const [isAutoRepayChecked, setAutoRepayChecked] = useToggle(
|
||||
isRepayable && ENABLE_AUTO_REPAY ? useAutoRepay : false,
|
||||
)
|
||||
const [isAutoRepayChecked, setAutoRepayChecked] = useToggle(isRepayable ? useAutoRepay : false)
|
||||
const [buyAssetAmount, setBuyAssetAmount] = useState(BN_ZERO)
|
||||
const [sellAssetAmount, setSellAssetAmount] = useState(BN_ZERO)
|
||||
const [maxBuyableAmountEstimation, setMaxBuyableAmountEstimation] = useState(BN_ZERO)
|
||||
@@ -316,7 +314,7 @@ export default function SwapForm(props: Props) {
|
||||
/>
|
||||
<Divider />
|
||||
|
||||
{isRepayable && ENABLE_AUTO_REPAY && (
|
||||
{isRepayable && (
|
||||
<AutoRepayToggle
|
||||
checked={isAutoRepayChecked}
|
||||
onChange={handleAutoRepayToggleChange}
|
||||
@@ -324,9 +322,7 @@ export default function SwapForm(props: Props) {
|
||||
/>
|
||||
)}
|
||||
<Divider />
|
||||
<div className='px-3'>
|
||||
<OrderTypeSelector selected={selectedOrderType} onChange={setSelectedOrderType} />
|
||||
</div>
|
||||
<OrderTypeSelector selected={selectedOrderType} onChange={setSelectedOrderType} />
|
||||
<div className='flex flex-col gap-6 px-3 mt-6'>
|
||||
<AssetAmountInput
|
||||
label='Buy'
|
||||
|
||||
@@ -229,42 +229,6 @@ export const ASSETS: Asset[] = [
|
||||
poolId: 1249,
|
||||
pythHistoryFeedId: 'Crypto.TIA/USD',
|
||||
},
|
||||
{
|
||||
symbol: 'AKT',
|
||||
id: 'AKT',
|
||||
name: 'Akash',
|
||||
denom: 'ibc/1480B8FD20AD5FCAE81EA87584D269547DD4D436843C1D20F15E00EB64743EF4',
|
||||
color: '#F34C2D',
|
||||
logo: '/images/tokens/akt.svg',
|
||||
decimals: 6,
|
||||
hasOraclePrice: true,
|
||||
isEnabled: true,
|
||||
isMarket: true,
|
||||
isDisplayCurrency: true,
|
||||
isAutoLendEnabled: true,
|
||||
isBorrowEnabled: true,
|
||||
pythPriceFeedId: '4ea5bb4d2f5900cc2e97ba534240950740b4d3b89fe712a94a7304fd2fd92702',
|
||||
poolId: 1093,
|
||||
pythHistoryFeedId: 'Crypto.AKT/USD',
|
||||
},
|
||||
{
|
||||
symbol: 'DYDX',
|
||||
id: 'DYDX',
|
||||
name: 'dYdX',
|
||||
denom: 'ibc/831F0B1BBB1D08A2B75311892876D71565478C532967545476DF4C2D7492E48C',
|
||||
color: '#6966ff',
|
||||
logo: '/images/tokens/dydx.svg',
|
||||
decimals: 18,
|
||||
hasOraclePrice: true,
|
||||
isEnabled: true,
|
||||
isMarket: true,
|
||||
isDisplayCurrency: true,
|
||||
isAutoLendEnabled: true,
|
||||
isBorrowEnabled: true,
|
||||
pythPriceFeedId: '6489800bb8974169adfe35937bf6736507097d13c190d760c557108c7e93a81b',
|
||||
poolId: 1245,
|
||||
pythHistoryFeedId: 'Crypto.DYDX/USD',
|
||||
},
|
||||
{
|
||||
symbol: '$',
|
||||
name: 'US Dollar',
|
||||
|
||||
@@ -7,10 +7,3 @@ export const HLS_TABS: Tab[] = [
|
||||
{ page: 'hls-staking', name: 'Staking' },
|
||||
{ page: 'hls-farm', name: 'Farm' },
|
||||
]
|
||||
|
||||
export const STATS_TABS: Tab[] = [
|
||||
{ page: 'stats', name: 'Trading' },
|
||||
{ page: 'stats-farm', name: 'Farm' },
|
||||
{ page: 'stats-lend-borrow', name: 'Lend & Borrow' },
|
||||
{ page: 'stats-additional', name: 'Additional' },
|
||||
]
|
||||
|
||||
@@ -3,6 +3,7 @@ import { useMemo } from 'react'
|
||||
import useCurrentAccountLends from 'hooks/useCurrentAccountLends'
|
||||
import useDepositEnabledMarkets from 'hooks/useDepositEnabledMarkets'
|
||||
import useDisplayCurrencyPrice from 'hooks/useDisplayCurrencyPrice'
|
||||
import useMarketDeposits from 'hooks/useMarketDeposits'
|
||||
import useMarketLiquidities from 'hooks/useMarketLiquidities'
|
||||
import { byDenom } from 'utils/array'
|
||||
import { getAssetByDenom } from 'utils/assets'
|
||||
@@ -15,6 +16,7 @@ function useLendingMarketAssetsTableData(): {
|
||||
} {
|
||||
const markets = useDepositEnabledMarkets()
|
||||
const accountLentAmounts = useCurrentAccountLends()
|
||||
const { data: marketDeposits } = useMarketDeposits()
|
||||
const { data: marketLiquidities } = useMarketLiquidities()
|
||||
const { convertAmount } = useDisplayCurrencyPrice()
|
||||
|
||||
@@ -25,6 +27,7 @@ function useLendingMarketAssetsTableData(): {
|
||||
markets.forEach(
|
||||
({ denom, cap, liquidityRate, liquidationThreshold, maxLtv, borrowEnabled }) => {
|
||||
const asset = getAssetByDenom(denom) as Asset
|
||||
const marketDepositAmount = BN(marketDeposits.find(byDenom(denom))?.amount ?? 0)
|
||||
const marketLiquidityAmount = BN(marketLiquidities.find(byDenom(denom))?.amount ?? 0)
|
||||
const accountLentAmount = accountLentAmounts.find(byDenom(denom))?.amount
|
||||
const accountLentValue = accountLentAmount
|
||||
@@ -33,7 +36,7 @@ function useLendingMarketAssetsTableData(): {
|
||||
|
||||
const lendingMarketAsset: LendingMarketTableData = {
|
||||
asset,
|
||||
marketDepositAmount: cap.used,
|
||||
marketDepositAmount,
|
||||
accountLentValue,
|
||||
accountLentAmount,
|
||||
marketLiquidityAmount,
|
||||
@@ -55,7 +58,7 @@ function useLendingMarketAssetsTableData(): {
|
||||
availableAssets,
|
||||
allAssets: [...accountLentAssets, ...availableAssets],
|
||||
}
|
||||
}, [markets, marketLiquidities, accountLentAmounts, convertAmount])
|
||||
}, [markets, marketDeposits, marketLiquidities, accountLentAmounts, convertAmount])
|
||||
}
|
||||
|
||||
export default useLendingMarketAssetsTableData
|
||||
|
||||
@@ -201,7 +201,7 @@ export function useUpdatedAccount(account?: Account) {
|
||||
removeDeposits([BNCoin.fromDenomAndBigNumber(collateralDenom, removeDepositAmount)])
|
||||
removeDebts([BNCoin.fromDenomAndBigNumber(debtDenom, repayAmount)])
|
||||
},
|
||||
[prices, slippage],
|
||||
[prices],
|
||||
)
|
||||
|
||||
const simulateVaultDeposit = useCallback(
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
import { PerpsModule } from 'components/Perps/Module/PerpsModule'
|
||||
import { PerpsChart } from 'components/Perps/PerpsChart'
|
||||
import { PerpsInfo } from 'components/Perps/PerpsInfo'
|
||||
import { PerpsPositions } from 'components/Perps/PerpsPositions'
|
||||
|
||||
export default function PerpsPage() {
|
||||
return (
|
||||
<div className='flex flex-col w-full h-full gap-4'>
|
||||
<div className='grid w-full grid-cols-[auto_346px] gap-4 pb-4'>
|
||||
<div className='grid grid-cols-1 grid-rows-[min-content_auto_min-content] gap-4 h-[calc(100vh-93px)] pb-4'>
|
||||
<PerpsInfo />
|
||||
<PerpsChart />
|
||||
<PerpsPositions />
|
||||
</div>
|
||||
<PerpsModule />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
import { useLocation } from 'react-router-dom'
|
||||
|
||||
import Tab from 'components/Earn/Tab'
|
||||
import MigrationBanner from 'components/MigrationBanner'
|
||||
import StatsAccounts from 'components/Stats/StatsAdditional'
|
||||
import StatsFarm from 'components/Stats/StatsFarm'
|
||||
import StatsLendAndBorrow from 'components/Stats/StatsLendAndBorrow'
|
||||
import StatsTrading from 'components/Stats/StatsTrading'
|
||||
import { STATS_TABS } from 'constants/pages'
|
||||
import { getPage } from 'utils/route'
|
||||
|
||||
function getStatsComponent(page: Page) {
|
||||
switch (page) {
|
||||
case 'stats-farm':
|
||||
return <StatsFarm />
|
||||
case 'stats-lend-borrow':
|
||||
return <StatsLendAndBorrow />
|
||||
case 'stats-additional':
|
||||
return <StatsAccounts />
|
||||
default:
|
||||
return <StatsTrading />
|
||||
}
|
||||
}
|
||||
|
||||
export default function StatsPage() {
|
||||
const { pathname } = useLocation()
|
||||
const page = getPage(pathname)
|
||||
const activeIndex = STATS_TABS.findIndex((tab) => tab.page === page)
|
||||
|
||||
return (
|
||||
<div className='flex flex-wrap w-full'>
|
||||
<MigrationBanner />
|
||||
<Tab tabs={STATS_TABS} activeTabIdx={activeIndex === -1 ? 0 : activeIndex} className='mb-8' />
|
||||
{getStatsComponent(page)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -47,10 +47,7 @@ export default function Layout({ children }: { children: React.ReactNode }) {
|
||||
DEFAULT_SETTINGS.reduceMotion,
|
||||
)
|
||||
const accountDetailsExpanded = useStore((s) => s.accountDetailsExpanded)
|
||||
const isFullWidth =
|
||||
location.pathname.includes('trade') ||
|
||||
location.pathname === '/' ||
|
||||
location.pathname.includes('perps')
|
||||
const isFullWidth = location.pathname.includes('trade') || location.pathname === '/'
|
||||
const accountId = useAccountId()
|
||||
|
||||
return (
|
||||
|
||||
@@ -15,6 +15,6 @@ export default function createCommonSlice(set: SetState<CommonSlice>, get: GetSt
|
||||
useMargin: true,
|
||||
useAutoRepay: true,
|
||||
isOracleStale: false,
|
||||
currentAppSection: 'app',
|
||||
isHLS: false,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,9 +61,3 @@
|
||||
table tr:last-child td {
|
||||
border-bottom-width: 0;
|
||||
}
|
||||
|
||||
.recharts-dot {
|
||||
stroke: theme('colors.body');
|
||||
fill: theme('colors.martian-red');
|
||||
r: 5px;
|
||||
}
|
||||
|
||||
Vendored
-4
@@ -3,10 +3,8 @@ interface Asset {
|
||||
name: string
|
||||
denom: string
|
||||
symbol:
|
||||
| 'AKT'
|
||||
| 'ATOM'
|
||||
| 'AXL'
|
||||
| 'DYDX'
|
||||
| 'INJ'
|
||||
| 'MARS'
|
||||
| 'OSMO'
|
||||
@@ -26,10 +24,8 @@ interface Asset {
|
||||
| 'stATOM-ATOM'
|
||||
| '$'
|
||||
id:
|
||||
| 'AKT'
|
||||
| 'ATOM'
|
||||
| 'AXL'
|
||||
| 'DYDX'
|
||||
| 'INJ'
|
||||
| 'axlUSDC'
|
||||
| 'axlWBTC'
|
||||
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
type ChartDataItem = { date: string; value: number }
|
||||
|
||||
type ChartData = ChartDataItem[]
|
||||
Vendored
-1
@@ -1 +0,0 @@
|
||||
type OrderDirection = 'long' | 'short'
|
||||
Vendored
-5
@@ -1,6 +1,5 @@
|
||||
type Page =
|
||||
| 'trade'
|
||||
| 'perps'
|
||||
| 'borrow'
|
||||
| 'farm'
|
||||
| 'lend'
|
||||
@@ -9,7 +8,3 @@ type Page =
|
||||
| 'hls-farm'
|
||||
| 'hls-staking'
|
||||
| 'governance'
|
||||
| 'stats'
|
||||
| 'stats-farm'
|
||||
| 'stats-lend-borrow'
|
||||
| 'stats-additional'
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@ interface CommonSlice {
|
||||
useMargin: boolean
|
||||
useAutoRepay: boolean
|
||||
isOracleStale: boolean
|
||||
currentAppSection: string
|
||||
isHLS: boolean
|
||||
}
|
||||
|
||||
interface FocusComponent {
|
||||
|
||||
@@ -19,12 +19,6 @@ export const DEFAULT_PORTFOLIO_STATS = [
|
||||
{ title: null, sub: 'APR' },
|
||||
{ title: null, sub: 'Account Leverage' },
|
||||
]
|
||||
export const DEFAULT_ADDITIONAL_STATS = [
|
||||
{ head: 'Total TVL', title: null, sub: 'Last Observed on 28 Jan 2023' },
|
||||
{ head: 'Total Credit Accounts', title: null, sub: '494 new credit accounts this week' },
|
||||
{ head: 'Total Fees Generated', title: null, sub: 'Includes liquidation, swap and borrow fees' },
|
||||
]
|
||||
|
||||
export const ENABLE_HLS = true
|
||||
export const ENABLE_PERPS = false
|
||||
export const ENABLE_AUTO_REPAY = false
|
||||
|
||||
Vendored
+7
-1
@@ -37,6 +37,12 @@ export function max_swap_estimate_js(
|
||||
kind: SwapKind,
|
||||
slippage: Slippage,
|
||||
): string
|
||||
/**
|
||||
* @param {HealthComputer} c
|
||||
* @param {string} denom
|
||||
* @returns {string}
|
||||
*/
|
||||
export function liquidation_price_js(c: HealthComputer, denom: string): string
|
||||
export interface HealthComputer {
|
||||
kind: AccountKind
|
||||
positions: Positions
|
||||
@@ -82,9 +88,9 @@ export interface InitOutput {
|
||||
g: number,
|
||||
h: number,
|
||||
) => void
|
||||
readonly liquidation_price_js: (a: number, b: number, c: number, d: number) => void
|
||||
readonly allocate: (a: number) => number
|
||||
readonly deallocate: (a: number) => void
|
||||
readonly requires_stargate: () => void
|
||||
readonly requires_iterator: () => void
|
||||
readonly interface_version_8: () => void
|
||||
readonly __wbindgen_malloc: (a: number, b: number) => number
|
||||
|
||||
@@ -230,6 +230,30 @@ export function max_swap_estimate_js(c, from_denom, to_denom, kind, slippage) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {HealthComputer} c
|
||||
* @param {string} denom
|
||||
* @returns {string}
|
||||
*/
|
||||
export function liquidation_price_js(c, denom) {
|
||||
let deferred2_0
|
||||
let deferred2_1
|
||||
try {
|
||||
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16)
|
||||
const ptr0 = passStringToWasm0(denom, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc)
|
||||
const len0 = WASM_VECTOR_LEN
|
||||
wasm.liquidation_price_js(retptr, addHeapObject(c), ptr0, len0)
|
||||
var r0 = getInt32Memory0()[retptr / 4 + 0]
|
||||
var r1 = getInt32Memory0()[retptr / 4 + 1]
|
||||
deferred2_0 = r0
|
||||
deferred2_1 = r1
|
||||
return getStringFromWasm0(r0, r1)
|
||||
} finally {
|
||||
wasm.__wbindgen_add_to_stack_pointer(16)
|
||||
wasm.__wbindgen_free(deferred2_0, deferred2_1, 1)
|
||||
}
|
||||
}
|
||||
|
||||
function handleError(f, args) {
|
||||
try {
|
||||
return f.apply(this, args)
|
||||
|
||||
Binary file not shown.
+1
-1
@@ -14,9 +14,9 @@ export function max_swap_estimate_js(
|
||||
g: number,
|
||||
h: number,
|
||||
): void
|
||||
export function liquidation_price_js(a: number, b: number, c: number, d: number): void
|
||||
export function allocate(a: number): number
|
||||
export function deallocate(a: number): void
|
||||
export function requires_stargate(): void
|
||||
export function requires_iterator(): void
|
||||
export function interface_version_8(): void
|
||||
export function __wbindgen_malloc(a: number, b: number): number
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
import { BN } from 'utils/helpers'
|
||||
import { BN } from './helpers'
|
||||
|
||||
export const devideByPotentiallyZero = (numerator: number, denominator: number): number => {
|
||||
if (denominator === 0) return 0
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { formatAmountWithSymbol } from 'utils/formatters'
|
||||
import { formatAmountWithSymbol } from './formatters'
|
||||
|
||||
export function getNoBalanceMessage(symbol: string) {
|
||||
return `You don't have an ${symbol} balance in your account.`
|
||||
|
||||
+1
-14
@@ -19,20 +19,7 @@ export function getRoute(page: Page, address?: string, accountId?: string | null
|
||||
}
|
||||
|
||||
export function getPage(pathname: string): Page {
|
||||
const pages: Page[] = [
|
||||
'trade',
|
||||
'perps',
|
||||
'borrow',
|
||||
'farm',
|
||||
'lend',
|
||||
'portfolio',
|
||||
'hls-farm',
|
||||
'hls-staking',
|
||||
'stats',
|
||||
'stats-farm',
|
||||
'stats-lend-borrow',
|
||||
'stats-additional',
|
||||
]
|
||||
const pages: Page[] = ['trade', 'borrow', 'farm', 'lend', 'portfolio', 'hls-farm', 'hls-staking']
|
||||
const segments = pathname.split('/')
|
||||
|
||||
const page = segments.find((segment) => pages.includes(segment as Page))
|
||||
|
||||
+1
-11
@@ -41,16 +41,12 @@ module.exports = {
|
||||
'@nav-3/navigation:inline-block',
|
||||
'@nav-4/navigation:inline-block',
|
||||
'@nav-5/navigation:inline-block',
|
||||
'@nav-6/navigation:inline-block',
|
||||
'@nav-7/navigation:inline-block',
|
||||
'@nav-0/navigation:hidden',
|
||||
'@nav-1/navigation:hidden',
|
||||
'@nav-2/navigation:hidden',
|
||||
'@nav-3/navigation:hidden',
|
||||
'@nav-4/navigation:hidden',
|
||||
'@nav-5/navigation:hidden',
|
||||
'@nav-6/navigation:hidden',
|
||||
'@nav-7/navigation:hidden',
|
||||
],
|
||||
theme: {
|
||||
extend: {
|
||||
@@ -123,13 +119,10 @@ module.exports = {
|
||||
osmo: '#9f1ab9',
|
||||
'orb-primary': '#b12f25',
|
||||
'orb-primary-hls': '#FF645F',
|
||||
'orb-primary-stats': '#597DFC',
|
||||
'orb-secondary': '#530781',
|
||||
'orb-secondary-hls': '#a03b45',
|
||||
'orb-secondary-stats': '#00144e',
|
||||
'orb-tertiary': '#FF00C7',
|
||||
'orb-tertiary': '#ff00c7',
|
||||
'orb-tertiary-hls': '#FB9562',
|
||||
'orb-tertiary-stats': '#6677FF',
|
||||
profit: '#41a4a9',
|
||||
primary: '#FF625E',
|
||||
secondary: '#FB9562',
|
||||
@@ -148,8 +141,6 @@ module.exports = {
|
||||
'nav-3': '400px',
|
||||
'nav-4': '500px',
|
||||
'nav-5': '600px',
|
||||
'nav-6': '700px',
|
||||
'nav-7': '800px',
|
||||
},
|
||||
fontFamily: {
|
||||
sans: ['Inter', 'sans-serif'],
|
||||
@@ -175,7 +166,6 @@ module.exports = {
|
||||
},
|
||||
height: {
|
||||
4.5: '18px',
|
||||
9: '36px',
|
||||
15: '60px',
|
||||
45: '180px',
|
||||
50: '200px',
|
||||
|
||||
Reference in New Issue
Block a user