This commit is contained in:
Linkie Link
2023-02-07 17:52:13 +01:00
parent 79db46721f
commit 5d7f86662a
62 changed files with 771 additions and 1156 deletions
@@ -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>
+13 -12
View File
@@ -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>
) : (
+50 -46
View File
@@ -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' />
</>
+8 -8
View File
@@ -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')}>
+11 -8
View File
@@ -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>
)
}
+4 -4
View File
@@ -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>
+9 -3
View File
@@ -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
View File
@@ -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[] = []
+1 -1
View File
@@ -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 */
+3 -1
View File
@@ -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}`
}
-10
View File
@@ -1,10 +0,0 @@
export const getBankQuery = (address: string) => {
return `
balance: bank {
balance(address: "${address}") {
amount
denom
}
}
`
}
@@ -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}
}
-2
View File
@@ -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 -2
View File
@@ -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
View File
@@ -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'
+53
View File
@@ -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])
}
+1
View File
@@ -10,6 +10,7 @@ export interface MarketDepositsData {
OSMODeposits: string
ATOMDeposits: string
JUNODeposits: string
axlUSDCDeposits: string
}
}
+4 -2
View File
@@ -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]
+2 -1
View File
@@ -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)
-62
View File
@@ -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
+3 -3
View File
@@ -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>
-15
View File
@@ -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
View File
@@ -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'
+3 -8
View File
@@ -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
View File
@@ -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
+8 -4
View File
@@ -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(
+10 -7
View File
@@ -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,
-1
View File
@@ -27,7 +27,6 @@
> .widthBox {
width: 100%;
overflow-x: hidden;
> .body {
min-height: calc(100vh - #{$headerHeight});
+1 -1
View File
@@ -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
View File
@@ -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[]
+2
View File
@@ -9,6 +9,8 @@ interface RedBankData {
ATOMMarketIncentive: MarketIncentive
JUNOMarket: Market
JUNOMarketIncentive: MarketIncentive
axlUSDCMarket: Market
axlUSDCMarketIncentive: MarketIncentive
collateral: UserCollateral[]
unclaimedRewards: string
}