mirror of
https://github.com/cerc-io/mars-interface.git
synced 2026-09-15 03:14:07 +00:00
v1.2.0
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
import Tippy from '@tippyjs/react'
|
||||
import classNames from 'classnames'
|
||||
import { AnimatedNumber, DisplayCurrency } from 'components/common'
|
||||
import { AnimatedNumber, DisplayCurrency, TextTooltip } from 'components/common'
|
||||
import { formatValue } from 'libs/parse'
|
||||
import { useMemo, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
@@ -82,73 +81,66 @@ export const BorrowCapacity = ({
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
<Tippy
|
||||
appendTo={() => document.body}
|
||||
interactive={true}
|
||||
animation={false}
|
||||
render={(attrs) => {
|
||||
return (
|
||||
<div className='tippyContainer' {...attrs}>
|
||||
{t('redbank.borrowingBarTooltip', {
|
||||
limit: formatValue(
|
||||
convertToDisplayCurrency({
|
||||
amount: limit.toString(),
|
||||
denom: baseCurrency.denom,
|
||||
}),
|
||||
2,
|
||||
2,
|
||||
true,
|
||||
'$',
|
||||
),
|
||||
liquidation: formatValue(
|
||||
convertToDisplayCurrency({
|
||||
amount: max.toString(),
|
||||
denom: baseCurrency.denom,
|
||||
}),
|
||||
2,
|
||||
2,
|
||||
true,
|
||||
'$',
|
||||
),
|
||||
})}
|
||||
</div>
|
||||
)
|
||||
}}
|
||||
>
|
||||
<div className={styles.progressbarContainer} style={{ height: barHeight }}>
|
||||
<div className={styles.progressbar}>
|
||||
<div className={styles.limitLine} style={{ left: `${limitPercentOfMax || 0}%` }} />
|
||||
<div
|
||||
className={styles.limitBar}
|
||||
style={{
|
||||
right: `${limitPercentOfMax ? 100 - limitPercentOfMax : 100}%`,
|
||||
}}
|
||||
></div>
|
||||
|
||||
<div className={styles.ltvContainer}>
|
||||
<TextTooltip
|
||||
hideUnderline
|
||||
tooltip={t('redbank.tooltips.borrow.bar', {
|
||||
limit: formatValue(
|
||||
convertToDisplayCurrency({
|
||||
amount: limit.toString(),
|
||||
denom: baseCurrency.denom,
|
||||
}),
|
||||
2,
|
||||
2,
|
||||
true,
|
||||
'$',
|
||||
),
|
||||
liquidation: formatValue(
|
||||
convertToDisplayCurrency({
|
||||
amount: max.toString(),
|
||||
denom: baseCurrency.denom,
|
||||
}),
|
||||
2,
|
||||
2,
|
||||
true,
|
||||
'$',
|
||||
),
|
||||
})}
|
||||
text={
|
||||
<div className={styles.progressbarContainer} style={{ height: barHeight }}>
|
||||
<div className={styles.progressbar}>
|
||||
<div className={styles.limitLine} style={{ left: `${limitPercentOfMax || 0}%` }} />
|
||||
<div
|
||||
className={styles.indicator}
|
||||
style={{ width: `${percentOfMaxRange || 0.01}%` }}
|
||||
>
|
||||
<div className={styles.gradient} />
|
||||
className={styles.limitBar}
|
||||
style={{
|
||||
right: `${limitPercentOfMax ? 100 - limitPercentOfMax : 100}%`,
|
||||
}}
|
||||
></div>
|
||||
|
||||
<div className={styles.ltvContainer}>
|
||||
<div
|
||||
className={styles.indicator}
|
||||
style={{ width: `${percentOfMaxRange || 0.01}%` }}
|
||||
>
|
||||
<div className={styles.gradient} />
|
||||
</div>
|
||||
{showPercentageText ? (
|
||||
<span className={classNames('overline', styles.percentage)}>
|
||||
{max !== 0 && (
|
||||
<AnimatedNumber
|
||||
amount={percentOfMaxRound}
|
||||
suffix='%'
|
||||
maxDecimals={roundPercentage ? 0 : undefined}
|
||||
minDecimals={roundPercentage ? 0 : undefined}
|
||||
abbreviated={false}
|
||||
/>
|
||||
)}
|
||||
</span>
|
||||
) : null}
|
||||
</div>
|
||||
{showPercentageText ? (
|
||||
<span className={classNames('overline', styles.percentage)}>
|
||||
{max !== 0 && (
|
||||
<AnimatedNumber
|
||||
amount={percentOfMaxRound}
|
||||
suffix='%'
|
||||
maxDecimals={roundPercentage ? 0 : undefined}
|
||||
minDecimals={roundPercentage ? 0 : undefined}
|
||||
abbreviated={false}
|
||||
/>
|
||||
)}
|
||||
</span>
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Tippy>
|
||||
}
|
||||
/>
|
||||
{!hideValues && (
|
||||
<div className={`overline ${styles.values} xxxsCaps`}>
|
||||
<DisplayCurrency
|
||||
|
||||
@@ -10,7 +10,7 @@ import { useQueryClient } from '@tanstack/react-query'
|
||||
import { MARS_SYMBOL, USDC_SYMBOL } from 'constants/appConstants'
|
||||
import {
|
||||
useBlockHeight,
|
||||
useMarketDeposits,
|
||||
useDepositAndDebt,
|
||||
useMarsOracle,
|
||||
useRedBank,
|
||||
useUserBalance,
|
||||
@@ -49,7 +49,6 @@ export const CommonContainer = ({ children }: CommonContainerProps) => {
|
||||
const exchangeRatesState = useStore((s) => s.exchangeRatesState)
|
||||
const isNetworkLoaded = useStore((s) => s.isNetworkLoaded)
|
||||
const rpc = useStore((s) => s.chainInfo?.rpc)
|
||||
const marketAssetLiquidity = useStore((s) => s.marketAssetLiquidity)
|
||||
const marketDeposits = useStore((s) => s.marketDeposits)
|
||||
const marketInfo = useStore((s) => s.marketInfo)
|
||||
const marketIncentiveInfo = useStore((s) => s.marketIncentiveInfo)
|
||||
@@ -131,7 +130,6 @@ export const CommonContainer = ({ children }: CommonContainerProps) => {
|
||||
userBalancesState,
|
||||
exchangeRates,
|
||||
marketInfo,
|
||||
marketAssetLiquidity,
|
||||
marketIncentiveInfo,
|
||||
userDebts,
|
||||
userDeposits,
|
||||
@@ -157,7 +155,7 @@ export const CommonContainer = ({ children }: CommonContainerProps) => {
|
||||
useMarsOracle()
|
||||
useSpotPrice(MARS_SYMBOL)
|
||||
useSpotPrice(USDC_SYMBOL)
|
||||
useMarketDeposits()
|
||||
useDepositAndDebt()
|
||||
useRedBank()
|
||||
|
||||
return <>{isNetworkLoaded && children}</>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ChainInfoID, WalletID, WalletManagerProvider } from '@marsprotocol/wallet-connector'
|
||||
import { WalletID, WalletManagerProvider } from '@marsprotocol/wallet-connector'
|
||||
import { CircularProgress, SVG } from 'components/common'
|
||||
import { useEffect, useState } from 'react'
|
||||
|
||||
@@ -8,10 +8,12 @@ type Props = {
|
||||
children?: React.ReactNode
|
||||
}
|
||||
|
||||
const defaultChain = ChainInfoID.OsmosisTestnet
|
||||
|
||||
export const CosmosWalletConnectProvider = ({ children }: Props) => {
|
||||
const [chainInfoOverrides, setChainInfoOverrides] = useState<{ rpc: string; rest: string }>()
|
||||
const [chainInfoOverrides, setChainInfoOverrides] = useState<{
|
||||
rpc: string
|
||||
rest: string
|
||||
chainID: string
|
||||
}>()
|
||||
const [enabledWallets, setEnabledWallets] = useState<WalletID[]>([])
|
||||
|
||||
useEffect(() => {
|
||||
@@ -29,6 +31,7 @@ export const CosmosWalletConnectProvider = ({ children }: Props) => {
|
||||
setChainInfoOverrides({
|
||||
rpc: networkConfig.rpcUrl,
|
||||
rest: networkConfig.restUrl,
|
||||
chainID: networkConfig.name,
|
||||
})
|
||||
setEnabledWallets(networkConfig.wallets)
|
||||
}
|
||||
@@ -42,7 +45,7 @@ export const CosmosWalletConnectProvider = ({ children }: Props) => {
|
||||
<WalletManagerProvider
|
||||
chainInfoOverrides={chainInfoOverrides}
|
||||
closeIcon={<SVG.Close />}
|
||||
defaultChainId={defaultChain}
|
||||
defaultChainId={chainInfoOverrides.chainID}
|
||||
enabledWallets={enabledWallets}
|
||||
persistent
|
||||
renderLoader={() => (
|
||||
|
||||
@@ -17,10 +17,12 @@ export const DisplayCurrency = ({
|
||||
isApproximation,
|
||||
className,
|
||||
}: Props) => {
|
||||
const displayCurrency = useStore((s) => s.displayCurrency)
|
||||
const networkConfig = useStore((s) => s.networkConfig)
|
||||
const convertToDisplayCurrency = useStore((s) => s.convertToDisplayCurrency)
|
||||
|
||||
const amount = convertToDisplayCurrency(coin)
|
||||
const displayCurrency = networkConfig?.displayCurrency
|
||||
|
||||
if (!displayCurrency) return null
|
||||
|
||||
return (
|
||||
<div className={className}>
|
||||
|
||||
@@ -47,9 +47,9 @@
|
||||
top: rem-calc(38);
|
||||
@include padding(6, 6, 5.5);
|
||||
@include layoutPopover;
|
||||
width: rem-calc(420);
|
||||
width: rem-calc(380);
|
||||
max-width: calc(100vw - 24px);
|
||||
right: 0;
|
||||
right: -25%;
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
@@ -191,6 +191,8 @@
|
||||
@media only screen and (min-width: $bpMediumLow) {
|
||||
.details {
|
||||
transform: none;
|
||||
width: rem-calc(420);
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.detailsBalance {
|
||||
|
||||
@@ -46,7 +46,7 @@ export const ConnectedButton = () => {
|
||||
const viewOnFinder = useCallback(() => {
|
||||
const explorerUrl = chainInfo ? chainInfo.explorer : ''
|
||||
|
||||
window.open(`${explorerUrl}account/${userWalletAddress}`, '_blank')
|
||||
window.open(`${explorerUrl}/account/${userWalletAddress}`, '_blank')
|
||||
}, [chainInfo, userWalletAddress])
|
||||
|
||||
const onClickAway = useCallback(() => {
|
||||
@@ -103,7 +103,7 @@ export const ConnectedButton = () => {
|
||||
className='s faded'
|
||||
coin={{
|
||||
amount: baseCurrencyBalance.toString(),
|
||||
denom: baseCurrency.symbol,
|
||||
denom: baseCurrency.denom,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -31,18 +31,19 @@ export const Header = () => {
|
||||
>
|
||||
{t('global.redBank')}
|
||||
</Link>
|
||||
<Link
|
||||
passHref
|
||||
href='/farm'
|
||||
className={classNames(
|
||||
!FIELDS_FEATURE && styles.disabled,
|
||||
styles.nav,
|
||||
router.pathname.includes('farm') && styles.active,
|
||||
router.pathname === '/farm' && styles.unclickable,
|
||||
)}
|
||||
>
|
||||
{t('global.fields')}
|
||||
</Link>
|
||||
{FIELDS_FEATURE && (
|
||||
<Link
|
||||
passHref
|
||||
href='/farm'
|
||||
className={classNames(
|
||||
styles.nav,
|
||||
router.pathname.includes('farm') && styles.active,
|
||||
router.pathname === '/farm' && styles.unclickable,
|
||||
)}
|
||||
>
|
||||
{t('global.fields')}
|
||||
</Link>
|
||||
)}
|
||||
<a className={styles.nav} href={networkConfig?.councilUrl} target='_blank' rel='noreferrer'>
|
||||
{t('global.council')}
|
||||
</a>
|
||||
|
||||
@@ -156,7 +156,7 @@ export const IncentivesButton = () => {
|
||||
<p className='m'>{t('incentives.successfullyClaimed')}</p>
|
||||
<TxLink
|
||||
hash={response?.hash || ''}
|
||||
link={`${explorerUrl}txs/${response?.hash}`}
|
||||
link={`${explorerUrl}/txs/${response?.hash}`}
|
||||
/>
|
||||
</div>
|
||||
) : (
|
||||
|
||||
@@ -2,6 +2,7 @@ import { useWalletManager, WalletConnectionStatus } from '@marsprotocol/wallet-c
|
||||
import BigNumber from 'bignumber.js'
|
||||
import classNames from 'classnames'
|
||||
import { Button, NumberInput, SVG, Toggle, Tooltip } from 'components/common'
|
||||
import { FIELDS_FEATURE } from 'constants/appConstants'
|
||||
import React, { useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import useStore from 'store'
|
||||
@@ -88,54 +89,57 @@ export const Settings = () => {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={styles.header}>
|
||||
<p className={styles.text}>{t('fields.settings')}</p>
|
||||
</div>
|
||||
<div className={styles.settings}>
|
||||
<div className={styles.setting}>
|
||||
<div className={styles.name}>
|
||||
{t('common.slippage')}
|
||||
<Tooltip content={t('fields.tooltips.slippage')} className={styles.tooltip} />
|
||||
{FIELDS_FEATURE && (
|
||||
<>
|
||||
<div className={styles.header}>
|
||||
<p className={styles.text}>{t('fields.settings')}</p>
|
||||
</div>
|
||||
<div className={styles.content}>
|
||||
{slippages.map((value) => (
|
||||
<button
|
||||
key={`slippage-${value}`}
|
||||
onClick={() => {
|
||||
useStore.setState({ slippage: value })
|
||||
}}
|
||||
className={classNames([
|
||||
styles.button,
|
||||
slippage === value && !isCustom ? styles.solid : '',
|
||||
])}
|
||||
>
|
||||
{value * 100}%
|
||||
</button>
|
||||
))}
|
||||
<button
|
||||
onClick={() => inputRef?.current?.focus()}
|
||||
className={classNames([
|
||||
styles.button,
|
||||
!slippages.includes(slippage) || isCustom ? styles.solid : '',
|
||||
])}
|
||||
>
|
||||
<NumberInput
|
||||
onRef={setInputRef}
|
||||
onChange={onInputChange}
|
||||
onBlur={onInputBlur}
|
||||
onFocus={onInputFocus}
|
||||
value={customSlippage}
|
||||
maxValue={10}
|
||||
maxDecimals={1}
|
||||
maxLength={3}
|
||||
className={styles.customSlippageBtn}
|
||||
/>
|
||||
%
|
||||
</button>
|
||||
<div className={styles.settings}>
|
||||
<div className={styles.setting}>
|
||||
<div className={styles.name}>
|
||||
{t('common.slippage')}
|
||||
<Tooltip content={t('fields.tooltips.slippage')} className={styles.tooltip} />
|
||||
</div>
|
||||
<div className={styles.content}>
|
||||
{slippages.map((value) => (
|
||||
<button
|
||||
key={`slippage-${value}`}
|
||||
onClick={() => {
|
||||
useStore.setState({ slippage: value })
|
||||
}}
|
||||
className={classNames([
|
||||
styles.button,
|
||||
slippage === value && !isCustom ? styles.solid : '',
|
||||
])}
|
||||
>
|
||||
{value * 100}%
|
||||
</button>
|
||||
))}
|
||||
<button
|
||||
onClick={() => inputRef?.current?.focus()}
|
||||
className={classNames([
|
||||
styles.button,
|
||||
!slippages.includes(slippage) || isCustom ? styles.solid : '',
|
||||
])}
|
||||
>
|
||||
<NumberInput
|
||||
onRef={setInputRef}
|
||||
onChange={onInputChange}
|
||||
onBlur={onInputBlur}
|
||||
onFocus={onInputFocus}
|
||||
value={customSlippage}
|
||||
maxValue={10}
|
||||
maxDecimals={1}
|
||||
maxLength={3}
|
||||
className={styles.customSlippageBtn}
|
||||
/>
|
||||
%
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
<div className={styles.clickAway} onClick={() => setShowDetails(false)} role='button' />
|
||||
</>
|
||||
|
||||
@@ -15,23 +15,23 @@ type Props = {
|
||||
|
||||
export const Layout = ({ children }: Props) => {
|
||||
const router = useRouter()
|
||||
const { status } = useWalletManager()
|
||||
useAnimations()
|
||||
|
||||
const userWalletAddress = useStore((s) => s.userWalletAddress)
|
||||
const enableAnimations = useStore((s) => s.enableAnimations)
|
||||
const backgroundClasses = classNames('background', !userWalletAddress && 'night')
|
||||
const vaultConfigs = useStore((s) => s.vaultConfigs)
|
||||
const { status } = useWalletManager()
|
||||
const isConnected = status === WalletConnectionStatus.Connected
|
||||
const backgroundClasses = classNames('background', !isConnected && 'night')
|
||||
const vaultConfigs = useStore((s) => s.vaultConfigs)
|
||||
const wasConnectedBefore =
|
||||
localStorage.getItem(SESSION_WALLET_KEY) !== null &&
|
||||
localStorage.getItem(SESSION_WALLET_KEY) !== '[]'
|
||||
localStorage.getItem(SESSION_WALLET_KEY) &&
|
||||
localStorage.getItem(SESSION_WALLET_KEY) !== '[]' &&
|
||||
status !== WalletConnectionStatus.Errored
|
||||
|
||||
useEffect(() => {
|
||||
if (!userWalletAddress) {
|
||||
if (!isConnected) {
|
||||
useStore.setState({ availableVaults: vaultConfigs, activeVaults: [] })
|
||||
}
|
||||
}, [userWalletAddress, vaultConfigs])
|
||||
}, [isConnected, vaultConfigs])
|
||||
|
||||
return (
|
||||
<div className={classNames('app', !enableAnimations && 'no-motion')}>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import classNames from 'classnames'
|
||||
import { SVG } from 'components/common'
|
||||
import { FIELDS_FEATURE } from 'constants/appConstants'
|
||||
import Link from 'next/link'
|
||||
import { useRouter } from 'next/router'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
@@ -26,14 +27,16 @@ export const MobileNav = () => {
|
||||
<SVG.CouncilIcon />
|
||||
<span>{t('global.council')}</span>
|
||||
</a>
|
||||
<Link
|
||||
href='/farm'
|
||||
passHref
|
||||
className={classNames(styles.nav, router.pathname.includes('farm') && styles.active)}
|
||||
>
|
||||
<SVG.FieldsIcon />
|
||||
<span>{t('global.fields')}</span>
|
||||
</Link>
|
||||
{FIELDS_FEATURE && (
|
||||
<Link
|
||||
href='/farm'
|
||||
passHref
|
||||
className={classNames(styles.nav, router.pathname.includes('farm') && styles.active)}
|
||||
>
|
||||
<SVG.FieldsIcon />
|
||||
<span>{t('global.fields')}</span>
|
||||
</Link>
|
||||
)}
|
||||
</nav>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
@import 'src/styles/master';
|
||||
|
||||
.pointer {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.tooltip {
|
||||
border-bottom: 1px dashed $alphaWhite40;
|
||||
transition: border 0.2s;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
border-bottom-color: transparent;
|
||||
}
|
||||
}
|
||||
@@ -1,23 +1,31 @@
|
||||
import Tippy from '@tippyjs/react'
|
||||
|
||||
import styles from './TextTooltip.module.scss'
|
||||
|
||||
interface Props {
|
||||
text: string
|
||||
tooltip: string
|
||||
text: string | React.ReactNode
|
||||
tooltip: string | React.ReactNode
|
||||
hideUnderline?: boolean
|
||||
hideStyling?: boolean
|
||||
}
|
||||
export const TextTooltip = (props: Props) => {
|
||||
return (
|
||||
<Tippy
|
||||
appendTo={() => document.body}
|
||||
animation={false}
|
||||
delay={[400, 0]}
|
||||
render={(attrs) => {
|
||||
if (!props.tooltip) return null
|
||||
return (
|
||||
<div className='tippyContainer' {...attrs}>
|
||||
<div className={props.hideStyling ? '' : 'tippyContainer'} {...attrs}>
|
||||
{props.tooltip}
|
||||
</div>
|
||||
)
|
||||
}}
|
||||
>
|
||||
<div>{props.text}</div>
|
||||
<span className={props.hideUnderline ? styles.pointer : styles.tooltip} style={{}}>
|
||||
{props.text}
|
||||
</span>
|
||||
</Tippy>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -447,13 +447,13 @@ export const Action = ({
|
||||
const getTooltip = (): string | undefined => {
|
||||
switch (activeView) {
|
||||
case ViewType.Borrow:
|
||||
return t('redbank.redbankActionBorrowTooltip')
|
||||
return t('redbank.tooltips.borrow.action')
|
||||
case ViewType.Deposit:
|
||||
return t('redbank.redbankActionDepositTooltip')
|
||||
return t('redbank.tooltips.deposit.action')
|
||||
case ViewType.Withdraw:
|
||||
return t('redbank.redbankActionWithdrawTooltip')
|
||||
return t('redbank.tooltips.withdraw.action')
|
||||
case ViewType.Repay:
|
||||
return t('redbank.redbankActionRepayTooltip')
|
||||
return t('redbank.tooltips.repay.action')
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ export const TxFailedContent = ({ message, hash, handleClose }: Props) => {
|
||||
<InfoTitle src={TxStatus.FAILURE} subTitle='' title={t('common.transactionFailed')} />
|
||||
<div className={styles.failure}>
|
||||
<div className={styles.message}>{message}</div>
|
||||
{hash ? <TxLink hash={hash} link={`${explorerUrl}txs/${hash}`} /> : null}
|
||||
{hash ? <TxLink hash={hash} link={`${explorerUrl}/txs/${hash}`} /> : null}
|
||||
</div>
|
||||
|
||||
<div
|
||||
|
||||
@@ -67,7 +67,7 @@ export const TxSuccessContent = ({
|
||||
<div className={styles.label}>{t('common.txHash')}</div>
|
||||
<TxLink
|
||||
hash={response?.response.transactionHash || ''}
|
||||
link={`${explorerUrl}txs/${response?.response.transactionHash}`}
|
||||
link={`${explorerUrl}/txs/${response?.response.transactionHash}`}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
import Tippy from '@tippyjs/react'
|
||||
import BigNumber from 'bignumber.js'
|
||||
import { AnimatedNumber, Apy, BorrowCapacity, Card, DisplayCurrency } from 'components/common'
|
||||
import {
|
||||
AnimatedNumber,
|
||||
Apy,
|
||||
BorrowCapacity,
|
||||
Card,
|
||||
DisplayCurrency,
|
||||
TextTooltip,
|
||||
} from 'components/common'
|
||||
import { VaultLogo, VaultName } from 'components/fields'
|
||||
import { FIELDS_TUTORIAL_KEY } from 'constants/appConstants'
|
||||
import Link from 'next/link'
|
||||
@@ -60,8 +66,18 @@ export const ActiveVaultsTableMobile = () => {
|
||||
<div className='xl' onClick={(e) => e.preventDefault()}>
|
||||
<span className='faded'>{t('common.apy')} </span>
|
||||
<span>
|
||||
<Tippy
|
||||
content={
|
||||
<TextTooltip
|
||||
hideStyling
|
||||
text={
|
||||
<span>
|
||||
<AnimatedNumber
|
||||
amount={vault.position.apy.net}
|
||||
className='xl'
|
||||
suffix='%'
|
||||
/>
|
||||
</span>
|
||||
}
|
||||
tooltip={
|
||||
<Apy
|
||||
apyData={{
|
||||
borrow: vault.position.apy.borrow,
|
||||
@@ -70,11 +86,7 @@ export const ActiveVaultsTableMobile = () => {
|
||||
leverage={vault.position.currentLeverage}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<span className='tooltip xl'>
|
||||
<AnimatedNumber amount={vault.position.apy.net} className='xl' suffix='%' />
|
||||
</span>
|
||||
</Tippy>
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
<div className='s'>
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { ColumnDef, createColumnHelper } from '@tanstack/react-table'
|
||||
import Tippy from '@tippyjs/react'
|
||||
import BigNumber from 'bignumber.js'
|
||||
import classNames from 'classnames'
|
||||
import {
|
||||
@@ -53,25 +52,14 @@ export const useActiveVaultsColumns = () => {
|
||||
header: t('fields.position'),
|
||||
cell: ({ row }) => {
|
||||
return (
|
||||
<Tippy
|
||||
appendTo={() => document.body}
|
||||
animation={false}
|
||||
render={(attrs) => {
|
||||
return (
|
||||
<div className='tippyContainer' {...attrs}>
|
||||
{t('fields.tooltips.name', {
|
||||
asset1: row.original.symbols.primary,
|
||||
asset2: row.original.symbols.secondary,
|
||||
...getTimeAndUnit(row.original.lockup),
|
||||
})}
|
||||
</div>
|
||||
)
|
||||
}}
|
||||
>
|
||||
<div>
|
||||
<VaultName vault={row.original} />
|
||||
</div>
|
||||
</Tippy>
|
||||
<TextTooltip
|
||||
text={<VaultName vault={row.original} />}
|
||||
tooltip={t('fields.tooltips.name', {
|
||||
asset1: row.original.symbols.primary,
|
||||
asset2: row.original.symbols.secondary,
|
||||
...getTimeAndUnit(row.original.lockup),
|
||||
})}
|
||||
/>
|
||||
)
|
||||
},
|
||||
}),
|
||||
@@ -97,28 +85,23 @@ export const useActiveVaultsColumns = () => {
|
||||
}
|
||||
|
||||
return (
|
||||
<Tippy
|
||||
appendTo={() => document.body}
|
||||
animation={false}
|
||||
render={(attrs) => {
|
||||
return (
|
||||
<div className='tippyContainer' {...attrs}>
|
||||
<TokenBalance coin={primaryCoin} maxDecimals={2} showSymbol />
|
||||
<br />
|
||||
<TokenBalance coin={secondaryCoin} maxDecimals={2} showSymbol />
|
||||
</div>
|
||||
)
|
||||
}}
|
||||
>
|
||||
<div>
|
||||
<TextTooltip
|
||||
text={
|
||||
<DisplayCurrency
|
||||
coin={{
|
||||
denom: baseCurrency.denom,
|
||||
amount: row.original.position.values.total.toString(),
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</Tippy>
|
||||
}
|
||||
tooltip={
|
||||
<>
|
||||
<TokenBalance coin={primaryCoin} maxDecimals={2} showSymbol />
|
||||
<br />
|
||||
<TokenBalance coin={secondaryCoin} maxDecimals={2} showSymbol />
|
||||
</>
|
||||
}
|
||||
/>
|
||||
)
|
||||
},
|
||||
}),
|
||||
@@ -142,25 +125,20 @@ export const useActiveVaultsColumns = () => {
|
||||
]
|
||||
|
||||
return (
|
||||
<Tippy
|
||||
appendTo={() => document.body}
|
||||
animation={false}
|
||||
render={(attrs) => {
|
||||
return (
|
||||
<div className='tippyContainer' {...attrs}>
|
||||
<TokenBalance coin={coins[0]} maxDecimals={2} showSymbol />
|
||||
<br />
|
||||
<TokenBalance coin={coins[1]} maxDecimals={2} showSymbol />
|
||||
</div>
|
||||
)
|
||||
}}
|
||||
>
|
||||
<div>
|
||||
<TextTooltip
|
||||
text={
|
||||
<DisplayCurrency
|
||||
coin={{ denom: baseCurrency.denom, amount: netValue.toString() }}
|
||||
/>
|
||||
</div>
|
||||
</Tippy>
|
||||
}
|
||||
tooltip={
|
||||
<>
|
||||
<TokenBalance coin={coins[0]} maxDecimals={2} showSymbol />
|
||||
<br />
|
||||
<TokenBalance coin={coins[1]} maxDecimals={2} showSymbol />
|
||||
</>
|
||||
}
|
||||
/>
|
||||
)
|
||||
},
|
||||
}),
|
||||
@@ -176,33 +154,26 @@ export const useActiveVaultsColumns = () => {
|
||||
if (!borrowAsset) return
|
||||
|
||||
return (
|
||||
<Tippy
|
||||
appendTo={() => document.body}
|
||||
animation={false}
|
||||
render={(attrs) => {
|
||||
return (
|
||||
<div className='tippyContainer' {...attrs}>
|
||||
<TokenBalance
|
||||
coin={{
|
||||
denom: info.row.original.denoms.secondary,
|
||||
amount: info.row.original.position.amounts.borrowed.toString(),
|
||||
}}
|
||||
maxDecimals={2}
|
||||
showSymbol
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}}
|
||||
>
|
||||
<div>
|
||||
<TextTooltip
|
||||
text={
|
||||
<DisplayCurrency
|
||||
coin={{
|
||||
denom: baseCurrency.denom,
|
||||
amount: info.row.original.position.values.borrowed.toString(),
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</Tippy>
|
||||
}
|
||||
tooltip={
|
||||
<TokenBalance
|
||||
coin={{
|
||||
denom: info.row.original.denoms.secondary,
|
||||
amount: info.row.original.position.amounts.borrowed.toString(),
|
||||
}}
|
||||
maxDecimals={2}
|
||||
showSymbol
|
||||
/>
|
||||
}
|
||||
/>
|
||||
)
|
||||
},
|
||||
}),
|
||||
@@ -223,35 +194,30 @@ export const useActiveVaultsColumns = () => {
|
||||
const vaultCap = row.original.vaultCap
|
||||
|
||||
return (
|
||||
<Tippy
|
||||
appendTo={() => document.body}
|
||||
animation={false}
|
||||
render={(attrs) => {
|
||||
return (
|
||||
<div className='tippyContainer' {...attrs}>
|
||||
<TokenBalance
|
||||
showSymbol
|
||||
coin={{
|
||||
denom: baseCurrency.denom,
|
||||
amount: vaultCap.max.toString(),
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}}
|
||||
>
|
||||
<div>
|
||||
<DisplayCurrency
|
||||
<TextTooltip
|
||||
text={
|
||||
<>
|
||||
<DisplayCurrency
|
||||
coin={{
|
||||
denom: baseCurrency.denom,
|
||||
amount: vaultCap.max.toString(),
|
||||
}}
|
||||
/>
|
||||
<p className={percentClasses}>
|
||||
{percent}% {t('common.used')}
|
||||
</p>
|
||||
</>
|
||||
}
|
||||
tooltip={
|
||||
<TokenBalance
|
||||
showSymbol
|
||||
coin={{
|
||||
denom: baseCurrency.denom,
|
||||
amount: vaultCap.max.toString(),
|
||||
}}
|
||||
/>
|
||||
<p className={percentClasses}>
|
||||
{percent}% {t('common.used')}
|
||||
</p>
|
||||
</div>
|
||||
</Tippy>
|
||||
}
|
||||
/>
|
||||
)
|
||||
},
|
||||
}),
|
||||
@@ -279,20 +245,20 @@ export const useActiveVaultsColumns = () => {
|
||||
}
|
||||
return (
|
||||
<>
|
||||
<Tippy
|
||||
appendTo={() => document.body}
|
||||
animation={false}
|
||||
content={
|
||||
<TextTooltip
|
||||
hideStyling
|
||||
text={
|
||||
<>
|
||||
<AnimatedNumber amount={apy} className='m' suffix='%' />
|
||||
<p className='s faded'>
|
||||
{convertApyToDailyApy(row.original.position.apy.net)}%/{t('common.day')}
|
||||
</p>
|
||||
</>
|
||||
}
|
||||
tooltip={
|
||||
<Apy apyData={apyData} leverage={row.original.position.currentLeverage} />
|
||||
}
|
||||
>
|
||||
<span className='tooltip'>
|
||||
<AnimatedNumber amount={apy} className='m' suffix='%' />
|
||||
<p className='s faded'>
|
||||
{convertApyToDailyApy(row.original.position.apy.net)}%/{t('common.day')}
|
||||
</p>
|
||||
</span>
|
||||
</Tippy>
|
||||
/>
|
||||
</>
|
||||
)
|
||||
case 'unlocking':
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import Tippy from '@tippyjs/react'
|
||||
import BigNumber from 'bignumber.js'
|
||||
import { AnimatedNumber, Apy, Card, DisplayCurrency } from 'components/common'
|
||||
import { AnimatedNumber, Apy, Card, DisplayCurrency, TextTooltip } from 'components/common'
|
||||
import { VaultLogo, VaultName } from 'components/fields'
|
||||
import { getTimeAndUnit, ltvToLeverage } from 'libs/parse'
|
||||
import Link from 'next/link'
|
||||
@@ -52,20 +51,18 @@ export const AvailableVaultsTableMobile = () => {
|
||||
<div onClick={(e) => e.preventDefault()} className='xl'>
|
||||
<span className='faded'>{t('common.apy')} </span>
|
||||
<span>
|
||||
<Tippy content={<Apy apyData={apyDataNoLev} leverage={1} />}>
|
||||
<span className='tooltip xl'>
|
||||
<AnimatedNumber amount={minAPY} suffix='-' />
|
||||
</span>
|
||||
</Tippy>
|
||||
<Tippy
|
||||
content={
|
||||
<TextTooltip
|
||||
hideStyling
|
||||
text={<AnimatedNumber amount={minAPY} suffix='-' />}
|
||||
tooltip={<Apy apyData={apyDataNoLev} leverage={1} />}
|
||||
/>
|
||||
<TextTooltip
|
||||
hideStyling
|
||||
text={<AnimatedNumber amount={maxAPY} suffix='%' />}
|
||||
tooltip={
|
||||
<Apy apyData={apyDataLev} leverage={ltvToLeverage(vault.ltv.max)} />
|
||||
}
|
||||
>
|
||||
<span className='tooltip xl'>
|
||||
<AnimatedNumber amount={maxAPY} suffix='%' />
|
||||
</span>
|
||||
</Tippy>
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
<div className='s'>
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { ColumnDef, createColumnHelper } from '@tanstack/react-table'
|
||||
import Tippy from '@tippyjs/react'
|
||||
import BigNumber from 'bignumber.js'
|
||||
import classNames from 'classnames'
|
||||
import {
|
||||
@@ -46,25 +45,14 @@ export const useAvailableVaultsColumns = () => {
|
||||
header: t('fields.name'),
|
||||
cell: ({ row }) => {
|
||||
return (
|
||||
<Tippy
|
||||
appendTo={() => document.body}
|
||||
animation={false}
|
||||
render={(attrs) => {
|
||||
return (
|
||||
<div className='tippyContainer' {...attrs}>
|
||||
{t('fields.tooltips.name', {
|
||||
asset1: row.original.symbols.primary,
|
||||
asset2: row.original.symbols.secondary,
|
||||
...getTimeAndUnit(row.original.lockup),
|
||||
})}
|
||||
</div>
|
||||
)
|
||||
}}
|
||||
>
|
||||
<div>
|
||||
<VaultName vault={row.original} />
|
||||
</div>
|
||||
</Tippy>
|
||||
<TextTooltip
|
||||
text={<VaultName vault={row.original} />}
|
||||
tooltip={t('fields.tooltips.name', {
|
||||
asset1: row.original.symbols.primary,
|
||||
asset2: row.original.symbols.secondary,
|
||||
...getTimeAndUnit(row.original.lockup),
|
||||
})}
|
||||
/>
|
||||
)
|
||||
},
|
||||
}),
|
||||
@@ -118,21 +106,19 @@ export const useAvailableVaultsColumns = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<Tippy content={<Apy apyData={apyDataNoLev} leverage={1} />}>
|
||||
<span className='tooltip m'>
|
||||
<AnimatedNumber amount={minAPY} />
|
||||
</span>
|
||||
</Tippy>
|
||||
<TextTooltip
|
||||
hideStyling
|
||||
text={<AnimatedNumber amount={minAPY} />}
|
||||
tooltip={<Apy apyData={apyDataNoLev} leverage={1} />}
|
||||
/>
|
||||
<span>-</span>
|
||||
<Tippy
|
||||
content={
|
||||
<TextTooltip
|
||||
hideStyling
|
||||
text={<AnimatedNumber amount={maxAPY} suffix='%' />}
|
||||
tooltip={
|
||||
<Apy apyData={apyDataLev} leverage={ltvToLeverage(row.original.ltv.max)} />
|
||||
}
|
||||
>
|
||||
<span className='tooltip ,'>
|
||||
<AnimatedNumber amount={maxAPY} suffix='%' />
|
||||
</span>
|
||||
</Tippy>
|
||||
/>
|
||||
|
||||
<p className='s faded'>
|
||||
{minDailyAPY}-{maxDailyAPY}%/
|
||||
@@ -159,35 +145,30 @@ export const useAvailableVaultsColumns = () => {
|
||||
const vaultCap = row.original.vaultCap
|
||||
|
||||
return (
|
||||
<Tippy
|
||||
appendTo={() => document.body}
|
||||
animation={false}
|
||||
render={(attrs) => {
|
||||
return (
|
||||
<div className='tippyContainer' {...attrs}>
|
||||
<TokenBalance
|
||||
showSymbol
|
||||
coin={{
|
||||
denom: baseCurrency.denom,
|
||||
amount: vaultCap.max.toString(),
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}}
|
||||
>
|
||||
<div>
|
||||
<DisplayCurrency
|
||||
<TextTooltip
|
||||
text={
|
||||
<>
|
||||
<DisplayCurrency
|
||||
coin={{
|
||||
denom: baseCurrency.denom,
|
||||
amount: vaultCap.max.toString(),
|
||||
}}
|
||||
/>
|
||||
<p className={percentClasses}>
|
||||
{percent}% {t('common.used')}
|
||||
</p>
|
||||
</>
|
||||
}
|
||||
tooltip={
|
||||
<TokenBalance
|
||||
showSymbol
|
||||
coin={{
|
||||
denom: baseCurrency.denom,
|
||||
amount: vaultCap.max.toString(),
|
||||
}}
|
||||
/>
|
||||
<p className={percentClasses}>
|
||||
{percent}% {t('common.used')}
|
||||
</p>
|
||||
</div>
|
||||
</Tippy>
|
||||
}
|
||||
/>
|
||||
)
|
||||
},
|
||||
}),
|
||||
@@ -200,23 +181,15 @@ export const useAvailableVaultsColumns = () => {
|
||||
enableSorting: true,
|
||||
header: t('common.description'),
|
||||
cell: ({ row }) => (
|
||||
<Tippy
|
||||
appendTo={() => document.body}
|
||||
animation={false}
|
||||
render={(attrs) => {
|
||||
return (
|
||||
<div className='tippyContainer' {...attrs}>
|
||||
{t('fields.tooltips.name', {
|
||||
asset1: row.original.symbols.primary,
|
||||
asset2: row.original.symbols.secondary,
|
||||
...getTimeAndUnit(row.original.lockup),
|
||||
})}
|
||||
</div>
|
||||
)
|
||||
}}
|
||||
>
|
||||
<p>{row.original.description}</p>
|
||||
</Tippy>
|
||||
<TextTooltip
|
||||
hideUnderline
|
||||
text={row.original.description}
|
||||
tooltip={t('fields.tooltips.name', {
|
||||
asset1: row.original.symbols.primary,
|
||||
asset2: row.original.symbols.secondary,
|
||||
...getTimeAndUnit(row.original.lockup),
|
||||
})}
|
||||
/>
|
||||
),
|
||||
}),
|
||||
columnHelper.display({
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import Tippy from '@tippyjs/react'
|
||||
import classNames from 'classnames'
|
||||
import {
|
||||
AnimatedNumber,
|
||||
Apy,
|
||||
BorrowCapacity,
|
||||
DisplayCurrency,
|
||||
TextTooltip,
|
||||
TokenBalance,
|
||||
} from 'components/common'
|
||||
import { MARS_DECIMALS, MARS_SYMBOL, VAULT_DEPOSIT_BUFFER } from 'constants/appConstants'
|
||||
@@ -214,11 +214,11 @@ export const BreakdownTable = (props: Props) => {
|
||||
<div className={styles.stats}>
|
||||
<div className={styles.apy}>
|
||||
<span className='faded'>{t('common.apy')}: </span>
|
||||
<Tippy content={<Apy apyData={apyData} leverage={currentLeverage} />}>
|
||||
<span className='tooltip'>
|
||||
<AnimatedNumber amount={apy} suffix='%' abbreviated={false} />
|
||||
</span>
|
||||
</Tippy>
|
||||
<TextTooltip
|
||||
hideStyling
|
||||
text={<AnimatedNumber amount={apy} suffix='%' abbreviated={false} />}
|
||||
tooltip={<Apy apyData={apyData} leverage={currentLeverage} />}
|
||||
/>
|
||||
</div>
|
||||
<div className={styles.price}>
|
||||
<span className='faded'>{formatValue(1, 0, 0, false, false, ' OSMO ≈ ')}</span>
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
.td {
|
||||
.wrapper {
|
||||
@include padding(6, 0, 0);
|
||||
@include padding(3, 0, 0);
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
import { Row } from '@tanstack/react-table'
|
||||
import Tippy from '@tippyjs/react/headless'
|
||||
import classNames from 'classnames/bind'
|
||||
import { Button, SVG } from 'components/common'
|
||||
import { Button, SVG, TextTooltip } from 'components/common'
|
||||
import { getSwapUrl } from 'functions'
|
||||
import { balanceSum } from 'libs/assetInfo'
|
||||
import Link from 'next/link'
|
||||
import { useRouter } from 'next/router'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import useStore from 'store'
|
||||
|
||||
@@ -17,9 +16,11 @@ interface Props {
|
||||
|
||||
export const ActionsRow = ({ row, type }: Props) => {
|
||||
const { t } = useTranslation()
|
||||
const router = useRouter()
|
||||
const chainInfo = useStore((s) => s.chainInfo)
|
||||
const redBankAssets = useStore((s) => s.redBankAssets)
|
||||
const hasBalance = Number(row.original.walletBalance ?? 0) > 0
|
||||
|
||||
const hasDeposits = Number(row.original.depositBalance ?? 0) > 0
|
||||
const hasNeverDeposited = Number(balanceSum(redBankAssets, 'depositBalanceBaseCurrency')) === 0
|
||||
const appUrl = useStore((s) => s.networkConfig?.appUrl) || ''
|
||||
@@ -32,7 +33,7 @@ export const ActionsRow = ({ row, type }: Props) => {
|
||||
|
||||
return (
|
||||
<tr key={row.id} className={trClasses} onClick={() => row.toggleExpanded()}>
|
||||
<td key={row.id} className={styles.td} colSpan={10}>
|
||||
<td key={row.id} className={styles.td} colSpan={7}>
|
||||
<div className={styles.wrapper}>
|
||||
{type === 'deposit' && (
|
||||
<>
|
||||
@@ -50,41 +51,35 @@ export const ActionsRow = ({ row, type }: Props) => {
|
||||
size='small'
|
||||
text={t('common.buy')}
|
||||
/>
|
||||
<Tippy
|
||||
appendTo={() => document.body}
|
||||
interactive={false}
|
||||
render={(attrs) => {
|
||||
return hasBalance ? null : (
|
||||
<div className='tippyContainer' {...attrs}>
|
||||
{t('redbank.toDepositAssetOnChain', {
|
||||
asset: assetSymbol,
|
||||
chain: chainInfo?.name,
|
||||
})}
|
||||
</div>
|
||||
)
|
||||
}}
|
||||
>
|
||||
<div>
|
||||
<Link href={`/redbank/deposit/${assetSymbol}`} passHref>
|
||||
<Button
|
||||
color='tertiary'
|
||||
disabled={!hasBalance}
|
||||
prefix={<SVG.Deposit />}
|
||||
size='small'
|
||||
text={t('redbank.deposit')}
|
||||
/>
|
||||
</Link>
|
||||
</div>
|
||||
</Tippy>
|
||||
{hasDeposits && (
|
||||
<Link href={`/redbank/withdraw/${assetSymbol}`} passHref>
|
||||
<TextTooltip
|
||||
hideUnderline
|
||||
text={
|
||||
<Button
|
||||
color='tertiary'
|
||||
prefix={<SVG.Withdraw />}
|
||||
disabled={!hasBalance}
|
||||
prefix={<SVG.Deposit />}
|
||||
size='small'
|
||||
text={t('redbank.withdraw')}
|
||||
text={t('redbank.deposit')}
|
||||
onClick={() => router.push(`/redbank/deposit/${assetSymbol}`)}
|
||||
/>
|
||||
</Link>
|
||||
}
|
||||
tooltip={
|
||||
hasBalance
|
||||
? null
|
||||
: t('redbank.toDepositAssetOnChain', {
|
||||
asset: assetSymbol,
|
||||
chain: chainInfo?.name,
|
||||
})
|
||||
}
|
||||
/>
|
||||
{hasDeposits && (
|
||||
<Button
|
||||
color='tertiary'
|
||||
prefix={<SVG.Withdraw />}
|
||||
size='small'
|
||||
text={t('redbank.withdraw')}
|
||||
onClick={() => router.push(`/redbank/withdraw/${assetSymbol}`)}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
@@ -108,60 +103,48 @@ export const ActionsRow = ({ row, type }: Props) => {
|
||||
text={t('common.buy')}
|
||||
/>
|
||||
)}
|
||||
<Tippy
|
||||
appendTo={() => document.body}
|
||||
interactive={false}
|
||||
render={(attrs) => {
|
||||
return !hasBalance || hasNeverDeposited ? (
|
||||
<div className='tippyContainer' {...attrs}>
|
||||
{hasBalance
|
||||
? t('redbank.warning.borrow')
|
||||
: t('redbank.noFundsForRepay', {
|
||||
symbol: assetSymbol,
|
||||
})}
|
||||
</div>
|
||||
) : null
|
||||
}}
|
||||
>
|
||||
<div>
|
||||
<Link href={`/redbank/repay/${assetSymbol}`} passHref>
|
||||
<Button
|
||||
disabled={!hasBalance}
|
||||
color='tertiary'
|
||||
prefix={<SVG.Deposit />}
|
||||
size='small'
|
||||
text={t('common.repay')}
|
||||
/>
|
||||
</Link>
|
||||
</div>
|
||||
</Tippy>
|
||||
<TextTooltip
|
||||
hideUnderline
|
||||
text={
|
||||
<Button
|
||||
disabled={!hasBalance}
|
||||
color='tertiary'
|
||||
prefix={<SVG.Deposit />}
|
||||
size='small'
|
||||
text={t('common.repay')}
|
||||
onClick={() => router.push(`/redbank/repay/${assetSymbol}`)}
|
||||
/>
|
||||
}
|
||||
tooltip={
|
||||
!hasBalance
|
||||
? t('redbank.noFundsForRepay', {
|
||||
symbol: assetSymbol,
|
||||
})
|
||||
: null
|
||||
}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
<Tippy
|
||||
appendTo={() => document.body}
|
||||
interactive={false}
|
||||
render={(attrs) => {
|
||||
return row.original.marketLiquidity === '0' || hasNeverDeposited ? (
|
||||
<div className='tippyContainer' {...attrs}>
|
||||
{hasNeverDeposited
|
||||
? t('redbank.warning.borrow')
|
||||
: t('redbank.notEnoughMarketLiquidity')}
|
||||
</div>
|
||||
) : null
|
||||
}}
|
||||
>
|
||||
<div>
|
||||
<Link href={`/redbank/borrow/${assetSymbol}`} passHref>
|
||||
<Button
|
||||
color='tertiary'
|
||||
prefix={<SVG.Withdraw />}
|
||||
disabled={row.original.marketLiquidity === '0' || hasNeverDeposited}
|
||||
size='small'
|
||||
text={t('common.borrow')}
|
||||
/>
|
||||
</Link>
|
||||
</div>
|
||||
</Tippy>
|
||||
<TextTooltip
|
||||
hideUnderline
|
||||
text={
|
||||
<Button
|
||||
color='tertiary'
|
||||
prefix={<SVG.Withdraw />}
|
||||
disabled={row.original.marketLiquidity === '0' || hasNeverDeposited}
|
||||
size='small'
|
||||
text={t('common.borrow')}
|
||||
onClick={() => router.push(`/redbank/borrow/${assetSymbol}`)}
|
||||
/>
|
||||
}
|
||||
tooltip={
|
||||
row.original.marketLiquidity === '0' || hasNeverDeposited
|
||||
? hasNeverDeposited
|
||||
? t('redbank.warning.borrow')
|
||||
: t('redbank.notEnoughMarketLiquidity')
|
||||
: null
|
||||
}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -30,14 +30,6 @@
|
||||
@include bgTableHover;
|
||||
}
|
||||
}
|
||||
|
||||
> .td {
|
||||
border-bottom: 1px solid $alphaWhite20;
|
||||
&:nth-child(1),
|
||||
&:nth-child(2) {
|
||||
border-bottom: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.td {
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
@include padding(4, 0);
|
||||
font-weight: $fontWeightRegular;
|
||||
opacity: 0.6;
|
||||
white-space: nowrap;
|
||||
|
||||
&:not(.disabled) {
|
||||
&.canSort {
|
||||
@@ -24,7 +25,11 @@
|
||||
.wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
justify-content: flex-end;
|
||||
|
||||
&.left {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
svg {
|
||||
display: none;
|
||||
@@ -52,14 +57,13 @@
|
||||
}
|
||||
|
||||
.wrapper {
|
||||
justify-content: flex-end;
|
||||
|
||||
svg {
|
||||
display: block;
|
||||
}
|
||||
|
||||
&.left {
|
||||
flex-direction: row-reverse;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ export const MetricsRow = ({ row, type }: Props) => {
|
||||
|
||||
return (
|
||||
<tr key={row.id} className={trClasses} onClick={() => row.toggleExpanded()}>
|
||||
<td key={row.id} className={styles.td} colSpan={10}>
|
||||
<td key={row.id} className={styles.td} colSpan={7}>
|
||||
<div className={styles.wrapper}>
|
||||
<div className={styles.body}>
|
||||
<ValueWithLabel
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { ColumnDef, createColumnHelper } from '@tanstack/react-table'
|
||||
import { AnimatedNumber, Button, CellAmount, SVG } from 'components/common'
|
||||
import { AnimatedNumber, Button, CellAmount, SVG, TextTooltip } from 'components/common'
|
||||
import Image from 'next/image'
|
||||
import { useMemo } from 'react'
|
||||
import { isMobile, isTablet } from 'react-device-detect'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
import styles from './useBorrowColumns.module.scss'
|
||||
@@ -9,6 +10,8 @@ import styles from './useBorrowColumns.module.scss'
|
||||
export const useBorrowColumns = () => {
|
||||
const { t } = useTranslation()
|
||||
const columnHelper = createColumnHelper<RedBankAsset>()
|
||||
const enableSorting = !isMobile && !isTablet
|
||||
|
||||
const defaultBorrowColumns: ColumnDef<RedBankAsset, any>[] = useMemo(
|
||||
() => [
|
||||
columnHelper.accessor('color', {
|
||||
@@ -32,7 +35,10 @@ export const useBorrowColumns = () => {
|
||||
),
|
||||
}),
|
||||
columnHelper.accessor('name', {
|
||||
header: t('common.asset'),
|
||||
enableSorting: enableSorting,
|
||||
header: () => (
|
||||
<TextTooltip text={t('common.asset')} tooltip={t('redbank.tooltips.borrow.assets')} />
|
||||
),
|
||||
id: 'name',
|
||||
cell: (info) => (
|
||||
<>
|
||||
@@ -42,7 +48,13 @@ export const useBorrowColumns = () => {
|
||||
),
|
||||
}),
|
||||
columnHelper.accessor('borrowBalance', {
|
||||
header: t('common.borrowed'),
|
||||
enableSorting: enableSorting,
|
||||
header: () => (
|
||||
<TextTooltip
|
||||
text={t('common.borrowed')}
|
||||
tooltip={t('redbank.tooltips.borrow.borrowed')}
|
||||
/>
|
||||
),
|
||||
cell: (info) => (
|
||||
<CellAmount
|
||||
amount={Number(info.row.original.borrowBalance)}
|
||||
@@ -53,7 +65,11 @@ export const useBorrowColumns = () => {
|
||||
),
|
||||
}),
|
||||
columnHelper.accessor('borrowRate', {
|
||||
header: t('common.rate'),
|
||||
enableSorting: enableSorting,
|
||||
|
||||
header: () => (
|
||||
<TextTooltip text={t('common.rate')} tooltip={t('redbank.tooltips.borrow.rate')} />
|
||||
),
|
||||
cell: (info) => {
|
||||
return (
|
||||
<AnimatedNumber
|
||||
@@ -67,7 +83,13 @@ export const useBorrowColumns = () => {
|
||||
},
|
||||
}),
|
||||
columnHelper.accessor('marketLiquidity', {
|
||||
header: t('common.marketLiquidityShort'),
|
||||
enableSorting: enableSorting,
|
||||
header: () => (
|
||||
<TextTooltip
|
||||
text={t('common.marketLiquidityShort')}
|
||||
tooltip={t('redbank.tooltips.borrow.marketLiquidity')}
|
||||
/>
|
||||
),
|
||||
cell: (info) => (
|
||||
<CellAmount
|
||||
amount={Number(info.row.original.marketLiquidity)}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { ColumnDef, createColumnHelper } from '@tanstack/react-table'
|
||||
import Tippy from '@tippyjs/react'
|
||||
import classNames from 'classnames'
|
||||
import { AnimatedNumber, Apr, Button, CellAmount, SVG } from 'components/common'
|
||||
import { AnimatedNumber, Apr, Button, CellAmount, SVG, TextTooltip } from 'components/common'
|
||||
import { convertPercentage } from 'functions'
|
||||
import { formatValue } from 'libs/parse'
|
||||
import Image from 'next/image'
|
||||
import { useMemo } from 'react'
|
||||
import { isMobile, isTablet } from 'react-device-detect'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
import styles from './useDepositColumns.module.scss'
|
||||
@@ -14,6 +14,8 @@ export const useDepositColumns = () => {
|
||||
const { t } = useTranslation()
|
||||
const columnHelper = createColumnHelper<RedBankAsset>()
|
||||
|
||||
const enableSorting = !isMobile && !isTablet
|
||||
|
||||
const defaultDepositColumns: ColumnDef<RedBankAsset, any>[] = useMemo(() => {
|
||||
return [
|
||||
columnHelper.accessor('color', {
|
||||
@@ -37,7 +39,10 @@ export const useDepositColumns = () => {
|
||||
),
|
||||
}),
|
||||
columnHelper.accessor('name', {
|
||||
header: t('common.asset'),
|
||||
enableSorting: enableSorting,
|
||||
header: () => (
|
||||
<TextTooltip text={t('common.asset')} tooltip={t('redbank.tooltips.deposit.assets')} />
|
||||
),
|
||||
id: 'name',
|
||||
cell: (info) => (
|
||||
<>
|
||||
@@ -47,7 +52,13 @@ export const useDepositColumns = () => {
|
||||
),
|
||||
}),
|
||||
columnHelper.accessor('depositBalance', {
|
||||
header: t('common.deposited'),
|
||||
enableSorting: enableSorting,
|
||||
header: () => (
|
||||
<TextTooltip
|
||||
text={t('common.deposited')}
|
||||
tooltip={t('redbank.tooltips.deposit.deposited')}
|
||||
/>
|
||||
),
|
||||
cell: (info) => {
|
||||
return (
|
||||
<CellAmount
|
||||
@@ -60,10 +71,14 @@ export const useDepositColumns = () => {
|
||||
},
|
||||
}),
|
||||
columnHelper.accessor('apy', {
|
||||
header: t('common.apy'),
|
||||
enableSorting: enableSorting,
|
||||
header: () => (
|
||||
<TextTooltip text={t('common.apy')} tooltip={t('redbank.tooltips.deposit.apy')} />
|
||||
),
|
||||
cell: (info) => (
|
||||
<Tippy content={<Apr data={info.row.original} />}>
|
||||
<div>
|
||||
<TextTooltip
|
||||
hideStyling
|
||||
text={
|
||||
<AnimatedNumber
|
||||
amount={info.getValue() + Number(info.row.original.incentiveInfo?.apy || 0)}
|
||||
suffix='%'
|
||||
@@ -71,13 +86,19 @@ export const useDepositColumns = () => {
|
||||
rounded={false}
|
||||
className='m'
|
||||
/>
|
||||
</div>
|
||||
</Tippy>
|
||||
}
|
||||
tooltip={<Apr data={info.row.original} />}
|
||||
/>
|
||||
),
|
||||
}),
|
||||
columnHelper.accessor('depositCap', {
|
||||
enableSorting: true,
|
||||
header: t('redbank.depositCap'),
|
||||
enableSorting: enableSorting,
|
||||
header: () => (
|
||||
<TextTooltip
|
||||
text={t('redbank.depositCap')}
|
||||
tooltip={t('redbank.tooltips.deposit.caps')}
|
||||
/>
|
||||
),
|
||||
cell: ({ row }) => {
|
||||
const depositLiquidity = Number(row.original.depositLiquidity)
|
||||
const percent = convertPercentage((depositLiquidity / row.original.depositCap) * 100)
|
||||
|
||||
@@ -84,6 +84,9 @@
|
||||
td {
|
||||
display: table-cell;
|
||||
}
|
||||
td {
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import { Coin } from '@cosmjs/stargate'
|
||||
import { Card, ConnectButton, SVG, Title } from 'components/common'
|
||||
import { AssetTable, useBorrowColumns, useDepositColumns } from 'components/redbank'
|
||||
import { findByDenom } from 'functions'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { Trans, useTranslation } from 'react-i18next'
|
||||
import useStore from 'store'
|
||||
@@ -21,10 +19,7 @@ export const RedbankNotConnected = () => {
|
||||
// STORE STATE
|
||||
// ------------------
|
||||
const whitelistedAssets = useStore((s) => s.whitelistedAssets)
|
||||
const marketAssetLiquidity = useStore((s) => s.marketAssetLiquidity)
|
||||
const marketInfo = useStore((s) => s.marketInfo)
|
||||
const convertToBaseCurrency = useStore((s) => s.convertToBaseCurrency)
|
||||
|
||||
// ------------------
|
||||
// LOCAL STATE
|
||||
// ------------------
|
||||
@@ -34,29 +29,24 @@ export const RedbankNotConnected = () => {
|
||||
const dummyData: RedBankAsset[] = []
|
||||
if (!whitelistedAssets?.length) return
|
||||
whitelistedAssets.forEach((asset) => {
|
||||
const reserveInfo = findByDenom(marketInfo, asset.denom)
|
||||
const depositApy = reserveInfo?.liquidity_rate || 0
|
||||
const borrowApy = reserveInfo?.borrow_rate || 0
|
||||
const liquidity = findByDenom(marketAssetLiquidity, asset.denom) as Coin
|
||||
|
||||
dummyData.push({
|
||||
...asset,
|
||||
apy: depositApy * 100,
|
||||
borrowRate: borrowApy * 100,
|
||||
marketLiquidity: liquidity?.amount.toString() || '0',
|
||||
apy: 0,
|
||||
borrowRate: 0,
|
||||
marketLiquidity: '0',
|
||||
walletBalance: '0',
|
||||
borrowBalance: '0',
|
||||
depositBalance: '0',
|
||||
isCollateral: true,
|
||||
borrowBalanceBaseCurrency: 0,
|
||||
depositBalanceBaseCurrency: 0,
|
||||
depositCap: 100000000,
|
||||
depositLiquidity: 1000000,
|
||||
depositCap: 0,
|
||||
depositLiquidity: 0,
|
||||
})
|
||||
})
|
||||
|
||||
setDummyData(dummyData)
|
||||
}, [marketAssetLiquidity, marketInfo, convertToBaseCurrency, whitelistedAssets])
|
||||
}, [convertToBaseCurrency, whitelistedAssets])
|
||||
|
||||
return (
|
||||
<div className={styles.notConnected}>
|
||||
@@ -86,14 +76,14 @@ export const RedbankNotConnected = () => {
|
||||
<div className={styles.grids}>
|
||||
<Card
|
||||
title={t('redbank.depositMarkets')}
|
||||
tooltip={t('redbank.redBankMarketsDepositedNotConnectedTooltip')}
|
||||
tooltip={t('redbank.tooltips.deposit.market.unconnected')}
|
||||
>
|
||||
<AssetTable columns={defaultDepositColumns} data={dummyData} disabled type='deposit' />
|
||||
</Card>
|
||||
|
||||
<Card
|
||||
title={t('redbank.borrowMarkets')}
|
||||
tooltip={t('redbank.redbankMarketsBorrowedNotConnectedTooltip')}
|
||||
tooltip={t('redbank.tooltips.borrow.market.unconnected')}
|
||||
>
|
||||
<AssetTable columns={defaultBorrowColumns} data={dummyData} disabled type='borrow' />
|
||||
</Card>
|
||||
|
||||
@@ -63,9 +63,9 @@ const OTHER_ASSETS: { [denom: string]: OtherAsset } = {
|
||||
|
||||
export const NETWORK_CONFIG: NetworkConfig = {
|
||||
name: ChainInfoID.OsmosisTestnet,
|
||||
hiveUrl: 'https://osmosis-delphi-testnet-1.simply-vc.com.mt/XF32UOOU55CX/osmosis-hive/graphql/',
|
||||
rpcUrl: 'https://osmosis-delphi-testnet-1.simply-vc.com.mt/XF32UOOU55CX/osmosis-rpc/',
|
||||
restUrl: 'https://osmosis-delphi-testnet-1.simply-vc.com.mt/XF32UOOU55CX/osmosis-lcd/',
|
||||
hiveUrl: 'https://testnet-osmosis-node.marsprotocol.io/XF32UOOU55CX/osmosis-hive-front/graphql',
|
||||
rpcUrl: 'https://rpc-test.osmosis.zone/',
|
||||
restUrl: 'https://lcd-test.osmosis.zone/',
|
||||
apolloAprUrl: 'https://stats.apollo.farm/api/apr/v1/all',
|
||||
contracts: {
|
||||
addressProvider: 'osmo17dyy6hyzzy6u5khy5lau7afa2y9kwknu0aprwqn8twndw2qhv8ls6msnjr',
|
||||
@@ -84,6 +84,12 @@ export const NETWORK_CONFIG: NetworkConfig = {
|
||||
whitelist: [ASSETS.osmo, ASSETS.atom, ASSETS.juno],
|
||||
other: [OTHER_ASSETS.mars, OTHER_ASSETS.axlusdc],
|
||||
},
|
||||
displayCurrency: {
|
||||
denom: 'ibc/88D70440A05BFB25C7FF0BA62DA357EAA993CB1B036077CF1DAAEFB28721D935',
|
||||
prefix: '$',
|
||||
suffix: '',
|
||||
decimals: 2,
|
||||
},
|
||||
appUrl: 'https://testnet.osmosis.zone',
|
||||
councilUrl: 'https://testnet.keplr.app/chains/mars-hub-testnet',
|
||||
wallets: [WalletID.Keplr, WalletID.Leap, WalletID.Cosmostation],
|
||||
|
||||
+31
-63
@@ -25,13 +25,14 @@ export const ASSETS: { [denom: string]: Asset } = {
|
||||
hasOraclePrice: true,
|
||||
},
|
||||
axlusdc: {
|
||||
symbol: 'JUNO',
|
||||
name: 'Juno',
|
||||
denom: 'ibc/46B44899322F3CD854D2D46DEEF881958467CDD4B3B10086DA49296BBED94BED',
|
||||
color: colors.juno,
|
||||
symbol: 'axlUSDC',
|
||||
name: 'Axelar USDC',
|
||||
denom: 'ibc/D189335C6E4A68B513C10AB227BF1C1D38C746766278BA3EEB4FB14124F1D858',
|
||||
color: colors.axlUSDC,
|
||||
logo: axlusdc,
|
||||
decimals: 6,
|
||||
hasOraclePrice: true,
|
||||
poolId: 678,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -39,27 +40,27 @@ const OTHER_ASSETS: { [denom: string]: OtherAsset } = {
|
||||
mars: {
|
||||
symbol: 'MARS',
|
||||
name: 'Mars',
|
||||
denom: 'ibc/ACA4C8A815A053CC027DB90D15915ADA31939FA331CE745862CDD00A2904FA17',
|
||||
denom: 'ibc/573FCD90FACEE750F55A8864EF7D38265F07E5A9273FA0E8DAFD39951332B580',
|
||||
color: colors.mars,
|
||||
logo: mars,
|
||||
decimals: 6,
|
||||
hasOraclePrice: true,
|
||||
poolId: 768,
|
||||
poolId: 907,
|
||||
},
|
||||
}
|
||||
|
||||
export const NETWORK_CONFIG: NetworkConfig = {
|
||||
name: ChainInfoID.OsmosisTestnet,
|
||||
hiveUrl: 'https://osmosis-delphi-testnet-1.simply-vc.com.mt/XF32UOOU55CX/osmosis-hive/graphql/',
|
||||
rpcUrl: 'https://osmosis-delphi-testnet-1.simply-vc.com.mt/XF32UOOU55CX/osmosis-rpc/',
|
||||
restUrl: 'https://osmosis-delphi-testnet-1.simply-vc.com.mt/XF32UOOU55CX/osmosis-lcd/',
|
||||
name: ChainInfoID.Osmosis1,
|
||||
hiveUrl: 'https://osmosis-node.marsprotocol.io/GGSFGSFGFG34/osmosis-hive-front/graphql',
|
||||
rpcUrl: 'https://rpc-osmosis.blockapsis.com/',
|
||||
restUrl: 'https://lcd-osmosis.blockapsis.com/',
|
||||
apolloAprUrl: 'https://stats.apollo.farm/api/apr/v1/all',
|
||||
contracts: {
|
||||
addressProvider: 'osmo17dyy6hyzzy6u5khy5lau7afa2y9kwknu0aprwqn8twndw2qhv8ls6msnjr',
|
||||
redBank: 'osmo1t0dl6r27phqetfu0geaxrng0u9zn8qgrdwztapt5xr32adtwptaq6vwg36',
|
||||
incentives: 'osmo1zxs8fry3m8j94pqg7h4muunyx86en27cl0xgk76fc839xg2qnn6qtpjs48',
|
||||
oracle: 'osmo1dqz2u3c8rs5e7w5fnchsr2mpzzsxew69wtdy0aq4jsd76w7upmsstqe0s8',
|
||||
rewardsCollector: 'osmo14kzsqw5tatdvwlkj383lgkh6gcdetwn7kfqm7488uargyy2lpucqsyv53j',
|
||||
addressProvider: 'osmo1g677w7mfvn78eeudzwylxzlyz69fsgumqrscj6tekhdvs8fye3asufmvxr',
|
||||
redBank: 'osmo1c3ljch9dfw5kf52nfwpxd2zmj2ese7agnx0p9tenkrryasrle5sqf3ftpg',
|
||||
incentives: 'osmo1nkahswfr8shg8rlxqwup0vgahp0dk4x8w6tkv3rra8rratnut36sk22vrm',
|
||||
oracle: 'osmo1mhznfr60vjdp2gejhyv2gax9nvyyzhd3z0qcwseyetkfustjauzqycsy2g',
|
||||
rewardsCollector: 'osmo1urvqe5mw00ws25yqdd4c4hlh8kdyf567mpcml7cdve9w08z0ydcqvsrgdy',
|
||||
treasury: 'osmo1qv74pu0gjc9vuvkhayuj5j3q8fzmf4pnl643djqpv7enxr925g5q0wf7p3',
|
||||
safetyFund: 'osmo1j2mnzs7eqld4umtwky4hyf6f7kqcsg7ragh2l76ev7ucxcjvdjrs3tdezf',
|
||||
protocolRewardsCollector: 'osmo1xl7jguvkg807ya00s0l722nwcappfzyzrac3ug5tnjassnrmnfrs47wguz',
|
||||
@@ -71,54 +72,21 @@ export const NETWORK_CONFIG: NetworkConfig = {
|
||||
whitelist: [ASSETS.osmo, ASSETS.atom, ASSETS.axlusdc],
|
||||
other: [OTHER_ASSETS.mars],
|
||||
},
|
||||
appUrl: 'https://testnet.osmosis.zone',
|
||||
displayCurrency: {
|
||||
denom: 'ibc/D189335C6E4A68B513C10AB227BF1C1D38C746766278BA3EEB4FB14124F1D858',
|
||||
prefix: '$',
|
||||
suffix: '',
|
||||
decimals: 2,
|
||||
},
|
||||
appUrl: 'https://app.osmosis.zone',
|
||||
councilUrl: 'https://council.marsprotocol.io',
|
||||
wallets: [WalletID.Keplr, WalletID.Leap, WalletID.Cosmostation, WalletID.Falcon],
|
||||
wallets: [
|
||||
WalletID.Keplr,
|
||||
WalletID.Leap,
|
||||
WalletID.Cosmostation,
|
||||
WalletID.Falcon,
|
||||
WalletID.KeplrMobile,
|
||||
],
|
||||
}
|
||||
|
||||
export const VAULT_CONFIGS: Vault[] = [
|
||||
{
|
||||
address: '',
|
||||
name: 'OSMO-ATOM LP (14 day)',
|
||||
denoms: {
|
||||
primary: 'uosmo',
|
||||
secondary: 'ibc/27394FB092D2ECCD56123C74F36E4C1F926001CEADA9CA97EA622B25F41E5EB2',
|
||||
lpToken: 'gamm/pool/1',
|
||||
},
|
||||
symbols: {
|
||||
primary: 'OSMO',
|
||||
secondary: 'ATOM',
|
||||
},
|
||||
color: '#DD5B65',
|
||||
lockup: 86400 * 14,
|
||||
provider: 'Apollo vault',
|
||||
description: 'Up to 2× Leveraged Yield Farming with auto compounding of the LP tokens.',
|
||||
ltv: {
|
||||
max: 0.625,
|
||||
contract: 0.63,
|
||||
liq: 0.65,
|
||||
},
|
||||
},
|
||||
{
|
||||
address: '',
|
||||
name: 'OSMO-axlUSDC LP (14 day)',
|
||||
denoms: {
|
||||
primary: 'uosmo',
|
||||
secondary: 'ibc/27394FB092D2ECCD56123C74F36E4C1F926001CEADA9CA97EA622B25F41E5EB2',
|
||||
lpToken: 'gamm/pool/1',
|
||||
},
|
||||
symbols: {
|
||||
primary: 'OSMO',
|
||||
secondary: 'ATOM',
|
||||
},
|
||||
color: '#DD5B65',
|
||||
lockup: 86400 * 14,
|
||||
provider: 'Apollo vault',
|
||||
description: 'Up to 2× Leveraged Yield Farming with auto compounding of the LP tokens.',
|
||||
ltv: {
|
||||
max: 0.666,
|
||||
contract: 0.67,
|
||||
liq: 0.69,
|
||||
},
|
||||
},
|
||||
]
|
||||
export const VAULT_CONFIGS: Vault[] = []
|
||||
|
||||
@@ -18,7 +18,7 @@ export const GAS_ADJUSTMENT = 1.3
|
||||
export const GAS_PRICE = '0.025uosmo'
|
||||
|
||||
/* feature flags */
|
||||
export const FIELDS_FEATURE = true
|
||||
export const FIELDS_FEATURE = false
|
||||
export const PROPOSAL_ACTION_BUTTONS_FEATURE = false
|
||||
|
||||
/* fields query keys */
|
||||
|
||||
@@ -7,9 +7,11 @@ type Options = {
|
||||
export const getSwapUrl = (options: Options) => {
|
||||
const { from, to, baseUrl } = options
|
||||
let fromName = from
|
||||
let toName = to
|
||||
|
||||
if (!fromName) fromName = 'ATOM'
|
||||
if (fromName === to) fromName = 'OSMO'
|
||||
if (to === 'axlUSDC') toName = 'USDC'
|
||||
|
||||
return `${baseUrl}?from=${fromName}&to=${to}`
|
||||
return `${baseUrl}?from=${fromName}&to=${toName}`
|
||||
}
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
export const getBankQuery = (address: string) => {
|
||||
return `
|
||||
balance: bank {
|
||||
balance(address: "${address}") {
|
||||
amount
|
||||
denom
|
||||
}
|
||||
}
|
||||
`
|
||||
}
|
||||
+24
-6
@@ -1,6 +1,6 @@
|
||||
import { getContractQuery } from './getContractQuery'
|
||||
|
||||
export const getMarketDepositsQuery = (
|
||||
export const getDepositDebtQuery = (
|
||||
redBankAddress: string,
|
||||
whitelistedAssets: Asset[],
|
||||
marketInfo: Market[],
|
||||
@@ -15,24 +15,42 @@ export const getMarketDepositsQuery = (
|
||||
const totalCollateralScaled =
|
||||
marketInfo.find((market) => market.denom === asset.denom)?.collateral_total_scaled || '0'
|
||||
|
||||
const marketKey = `${symbol}Deposits`
|
||||
const depositMarketKey = `${symbol}Deposits`
|
||||
query =
|
||||
query +
|
||||
getContractQuery(
|
||||
marketKey,
|
||||
depositMarketKey,
|
||||
redBankAddress || '',
|
||||
`
|
||||
{
|
||||
underlying_liquidity_amount: {
|
||||
underlying_liquidity_amount: {
|
||||
denom: "${denom}"
|
||||
amount_scaled: "${totalCollateralScaled}"
|
||||
}
|
||||
}`,
|
||||
)
|
||||
|
||||
const totalDebtScaled =
|
||||
marketInfo.find((market) => market.denom === asset.denom)?.debt_total_scaled || '0'
|
||||
const debtMarketKey = `${symbol}Debt`
|
||||
query =
|
||||
query +
|
||||
getContractQuery(
|
||||
debtMarketKey,
|
||||
redBankAddress || '',
|
||||
`
|
||||
{
|
||||
underlying_debt_amount: {
|
||||
denom: "${denom}"
|
||||
amount_scaled: "${totalCollateralScaled}"
|
||||
amount_scaled: "${totalDebtScaled}"
|
||||
}
|
||||
}`,
|
||||
)
|
||||
|
||||
return query
|
||||
})
|
||||
|
||||
return `query MarketDepositsQuery {
|
||||
return `query DepositDebtQuery {
|
||||
mdwasmkey: wasm {
|
||||
${wasmQueries}
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
import {
|
||||
getBalanceQuery,
|
||||
getBankQuery,
|
||||
getContractQuery,
|
||||
getIncentiveQuery,
|
||||
getMarketQuery,
|
||||
@@ -46,7 +45,6 @@ export const getRedbankQuery = (
|
||||
})
|
||||
|
||||
return `query RedbankQuery {
|
||||
${getBankQuery(redBankContractAddress)}
|
||||
${REDBANK_WASM_KEY}: wasm {
|
||||
${wasmQueries}
|
||||
${
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
// @index(['./*.ts'], f => `export { ${f.name} } from '${f.path}'`)
|
||||
export { getBalanceQuery } from './getBalanceQuery'
|
||||
export { getBankQuery } from './getBankQuery'
|
||||
export { getConfigQuery } from './getConfigQuery'
|
||||
export { getContractQuery } from './getContractQuery'
|
||||
export { getDebtQuery } from './getDebtQuery'
|
||||
export { getDepositDebtQuery } from './getDepositDebtQuery'
|
||||
export { getDepositsQuery } from './getDepositsQuery'
|
||||
export { getGlobalStateQuery } from './getGlobalStateQuery'
|
||||
export { getIncentiveQuery } from './getIncentiveQuery'
|
||||
export { getInfoQuery } from './getInfoQuery'
|
||||
export { getMarketDepositsQuery } from './getMarketDepositsQuery'
|
||||
export { getMarketQuery } from './getMarketQuery'
|
||||
export { getRedbankQuery } from './getRedbankQuery'
|
||||
export { getSnapshotQuery } from './getSnapshotQuery'
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// @index(['./*.tsx'], f => `export { ${f.name} } from '${f.path}'`)
|
||||
export { useBlockHeight } from './useBlockHeight'
|
||||
export { useClosePosition } from './useClosePosition'
|
||||
export { useDepositAndDebt } from './useDepositAndDebt'
|
||||
export { useEditPosition } from './useEditPosition'
|
||||
export { useEstimateFarmFee } from './useEstimateFarmFee'
|
||||
export { useEstimateFee } from './useEstimateFee'
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
import { useQuery } from '@tanstack/react-query'
|
||||
import { getDepositDebtQuery } from 'functions/queries'
|
||||
import { gql, request } from 'graphql-request'
|
||||
import { useEffect } from 'react'
|
||||
import useStore from 'store'
|
||||
import { QUERY_KEYS } from 'types/enums/queryKeys'
|
||||
|
||||
export interface DepositAndDebtData {
|
||||
mdwasmkey: {
|
||||
OSMODeposits: string
|
||||
OSMODebt: string
|
||||
ATOMDeposits: string
|
||||
ATOMDebt: string
|
||||
JUNODeposits: string
|
||||
JUNODebt: string
|
||||
axlUSDCDeposits: string
|
||||
axlUSDCDebt: string
|
||||
}
|
||||
}
|
||||
|
||||
export const useDepositAndDebt = () => {
|
||||
const hiveUrl = useStore((s) => s.networkConfig?.hiveUrl)
|
||||
const whitelistedAssets = useStore((s) => s.whitelistedAssets)
|
||||
const redBankAddress = useStore((s) => s.networkConfig?.contracts.redBank) || ''
|
||||
const marketInfo = useStore((s) => s.marketInfo)
|
||||
const processDepositAndDebtQuery = useStore((s) => s.processDepositAndDebtQuery)
|
||||
|
||||
const { refetch } = useQuery<DepositAndDebtData>(
|
||||
[QUERY_KEYS.MARKET_DEPOSITS],
|
||||
async () => {
|
||||
return await request(
|
||||
hiveUrl!,
|
||||
gql`
|
||||
${getDepositDebtQuery(redBankAddress, whitelistedAssets, marketInfo)}
|
||||
`,
|
||||
)
|
||||
},
|
||||
{
|
||||
enabled: !!hiveUrl && !!whitelistedAssets.length && !!redBankAddress && !!marketInfo.length,
|
||||
refetchInterval: 120000,
|
||||
onSuccess: processDepositAndDebtQuery,
|
||||
},
|
||||
)
|
||||
|
||||
// ! Workaround:
|
||||
// Invalidating this query in RB action somehow resolves to Zustand with outdated marketInfo data
|
||||
// It does not retrigger, and therefore a useEffect is placed here to manually rerun when the
|
||||
// marketInfo actually updates.
|
||||
useEffect(() => {
|
||||
if (!marketInfo.length) return
|
||||
refetch()
|
||||
}, [marketInfo, refetch])
|
||||
}
|
||||
@@ -10,6 +10,7 @@ export interface MarketDepositsData {
|
||||
OSMODeposits: string
|
||||
ATOMDeposits: string
|
||||
JUNODeposits: string
|
||||
axlUSDCDeposits: string
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,12 +8,14 @@ import { QUERY_KEYS } from 'types/enums/queryKeys'
|
||||
const poolsEndpoint = 'osmosis/gamm/v1beta1/pools/'
|
||||
|
||||
export const useSpotPrice = (symbol: string) => {
|
||||
const displayCurrency = useStore((s) => s.displayCurrency)
|
||||
const networkConfig = useStore((s) => s.networkConfig)
|
||||
const lcd = useStore((s) => s.chainInfo?.rest)
|
||||
const exchangeRates = useStore((s) => s.exchangeRates)
|
||||
|
||||
const asset = useAsset({ symbol })
|
||||
|
||||
const displayCurrency = networkConfig?.displayCurrency
|
||||
|
||||
useQuery<PoolResponse>(
|
||||
[QUERY_KEYS.MARS_PRICE, asset?.poolId],
|
||||
async () => {
|
||||
@@ -27,7 +29,7 @@ export const useSpotPrice = (symbol: string) => {
|
||||
staleTime: 30000,
|
||||
refetchInterval: 30000,
|
||||
onSuccess: (data) => {
|
||||
if (!asset) return
|
||||
if (!asset || !displayCurrency) return
|
||||
const poolDataAssets = data.pool.pool_assets
|
||||
const assetFirst = poolDataAssets[0].token.denom === asset.denom
|
||||
const targetAsset = poolDataAssets[assetFirst ? 0 : 1]
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { useQuery } from '@tanstack/react-query'
|
||||
import { NETWORK_CONFIG } from 'configs/osmosis-1'
|
||||
import { gql, request } from 'graphql-request'
|
||||
import { useMemo } from 'react'
|
||||
import useStore from 'store'
|
||||
@@ -15,7 +16,7 @@ export interface UserIcnsData {
|
||||
|
||||
export const useUserIcns = () => {
|
||||
/* only possible to query on mainnet */
|
||||
const hiveUrl = 'https://osmosis-mars-frontend.simply-vc.com.mt/GGSFGSFGFG34/osmosis-hive/graphql'
|
||||
const hiveUrl = NETWORK_CONFIG.hiveUrl
|
||||
const resolverContract = 'osmo1xk0s8xgktn9x5vwcgtjdxqzadg88fgn33p8u9cnpdxwemvxscvast52cdd'
|
||||
|
||||
const userWalletAddress = useStore((s) => s.userWalletAddress)
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
import * as Sentry from '@sentry/nextjs'
|
||||
import NextErrorComponent from 'next/error'
|
||||
|
||||
const CustomErrorComponent = ({ statusCode, hasGetInitialPropsRun, err }) => {
|
||||
if (!hasGetInitialPropsRun && err) {
|
||||
// getInitialProps is not called in case of
|
||||
// https://github.com/vercel/next.js/issues/8592. As a workaround, we pass
|
||||
// err via _app.js so it can be captured
|
||||
Sentry.captureException(err)
|
||||
// Flushing is not required in this case as it only happens on the client
|
||||
}
|
||||
|
||||
return <NextErrorComponent statusCode={statusCode} />
|
||||
}
|
||||
|
||||
CustomErrorComponent.getInitialProps = async (context) => {
|
||||
const errorInitialProps = await NextErrorComponent.getInitialProps(context)
|
||||
|
||||
const { res, err, asPath } = context
|
||||
|
||||
// Workaround for https://github.com/vercel/next.js/issues/8592, mark when
|
||||
// getInitialProps has run
|
||||
errorInitialProps.hasGetInitialPropsRun = true
|
||||
|
||||
// Returning early because we don't want to log 404 errors to Sentry.
|
||||
if (res?.statusCode === 404) {
|
||||
return errorInitialProps
|
||||
}
|
||||
|
||||
// Running on the server, the response object (`res`) is available.
|
||||
//
|
||||
// Next.js will pass an err on the server if a page's data fetching methods
|
||||
// threw or returned a Promise that rejected
|
||||
//
|
||||
// Running on the client (browser), Next.js will provide an err if:
|
||||
//
|
||||
// - a page's `getInitialProps` threw or returned a Promise that rejected
|
||||
// - an exception was thrown somewhere in the React lifecycle (render,
|
||||
// componentDidMount, etc) that was caught by Next.js's React Error
|
||||
// Boundary. Read more about what types of exceptions are caught by Error
|
||||
// Boundaries: https://reactjs.org/docs/error-boundaries.html
|
||||
|
||||
if (err) {
|
||||
Sentry.captureException(err)
|
||||
|
||||
// Flushing before returning is necessary if deploying to Vercel, see
|
||||
// https://vercel.com/docs/platform/limits#streaming-responses
|
||||
await Sentry.flush(2000)
|
||||
|
||||
return errorInitialProps
|
||||
}
|
||||
|
||||
// If this point is reached, getInitialProps was called without any
|
||||
// information about what the error might be. This is unexpected and may
|
||||
// indicate a bug introduced in Next.js, so record it in Sentry
|
||||
Sentry.captureException(new Error(`_error.js getInitialProps missing data at path: ${asPath}`))
|
||||
await Sentry.flush(2000)
|
||||
|
||||
return errorInitialProps
|
||||
}
|
||||
|
||||
export default CustomErrorComponent
|
||||
@@ -75,7 +75,7 @@ const RedBank = () => {
|
||||
<Card
|
||||
hideHeaderBorder
|
||||
title={t('redbank.myDeposits')}
|
||||
tooltip={t('redbank.redBankMarketsDepositedTooltip')}
|
||||
tooltip={<Trans i18nKey='redbank.tooltips.deposit.market.connected' />}
|
||||
>
|
||||
<AssetTable columns={defaultDepositColumns} data={redBankAssets} type='deposit' />
|
||||
</Card>
|
||||
@@ -85,7 +85,7 @@ const RedBank = () => {
|
||||
<Card
|
||||
hideHeaderBorder
|
||||
title={t('redbank.myBorrowings')}
|
||||
tooltip={t('redbank.redbankMarketsBorrowedTooltip')}
|
||||
tooltip={<Trans i18nKey='redbank.tooltips.borrow.market.connected' />}
|
||||
>
|
||||
<AssetTable columns={defaultBorrowColumns} data={redBankAssets} type='borrow' />
|
||||
</Card>
|
||||
@@ -107,7 +107,7 @@ const RedBank = () => {
|
||||
/>
|
||||
<Highlight show={tutorialStep === 3 || !showTutorial}>
|
||||
<div className={styles.summaryContainer}>
|
||||
<Card title={t('common.portfolio')} tooltip={t('redbank.redbankPortfolioTooltip')}>
|
||||
<Card title={t('common.portfolio')} tooltip={t('redbank.tooltips.portfolio')}>
|
||||
<div className={styles.summary}>
|
||||
<Portfolio borrowLimit={maxBorrowLimit} liquidationThreshold={liquidationThreshold} />
|
||||
</div>
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
import { ReportHandler } from 'web-vitals'
|
||||
|
||||
const reportWebVitals = (onPerfEntry?: ReportHandler) => {
|
||||
if (onPerfEntry && onPerfEntry instanceof Function) {
|
||||
import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
|
||||
getCLS(onPerfEntry)
|
||||
getFID(onPerfEntry)
|
||||
getFCP(onPerfEntry)
|
||||
getLCP(onPerfEntry)
|
||||
getTTFB(onPerfEntry)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export default reportWebVitals
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
import create, { StoreApi, UseBoundStore } from 'zustand'
|
||||
import { create, StoreApi, UseBoundStore } from 'zustand'
|
||||
import { devtools } from 'zustand/middleware'
|
||||
|
||||
import { Store } from './interfaces/store.interface'
|
||||
|
||||
@@ -6,7 +6,7 @@ import {
|
||||
WalletClient,
|
||||
} from '@marsprotocol/wallet-connector'
|
||||
import { BlockHeightData } from 'hooks/queries/useBlockHeight'
|
||||
import { MarketDepositsData } from 'hooks/queries/useMarketDeposits'
|
||||
import { DepositAndDebtData } from 'hooks/queries/useDepositAndDebt'
|
||||
import { SafetyFundBalanceData } from 'hooks/queries/useSafetyFundBalance'
|
||||
import { UserBalanceData } from 'hooks/queries/useUserBalance'
|
||||
import { UserIcnsData } from 'hooks/queries/useUserIcns'
|
||||
@@ -29,12 +29,7 @@ export interface CommonSlice {
|
||||
chainInfo?: SimplifiedChainInfo
|
||||
client?: WalletClient
|
||||
currentNetwork: Network
|
||||
displayCurrency: {
|
||||
denom: string
|
||||
prefix: string
|
||||
suffix: string
|
||||
decimals: number
|
||||
}
|
||||
marketDebts: Coin[]
|
||||
enableAnimations?: boolean
|
||||
errors: {
|
||||
network: boolean
|
||||
@@ -98,7 +93,7 @@ export interface CommonSlice {
|
||||
previousUserBalanceQueryData?: UserBalanceData
|
||||
previousUserIcnsQueryData?: UserIcnsData
|
||||
previousUserUnclaimedBalanceQueryData?: number
|
||||
processMarketDepositsQuery: (data: MarketDepositsData) => void
|
||||
processDepositAndDebtQuery: (data: DepositAndDebtData) => void
|
||||
processUserBalanceQuery: (data: UserBalanceData) => void
|
||||
processBlockHeightQuery: (data: BlockHeightData) => void
|
||||
processSafetyFundQuery: (data: SafetyFundBalanceData) => void
|
||||
|
||||
+10
-11
@@ -8,7 +8,7 @@ import {
|
||||
} from '@marsprotocol/wallet-connector'
|
||||
import BigNumber from 'bignumber.js'
|
||||
import { BlockHeightData } from 'hooks/queries/useBlockHeight'
|
||||
import { MarketDepositsData } from 'hooks/queries/useMarketDeposits'
|
||||
import { DepositAndDebtData } from 'hooks/queries/useDepositAndDebt'
|
||||
import { SafetyFundBalanceData } from 'hooks/queries/useSafetyFundBalance'
|
||||
import { UserBalanceData } from 'hooks/queries/useUserBalance'
|
||||
import isEqual from 'lodash.isequal'
|
||||
@@ -30,13 +30,6 @@ const commonSlice = (
|
||||
symbol: 'OSMO',
|
||||
decimals: 6,
|
||||
},
|
||||
displayCurrency: {
|
||||
// The denom of DAI, not USDC
|
||||
denom: 'ibc/88D70440A05BFB25C7FF0BA62DA357EAA993CB1B036077CF1DAAEFB28721D935',
|
||||
prefix: '$',
|
||||
suffix: '',
|
||||
decimals: 2,
|
||||
},
|
||||
currentNetwork: Network.TESTNET,
|
||||
errors: {
|
||||
network: false,
|
||||
@@ -46,6 +39,7 @@ const commonSlice = (
|
||||
isNetworkLoaded: false,
|
||||
latestBlockHeight: 0,
|
||||
marketDeposits: [],
|
||||
marketDebts: [],
|
||||
otherAssets: [],
|
||||
queryErrors: [],
|
||||
slippage: 0.02,
|
||||
@@ -196,16 +190,21 @@ const commonSlice = (
|
||||
if (blockFetched !== -1) set({ latestBlockHeight: blockFetched })
|
||||
set({ previousBlockHeightQueryData: data })
|
||||
},
|
||||
processMarketDepositsQuery: (data: MarketDepositsData) => {
|
||||
processDepositAndDebtQuery: (data: DepositAndDebtData) => {
|
||||
const whitelistedAssets = get().whitelistedAssets
|
||||
if (!whitelistedAssets.length) return
|
||||
|
||||
const coins: Coin[] = whitelistedAssets.map((asset) => ({
|
||||
const depositCoins: Coin[] = whitelistedAssets.map((asset) => ({
|
||||
amount: data.mdwasmkey[`${asset.symbol}Deposits`],
|
||||
denom: asset.denom,
|
||||
}))
|
||||
|
||||
set({ marketDeposits: coins })
|
||||
const debtCoins: Coin[] = whitelistedAssets.map((asset) => ({
|
||||
amount: data.mdwasmkey[`${asset.symbol}Debt`],
|
||||
denom: asset.denom,
|
||||
}))
|
||||
|
||||
set({ marketDeposits: depositCoins, marketDebts: debtCoins })
|
||||
},
|
||||
processSafetyFundQuery: (data: SafetyFundBalanceData) => {
|
||||
if (isEqual(data, get().previousSafetyFundBalanceQueryData)) return
|
||||
|
||||
@@ -2,6 +2,7 @@ import { Coin } from '@cosmjs/stargate'
|
||||
import BigNumber from 'bignumber.js'
|
||||
import { updateExchangeRate } from 'functions/updateExchangeRate'
|
||||
import { MarsOracleData } from 'hooks/queries/useMarsOracle'
|
||||
import { findAssetByDenom, lookup } from 'libs/parse'
|
||||
import isEqual from 'lodash.isequal'
|
||||
import { OraclesSlice } from 'store/interfaces/oracles.interface'
|
||||
import { Store } from 'store/interfaces/store.interface'
|
||||
@@ -22,15 +23,18 @@ const oraclesSlice = (set: NamedSet<Store>, get: GetState<Store>): OraclesSlice
|
||||
const exchangeRates = get().exchangeRates
|
||||
const otherAssets = get().otherAssets
|
||||
const baseCurrency = get().baseCurrency
|
||||
const displayCurrency = get().displayCurrency
|
||||
const networkConfig = get().networkConfig
|
||||
const displayCurrency = networkConfig?.displayCurrency
|
||||
const assets = [...whitelistedAssets, ...otherAssets]
|
||||
|
||||
if (!coin || !exchangeRates || !assets.length) {
|
||||
if (!coin || !exchangeRates || !assets.length || !displayCurrency) {
|
||||
return 0
|
||||
}
|
||||
|
||||
if (coin.denom === displayCurrency.denom) {
|
||||
return Number(coin.amount)
|
||||
if (coin.denom.toLowerCase() === displayCurrency.denom.toLowerCase()) {
|
||||
const displayAsset = findAssetByDenom(displayCurrency.denom, assets)
|
||||
if (!displayAsset) return 0
|
||||
return lookup(Number(coin.amount), displayAsset.symbol, displayAsset.decimals)
|
||||
}
|
||||
|
||||
const assetToBaseRatio = Number(
|
||||
|
||||
@@ -75,6 +75,7 @@ const redBankSlice = (set: NamedSet<Store>, get: GetState<Store>): RedBankSlice
|
||||
)
|
||||
return
|
||||
const redBankAssets: RedBankAsset[] = []
|
||||
const marketAssetLiquidity: Coin[] = []
|
||||
const whitelistedAssets = get().whitelistedAssets
|
||||
|
||||
if (!whitelistedAssets?.length) return
|
||||
@@ -84,7 +85,6 @@ const redBankSlice = (set: NamedSet<Store>, get: GetState<Store>): RedBankSlice
|
||||
const convertToBaseCurrency = get().convertToBaseCurrency
|
||||
const reserveInfo = findByDenom(get().marketInfo, asset.denom)
|
||||
const depositApy = reserveInfo?.liquidity_rate || 0
|
||||
const liquidity = findByDenom(get().marketAssetLiquidity, asset.denom) as Coin
|
||||
const incentiveInfo = get().calculateIncentiveAssetInfo(
|
||||
findByDenom(get().marketIncentiveInfo, asset.denom),
|
||||
{ denom: asset.denom, amount: get().computeMarketLiquidity(asset.denom).toString() },
|
||||
@@ -96,6 +96,11 @@ const redBankSlice = (set: NamedSet<Store>, get: GetState<Store>): RedBankSlice
|
||||
const depositCap = Number(marketInfo?.deposit_cap) || 0
|
||||
const depositLiquidity =
|
||||
Number(get().marketDeposits.find((coin) => coin.denom === asset.denom)?.amount) || 0
|
||||
const debtLiquidity =
|
||||
Number(get().marketDebts.find((coin) => coin.denom === asset.denom)?.amount) || 0
|
||||
|
||||
const marketLiquidity = (depositLiquidity - debtLiquidity).toString()
|
||||
marketAssetLiquidity.push({ denom: asset.denom, amount: marketLiquidity })
|
||||
const redBankAsset: RedBankAsset = {
|
||||
...asset,
|
||||
walletBalance: assetWallet?.amount.toString(),
|
||||
@@ -112,7 +117,7 @@ const redBankSlice = (set: NamedSet<Store>, get: GetState<Store>): RedBankSlice
|
||||
borrowRate: borrowApy * 100 >= 0.01 ? borrowApy * 100 : 0.0,
|
||||
apy: depositApy * 100 >= 0.01 ? depositApy * 100 : 0.0,
|
||||
depositLiquidity: depositLiquidity,
|
||||
marketLiquidity: liquidity?.amount.toString() || '0',
|
||||
marketLiquidity: marketLiquidity,
|
||||
incentiveInfo,
|
||||
isCollateral: true,
|
||||
depositCap: depositCap,
|
||||
@@ -123,6 +128,7 @@ const redBankSlice = (set: NamedSet<Store>, get: GetState<Store>): RedBankSlice
|
||||
|
||||
set({
|
||||
redBankAssets,
|
||||
marketAssetLiquidity,
|
||||
})
|
||||
},
|
||||
setUserBalancesState: (userBalancesState: State) => set({ userBalancesState }),
|
||||
@@ -135,11 +141,7 @@ const redBankSlice = (set: NamedSet<Store>, get: GetState<Store>): RedBankSlice
|
||||
processRedBankQuery: (data: RedBankData, whitelistedAssets: Asset[]) => {
|
||||
if (isEqual(data, get().previousRedBankQueryData)) return
|
||||
|
||||
const rawBalances: Coin[] = data.balance.balance
|
||||
const userUnclaimedRewards = data.rbwasmkey.unclaimedRewards
|
||||
const marketAssetLiquidity: Coin[] = rawBalances.map((coin) => {
|
||||
return { denom: coin.denom, amount: coin.amount }
|
||||
})
|
||||
const marketInfo: Market[] = []
|
||||
const marketIncentiveInfo: MarketIncentive[] = []
|
||||
|
||||
@@ -160,7 +162,6 @@ const redBankSlice = (set: NamedSet<Store>, get: GetState<Store>): RedBankSlice
|
||||
marketIncentiveInfo.push(marketIncentiveData)
|
||||
})
|
||||
set({
|
||||
marketAssetLiquidity,
|
||||
marketInfo,
|
||||
marketIncentiveInfo,
|
||||
previousRedBankQueryData: data,
|
||||
@@ -188,6 +189,8 @@ const redBankSlice = (set: NamedSet<Store>, get: GetState<Store>): RedBankSlice
|
||||
|
||||
const deposits = data.deposits.deposits
|
||||
|
||||
if (!deposits) return
|
||||
|
||||
const userDeposits = deposits.map((deposit) => ({
|
||||
denom: deposit.denom,
|
||||
amount: deposit.amount,
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
|
||||
> .widthBox {
|
||||
width: 100%;
|
||||
overflow-x: hidden;
|
||||
|
||||
> .body {
|
||||
min-height: calc(100vh - #{$headerHeight});
|
||||
|
||||
Vendored
+1
-1
@@ -2,7 +2,7 @@ interface Asset {
|
||||
color: string
|
||||
name: string
|
||||
denom: string
|
||||
symbol: 'OSMO' | 'ATOM' | 'JUNO'
|
||||
symbol: 'OSMO' | 'ATOM' | 'JUNO' | 'axlUSDC'
|
||||
contract_addr?: string
|
||||
logo: string
|
||||
decimals: number
|
||||
|
||||
+6
@@ -21,6 +21,12 @@ interface NetworkConfig {
|
||||
whitelist: Asset[]
|
||||
other: OtherAsset[]
|
||||
}
|
||||
displayCurrency: {
|
||||
denom: string
|
||||
prefix: string
|
||||
suffix: string
|
||||
decimals: number
|
||||
}
|
||||
appUrl: string
|
||||
councilUrl: string
|
||||
wallets: import('@marsprotocol/wallet-connector').WalletID[]
|
||||
|
||||
Vendored
+2
@@ -9,6 +9,8 @@ interface RedBankData {
|
||||
ATOMMarketIncentive: MarketIncentive
|
||||
JUNOMarket: Market
|
||||
JUNOMarketIncentive: MarketIncentive
|
||||
axlUSDCMarket: Market
|
||||
axlUSDCMarketIncentive: MarketIncentive
|
||||
collateral: UserCollateral[]
|
||||
unclaimedRewards: string
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user