Merge pull request #5 from mars-protocol/v1.2.0

v1.2.0
This commit is contained in:
Bob van der Helm 2023-02-07 18:10:49 +01:00 committed by GitHub
commit 3bf8b96b8c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
62 changed files with 771 additions and 1156 deletions

2
.env Normal file
View File

@ -0,0 +1,2 @@
NEXT_PUBLIC_NETWORK=mainnet
NEXT_PUBLIC_STAGE=production

5
.gitignore vendored
View File

@ -33,8 +33,5 @@ yarn-error.log*
# vercel
.vercel
# Sentry
.sentryclirc
# IDE
.idea
.idea

View File

@ -12,8 +12,6 @@ Typescript is added and utilised (but optional if you want to create .jsx or .ts
SCSS with [CSS modules](https://create-react-app.dev/docs/adding-a-css-modules-stylesheet) (webpack allows importing css files into javascript, use the CSS module technique to avoid className clashes).
Sentry is used for front end error logging/exception & bug reporting.
## 2. Deployment
Start web server

View File

@ -1,6 +1,5 @@
/** @type {import('next').NextConfig} */
const { withSentryConfig } = require('@sentry/nextjs')
const path = require('path')
const moduleExports = {
@ -50,18 +49,4 @@ const moduleExports = {
},
}
const sentryWebpackPluginOptions = {
// Additional config options for the Sentry Webpack plugin. Keep in mind that
// the following options are set automatically, and overriding them is not
// recommended:
// release, url, org, project, authToken, configFile, stripPrefix,
// urlPrefix, include, ignore
silent: true, // Suppresses all logs
// For all available options, see:
// https://github.com/getsentry/sentry-webpack-plugin#options.
}
// Make sure adding Sentry options is the last code to run before exporting, to
// ensure that your source maps include changes from all other Webpack plugins
module.exports = withSentryConfig(moduleExports, sentryWebpackPluginOptions)
module.exports = moduleExports

View File

@ -1,7 +1,7 @@
{
"name": "mars",
"homepage": "./",
"version": "1.1.0",
"version": "1.2.0",
"private": false,
"license": "SEE LICENSE IN LICENSE FILE",
"scripts": {
@ -22,11 +22,10 @@
"@cosmjs/launchpad": "^0.27.1",
"@cosmjs/proto-signing": "^0.29.5",
"@cosmjs/stargate": "^0.29.5",
"@marsprotocol/wallet-connector": "^1.2.3",
"@marsprotocol/wallet-connector": "^1.3.0",
"@material-ui/core": "^4.12.4",
"@material-ui/icons": "^4.11.3",
"@ramonak/react-progress-bar": "^5.0.3",
"@sentry/nextjs": "^7.34.0",
"@tanstack/react-query": "^4.24.4",
"@tanstack/react-table": "^8.7.9",
"@testing-library/dom": "^8.20.0",
@ -53,14 +52,14 @@
"ramda": "^0.28.0",
"react": "^18.2.0",
"react-chartjs-2": "^5.2.0",
"react-currency-input-field": "^3.6.9",
"react-currency-input-field": "^3.6.10",
"react-device-detect": "^2.2.2",
"react-dom": "^18.2.0",
"react-i18next": "^12.1.4",
"react-i18next": "^12.1.5",
"react-spring": "^9.6.1",
"react-table": "^7.8.0",
"react-use-clipboard": "^1.0.9",
"sass": "^1.57.1",
"sass": "^1.58.0",
"typescript": "^4.9.5",
"web-vitals": "^3.1.1",
"zustand": "^4.3.2"
@ -84,7 +83,7 @@
"@types/lodash.clonedeep": "^4.5.7",
"@types/lodash.isequal": "^4.5.6",
"@types/lodash.throttle": "^4.1.7",
"@types/node": "^18.11.18",
"@types/node": "^18.13.0",
"@types/numeral": "^2.0.2",
"@types/prettier": "^2.7.2",
"@types/ramda": "^0.28.22",

View File

@ -2,10 +2,11 @@
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="https://app.marsprotocol.io/favicon.svg" />
<link rel="icon" href="https://osmosis.marsprotocol.io/favicon.svg" />
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
<link rel="manifest" href="/site.webmanifest" />
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#dd5b65" />
<link rel="canonical" href="https://osmosis.marsprotocol.io" />
<meta name="robots" content="index,follow" />
<meta
name="description"
@ -14,13 +15,13 @@
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:site" content="@mars_protocol" />
<meta name="twitter:creator" content="@mars_protocol" />
<meta property="og:url" content="https://app.marsprotocol.io" />
<meta property="og:url" content="https://osmosis.marsprotocol.io" />
<meta property="og:title" content="Mars Protocol Application - Powered by Terra" />
<meta
property="og:description"
content="Lend, borrow and earn on the galaxy's most powerful credit protocol or enter the Fields of Mars for advanced DeFi strategies."
/>
<meta property="og:image" content="https://app.marsprotocol.io/banner.png" />
<meta property="og:image" content="https://osmosis.marsprotocol.io/banner.png" />
<meta property="og:site_name" content="Mars Protocol" />
<meta name="msapplication-TileColor" content="#ffffff" />
<meta name="theme-color" content="#ffffff" />

View File

@ -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

View File

@ -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}</>

View File

@ -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={() => (

View File

@ -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}>

View File

@ -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 {

View File

@ -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>

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>

View File

@ -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>
) : (

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' />
</>

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')}>

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>
)
}

View File

@ -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;
}
}

View File

@ -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>
)
}

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')
}
}

View File

@ -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

View File

@ -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>

View File

@ -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'>

View File

@ -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':

View File

@ -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'>

View File

@ -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({

View File

@ -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>

View File

@ -12,7 +12,7 @@
.td {
.wrapper {
@include padding(6, 0, 0);
@include padding(3, 0, 0);
display: flex;
flex-wrap: wrap;
justify-content: center;

View File

@ -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>

View File

@ -30,14 +30,6 @@
@include bgTableHover;
}
}
> .td {
border-bottom: 1px solid $alphaWhite20;
&:nth-child(1),
&:nth-child(2) {
border-bottom: none;
}
}
}
.td {

View File

@ -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;
}
}
}

View File

@ -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

View File

@ -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)}

View File

@ -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)

View File

@ -84,6 +84,9 @@
td {
display: table-cell;
}
td {
pointer-events: none;
}
}
}
}

View File

@ -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>

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],

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[] = []

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 */

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}`
}

View File

@ -1,10 +0,0 @@
export const getBankQuery = (address: string) => {
return `
balance: bank {
balance(address: "${address}") {
amount
denom
}
}
`
}

View File

@ -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}
}

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}
${

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'

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'

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])
}

View File

@ -10,6 +10,7 @@ export interface MarketDepositsData {
OSMODeposits: string
ATOMDeposits: string
JUNODeposits: string
axlUSDCDeposits: string
}
}

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]

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)

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

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>

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

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'

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

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

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(

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,

View File

@ -27,7 +27,6 @@
> .widthBox {
width: 100%;
overflow-x: hidden;
> .body {
min-height: calc(100vh - #{$headerHeight});

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

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[]

View File

@ -9,6 +9,8 @@ interface RedBankData {
ATOMMarketIncentive: MarketIncentive
JUNOMarket: Market
JUNOMarketIncentive: MarketIncentive
axlUSDCMarket: Market
axlUSDCMarketIncentive: MarketIncentive
collateral: UserCollateral[]
unclaimedRewards: string
}

491
yarn.lock
View File

@ -537,10 +537,10 @@
resolved "https://registry.yarnpkg.com/@cosmjs/utils/-/utils-0.29.5.tgz#3fed1b3528ae8c5f1eb5d29b68755bebfd3294ee"
integrity sha512-m7h+RXDUxOzEOGt4P+3OVPX7PuakZT3GBmaM/Y2u+abN3xZkziykD/NvedYFvvCCdQo714XcGl33bwifS9FZPQ==
"@delphi-labs/shuttle@^2.1.2":
version "2.1.2"
resolved "https://registry.yarnpkg.com/@delphi-labs/shuttle/-/shuttle-2.1.2.tgz#1db50e81ccf2f72b00282416b05b2007591b6a58"
integrity sha512-V0aMimsraWxqf+RKFkwvCokWCNU0sGbw58hXyo92abBeKvIkN7GkrT2R+pEM37S0/uJ4VyRTT9ly/ky6/435Ug==
"@delphi-labs/shuttle@^2.3.2":
version "2.3.2"
resolved "https://registry.yarnpkg.com/@delphi-labs/shuttle/-/shuttle-2.3.2.tgz#d05890bca91b3b18fc451bde3cb03d83072c1c42"
integrity sha512-xgebNiS761IPiqQ5q3no1CBNGD/Q5vznV7ydUqismzR/Vw4GIEAqJv6QFIe7HbjHPXkIPeL/enimEGwAnNB1Ag==
dependencies:
"@cosmjs/amino" "^0.29.5"
"@cosmjs/cosmwasm-stargate" "^0.29.2"
@ -551,6 +551,8 @@
"@injectivelabs/sdk-ts" "^1.0.360"
"@injectivelabs/ts-types" "^1.0.28"
"@injectivelabs/utils" "^1.0.60"
"@keplr-wallet/cosmos" "^0.11.34"
"@keplr-wallet/proto-types" "^0.11.38"
"@metamask/eth-sig-util" "^5.0.2"
"@walletconnect/client" "^1.8.0"
"@walletconnect/core" "^1.8.0"
@ -558,6 +560,7 @@
"@walletconnect/utils" "^1.8.0"
cosmjs-types "^0.6.1"
ethereumjs-util "^7.1.5"
long "^5.2.1"
secp256k1 "^5.0.0"
tslib "^2.4.0"
zustand "^4.3.1"
@ -1409,7 +1412,7 @@
"@jridgewell/gen-mapping" "^0.3.0"
"@jridgewell/trace-mapping" "^0.3.9"
"@jridgewell/sourcemap-codec@1.4.14", "@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.13":
"@jridgewell/sourcemap-codec@1.4.14", "@jridgewell/sourcemap-codec@^1.4.10":
version "1.4.14"
resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24"
integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==
@ -1431,7 +1434,7 @@
buffer "^6.0.3"
delay "^4.4.0"
"@keplr-wallet/cosmos@^0.11.38":
"@keplr-wallet/cosmos@^0.11.34", "@keplr-wallet/cosmos@^0.11.38":
version "0.11.38"
resolved "https://registry.yarnpkg.com/@keplr-wallet/cosmos/-/cosmos-0.11.38.tgz#5657e3fed10c9a9f75d29f01a137913403196348"
integrity sha512-0N7pf77cSPp/tNzsCp9dhbmEStXZJv+7KZv3FICRpgSp2w6vKwMPwJ5GIt0T0X4RuiQfgkabnDX77DkBSHo9ng==
@ -1462,7 +1465,7 @@
elliptic "^6.5.3"
sha.js "^2.4.11"
"@keplr-wallet/proto-types@0.11.38":
"@keplr-wallet/proto-types@0.11.38", "@keplr-wallet/proto-types@^0.11.38":
version "0.11.38"
resolved "https://registry.yarnpkg.com/@keplr-wallet/proto-types/-/proto-types-0.11.38.tgz#b31152b06e1f7a9d7c5768767a22d79dbf4c9161"
integrity sha512-fMiINr1Y59GfIID1oeCuPkGuBm2WTBjQ/qekDHvwM0aBEB0Ca0J9chhyqwziHvmKAShVmZVyb9P2r/1ZqKV21g==
@ -1492,16 +1495,18 @@
resolved "https://registry.yarnpkg.com/@kurkle/color/-/color-0.3.2.tgz#5acd38242e8bde4f9986e7913c8fdf49d3aa199f"
integrity sha512-fuscdXJ9G1qb7W8VdHi+IwRqij3lBkosAm4ydQtEmbY58OzHXqQhvlxqEkoz0yssNVn38bcpRWgA9PP+OGoisw==
"@marsprotocol/wallet-connector@^1.2.3":
version "1.2.3"
resolved "https://registry.yarnpkg.com/@marsprotocol/wallet-connector/-/wallet-connector-1.2.3.tgz#caa0612e914ba42319a49a9372bc0ce26603a9bf"
integrity sha512-Xx2gw9FYF7DAfSFsDPsvuVf8IvtgQ1Scm10qHx69dC6KtNzMdOFh4rzzl/RSYiijaDBh1ItiNMqOpJemzQUujQ==
"@marsprotocol/wallet-connector@^1.3.0":
version "1.3.0"
resolved "https://registry.yarnpkg.com/@marsprotocol/wallet-connector/-/wallet-connector-1.3.0.tgz#1d7a47c5a2ee94e23f7b3703638a7526b35fd8ba"
integrity sha512-O9zyUtWNrggRE1LeilofR8BunhwP6lCY5g5+WU1BDI/V2AqzV9tdNdjYg5CGEO2Z8iXb21Y+o4RoiZ7mknezzQ==
dependencies:
"@cosmjs/cosmwasm-stargate" "^0.29.5"
"@delphi-labs/shuttle" "^2.1.2"
"@delphi-labs/shuttle" "^2.3.2"
"@keplr-wallet/cosmos" "^0.11.38"
axios "^1.3.1"
axios "^1.3.2"
react-device-detect "^2.2.2"
react-modal "^3.16.1"
react-qr-code "^2.0.11"
webpack "^5.75.0"
webpack-cli "^5.0.1"
webpack-node-externals "^3.0.0"
@ -1874,27 +1879,6 @@
"@react-spring/shared" "~9.6.1"
"@react-spring/types" "~9.6.1"
"@rollup/plugin-commonjs@24.0.0":
version "24.0.0"
resolved "https://registry.yarnpkg.com/@rollup/plugin-commonjs/-/plugin-commonjs-24.0.0.tgz#fb7cf4a6029f07ec42b25daa535c75b05a43f75c"
integrity sha512-0w0wyykzdyRRPHOb0cQt14mIBLujfAv6GgP6g8nvg/iBxEm112t3YPPq+Buqe2+imvElTka+bjNlJ/gB56TD8g==
dependencies:
"@rollup/pluginutils" "^5.0.1"
commondir "^1.0.1"
estree-walker "^2.0.2"
glob "^8.0.3"
is-reference "1.2.1"
magic-string "^0.27.0"
"@rollup/pluginutils@^5.0.1":
version "5.0.2"
resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-5.0.2.tgz#012b8f53c71e4f6f9cb317e311df1404f56e7a33"
integrity sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==
dependencies:
"@types/estree" "^1.0.0"
estree-walker "^2.0.2"
picomatch "^2.3.1"
"@rushstack/eslint-patch@^1.1.3":
version "1.2.0"
resolved "https://registry.yarnpkg.com/@rushstack/eslint-patch/-/eslint-patch-1.2.0.tgz#8be36a1f66f3265389e90b5f9c9962146758f728"
@ -1922,131 +1906,6 @@
"@noble/hashes" "~1.1.1"
"@scure/base" "~1.1.0"
"@sentry/browser@7.34.0":
version "7.34.0"
resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-7.34.0.tgz#6a521c5d95d535e6e89cf4eae85153f90c37d17a"
integrity sha512-5Jmjj0DLxx+31o12T+VH4U+gO7wz3L+ftjuTxcQaC8GeFVe5qCyXZoDmWKNV9NEyREiZ3azV62bJc5wojZrIIg==
dependencies:
"@sentry/core" "7.34.0"
"@sentry/replay" "7.34.0"
"@sentry/types" "7.34.0"
"@sentry/utils" "7.34.0"
tslib "^1.9.3"
"@sentry/cli@^1.74.6":
version "1.74.6"
resolved "https://registry.yarnpkg.com/@sentry/cli/-/cli-1.74.6.tgz#c4f276e52c6f5e8c8d692845a965988068ebc6f5"
integrity sha512-pJ7JJgozyjKZSTjOGi86chIngZMLUlYt2HOog+OJn+WGvqEkVymu8m462j1DiXAnex9NspB4zLLNuZ/R6rTQHg==
dependencies:
https-proxy-agent "^5.0.0"
mkdirp "^0.5.5"
node-fetch "^2.6.7"
npmlog "^4.1.2"
progress "^2.0.3"
proxy-from-env "^1.1.0"
which "^2.0.2"
"@sentry/core@7.34.0":
version "7.34.0"
resolved "https://registry.yarnpkg.com/@sentry/core/-/core-7.34.0.tgz#bfda8d386cf7343200aa9fb7a7a26e99b839fc0c"
integrity sha512-J1oxsYZX1N0tkEcaHt/uuDqk6zOnaivyampp+EvBsUMCdemjg7rwKvawlRB0ZtBEQu3HAhi8zecm03mlpWfCDw==
dependencies:
"@sentry/types" "7.34.0"
"@sentry/utils" "7.34.0"
tslib "^1.9.3"
"@sentry/integrations@7.34.0":
version "7.34.0"
resolved "https://registry.yarnpkg.com/@sentry/integrations/-/integrations-7.34.0.tgz#891dd31a7c021cd1b78b3a05dff80deddfbca71b"
integrity sha512-xbWnTvG4gkKeCVpmhhdPtMbQkPO0RAfEJ8VPO5TWmUMT23ZWy2kE0gTZHtnBopy7AXxg231XxTi4fxnwgQGxEQ==
dependencies:
"@sentry/types" "7.34.0"
"@sentry/utils" "7.34.0"
localforage "^1.8.1"
tslib "^1.9.3"
"@sentry/nextjs@^7.34.0":
version "7.34.0"
resolved "https://registry.yarnpkg.com/@sentry/nextjs/-/nextjs-7.34.0.tgz#5c649c9cf02db171bce1f0b351e2aef9af37f97d"
integrity sha512-vXtlpONIDU2kT2eA5STLBuGvw5njM7K/7IqjvvkwTwYUpKWs7xZvp7NeHAHpH6LkDSBljokS45fnvfMijEqN7A==
dependencies:
"@rollup/plugin-commonjs" "24.0.0"
"@sentry/core" "7.34.0"
"@sentry/integrations" "7.34.0"
"@sentry/node" "7.34.0"
"@sentry/react" "7.34.0"
"@sentry/tracing" "7.34.0"
"@sentry/types" "7.34.0"
"@sentry/utils" "7.34.0"
"@sentry/webpack-plugin" "1.20.0"
chalk "3.0.0"
rollup "2.78.0"
tslib "^1.9.3"
"@sentry/node@7.34.0":
version "7.34.0"
resolved "https://registry.yarnpkg.com/@sentry/node/-/node-7.34.0.tgz#acf51e40b1ecbd91d7bf2df55c47ae1b30c39b40"
integrity sha512-VM4XeydRdgeaNTRe8kwqYg2oNPddVyY74PlCFEFnPEN1NccycNuwiFno68kNrApeqxxLlTTmzkJy0BWo16x2Yg==
dependencies:
"@sentry/core" "7.34.0"
"@sentry/types" "7.34.0"
"@sentry/utils" "7.34.0"
cookie "^0.4.1"
https-proxy-agent "^5.0.0"
lru_map "^0.3.3"
tslib "^1.9.3"
"@sentry/react@7.34.0":
version "7.34.0"
resolved "https://registry.yarnpkg.com/@sentry/react/-/react-7.34.0.tgz#8d69d3957736fe2692cd5547ad2d2f6f307e5590"
integrity sha512-vdonnZK9R8xyEBDaXNofHyoqy9biNRvlKrQXZp4x8WlYcBCwbU46qxZlSVsxa89pm7yUYS+KHq8cYL801+weqg==
dependencies:
"@sentry/browser" "7.34.0"
"@sentry/types" "7.34.0"
"@sentry/utils" "7.34.0"
hoist-non-react-statics "^3.3.2"
tslib "^1.9.3"
"@sentry/replay@7.34.0":
version "7.34.0"
resolved "https://registry.yarnpkg.com/@sentry/replay/-/replay-7.34.0.tgz#66d63b1e04d7e8068cac0c623a607f470d000751"
integrity sha512-4L4YZfWt8mcVNcI99RxHORPb308URI1R9xsFj97fagk0ATjexLKr5QCA2ApnKaSn8Q0q1Zdzd4XmFtW9anU45Q==
dependencies:
"@sentry/core" "7.34.0"
"@sentry/types" "7.34.0"
"@sentry/utils" "7.34.0"
"@sentry/tracing@7.34.0":
version "7.34.0"
resolved "https://registry.yarnpkg.com/@sentry/tracing/-/tracing-7.34.0.tgz#bc084389cad4f1e8520311ac195b070eced72b40"
integrity sha512-JtfSWBfcWslfIujcpGEPF5oOiAOCd5shMoWYrdTvCfruHhYjp4w5kv/ndkvq2EpFkcQYhdmtQEytXEO8IJIqRw==
dependencies:
"@sentry/core" "7.34.0"
"@sentry/types" "7.34.0"
"@sentry/utils" "7.34.0"
tslib "^1.9.3"
"@sentry/types@7.34.0":
version "7.34.0"
resolved "https://registry.yarnpkg.com/@sentry/types/-/types-7.34.0.tgz#e0dc6a927dd13e4cacbca7bfee67a088885e8309"
integrity sha512-K+OeHIrl35PSYn6Zwqe4b8WWyAJQoI5NeWxHVkM7oQTGJ1YLG4BvLsR+UiUXnKdR5krE4EDtEA5jLsDlBEyPvw==
"@sentry/utils@7.34.0":
version "7.34.0"
resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-7.34.0.tgz#32fb6db8b352477d219ddff8200372959c68b445"
integrity sha512-VIHHXEBw0htzqxnU8A7WkXKvmsG2pZVqHlAn0H9W/yyFQtXMuP1j1i0NsjADB/3JXUKK83kTNWGzScXvp0o+Jg==
dependencies:
"@sentry/types" "7.34.0"
tslib "^1.9.3"
"@sentry/webpack-plugin@1.20.0":
version "1.20.0"
resolved "https://registry.yarnpkg.com/@sentry/webpack-plugin/-/webpack-plugin-1.20.0.tgz#e7add76122708fb6b4ee7951294b521019720e58"
integrity sha512-Ssj1mJVFsfU6vMCOM2d+h+KQR7QHSfeIP16t4l20Uq/neqWXZUQ2yvQfe4S3BjdbJXz/X4Rw8Hfy1Sd0ocunYw==
dependencies:
"@sentry/cli" "^1.74.6"
webpack-sources "^2.0.0 || ^3.0.0"
"@sinclair/typebox@^0.24.1":
version "0.24.51"
resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.24.51.tgz#645f33fe4e02defe26f2f5c0410e1c094eac7f5f"
@ -2240,7 +2099,7 @@
"@types/estree" "*"
"@types/json-schema" "*"
"@types/estree@*", "@types/estree@^1.0.0":
"@types/estree@*":
version "1.0.0"
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.0.tgz#5fb2e536c1ae9bf35366eed879e827fa59ca41c2"
integrity sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ==
@ -2907,11 +2766,6 @@ ansi-escapes@^4.2.1:
dependencies:
type-fest "^0.21.3"
ansi-regex@^2.0.0:
version "2.1.1"
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df"
integrity sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==
ansi-regex@^5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304"
@ -2944,19 +2798,6 @@ anymatch@^3.0.3, anymatch@~3.1.2:
normalize-path "^3.0.0"
picomatch "^2.0.4"
aproba@^1.0.3:
version "1.2.0"
resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a"
integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==
are-we-there-yet@~1.1.2:
version "1.1.7"
resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz#b15474a932adab4ff8a50d9adfa7e4e926f21146"
integrity sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g==
dependencies:
delegates "^1.0.0"
readable-stream "^2.0.6"
argparse@^1.0.7:
version "1.0.10"
resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911"
@ -3073,10 +2914,10 @@ axios@^0.27.2:
follow-redirects "^1.14.9"
form-data "^4.0.0"
axios@^1.3.1:
version "1.3.1"
resolved "https://registry.yarnpkg.com/axios/-/axios-1.3.1.tgz#80bf6c8dbb46e6db1fa8fe9ab114c1ca7405c2ee"
integrity sha512-78pWJsQTceInlyaeBQeYZ/QgZeWS8hGeKiIJiDKQe3hEyBb7sEMq0K4gjx+Va6WHTYO4zI/RRl8qGRzn0YMadA==
axios@^1.3.2:
version "1.3.2"
resolved "https://registry.yarnpkg.com/axios/-/axios-1.3.2.tgz#7ac517f0fa3ec46e0e636223fd973713a09c72b3"
integrity sha512-1M3O703bYqYuPhbHeya5bnhpYVsDDRyQSabNja04mZtboLNSuZ4YrltestrLXfHgmzua4TpUqRiVKbiQuo2epw==
dependencies:
follow-redirects "^1.15.0"
form-data "^4.0.0"
@ -3256,13 +3097,6 @@ brace-expansion@^1.1.7:
balanced-match "^1.0.0"
concat-map "0.0.1"
brace-expansion@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae"
integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==
dependencies:
balanced-match "^1.0.0"
braces@^3.0.2, braces@~3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107"
@ -3371,14 +3205,6 @@ caniuse-lite@^1.0.30001400, caniuse-lite@^1.0.30001406:
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001447.tgz#ef1f39ae38d839d7176713735a8e467a0a2523bd"
integrity sha512-bdKU1BQDPeEXe9A39xJnGtY0uRq/z5osrnXUw0TcK+EYno45Y+U7QU9HhHEyzvMDffpYadFXi3idnSNkcwLkTw==
chalk@3.0.0, chalk@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-3.0.0.tgz#3f73c2bf526591f574cc492c51e2456349f844e4"
integrity sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==
dependencies:
ansi-styles "^4.1.0"
supports-color "^7.1.0"
chalk@^2.0.0, chalk@^2.4.1:
version "2.4.2"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
@ -3388,6 +3214,14 @@ chalk@^2.0.0, chalk@^2.4.1:
escape-string-regexp "^1.0.5"
supports-color "^5.3.0"
chalk@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-3.0.0.tgz#3f73c2bf526591f574cc492c51e2456349f844e4"
integrity sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==
dependencies:
ansi-styles "^4.1.0"
supports-color "^7.1.0"
chalk@^4.0.0, chalk@^4.1.0:
version "4.1.2"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01"
@ -3493,11 +3327,6 @@ co@^4.6.0:
resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184"
integrity sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==
code-point-at@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77"
integrity sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==
collect-v8-coverage@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz#cc2c8e94fc18bbdffe64d6534570c8a673b27f59"
@ -3549,21 +3378,11 @@ commander@^9.4.1:
resolved "https://registry.yarnpkg.com/commander/-/commander-9.5.0.tgz#bc08d1eb5cedf7ccb797a96199d41c7bc3e60d30"
integrity sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==
commondir@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b"
integrity sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==
concat-map@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==
console-control-strings@^1.0.0, console-control-strings@~1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e"
integrity sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==
convert-source-map@^1.6.0, convert-source-map@^1.7.0:
version "1.9.0"
resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.9.0.tgz#7faae62353fb4213366d0ca98358d22e8368b05f"
@ -3574,11 +3393,6 @@ convert-source-map@^2.0.0:
resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-2.0.0.tgz#4b560f649fc4e918dd0ab75cf4961e8bc882d82a"
integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==
cookie@^0.4.1:
version "0.4.2"
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.2.tgz#0e41f24de5ecf317947c82fc789e06a884824432"
integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==
copy-to-clipboard@^3.3.1:
version "3.3.3"
resolved "https://registry.yarnpkg.com/copy-to-clipboard/-/copy-to-clipboard-3.3.3.tgz#55ac43a1db8ae639a4bd99511c148cdd1b83a1b0"
@ -3813,11 +3627,6 @@ delayed-stream@~1.0.0:
resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==
delegates@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a"
integrity sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==
detect-browser@5.2.0:
version "5.2.0"
resolved "https://registry.yarnpkg.com/detect-browser/-/detect-browser-5.2.0.tgz#c9cd5afa96a6a19fda0bbe9e9be48a6b6e1e9c97"
@ -4335,11 +4144,6 @@ estraverse@^5.1.0, estraverse@^5.2.0, estraverse@^5.3.0:
resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123"
integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==
estree-walker@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac"
integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==
esutils@^2.0.2:
version "2.0.3"
resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64"
@ -4698,20 +4502,6 @@ functions-have-names@^1.2.2:
resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834"
integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==
gauge@~2.7.3:
version "2.7.4"
resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7"
integrity sha512-14x4kjc6lkD3ltw589k0NrPD6cCNTD6CWoVUNpB85+DrtONoZn+Rug6xZU5RvSC4+TZPxA5AnBibQYAvZn41Hg==
dependencies:
aproba "^1.0.3"
console-control-strings "^1.0.0"
has-unicode "^2.0.0"
object-assign "^4.1.0"
signal-exit "^3.0.0"
string-width "^1.0.1"
strip-ansi "^3.0.1"
wide-align "^1.1.0"
gensync@^1.0.0-beta.2:
version "1.0.0-beta.2"
resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0"
@ -4804,17 +4594,6 @@ glob@^7.0.0, glob@^7.0.5, glob@^7.1.3, glob@^7.1.4:
once "^1.3.0"
path-is-absolute "^1.0.0"
glob@^8.0.3:
version "8.1.0"
resolved "https://registry.yarnpkg.com/glob/-/glob-8.1.0.tgz#d388f656593ef708ee3e34640fdfb99a9fd1c33e"
integrity sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==
dependencies:
fs.realpath "^1.0.0"
inflight "^1.0.4"
inherits "2"
minimatch "^5.0.1"
once "^1.3.0"
globals@^11.1.0:
version "11.12.0"
resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e"
@ -4950,11 +4729,6 @@ has-tostringtag@^1.0.0:
dependencies:
has-symbols "^1.0.2"
has-unicode@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9"
integrity sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==
has@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796"
@ -5028,7 +4802,7 @@ http-status-codes@^2.2.0:
resolved "https://registry.yarnpkg.com/http-status-codes/-/http-status-codes-2.2.0.tgz#bb2efe63d941dfc2be18e15f703da525169622be"
integrity sha512-feERVo9iWxvnejp3SEfm/+oNG517npqL2/PIA8ORjyOZjGC7TwCRQsZylciLS64i6pJ0wRYz3rkXLRwbtFa8Ng==
https-proxy-agent@^5.0.0, https-proxy-agent@^5.0.1:
https-proxy-agent@^5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6"
integrity sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==
@ -5089,11 +4863,6 @@ ignore@^5.1.4, ignore@^5.2.0:
resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324"
integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==
immediate@~3.0.5:
version "3.0.6"
resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.0.6.tgz#9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b"
integrity sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==
immutable@^4.0.0:
version "4.2.2"
resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.2.2.tgz#2da9ff4384a4330c36d4d1bc88e90f9e0b0ccd16"
@ -5230,13 +4999,6 @@ is-extglob@^2.1.1:
resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2"
integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==
is-fullwidth-code-point@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb"
integrity sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==
dependencies:
number-is-nan "^1.0.0"
is-fullwidth-code-point@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d"
@ -5303,13 +5065,6 @@ is-potential-custom-element-name@^1.0.1:
resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz#171ed6f19e3ac554394edf78caa05784a45bebb5"
integrity sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==
is-reference@1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/is-reference/-/is-reference-1.2.1.tgz#8b2dac0b371f4bc994fdeaba9eb542d03002d0b7"
integrity sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==
dependencies:
"@types/estree" "*"
is-regex@^1.1.4:
version "1.1.4"
resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958"
@ -6156,13 +5911,6 @@ libsodium@^0.7.0:
resolved "https://registry.yarnpkg.com/libsodium/-/libsodium-0.7.10.tgz#c2429a7e4c0836f879d701fec2c8a208af024159"
integrity sha512-eY+z7hDrDKxkAK+QKZVNv92A5KYkxfvIshtBJkmg5TSiCnYqZP3i9OO9whE79Pwgm4jGaoHgkM4ao/b9Cyu4zQ==
lie@3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/lie/-/lie-3.1.1.tgz#9a436b2cc7746ca59de7a41fa469b3efb76bd87e"
integrity sha512-RiNhHysUjhrDQntfYSfY4MU24coXXdEOgw9WGcKHNeEwffDYbF//u87M1EWaMGzuFoSbqW0C9C6lEEhDOAswfw==
dependencies:
immediate "~3.0.5"
lines-and-columns@^1.1.6:
version "1.2.4"
resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632"
@ -6180,13 +5928,6 @@ loader-runner@^4.2.0:
resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.3.0.tgz#c1b4a163b99f614830353b16755e7149ac2314e1"
integrity sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==
localforage@^1.8.1:
version "1.10.0"
resolved "https://registry.yarnpkg.com/localforage/-/localforage-1.10.0.tgz#5c465dc5f62b2807c3a84c0c6a1b1b3212781dd4"
integrity sha512-14/H1aX7hzBBmmh7sGPd+AOMkkIrHM3Z1PAyGgZigA1H1p5O5ANnMyWzvpAETtG68/dC4pC0ncy3+PPGzXZHPg==
dependencies:
lie "3.1.1"
locate-path@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0"
@ -6236,6 +5977,11 @@ long@^4.0.0:
resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28"
integrity sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==
long@^5.2.1:
version "5.2.1"
resolved "https://registry.yarnpkg.com/long/-/long-5.2.1.tgz#e27595d0083d103d2fa2c20c7699f8e0c92b897f"
integrity sha512-GKSNGeNAtw8IryjjkhZxuKB3JzlcLTwjtiQCHKvqQet81I93kXslhDQruGI/QsddO83mcDToBVy7GqGS/zYf/A==
loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
@ -6264,23 +6010,11 @@ lru-cache@^6.0.0:
dependencies:
yallist "^4.0.0"
lru_map@^0.3.3:
version "0.3.3"
resolved "https://registry.yarnpkg.com/lru_map/-/lru_map-0.3.3.tgz#b5c8351b9464cbd750335a79650a0ec0e56118dd"
integrity sha512-Pn9cox5CsMYngeDbmChANltQl+5pi6XmTrraMSzhPmMBbmgcxmqWry0U3PGapCU1yB4/LqCcom7qhHZiF/jGfQ==
lz-string@^1.4.4:
version "1.4.4"
resolved "https://registry.yarnpkg.com/lz-string/-/lz-string-1.4.4.tgz#c0d8eaf36059f705796e1e344811cf4c498d3a26"
integrity sha512-0ckx7ZHRPqb0oUm8zNr+90mtf9DQB60H1wMCjBtfi62Kl3a7JbHob6gA2bC+xRvZoOL+1hzUK8jeuEIQE8svEQ==
magic-string@^0.27.0:
version "0.27.0"
resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.27.0.tgz#e4a3413b4bab6d98d2becffd48b4a257effdbbf3"
integrity sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==
dependencies:
"@jridgewell/sourcemap-codec" "^1.4.13"
make-dir@^3.0.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f"
@ -6366,25 +6100,11 @@ minimatch@^3.0.3, minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatc
dependencies:
brace-expansion "^1.1.7"
minimatch@^5.0.1:
version "5.1.6"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.6.tgz#1cfcb8cf5522ea69952cd2af95ae09477f122a96"
integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==
dependencies:
brace-expansion "^2.0.1"
minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.6:
version "1.2.7"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.7.tgz#daa1c4d91f507390437c6a8bc01078e7000c4d18"
integrity sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==
mkdirp@^0.5.5:
version "0.5.6"
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6"
integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==
dependencies:
minimist "^1.2.6"
mkdirp@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e"
@ -6501,13 +6221,6 @@ node-fetch@2.6.7:
dependencies:
whatwg-url "^5.0.0"
node-fetch@^2.6.7:
version "2.6.8"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.8.tgz#a68d30b162bc1d8fd71a367e81b997e1f4d4937e"
integrity sha512-RZ6dBYuj8dRSfxpUSu+NsdF1dpPpluJxwOp+6IoDp/sH2QNDSvurYsAa+F1WxY2RjA1iP93xhcsUoYbF2XBqVg==
dependencies:
whatwg-url "^5.0.0"
node-gyp-build@^4.2.0:
version "4.6.0"
resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.6.0.tgz#0c52e4cbf54bbd28b709820ef7b6a3c2d6209055"
@ -6543,21 +6256,6 @@ npm-run-path@^4.0.0, npm-run-path@^4.0.1:
dependencies:
path-key "^3.0.0"
npmlog@^4.1.2:
version "4.1.2"
resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b"
integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==
dependencies:
are-we-there-yet "~1.1.2"
console-control-strings "~1.1.0"
gauge "~2.7.3"
set-blocking "~2.0.0"
number-is-nan@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d"
integrity sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==
numeral@^2.0.6:
version "2.0.6"
resolved "https://registry.yarnpkg.com/numeral/-/numeral-2.0.6.tgz#4ad080936d443c2561aed9f2197efffe25f4e506"
@ -6568,7 +6266,7 @@ nwsapi@^2.2.2:
resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.2.tgz#e5418863e7905df67d51ec95938d67bf801f0bb0"
integrity sha512-90yv+6538zuvUMnN+zCr8LuV6bPFdq50304114vJYJ8RDyK8D5O9Phpbd6SZWgI7PwzmmfN1upeOJlvybDSgCw==
object-assign@^4.1.0, object-assign@^4.1.1:
object-assign@^4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==
@ -6884,11 +6582,6 @@ process-nextick-args@~2.0.0:
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2"
integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==
progress@^2.0.3:
version "2.0.3"
resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8"
integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==
prompts@^2.0.1:
version "2.4.2"
resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.2.tgz#7b57e73b3a48029ad10ebd44f74b01722a4cb069"
@ -6948,6 +6641,11 @@ punycode@^2.1.0, punycode@^2.1.1:
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.0.tgz#f67fa67c94da8f4d0cfff981aee4118064199b8f"
integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==
qr.js@0.0.0:
version "0.0.0"
resolved "https://registry.yarnpkg.com/qr.js/-/qr.js-0.0.0.tgz#cace86386f59a0db8050fa90d9b6b0e88a1e364f"
integrity sha512-c4iYnWb+k2E+vYpRimHqSu575b1/wKl4XFeJGpFmrJQz5I88v9aY2czh7s0w36srfCM1sXgC/xpoJz5dJfq+OQ==
query-string@6.13.5:
version "6.13.5"
resolved "https://registry.yarnpkg.com/query-string/-/query-string-6.13.5.tgz#99e95e2fb7021db90a6f373f990c0c814b3812d8"
@ -6984,10 +6682,10 @@ react-chartjs-2@^5.2.0:
resolved "https://registry.yarnpkg.com/react-chartjs-2/-/react-chartjs-2-5.2.0.tgz#43c1e3549071c00a1a083ecbd26c1ad34d385f5d"
integrity sha512-98iN5aguJyVSxp5U3CblRLH67J8gkfyGNbiK3c+l1QI/G4irHMPQw44aEPmjVag+YKTyQ260NcF82GTQ3bdscA==
react-currency-input-field@^3.6.9:
version "3.6.9"
resolved "https://registry.yarnpkg.com/react-currency-input-field/-/react-currency-input-field-3.6.9.tgz#5eaa1190512d1de214863032045b67dd0582c87a"
integrity sha512-GNqG1Np+dz3VfBhDc9pFPIyar9SgB/fRjIofFSXOoyFNffda5r24n6LSoXfqQ9L7IKRDoUwveMMJV5GCM2eByw==
react-currency-input-field@^3.6.10:
version "3.6.10"
resolved "https://registry.yarnpkg.com/react-currency-input-field/-/react-currency-input-field-3.6.10.tgz#f04663a2074b894735edb6d9fae95499727596b1"
integrity sha512-KRAJJaLujarBTLlEVbznsUxQ56+Qyqwoe5w9DnGxmsGnHv4ycQRpRkuuCDfF9BcXHmegzsOXesfIGpW7Cw9mTQ==
react-device-detect@^2.2.2:
version "2.2.2"
@ -7004,10 +6702,10 @@ react-dom@^18.2.0:
loose-envify "^1.1.0"
scheduler "^0.23.0"
react-i18next@^12.1.4:
version "12.1.4"
resolved "https://registry.yarnpkg.com/react-i18next/-/react-i18next-12.1.4.tgz#be0a60d3a45acc4321909f8a4b8cde16518a2926"
integrity sha512-XQND7jYtgM7ht5PH3yIZljCRpAMTlH/zmngM9ZjToqa+0BR6xuu8c7QF0WIIOEjcMTB2S3iOfpN/xG/ZrAnO6g==
react-i18next@^12.1.5:
version "12.1.5"
resolved "https://registry.yarnpkg.com/react-i18next/-/react-i18next-12.1.5.tgz#b65f5733dd2f96188a9359c009b7dbe27443f009"
integrity sha512-7PQAv6DA0TcStG96fle+8RfTwxVbHVlZZJPoEszwUNvDuWpGldJmNWa3ZPesEsZQZGF6GkzwvEh6p57qpFD2gQ==
dependencies:
"@babel/runtime" "^7.20.6"
html-parse-stringify "^3.0.1"
@ -7042,6 +6740,14 @@ react-modal@^3.16.1:
react-lifecycles-compat "^3.0.0"
warning "^4.0.3"
react-qr-code@^2.0.11:
version "2.0.11"
resolved "https://registry.yarnpkg.com/react-qr-code/-/react-qr-code-2.0.11.tgz#444c759a2100424972e17135fbe0e32eaffa19e8"
integrity sha512-P7mvVM5vk9NjGdHMt4Z0KWeeJYwRAtonHTghZT2r+AASinLUUKQ9wfsGH2lPKsT++gps7hXmaiMGRvwTDEL9OA==
dependencies:
prop-types "^15.8.1"
qr.js "0.0.0"
react-spring@^9.6.1:
version "9.6.1"
resolved "https://registry.yarnpkg.com/react-spring/-/react-spring-9.6.1.tgz#e715b2fa523c1a3acfdcf1aaa93e081620b8cc8e"
@ -7083,19 +6789,6 @@ react@^18.2.0:
dependencies:
loose-envify "^1.1.0"
readable-stream@^2.0.6, readable-stream@~2.3.6:
version "2.3.7"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57"
integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==
dependencies:
core-util-is "~1.0.0"
inherits "~2.0.3"
isarray "~1.0.0"
process-nextick-args "~2.0.0"
safe-buffer "~5.1.1"
string_decoder "~1.1.1"
util-deprecate "~1.0.1"
readable-stream@^3.6.0:
version "3.6.0"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198"
@ -7115,6 +6808,19 @@ readable-stream@~1.0.31:
isarray "0.0.1"
string_decoder "~0.10.x"
readable-stream@~2.3.6:
version "2.3.7"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57"
integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==
dependencies:
core-util-is "~1.0.0"
inherits "~2.0.3"
isarray "~1.0.0"
process-nextick-args "~2.0.0"
safe-buffer "~5.1.1"
string_decoder "~1.1.1"
util-deprecate "~1.0.1"
readdirp@~3.6.0:
version "3.6.0"
resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7"
@ -7250,13 +6956,6 @@ rlp@^2.2.3, rlp@^2.2.4:
dependencies:
bn.js "^5.2.0"
rollup@2.78.0:
version "2.78.0"
resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.78.0.tgz#00995deae70c0f712ea79ad904d5f6b033209d9e"
integrity sha512-4+YfbQC9QEVvKTanHhIAFVUFSRsezvQF8vFOJwtGfb9Bb+r014S+qryr9PSmw8x6sMnPkmFBGAvIFVQxvJxjtg==
optionalDependencies:
fsevents "~2.3.2"
run-parallel@^1.1.9:
version "1.2.0"
resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee"
@ -7288,10 +6987,10 @@ safe-regex-test@^1.0.0:
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
sass@^1.57.1:
version "1.57.1"
resolved "https://registry.yarnpkg.com/sass/-/sass-1.57.1.tgz#dfafd46eb3ab94817145e8825208ecf7281119b5"
integrity sha512-O2+LwLS79op7GI0xZ8fqzF7X2m/m8WFfI02dHOdsK5R2ECeS5F62zrwg/relM1rjSLy7Vd/DiMNIvPrQGsA0jw==
sass@^1.58.0:
version "1.58.0"
resolved "https://registry.yarnpkg.com/sass/-/sass-1.58.0.tgz#ee8aea3ad5ea5c485c26b3096e2df6087d0bb1cc"
integrity sha512-PiMJcP33DdKtZ/1jSjjqVIKihoDc6yWmYr9K/4r3fVVIEDAluD0q7XZiRKrNJcPK3qkLRF/79DND1H5q1LBjgg==
dependencies:
chokidar ">=3.0.0 <4.0.0"
immutable "^4.0.0"
@ -7376,11 +7075,6 @@ serialize-javascript@^6.0.0:
dependencies:
randombytes "^2.1.0"
set-blocking@~2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7"
integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==
setimmediate@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285"
@ -7439,7 +7133,7 @@ side-channel@^1.0.4:
get-intrinsic "^1.0.2"
object-inspect "^1.9.0"
signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.7:
signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.7:
version "3.0.7"
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9"
integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==
@ -7544,16 +7238,7 @@ string-length@^4.0.1:
char-regex "^1.0.2"
strip-ansi "^6.0.0"
string-width@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3"
integrity sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==
dependencies:
code-point-at "^1.0.0"
is-fullwidth-code-point "^1.0.0"
strip-ansi "^3.0.0"
"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
version "4.2.3"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
@ -7613,13 +7298,6 @@ string_decoder@~1.1.1:
dependencies:
safe-buffer "~5.1.0"
strip-ansi@^3.0.0, strip-ansi@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf"
integrity sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==
dependencies:
ansi-regex "^2.0.0"
strip-ansi@^6.0.0, strip-ansi@^6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
@ -7862,7 +7540,7 @@ tsconfig-paths@^3.14.1:
minimist "^1.2.6"
strip-bom "^3.0.0"
tslib@1.14.1, tslib@^1.8.1, tslib@^1.9.3:
tslib@1.14.1, tslib@^1.8.1:
version "1.14.1"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
@ -8109,7 +7787,7 @@ webpack-node-externals@^3.0.0:
resolved "https://registry.yarnpkg.com/webpack-node-externals/-/webpack-node-externals-3.0.0.tgz#1a3407c158d547a9feb4229a9e3385b7b60c9917"
integrity sha512-LnL6Z3GGDPht/AigwRh2dvL9PQPFQ8skEpVrWZXLWBYmqcaojHNN0onvHzie6rq7EWKrrBfPYqNEzTJgiwEQDQ==
"webpack-sources@^2.0.0 || ^3.0.0", webpack-sources@^3.2.3:
webpack-sources@^3.2.3:
version "3.2.3"
resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde"
integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==
@ -8205,20 +7883,13 @@ which-typed-array@^1.1.9:
has-tostringtag "^1.0.0"
is-typed-array "^1.1.10"
which@^2.0.1, which@^2.0.2:
which@^2.0.1:
version "2.0.2"
resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1"
integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==
dependencies:
isexe "^2.0.0"
wide-align@^1.1.0:
version "1.1.5"
resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.5.tgz#df1d4c206854369ecf3c9a4898f1b23fbd9d15d3"
integrity sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==
dependencies:
string-width "^1.0.2 || 2 || 3 || 4"
wif@^2.0.6:
version "2.0.6"
resolved "https://registry.yarnpkg.com/wif/-/wif-2.0.6.tgz#08d3f52056c66679299726fade0d432ae74b4704"