This commit is contained in:
Linkie Link 2023-08-02 11:25:13 +02:00
parent 2ebc64a9d9
commit 6b6d717fac
No known key found for this signature in database
GPG Key ID: 5318B0F2564D38EA
48 changed files with 2644 additions and 1430 deletions

View File

@ -28,17 +28,20 @@ Copy `.env.example` to `.env` and modify the values to suit your needs.
We allow the use of environment variables to be passed to the Docker container to specify custom endpoints for the app. The variables are: We allow the use of environment variables to be passed to the Docker container to specify custom endpoints for the app. The variables are:
| Variable | Description | Default | | Variable | Description | Default |
| --------------------- | ------------------------------------------------ | ------------------------------------------------------------------------------------ | | --------------------- | ------------------------------------------------ | ----------------------------------------------------------------------------------------- |
| URL_OSMOSIS_GQL | The Osmosis Hive GraphQL endpoint to use | https://osmosis-node.marsprotocol.io/GGSFGSFGFG34/osmosis-hive-front/graphql | | URL_OSMOSIS_GQL | The Osmosis Hive GraphQL endpoint to use | https://osmosis-node.marsprotocol.io/GGSFGSFGFG34/osmosis-hive-front/graphql |
| URL_OSMOSIS_REST | The Osmosis node REST endpoint to use | https://lcd-osmosis.blockapsis.com | | URL_OSMOSIS_REST | The Osmosis node REST endpoint to use | https://lcd-osmosis.blockapsis.com |
| URL_OSMOSIS_RPC | The Osmosis node RPC endpoint to use | https://rpc-osmosis.blockapsis.com | | URL_OSMOSIS_RPC | The Osmosis node RPC endpoint to use | https://rpc-osmosis.blockapsis.com |
| URL_OSMOSIS_TEST_GQL | The Osmosis Testnet Hive GraphQL endpoint to use | https://testnet-osmosis-node.marsprotocol.io/XF32UOOU55CX/osmosis-hive-front/graphql | | URL_OSMOSIS_TEST_GQL | The Osmosis Testnet Hive GraphQL endpoint to use | https://testnet-osmosis-node.marsprotocol.io/XF32UOOU55CX/osmosis-hive-front/graphql |
| URL_OSMOSIS_TEST_REST | The Osmosis Testnet node REST endpoint to use | https://lcd.osmotest5.osmosis.zone | | URL_OSMOSIS_TEST_REST | The Osmosis Testnet node REST endpoint to use | https://lcd.osmotest5.osmosis.zone |
| URL_OSMOSIS_TEST_RPC | The Osmosis Testnet node RPC endpoint to use | https://rpc.osmotest5.osmosis.zone | | URL_OSMOSIS_TEST_RPC | The Osmosis Testnet node RPC endpoint to use | https://rpc.osmotest5.osmosis.zone |
| URL_NEUTRON_TEST_GQL | The Neutron Testnet Hive GraphQL endpoint to use | https://testnet-neutron-gql.marsprotocol.io/graphql | | URL_NEUTRON_GQL | The Neutron Hive GraphQL endpoint to use | https://neutron.rpc.p2p.world/qgrnU6PsQZA8F9S5Fb8Fn3tV3kXmMBl2M9bcc9jWLjQy8p/hive/graphql |
| URL_NEUTRON_TEST_REST | The Neutron Testnet node REST endpoint to use | https://rest-palvus.pion-1.ntrn.tech | | URL_NEUTRON_REST | The Neutron node REST endpoint to use | https://rest-kralum.neutron-1.neutron.org |
| URL_NEUTRON_TEST_RPC | The Neutron Testnet node RPC endpoint to use | https://rpc-palvus.pion-1.ntrn.tech | | URL_NEUTRON_RPC | The Neutron node RPC endpoint to use | https://rpc-kralum.neutron-1.neutron.org |
| URL_NEUTRON_TEST_GQL | The Neutron Testnet Hive GraphQL endpoint to use | https://testnet-neutron-gql.marsprotocol.io/graphql |
| URL_NEUTRON_TEST_REST | The Neutron Testnet node REST endpoint to use | https://rest-palvus.pion-1.ntrn.tech |
| URL_NEUTRON_TEST_RPC | The Neutron Testnet node RPC endpoint to use | https://rpc-palvus.pion-1.ntrn.tech |
**Sample Docker run command** **Sample Docker run command**
@ -52,6 +55,9 @@ docker run -it -p 3000:3000 \
-e URL_OSMOSIS_TEST_GQL=https://testnet-osmosis-node.marsprotocol.io/XF32UOOU55CX/osmosis-hive-front/graphql \ -e URL_OSMOSIS_TEST_GQL=https://testnet-osmosis-node.marsprotocol.io/XF32UOOU55CX/osmosis-hive-front/graphql \
-e URL_OSMOSIS_TEST_REST=https://lcd.osmotest5.osmosis.zone \ -e URL_OSMOSIS_TEST_REST=https://lcd.osmotest5.osmosis.zone \
-e URL_OSMOSIS_TEST_RPC=https://rpc.osmotest5.osmosis.zone \ -e URL_OSMOSIS_TEST_RPC=https://rpc.osmotest5.osmosis.zone \
-e URL_NEUTRON_GQL=https://neutron.rpc.p2p.world/qgrnU6PsQZA8F9S5Fb8Fn3tV3kXmMBl2M9bcc9jWLjQy8p/hive/graphql \
-e URL_NEUTRON_REST=https://rest-palvus.pion-1.ntrn.tech \
-e URL_NEUTRON_RPC=https://rpc-palvus.pion-1.ntrn.tech \
-e URL_NEUTRON_TEST_GQL=https://testnet-neutron-gql.marsprotocol.io/graphql \ -e URL_NEUTRON_TEST_GQL=https://testnet-neutron-gql.marsprotocol.io/graphql \
-e URL_NEUTRON_TEST_REST=https://rest-palvus.pion-1.ntrn.tech \ -e URL_NEUTRON_TEST_REST=https://rest-palvus.pion-1.ntrn.tech \
-e URL_NEUTRON_TEST_RPC=https://rpc-palvus.pion-1.ntrn.tech marsprotocol/interface:latest -e URL_NEUTRON_TEST_RPC=https://rpc-palvus.pion-1.ntrn.tech marsprotocol/interface:latest

View File

@ -10,6 +10,9 @@ echo "APP_NEXT_OSMOSIS_GQL=$URL_OSMOSIS_GQL" >> $envFilename
echo "APP_NEXT_OSMOSIS_TEST_RPC=$URL_OSMOSIS_TEST_RPC" >> $envFilename echo "APP_NEXT_OSMOSIS_TEST_RPC=$URL_OSMOSIS_TEST_RPC" >> $envFilename
echo "APP_NEXT_OSMOSIS_TEST_REST=$URL_OSMOSIS_TEST_REST" >> $envFilename echo "APP_NEXT_OSMOSIS_TEST_REST=$URL_OSMOSIS_TEST_REST" >> $envFilename
echo "APP_NEXT_OSMOSIS_TEST_GQL=$URL_OSMOSIS_TEST_GQL" >> $envFilename echo "APP_NEXT_OSMOSIS_TEST_GQL=$URL_OSMOSIS_TEST_GQL" >> $envFilename
echo "APP_NEXT_NEUTRON_RPC=$URL_NEUTRON_RPC" >> $envFilename
echo "APP_NEXT_NEUTRON_REST=$URL_NEUTRON_REST" >> $envFilename
echo "APP_NEXT_NEUTRON_GQL=$URL_NEUTRON_TEST_GQL" >> $envFilename
echo "APP_NEXT_NEUTRON_TEST_RPC=$URL_NEUTRON_TEST_RPC" >> $envFilename echo "APP_NEXT_NEUTRON_TEST_RPC=$URL_NEUTRON_TEST_RPC" >> $envFilename
echo "APP_NEXT_NEUTRON_TEST_REST=$URL_NEUTRON_TEST_REST" >> $envFilename echo "APP_NEXT_NEUTRON_TEST_REST=$URL_NEUTRON_TEST_REST" >> $envFilename
echo "APP_NEXT_NEUTRON_TEST_GQL=$URL_NEUTRON_TEST_GQL" >> $envFilename echo "APP_NEXT_NEUTRON_TEST_GQL=$URL_NEUTRON_TEST_GQL" >> $envFilename

View File

@ -1,7 +1,7 @@
{ {
"name": "mars", "name": "mars",
"homepage": "./", "homepage": "./",
"version": "1.5.3", "version": "1.6.0",
"license": "SEE LICENSE IN LICENSE FILE", "license": "SEE LICENSE IN LICENSE FILE",
"private": false, "private": false,
"scripts": { "scripts": {
@ -18,14 +18,15 @@
"test:coverage": "jest --coverage" "test:coverage": "jest --coverage"
}, },
"dependencies": { "dependencies": {
"@cosmjs/cosmwasm-stargate": "^0.30.1", "@cosmjs/cosmwasm-stargate": "^0.31.0",
"@cosmjs/launchpad": "^0.27.1", "@cosmjs/launchpad": "^0.27.1",
"@cosmjs/proto-signing": "^0.30.1", "@cosmjs/proto-signing": "^0.31.0",
"@cosmjs/stargate": "^0.30.1", "@cosmjs/stargate": "^0.31.0",
"@marsprotocol/wallet-connector": "^1.8.6", "@marsprotocol/wallet-connector": "^1.9.6",
"@material-ui/core": "^4.12.4", "@material-ui/core": "^4.12.4",
"@material-ui/icons": "^4.11.3", "@material-ui/icons": "^4.11.3",
"@ramonak/react-progress-bar": "^5.0.3", "@ramonak/react-progress-bar": "^5.0.3",
"@sentry/nextjs": "^7.36.0",
"@tanstack/react-query": "^4.24.4", "@tanstack/react-query": "^4.24.4",
"@tanstack/react-table": "^8.7.9", "@tanstack/react-table": "^8.7.9",
"@testing-library/dom": "^8.20.0", "@testing-library/dom": "^8.20.0",

View File

@ -7,7 +7,6 @@ import {
WalletConnectionStatus, WalletConnectionStatus,
} from '@marsprotocol/wallet-connector' } from '@marsprotocol/wallet-connector'
import { useQueryClient } from '@tanstack/react-query' import { useQueryClient } from '@tanstack/react-query'
import { MARS_SYMBOL } from 'constants/appConstants'
import { import {
useBlockHeight, useBlockHeight,
useDepositAndDebt, useDepositAndDebt,
@ -18,8 +17,8 @@ import {
useUserDebt, useUserDebt,
useUserIcns, useUserIcns,
} from 'hooks/queries' } from 'hooks/queries'
import { useMarsPrice } from 'hooks/queries/useMarsPrice'
import { usePythVaa } from 'hooks/queries/usePythVaa' import { usePythVaa } from 'hooks/queries/usePythVaa'
import { useSpotPrice } from 'hooks/queries/useSpotPrice'
import { useUserCollaterals } from 'hooks/queries/useUserCollaterals' import { useUserCollaterals } from 'hooks/queries/useUserCollaterals'
import { ReactNode, useEffect, useState } from 'react' import { ReactNode, useEffect, useState } from 'react'
import useStore from 'store' import useStore from 'store'
@ -52,7 +51,6 @@ export const CommonContainer = ({ children }: CommonContainerProps) => {
const networkConfig = useStore((s) => s.networkConfig) const networkConfig = useStore((s) => s.networkConfig)
const marketDeposits = useStore((s) => s.marketDeposits) const marketDeposits = useStore((s) => s.marketDeposits)
const marketInfo = useStore((s) => s.marketInfo) const marketInfo = useStore((s) => s.marketInfo)
const marketIncentiveInfo = useStore((s) => s.marketIncentiveInfo)
const migrationInProgress = useStore((s) => s.migrationInProgress) const migrationInProgress = useStore((s) => s.migrationInProgress)
const redBankState = useStore((s) => s.redBankState) const redBankState = useStore((s) => s.redBankState)
const rpc = useStore((s) => s.networkConfig.rpcUrl) const rpc = useStore((s) => s.networkConfig.rpcUrl)
@ -145,7 +143,6 @@ export const CommonContainer = ({ children }: CommonContainerProps) => {
userBalancesState, userBalancesState,
exchangeRates, exchangeRates,
marketInfo, marketInfo,
marketIncentiveInfo,
userDebts, userDebts,
userDeposits, userDeposits,
whitelistedAssets, whitelistedAssets,
@ -168,7 +165,7 @@ export const CommonContainer = ({ children }: CommonContainerProps) => {
useUserDebt() useUserDebt()
useUserCollaterals() useUserCollaterals()
useMarsOracle() useMarsOracle()
useSpotPrice(MARS_SYMBOL) useMarsPrice()
useDepositAndDebt() useDepositAndDebt()
useRedBank() useRedBank()
usePythVaa() usePythVaa()

View File

@ -30,15 +30,17 @@ export const CosmosWalletConnectProvider = ({ children }: Props) => {
rpc: networkConfig.rpcUrl, rpc: networkConfig.rpcUrl,
rest: networkConfig.restUrl, rest: networkConfig.restUrl,
}} }}
walletConnectProjectId='d93fdffb159bae5ec87d8fee4cdbb045'
chainIds={supportedChains} chainIds={supportedChains}
closeIcon={<SVG.Close />} closeIcon={<SVG.Close />}
defaultChainId={currentNetwork} defaultChainId={currentNetwork}
enabledWallets={[ enabledWallets={[
WalletID.Keplr, WalletID.Keplr,
WalletID.Xdefi, WalletID.Xdefi,
WalletID.StationWallet, WalletID.Station,
WalletID.Leap, WalletID.Leap,
WalletID.Cosmostation, WalletID.Cosmostation,
WalletID.Vectis,
WalletID.KeplrMobile, WalletID.KeplrMobile,
WalletID.CosmostationMobile, WalletID.CosmostationMobile,
]} ]}

View File

@ -65,7 +65,6 @@ export const ChainSelect = () => {
exchangeRates: [], exchangeRates: [],
assetPricesUSD: [], assetPricesUSD: [],
marketAssetLiquidity: [], marketAssetLiquidity: [],
marketIncentiveInfo: [],
marketInfo: [], marketInfo: [],
userIcns: undefined, userIcns: undefined,
redBankAssets: [], redBankAssets: [],

View File

@ -5,7 +5,7 @@ import { findByDenom } from 'functions'
import { useUserBalance } from 'hooks/queries' import { useUserBalance } from 'hooks/queries'
import { formatValue, lookup } from 'libs/parse' import { formatValue, lookup } from 'libs/parse'
import { truncate } from 'libs/text' import { truncate } from 'libs/text'
import { useCallback, useEffect, useState } from 'react' import { useCallback, useEffect, useMemo, useState } from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import useClipboard from 'react-use-clipboard' import useClipboard from 'react-use-clipboard'
import useStore from 'store' import useStore from 'store'
@ -61,6 +61,11 @@ export const ConnectedButton = () => {
baseCurrency.decimals, baseCurrency.decimals,
) )
const [connectedWalletAddress, connectedWalletIsLedger] = useMemo(() => {
if (!connectedWallet?.account) return ['', false]
return [connectedWallet.account.address, connectedWallet.account.isLedger]
}, [connectedWallet])
useEffect(() => { useEffect(() => {
if (!chainInfo) return if (!chainInfo) return
setIsTestnet( setIsTestnet(
@ -71,10 +76,10 @@ export const ConnectedButton = () => {
}, [chainInfo]) }, [chainInfo])
useEffect(() => { useEffect(() => {
if (userWalletAddress === connectedWallet?.account.address) return if (userWalletAddress === connectedWalletAddress) return
useStore.setState({ useStore.setState({
isLedger: !!connectedWallet?.account.isLedger, isLedger: connectedWalletIsLedger,
userWalletAddress: connectedWallet?.account.address, userWalletAddress: connectedWalletAddress,
marketAssetLiquidity: [], marketAssetLiquidity: [],
marketInfo: [], marketInfo: [],
userIcns: undefined, userIcns: undefined,
@ -82,7 +87,7 @@ export const ConnectedButton = () => {
redBankState: State.INITIALISING, redBankState: State.INITIALISING,
userBalancesState: State.INITIALISING, userBalancesState: State.INITIALISING,
}) })
}, [connectedWallet?.account.address, userWalletAddress]) }, [connectedWalletAddress, connectedWalletIsLedger, userWalletAddress])
return ( return (
<div className={styles.wrapper}> <div className={styles.wrapper}>

View File

@ -10,13 +10,15 @@ import {
Tooltip, Tooltip,
TxLink, TxLink,
} from 'components/common' } from 'components/common'
import { MARS_DECIMALS, MARS_SYMBOL } from 'constants/appConstants' import { MARS_SYMBOL } from 'constants/appConstants'
import { findByDenom } from 'functions'
import { getClaimUserRewardsMsgOptions } from 'functions/messages' import { getClaimUserRewardsMsgOptions } from 'functions/messages'
import { useEstimateFee } from 'hooks/queries' import { useEstimateFee } from 'hooks/queries'
import { lookup, lookupDenomBySymbol, lookupSymbol } from 'libs/parse' import { lookup, lookupSymbol } from 'libs/parse'
import { useCallback, useEffect, useMemo, useState } from 'react' import { useCallback, useEffect, useMemo, useState } from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import useStore from 'store' import useStore from 'store'
import { State } from 'types/enums'
import { QUERY_KEYS } from 'types/enums/queryKeys' import { QUERY_KEYS } from 'types/enums/queryKeys'
import styles from './IncentivesButton.module.scss' import styles from './IncentivesButton.module.scss'
@ -32,9 +34,13 @@ export const IncentivesButton = () => {
// STORE STATE // STORE STATE
// --------------- // ---------------
const client = useStore((s) => s.client) const client = useStore((s) => s.client)
const whitelistedAssets = useStore((s) => s.whitelistedAssets)
const otherAssets = useStore((s) => s.otherAssets) const otherAssets = useStore((s) => s.otherAssets)
const userWalletAddress = useStore((s) => s.userWalletAddress) const userWalletAddress = useStore((s) => s.userWalletAddress)
const networkConfig = useStore((s) => s.networkConfig)
const unclaimedRewards = useStore((s) => s.userUnclaimedRewards) const unclaimedRewards = useStore((s) => s.userUnclaimedRewards)
const convertToDisplayCurrency = useStore((s) => s.convertToDisplayCurrency)
const marsPriceState = useStore((s) => s.marsPriceState)
const incentivesContractAddress = useStore((s) => s.networkConfig.contracts.incentives) const incentivesContractAddress = useStore((s) => s.networkConfig.contracts.incentives)
const chainInfo = useStore((s) => s.chainInfo) const chainInfo = useStore((s) => s.chainInfo)
const executeMsg = useStore((s) => s.executeMsg) const executeMsg = useStore((s) => s.executeMsg)
@ -49,12 +55,13 @@ export const IncentivesButton = () => {
const [response, setResponse] = useState<TxBroadcastResult>() const [response, setResponse] = useState<TxBroadcastResult>()
const [error, setError] = useState<string>() const [error, setError] = useState<string>()
const [hasUnclaimedRewards, setHasUnclaimedRewards] = useState(false) const [hasUnclaimedRewards, setHasUnclaimedRewards] = useState(false)
const [unclaimedRewardsValue, setUnclaimedRewardsValue] = useState(0)
// --------------- // ---------------
// LOCAL VARIABLES // LOCAL VARIABLES
// --------------- // ---------------
const marsDenom = lookupDenomBySymbol(MARS_SYMBOL, otherAssets)
const explorerUrl = chainInfo && SimpleChainInfoList[chainInfo.chainId as ChainInfoID].explorer const explorerUrl = chainInfo && SimpleChainInfoList[chainInfo.chainId as ChainInfoID].explorer
const assets = [...whitelistedAssets, ...otherAssets]
// --------------- // ---------------
// FUNCTIONS // FUNCTIONS
@ -66,8 +73,18 @@ export const IncentivesButton = () => {
}, []) }, [])
useEffect(() => { useEffect(() => {
setHasUnclaimedRewards(Number(unclaimedRewards) > 0) let rewardsValue = 0
}, [unclaimedRewards]) let rewardsAmount = 0
if (marsPriceState !== State.READY) return
unclaimedRewards.forEach((reward) => {
rewardsValue += convertToDisplayCurrency(reward)
rewardsAmount += Number(reward.amount)
})
setUnclaimedRewardsValue(rewardsValue)
setHasUnclaimedRewards(rewardsAmount > 0)
}, [unclaimedRewards, convertToDisplayCurrency, marsPriceState])
const txMsgOptions = useMemo(() => { const txMsgOptions = useMemo(() => {
if (!hasUnclaimedRewards) return if (!hasUnclaimedRewards) return
@ -137,31 +154,39 @@ export const IncentivesButton = () => {
} }
const transactionHash = response?.hash || '' const transactionHash = response?.hash || ''
if (!userWalletAddress) return null if (!userWalletAddress) return null
return ( return (
<div className={styles.wrapper}> <div className={styles.wrapper}>
<button <button
className={classNames( className={classNames(
Number(unclaimedRewards) > 1000000 unclaimedRewardsValue > 1 ? `${styles.button} ${styles.buttonHighlight}` : styles.button,
? `${styles.button} ${styles.buttonHighlight}`
: styles.button,
)} )}
onClick={() => { onClick={() => {
setShowDetails(!showDetails) setShowDetails(!showDetails)
}} }}
> >
<SVG.Logo /> {networkConfig.hasMultiAssetIncentives ? (
<span>
<AnimatedNumber <AnimatedNumber
amount={Number(unclaimedRewards) / 1e6} amount={unclaimedRewardsValue}
minDecimals={2} minDecimals={2}
maxDecimals={2} maxDecimals={2}
className={styles.marsAmount} prefix='$'
/> />
{MARS_SYMBOL} ) : (
</span> <>
<SVG.Logo />
<span>
<AnimatedNumber
className={styles.marsAmount}
amount={Number(unclaimedRewards[0]?.amount ?? 0) / 1e6}
minDecimals={2}
maxDecimals={2}
/>
</span>
{MARS_SYMBOL}
</>
)}
</button> </button>
{showDetails && ( {showDetails && (
@ -181,36 +206,48 @@ export const IncentivesButton = () => {
<TxLink hash={transactionHash} link={`${explorerUrl}/txs/${transactionHash}`} /> <TxLink hash={transactionHash} link={`${explorerUrl}/txs/${transactionHash}`} />
</div> </div>
) : ( ) : (
<div className={styles.container}> <>
<div className={styles.position}> {unclaimedRewards.map((rewards, index) => {
<div className={styles.label}> const asset = findByDenom(assets, rewards.denom)
<p className={styles.token}>{lookupSymbol(marsDenom, otherAssets)}</p> if (!asset) return null
<p className={styles.subhead}>{t('redbank.redBankRewards')}</p> return (
</div> <div className={styles.container} key={index}>
<div className={styles.value}> <div className={styles.position}>
<AnimatedNumber <div className={styles.label}>
className={styles.tokenAmount} <p className={styles.token}>{lookupSymbol(asset.denom, assets)}</p>
amount={lookup(Number(unclaimedRewards) || 0, MARS_SYMBOL, MARS_DECIMALS)} <p className={styles.subhead}>{t('redbank.redBankRewards')}</p>
maxDecimals={MARS_DECIMALS} </div>
minDecimals={2} <div className={styles.value}>
/> <AnimatedNumber
<DisplayCurrency className={styles.tokenAmount}
className={styles.tokenValue} amount={lookup(
coin={{ Number(rewards.amount) || 0,
amount: unclaimedRewards, asset.symbol,
denom: marsDenom, asset.decimals,
}} )}
/> maxDecimals={asset.decimals}
</div> minDecimals={2}
</div> />
</div> <DisplayCurrency
className={styles.tokenValue}
coin={{
amount: rewards.amount,
denom: asset.denom,
}}
/>
</div>
</div>
</div>
)
})}
</>
)} )}
<div className={styles.claimButton}> <div className={styles.claimButton}>
<Button <Button
disabled={disabled} disabled={disabled}
showProgressIndicator={fetching} showProgressIndicator={fetching}
text={ text={
Number(unclaimedRewards) > 0 && !disabled hasUnclaimedRewards && !disabled
? t('incentives.claimRewards') ? t('incentives.claimRewards')
: t('incentives.nothingToClaim') : t('incentives.nothingToClaim')
} }

View File

@ -31,12 +31,13 @@ export const Apr = ({ data }: Props) => {
subtitle: key === 0 ? t('incentives.interestApr') : t('incentives.depositRewards'), subtitle: key === 0 ? t('incentives.interestApr') : t('incentives.depositRewards'),
}) })
}) })
return items return items
} }
useEffect( useEffect(
() => { () => {
const baseData = data.incentiveInfo ? [data, data.incentiveInfo] : [data] const baseData = data.incentiveInfo ? [data, ...data.incentiveInfo] : [data]
setAprData(produceData(baseData)) setAprData(produceData(baseData))
}, },
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps

View File

@ -225,14 +225,7 @@ export const Action = ({
const assetLiquidity = Number(findByDenom(marketAssetLiquidity, denom)?.amount || 0) const assetLiquidity = Number(findByDenom(marketAssetLiquidity, denom)?.amount || 0)
return maxBorrowableAmount(assetLiquidity, availableBalanceBaseCurrency, currentAssetPrice) return maxBorrowableAmount(assetLiquidity, availableBalanceBaseCurrency, currentAssetPrice)
}, [ }, [denom, availableBalanceBaseCurrency, currentAssetPrice, marketAssetLiquidity])
denom,
availableBalanceBaseCurrency,
currentAssetPrice,
marketAssetLiquidity,
baseCurrency.decimals,
currentAsset?.decimals,
])
const repayMax = Math.min(assetBorrowBalance, walletBalance) const repayMax = Math.min(assetBorrowBalance, walletBalance)

View File

@ -21,18 +21,23 @@ export const ActionsRow = ({ row, type }: Props) => {
const redBankAssets = useStore((s) => s.redBankAssets) const redBankAssets = useStore((s) => s.redBankAssets)
const assetPricesUSD = useStore((s) => s.assetPricesUSD) const assetPricesUSD = useStore((s) => s.assetPricesUSD)
const hasBalance = Number(row.original.walletBalance ?? 0) > 0 const hasBalance = Number(row.original.walletBalance ?? 0) > 0
const hasDeposits = Number(row.original.depositBalance ?? 0) > 0 const hasDeposits = Number(row.original.depositBalance ?? 0) > 0
const hasNeverDeposited = Number(balanceSum(redBankAssets, 'depositBalanceBaseCurrency')) === 0 const hasNeverDeposited = Number(balanceSum(redBankAssets, 'depositBalanceBaseCurrency')) === 0
const appUrl = useStore((s) => s.networkConfig.appUrl) || '' const networkConfig = useStore((s) => s.networkConfig)
const appUrl = networkConfig.appUrl
const classes = classNames.bind(styles) const classes = classNames.bind(styles)
const trClasses = classes({ const trClasses = classes({
tr: true, tr: true,
expanded: row.getIsExpanded(), expanded: row.getIsExpanded(),
}) })
const assetID = row.original.id
const assetPrice = assetPricesUSD?.find((asset) => asset.denom === row.original.denom)?.amount const assetPrice = assetPricesUSD?.find((asset) => asset.denom === row.original.denom)?.amount
const fromAsset =
networkConfig.assets.base.denom === row.original.denom
? networkConfig.assets.whitelist[1]
: networkConfig.assets.base
const toAsset = row.original
const assetID = row.original.id
return ( return (
<tr key={row.id} className={trClasses} onClick={() => row.toggleExpanded()}> <tr key={row.id} className={trClasses} onClick={() => row.toggleExpanded()}>
@ -46,7 +51,9 @@ export const ActionsRow = ({ row, type }: Props) => {
window.open( window.open(
getSwapUrl({ getSwapUrl({
baseUrl: appUrl, baseUrl: appUrl,
to: assetID, from: fromAsset,
to: toAsset,
chain: networkConfig.name,
}), }),
) )
}} }}
@ -99,7 +106,9 @@ export const ActionsRow = ({ row, type }: Props) => {
window.open( window.open(
getSwapUrl({ getSwapUrl({
baseUrl: appUrl, baseUrl: appUrl,
to: assetID, from: fromAsset,
to: toAsset,
chain: networkConfig.name,
}), }),
) )
}} }}

View File

@ -73,22 +73,34 @@ export const useDepositColumns = () => {
header: () => ( header: () => (
<TextTooltip text={t('common.apr')} tooltip={t('redbank.tooltips.deposit.apy')} /> <TextTooltip text={t('common.apr')} tooltip={t('redbank.tooltips.deposit.apy')} />
), ),
cell: (info) => cell: (info) => {
info.row.original.borrowEnabled ? ( const isEnabled = info.row.original.borrowEnabled
<TextTooltip const incentives = info.row.original.incentiveInfo
hideStyling let borrowApy = 0
text={
<AnimatedNumber if (!!incentives) {
amount={info.getValue() + Number(info.row.original.incentiveInfo?.apy || 0)} incentives.forEach((incentive) => {
suffix='%' borrowApy += Number(incentive.apy)
abbreviated={false} })
rounded={false} }
className='m'
/> if (isEnabled)
} return (
tooltip={<Apr data={info.row.original} />} <TextTooltip
/> hideStyling
) : ( text={
<AnimatedNumber
amount={info.getValue() + borrowApy}
suffix='%'
abbreviated={false}
rounded={false}
className='m'
/>
}
tooltip={<Apr data={info.row.original} />}
/>
)
return (
<TextTooltip <TextTooltip
text='' text=''
hideUnderline hideUnderline
@ -97,7 +109,8 @@ export const useDepositColumns = () => {
symbol: info.row.original.symbol, symbol: info.row.original.symbol,
})} })}
/> />
), )
},
}), }),
columnHelper.accessor('depositCap', { columnHelper.accessor('depositCap', {
enableSorting: enableSorting, enableSorting: enableSorting,

View File

@ -180,6 +180,9 @@ export const RedbankAction = React.memo(
} }
const handleClose = () => { const handleClose = () => {
queryClient.invalidateQueries([QUERY_KEYS.REDBANK])
queryClient.invalidateQueries([QUERY_KEYS.USER_DEPOSIT])
queryClient.invalidateQueries([QUERY_KEYS.USER_DEBT])
reset() reset()
// path on redbank action will always be /redbank/deposit/<denom> etce // path on redbank action will always be /redbank/deposit/<denom> etce
@ -236,10 +239,7 @@ export const RedbankAction = React.memo(
error={error} error={error}
handleClose={handleClose} handleClose={handleClose}
onSuccess={() => { onSuccess={() => {
queryClient.invalidateQueries([QUERY_KEYS.USER_DEPOSIT])
queryClient.invalidateQueries([QUERY_KEYS.REDBANK])
queryClient.invalidateQueries([QUERY_KEYS.USER_BALANCE]) queryClient.invalidateQueries([QUERY_KEYS.USER_BALANCE])
queryClient.invalidateQueries([QUERY_KEYS.USER_DEBT])
}} }}
response={response} response={response}
title={t('common.summaryOfTheTransaction')} title={t('common.summaryOfTheTransaction')}

101
src/configs/neutron-1.ts Normal file
View File

@ -0,0 +1,101 @@
import { ChainInfoID } from '@marsprotocol/wallet-connector'
import atom from 'images/atom.svg'
import axlusdc from 'images/axlusdc.svg'
import mars from 'images/mars.svg'
import ntrn from 'images/ntrn.svg'
import osmo from 'images/osmo.svg'
import colors from 'styles/_assets.module.scss'
export const ASSETS: NetworkAssets = {
ntrn: {
symbol: 'NTRN',
name: 'Neutron',
id: 'NTRN',
denom: 'untrn',
color: colors.ntrn,
logo: ntrn,
decimals: 6,
priceFeedId: 'a8e6517966a52cb1df864b2764f3629fde3f21d2b640b5c572fcd654cbccd65e',
},
axlusdc: {
symbol: 'USDC.axl',
name: 'Axelar USDC',
id: 'axlUSDC',
denom: 'ibc/F082B65C88E4B6D5EF1DB243CDA1D331D002759E938A0F5CD3FFDC5D53B3E349',
color: colors.usdc,
decimals: 6,
logo: axlusdc,
priceFeedId: 'eaa020c61cc479712813461ce153894a96a6c00b21ed0cfc2798d1f9a9e9c94a',
},
atom: {
symbol: 'ATOM',
name: 'Atom',
id: 'ATOM',
denom: 'ibc/C4CFF46FD6DE35CA4CF4CE031E643C8FDC9BA4B99AE598E9B0ED98FE3A2319F9',
color: colors.atom,
logo: atom,
decimals: 6,
priceFeedId: 'b00b60f88b03a6a625a8d1c048c3f66653edf217439983d037e7222c4e612819',
},
}
const OTHER_ASSETS: { [denom: string]: OtherAsset } = {
mars: {
symbol: 'MARS',
id: 'MARS',
name: 'Mars',
denom: 'ibc/9598CDEB7C6DB7FC21E746C8E0250B30CD5154F39CA111A9D4948A4362F638BD',
color: colors.mars,
logo: mars,
decimals: 6,
},
osmo: {
symbol: 'OSMO',
name: 'Osmosis',
id: 'OSMO',
denom: 'uosmo',
color: colors.osmo,
logo: osmo,
decimals: 6,
priceFeedId: '5867f5683c757393a0670ef0f701490950fe93fdb006d181c8265a831ac0c5c6',
},
usd: {
symbol: '',
prefix: '$',
name: 'US Dollar',
denom: 'usd',
color: '',
logo: '',
decimals: 2,
},
}
export const NETWORK_CONFIG: NetworkConfig = {
name: ChainInfoID.Neutron,
displayName: 'Neutron',
hiveUrl:
process.env.NEXT_PUBLIC_NEUTRON_GQL ??
'https://neutron.rpc.p2p.world/qgrnU6PsQZA8F9S5Fb8Fn3tV3kXmMBl2M9bcc9jWLjQy8p/hive/graphql',
rpcUrl: process.env.NEXT_PUBLIC_NEUTRON_RPC ?? 'https://rpc-kralum.neutron-1.neutron.org',
restUrl: process.env.NEXT_PUBLIC_NEUTRON_REST ?? 'https://rest-kralum.neutron-1.neutron.org',
usdPriceUrl: 'https://xc-mainnet.pyth.network/api/',
chainIcon: ntrn,
contracts: {
redBank: 'neutron1n97wnm7q6d2hrcna3rqlnyqw2we6k0l8uqvmyqq6gsml92epdu7quugyph',
incentives: 'neutron1aszpdh35zsaz0yj80mz7f5dtl9zq5jfl8hgm094y0j0vsychfekqxhzd39',
oracle: 'neutron1dwp6m7pdrz6rnhdyrx5ha0acsduydqcpzkylvfgspsz60pj2agxqaqrr7g',
pyth: 'neutron1m2emc93m9gpwgsrsf2vylv9xvgqh654630v7dfrhrkmr5slly53spg85wv',
},
assets: {
base: ASSETS.ntrn,
whitelist: [ASSETS.axlusdc, ASSETS.ntrn, ASSETS.atom],
other: [OTHER_ASSETS.usd, OTHER_ASSETS.mars, OTHER_ASSETS.osmo],
currencies: [OTHER_ASSETS.usd, ASSETS.axlusdc, ASSETS.ntrn, ASSETS.atom, OTHER_ASSETS.mars],
},
displayCurrency: OTHER_ASSETS.usd,
appUrl: 'https://neutron.astroport.fi/swap',
isFieldsEnabled: false,
hasMultiAssetIncentives: true,
}
export const VAULT_CONFIGS: Vault[] = []

View File

@ -3,7 +3,6 @@ import atom from 'images/atom.svg'
import axl from 'images/axl.svg' import axl from 'images/axl.svg'
import axlusdc from 'images/axlusdc.svg' import axlusdc from 'images/axlusdc.svg'
import mars from 'images/mars.svg' import mars from 'images/mars.svg'
import nusdc from 'images/nusdc.svg'
import osmo from 'images/osmo.svg' import osmo from 'images/osmo.svg'
import colors from 'styles/_assets.module.scss' import colors from 'styles/_assets.module.scss'
@ -36,6 +35,7 @@ const ASSETS: NetworkAssets = {
color: colors.axl, color: colors.axl,
logo: axl, logo: axl,
decimals: 6, decimals: 6,
priceFeedId: '60144b1d5c9e9851732ad1d9760e3485ef80be39b984f6bf60f82b28a2b7f126',
}, },
axlusdc: { axlusdc: {
symbol: 'USDC.axl', symbol: 'USDC.axl',
@ -47,16 +47,6 @@ const ASSETS: NetworkAssets = {
logo: axlusdc, logo: axlusdc,
priceFeedId: 'eaa020c61cc479712813461ce153894a96a6c00b21ed0cfc2798d1f9a9e9c94a', priceFeedId: 'eaa020c61cc479712813461ce153894a96a6c00b21ed0cfc2798d1f9a9e9c94a',
}, },
nusdc: {
symbol: 'USDC.n',
name: 'Noble USDC',
id: 'nUSDC',
denom: 'ibc/B3504E092456BA618CC28AC671A71FB08C6CA0FD0BE7C8A5B5A3E2DD933CC9E4',
color: colors.usdc,
decimals: 6,
logo: nusdc,
priceFeedId: 'eaa020c61cc479712813461ce153894a96a6c00b21ed0cfc2798d1f9a9e9c94a',
},
} }
const OTHER_ASSETS: { [denom: string]: OtherAsset } = { const OTHER_ASSETS: { [denom: string]: OtherAsset } = {
@ -68,7 +58,6 @@ const OTHER_ASSETS: { [denom: string]: OtherAsset } = {
color: colors.mars, color: colors.mars,
logo: mars, logo: mars,
decimals: 6, decimals: 6,
poolId: 9,
}, },
usd: { usd: {
symbol: '', symbol: '',
@ -95,14 +84,14 @@ export const NETWORK_CONFIG: NetworkConfig = {
contracts: { contracts: {
redBank: 'osmo1dl4rylasnd7mtfzlkdqn2gr0ss4gvyykpvr6d7t5ylzf6z535n9s5jjt8u', redBank: 'osmo1dl4rylasnd7mtfzlkdqn2gr0ss4gvyykpvr6d7t5ylzf6z535n9s5jjt8u',
incentives: 'osmo1zyz57xf82963mcsgqu3hq5y0h9mrltm4ttq2qe5mjth9ezp3375qe0sm7d', incentives: 'osmo1zyz57xf82963mcsgqu3hq5y0h9mrltm4ttq2qe5mjth9ezp3375qe0sm7d',
oracle: 'osmo1tx9987hjkx3kc9jvxmdzaf9uz8ukzscl88c476r7854205rkhecsc20tnk', oracle: 'osmo1khe29uw3t85nmmp3mtr8dls7v2qwsfk3tndu5h4w5g2r5tzlz5qqarq2e2',
creditManager: 'osmo15ywk53ck3wp6tnqgedfd8cnfx7fuhz9dr583hw8scp0xjgw46m0sf3kyyp', creditManager: 'osmo15ywk53ck3wp6tnqgedfd8cnfx7fuhz9dr583hw8scp0xjgw46m0sf3kyyp',
accountNft: 'osmo1ye2rntzz9qmxgv7eg09supww6k6xs0y0sekcr3x5clp087fymn4q3y33s4', accountNft: 'osmo1ye2rntzz9qmxgv7eg09supww6k6xs0y0sekcr3x5clp087fymn4q3y33s4',
pyth: 'osmo12u2vqdecdte84kg6c3d40nwzjsya59hsj048n687m9q3t6wdmqgsq6zrlx', pyth: 'osmo12u2vqdecdte84kg6c3d40nwzjsya59hsj048n687m9q3t6wdmqgsq6zrlx',
}, },
assets: { assets: {
base: ASSETS.osmo, base: ASSETS.osmo,
whitelist: [ASSETS.osmo, ASSETS.atom, ASSETS.axl, ASSETS.axlusdc, ASSETS.nusdc], whitelist: [ASSETS.osmo, ASSETS.atom, ASSETS.axl, ASSETS.axlusdc],
other: [OTHER_ASSETS.usd, OTHER_ASSETS.mars], other: [OTHER_ASSETS.usd, OTHER_ASSETS.mars],
currencies: [ currencies: [
OTHER_ASSETS.usd, OTHER_ASSETS.usd,
@ -110,7 +99,6 @@ export const NETWORK_CONFIG: NetworkConfig = {
ASSETS.atom, ASSETS.atom,
ASSETS.axl, ASSETS.axl,
ASSETS.axlusdc, ASSETS.axlusdc,
ASSETS.nusdc,
OTHER_ASSETS.mars, OTHER_ASSETS.mars,
], ],
}, },
@ -121,21 +109,21 @@ export const NETWORK_CONFIG: NetworkConfig = {
export const VAULT_CONFIGS: Vault[] = [ export const VAULT_CONFIGS: Vault[] = [
{ {
address: 'osmo1q40xvrzpldwq5he4ftsf7zm2jf80tj373qaven38yqrvhex8r9rs8n94kv', address: 'osmo1m45ap4rq4m2mfjkcqu9ks9mxmyx2hvx0cdca9sjmrg46q7lghzqqhxxup5',
name: { name: 'OSMO-USDC.n LP', unlockDuration: 1, unlockTimeframe: 'day' }, name: { name: 'OSMO-ATOM LP', unlockDuration: 1, unlockTimeframe: 'day' },
denoms: { denoms: {
primary: 'uosmo', primary: 'uosmo',
secondary: 'ibc/B3504E092456BA618CC28AC671A71FB08C6CA0FD0BE7C8A5B5A3E2DD933CC9E4', secondary: 'ibc/A8C2D23A1E6F95DA4E48BA349667E322BD7A6C996D8A4AAE8BA72E190F3D1477',
lpToken: 'gamm/pool/6', lpToken: 'gamm/pool/12',
}, },
symbols: { symbols: {
primary: 'OSMO', primary: 'OSMO',
secondary: 'USDC.n', secondary: 'ATOM',
}, },
color: colors.usdc, color: colors.usdc,
lockup: 86400 * 1, lockup: 86400 * 1,
provider: 'Apollo vault', provider: 'Apollo vault',
description: { maxLeverage: 1.43, lpName: 'OSMO-USDC.n' }, description: { maxLeverage: 1.43, lpName: 'OSMO-ATOM' },
ltv: { ltv: {
max: 0.295, max: 0.295,
contract: 0.3, contract: 0.3,
@ -150,48 +138,20 @@ export const VAULT_CONFIGS: Vault[] = [
}, },
{ {
address: 'osmo14lu7m4ganxs20258dazafrjfaulmfxruq9n0r0th90gs46jk3tuqwfkqwn', address: 'osmo14lu7m4ganxs20258dazafrjfaulmfxruq9n0r0th90gs46jk3tuqwfkqwn',
name: { name: 'OSMO-USDC.n LP', unlockDuration: 7, unlockTimeframe: 'days' }, name: { name: 'OSMO-USDC.axl LP', unlockDuration: 7, unlockTimeframe: 'days' },
denoms: { denoms: {
primary: 'uosmo', primary: 'uosmo',
secondary: 'ibc/B3504E092456BA618CC28AC671A71FB08C6CA0FD0BE7C8A5B5A3E2DD933CC9E4', secondary: 'ibc/6F34E1BD664C36CE49ACC28E60D62559A5F96C4F9A6CCE4FC5A67B2852E24CFE',
lpToken: 'gamm/pool/6', lpToken: 'gamm/pool/5',
}, },
symbols: { symbols: {
primary: 'OSMO', primary: 'OSMO',
secondary: 'USDC.n', secondary: 'USDC.axl',
}, },
color: colors.usdc, color: colors.usdc,
lockup: 86400 * 7, lockup: 86400 * 7,
provider: 'Apollo vault', provider: 'Apollo vault',
description: { maxLeverage: 1.43, lpName: 'OSMO-USDC.n' }, description: { maxLeverage: 1.43, lpName: 'OSMO-USDC.axl' },
ltv: {
max: 0.295,
contract: 0.3,
liq: 0.4,
},
apy: {
apys: null,
fees: null,
total: null,
vaultAddress: '',
},
},
{
address: 'osmo1fmq9hw224fgz8lk48wyd0gfg028kvvzggt6c3zvnaqkw23x68cws5nd5em',
name: { name: 'OSMO-USDC.n LP', unlockDuration: 14, unlockTimeframe: 'days' },
denoms: {
primary: 'uosmo',
secondary: 'ibc/B3504E092456BA618CC28AC671A71FB08C6CA0FD0BE7C8A5B5A3E2DD933CC9E4',
lpToken: 'gamm/pool/6',
},
symbols: {
primary: 'OSMO',
secondary: 'USDC.n',
},
color: colors.usdc,
lockup: 86400 * 14,
provider: 'Apollo vault',
description: { maxLeverage: 1.43, lpName: 'OSMO-USDC.n' },
ltv: { ltv: {
max: 0.295, max: 0.295,
contract: 0.3, contract: 0.3,

View File

@ -90,7 +90,6 @@ const OTHER_ASSETS: { [denom: string]: OtherAsset } = {
color: colors.mars, color: colors.mars,
logo: mars, logo: mars,
decimals: 6, decimals: 6,
poolId: 907,
}, },
usd: { usd: {
symbol: '', symbol: '',
@ -166,11 +165,11 @@ export const VAULT_CONFIGS: Vault[] = [
color: '#6f7390', color: '#6f7390',
lockup: 86400 * 14, lockup: 86400 * 14,
provider: 'Apollo vault', provider: 'Apollo vault',
description: { maxLeverage: 2.7, lpName: 'OSMO-ATOM' }, description: { maxLeverage: 3.7, lpName: 'OSMO-ATOM' },
ltv: { ltv: {
max: 0.625, max: 0.725,
contract: 0.63, contract: 0.73,
liq: 0.65, liq: 0.75,
}, },
apy: { apy: {
apys: null, apys: null,
@ -194,11 +193,11 @@ export const VAULT_CONFIGS: Vault[] = [
color: '#478edc', color: '#478edc',
lockup: 86400 * 14, lockup: 86400 * 14,
provider: 'Apollo vault', provider: 'Apollo vault',
description: { maxLeverage: 2.86, lpName: 'OSMO-USDC.axl' }, description: { maxLeverage: 4, lpName: 'OSMO-USDC.axl' },
ltv: { ltv: {
max: 0.645, max: 0.745,
contract: 0.65, contract: 0.75,
liq: 0.66, liq: 0.77,
}, },
apy: { apy: {
apys: null, apys: null,
@ -222,11 +221,11 @@ export const VAULT_CONFIGS: Vault[] = [
color: '#a446db', color: '#a446db',
lockup: 86400 * 14, lockup: 86400 * 14,
provider: 'Apollo vault', provider: 'Apollo vault',
description: { maxLeverage: 2.56, lpName: 'stATOM-ATOM' }, description: { maxLeverage: 2.78, lpName: 'stATOM-ATOM' },
ltv: { ltv: {
max: 0.6, max: 0.635,
contract: 0.61, contract: 0.64,
liq: 0.625, liq: 0.65,
}, },
apy: { apy: {
apys: null, apys: null,
@ -250,11 +249,11 @@ export const VAULT_CONFIGS: Vault[] = [
color: colors.wbtc, color: colors.wbtc,
lockup: 86400 * 14, lockup: 86400 * 14,
provider: 'Apollo vault', provider: 'Apollo vault',
description: { maxLeverage: 2.44, lpName: 'OSMO-WBTC.axl' }, description: { maxLeverage: 4, lpName: 'OSMO-WBTC.axl' },
ltv: { ltv: {
max: 0.58, max: 0.745,
contract: 0.59, contract: 0.75,
liq: 0.62, liq: 0.77,
}, },
apy: { apy: {
apys: null, apys: null,
@ -278,11 +277,11 @@ export const VAULT_CONFIGS: Vault[] = [
color: colors.weth, color: colors.weth,
lockup: 86400 * 14, lockup: 86400 * 14,
provider: 'Apollo vault', provider: 'Apollo vault',
description: { maxLeverage: 2.86, lpName: 'OSMO-WETH.axl' }, description: { maxLeverage: 4, lpName: 'OSMO-WETH.axl' },
ltv: { ltv: {
max: 0.645, max: 0.745,
contract: 0.65, contract: 0.75,
liq: 0.67, liq: 0.77,
}, },
apy: { apy: {
apys: null, apys: null,

View File

@ -3,6 +3,7 @@ import atom from 'images/atom.svg'
import axlusdc from 'images/axlusdc.svg' import axlusdc from 'images/axlusdc.svg'
import mars from 'images/mars.svg' import mars from 'images/mars.svg'
import ntrn from 'images/ntrn.svg' import ntrn from 'images/ntrn.svg'
import osmo from 'images/osmo.svg'
import colors from 'styles/_assets.module.scss' import colors from 'styles/_assets.module.scss'
export const ASSETS: NetworkAssets = { export const ASSETS: NetworkAssets = {
@ -14,6 +15,7 @@ export const ASSETS: NetworkAssets = {
color: colors.ntrn, color: colors.ntrn,
logo: ntrn, logo: ntrn,
decimals: 6, decimals: 6,
priceFeedId: 'a8e6517966a52cb1df864b2764f3629fde3f21d2b640b5c572fcd654cbccd65e',
}, },
atom: { atom: {
symbol: 'ATOM', symbol: 'ATOM',
@ -23,15 +25,17 @@ export const ASSETS: NetworkAssets = {
color: colors.atom, color: colors.atom,
logo: atom, logo: atom,
decimals: 6, decimals: 6,
priceFeedId: 'b00b60f88b03a6a625a8d1c048c3f66653edf217439983d037e7222c4e612819',
}, },
axlusdc: { axlusdc: {
symbol: 'USDC.axl', symbol: 'USDC.axl',
name: 'Axelar USDC', name: 'Axelar USDC',
id: 'axlUSDC', id: 'axlUSDC',
denom: 'ibc/EFB00E728F98F0C4BBE8CA362123ACAB466EDA2826DC6837E49F4C1902F21BBA', denom: 'ibc/F91EA2C0A23697A1048E08C2F787E3A58AC6F706A1CD2257A504925158CFC0F3',
color: colors.usdc, color: colors.usdc,
decimals: 6, decimals: 6,
logo: axlusdc, logo: axlusdc,
priceFeedId: 'eaa020c61cc479712813461ce153894a96a6c00b21ed0cfc2798d1f9a9e9c94a',
}, },
} }
@ -40,11 +44,21 @@ const OTHER_ASSETS: { [denom: string]: OtherAsset } = {
symbol: 'MARS', symbol: 'MARS',
id: 'MARS', id: 'MARS',
name: 'Mars', name: 'Mars',
denom: 'ibc/FAD9EE91F499D275D9135F95F52D59D90C621B8438A9CFF1757BB886EEE90E3E', denom: 'ibc/584A4A23736884E0C198FD1EE932455A9357A492A7B94324E4A02B5628687831',
color: colors.mars, color: colors.mars,
logo: mars, logo: mars,
decimals: 6, decimals: 6,
}, },
osmo: {
symbol: 'OSMO',
name: 'Osmosis',
id: 'OSMO',
denom: 'uosmo',
color: colors.osmo,
logo: osmo,
decimals: 6,
priceFeedId: '5867f5683c757393a0670ef0f701490950fe93fdb006d181c8265a831ac0c5c6',
},
usd: { usd: {
symbol: '', symbol: '',
prefix: '$', prefix: '$',
@ -64,21 +78,24 @@ export const NETWORK_CONFIG: NetworkConfig = {
'https://testnet-neutron-gql.marsprotocol.io/graphql', 'https://testnet-neutron-gql.marsprotocol.io/graphql',
rpcUrl: process.env.NEXT_PUBLIC_NEUTRON_TEST_RPC ?? 'https://rpc-palvus.pion-1.ntrn.tech/', rpcUrl: process.env.NEXT_PUBLIC_NEUTRON_TEST_RPC ?? 'https://rpc-palvus.pion-1.ntrn.tech/',
restUrl: process.env.NEXT_PUBLIC_NEUTRON_TEST_REST ?? 'https://rest-palvus.pion-1.ntrn.tech/', restUrl: process.env.NEXT_PUBLIC_NEUTRON_TEST_REST ?? 'https://rest-palvus.pion-1.ntrn.tech/',
usdPriceUrl: 'https://xc-mainnet.pyth.network/api/',
chainIcon: ntrn, chainIcon: ntrn,
contracts: { contracts: {
redBank: 'neutron15dld0kmz0zl89zt4yeks4gy8mhmawy3gp4x5rwkcgkj5krqvu9qs4q7wve', redBank: 'neutron1q53jr6wwus0c6g5had2zs6fzzachu5zun0c6etxuyarh5w7phxpq4wf39z',
incentives: 'neutron1t8fectc2ntxhuee2f9ty2mxh8l0ykzm6yxfsp9k35vdktksm2vfsd2d6rl', incentives: 'neutron1pg2fxw87fkzfwyn8q45hes4mmlt4ywjg53hf655mh83edd9yq65quqe07u',
oracle: 'neutron1nx9txtmpmkt58gxka20z72wdkguw4n0606zkeqvelv7q7uc06zmsym3qgx', oracle: 'neutron1u3lmzs3zhhhlvkmrnq9u4ep6pgqp3gxawt3xg82hl9jydwmug7jsgmhjrn',
pyth: 'neutron1f86ct5az9qpz2hqfd5uxru02px2a3tz5zkw7hugd7acqq496dcms22ehpy',
}, },
assets: { assets: {
base: ASSETS.ntrn, base: ASSETS.ntrn,
whitelist: [ASSETS.ntrn, ASSETS.atom, ASSETS.axlusdc], whitelist: [ASSETS.ntrn, ASSETS.atom, ASSETS.axlusdc],
other: [OTHER_ASSETS.usd, OTHER_ASSETS.mars], other: [OTHER_ASSETS.usd, OTHER_ASSETS.mars, OTHER_ASSETS.osmo],
currencies: [OTHER_ASSETS.usd, ASSETS.ntrn, ASSETS.atom, ASSETS.axlusdc, OTHER_ASSETS.mars], currencies: [OTHER_ASSETS.usd, ASSETS.ntrn, ASSETS.atom, ASSETS.axlusdc, OTHER_ASSETS.mars],
}, },
displayCurrency: OTHER_ASSETS.usd, displayCurrency: OTHER_ASSETS.usd,
appUrl: 'https://app.astroport.fi/swap', appUrl: 'https://testnet-neutron.astroport.fi/swap',
isFieldsEnabled: false, isFieldsEnabled: false,
hasMultiAssetIncentives: true,
} }
export const VAULT_CONFIGS: Vault[] = [] export const VAULT_CONFIGS: Vault[] = []

View File

@ -37,6 +37,7 @@ export const TERMS_OF_SERVICE = 'termsOfService'
/* chains */ /* chains */
export const SUPPORTED_CHAINS: { chainId: ChainInfoID; type: 'testnet' | 'mainnet' }[] = [ export const SUPPORTED_CHAINS: { chainId: ChainInfoID; type: 'testnet' | 'mainnet' }[] = [
{ chainId: ChainInfoID.Osmosis1, type: 'mainnet' }, { chainId: ChainInfoID.Osmosis1, type: 'mainnet' },
{ chainId: ChainInfoID.Neutron, type: 'mainnet' },
{ chainId: ChainInfoID.OsmosisTestnet, type: 'testnet' }, { chainId: ChainInfoID.OsmosisTestnet, type: 'testnet' },
{ chainId: ChainInfoID.NeutronTestnet, type: 'testnet' }, { chainId: ChainInfoID.NeutronTestnet, type: 'testnet' },
] ]

View File

@ -1,19 +1,34 @@
import { ChainInfoID } from '@marsprotocol/wallet-connector'
type Options = { type Options = {
from?: string from: Asset
to: string to: Asset
baseUrl: string baseUrl: string
chain?: ChainInfoID
} }
export const getSwapUrl = (options: Options) => { export const getSwapUrl = (options: Options) => {
const { from, to, baseUrl } = options const { from, to, baseUrl, chain } = options
let fromName = from let fromName: string
let toName = to let toName: string
if (!fromName) fromName = 'OSMO' if (!chain) return '#'
if (fromName === to) fromName = 'ATOM'
if (to === 'axlUSDC') toName = 'USDC'
if (to === 'axlWBTC') toName = 'WBTC'
if (to === 'axlWETH') toName = 'ETH'
return `${baseUrl}?from=${fromName}&to=${toName}` if (chain === ChainInfoID.Osmosis1 || chain === ChainInfoID.OsmosisTestnet) {
fromName = from.id
toName = to.id
if (fromName === to.id) fromName = 'ATOM'
if (to.id === 'axlUSDC') toName = 'USDC'
if (to.id === 'axlWBTC') toName = 'WBTC'
if (to.id === 'axlWETH') toName = 'ETH'
return `${baseUrl}?from=${fromName}&to=${toName}`
}
if (chain === ChainInfoID.Neutron || chain === ChainInfoID.NeutronTestnet) {
fromName = from.denom.replace('/', '%2F')
toName = to.denom.replace('/', '%2F')
return `${baseUrl}?from=${fromName}&to=${toName}`
}
} }

View File

@ -46,7 +46,6 @@ export const getDepositDebtQuery = (
} }
}`, }`,
) )
return query return query
}) })

View File

@ -1,7 +1,10 @@
export const getIncentiveQuery = (denom: string) => { export const getIncentiveQuery = (denom: string, hasMultiAssetIncentives: boolean) => {
const queryMethod = hasMultiAssetIncentives ? 'active_emissions' : 'asset_incentive'
const queryKey = hasMultiAssetIncentives ? 'collateral_denom' : 'denom'
return `{ return `{
asset_incentive: { ${queryMethod}: {
denom: "${denom}" ${queryKey}: "${denom}"
} }
}` }`
} }

View File

@ -12,6 +12,7 @@ export const getRedbankQuery = (
address: string, address: string,
redBankContractAddress: string, redBankContractAddress: string,
incentivesContractAddress: string, incentivesContractAddress: string,
hasMultiAssetIncentives: boolean,
whitelistedAssets?: Asset[], whitelistedAssets?: Asset[],
) => { ) => {
const wasmQueries = whitelistedAssets?.map((asset: Asset) => { const wasmQueries = whitelistedAssets?.map((asset: Asset) => {
@ -38,7 +39,7 @@ export const getRedbankQuery = (
getContractQuery( getContractQuery(
incentiveKey, incentiveKey,
incentivesContractAddress || '', incentivesContractAddress || '',
getIncentiveQuery(asset.denom || ''), getIncentiveQuery(asset.denom || '', hasMultiAssetIncentives),
) )
return query return query
}) })

View File

@ -6,12 +6,12 @@ export { useEditPosition } from './useEditPosition'
export { useEstimateFarmFee } from './useEstimateFarmFee' export { useEstimateFarmFee } from './useEstimateFarmFee'
export { useEstimateFee } from './useEstimateFee' export { useEstimateFee } from './useEstimateFee'
export { useMarsOracle } from './useMarsOracle' export { useMarsOracle } from './useMarsOracle'
export { useMarsPrice } from './useMarsPrice'
export { useProvideLiquidity } from './useProvideLiquidity' export { useProvideLiquidity } from './useProvideLiquidity'
export { usePythVaa } from './usePythVaa' export { usePythVaa } from './usePythVaa'
export { useRedBank } from './useRedBank' export { useRedBank } from './useRedBank'
export { useRepayPosition } from './useRepayPosition' export { useRepayPosition } from './useRepayPosition'
export { useRequestUnlockPosition } from './useRequestUnlockPosition' export { useRequestUnlockPosition } from './useRequestUnlockPosition'
export { useSpotPrice } from './useSpotPrice'
export { useUnlockMessages } from './useUnlockMessages' export { useUnlockMessages } from './useUnlockMessages'
export { useUsdPrice } from './useUsdPrice' export { useUsdPrice } from './useUsdPrice'
export { useUserBalance } from './useUserBalance' export { useUserBalance } from './useUserBalance'

View File

@ -11,6 +11,8 @@ export interface DepositAndDebtData {
OSMODebt: string OSMODebt: string
ATOMDeposits: string ATOMDeposits: string
ATOMDebt: string ATOMDebt: string
ASTRODeposits: string
ASTRODebt: string
AXLDeposits: string AXLDeposits: string
AXLDebt: string AXLDebt: string
JUNODeposits: string JUNODeposits: string

View File

@ -9,7 +9,6 @@ export const useMarsOracle = () => {
const hiveUrl = useStore((s) => s.networkConfig.hiveUrl) const hiveUrl = useStore((s) => s.networkConfig.hiveUrl)
const oracleAddress = useStore((s) => s.networkConfig.contracts.oracle) const oracleAddress = useStore((s) => s.networkConfig.contracts.oracle)
const whitelistedAssets = useStore((s) => s.whitelistedAssets) || [] const whitelistedAssets = useStore((s) => s.whitelistedAssets) || []
const basePriceState = useStore((s) => s.basePriceState)
const processMarsOracleQuery = useStore((s) => s.processMarsOracleQuery) const processMarsOracleQuery = useStore((s) => s.processMarsOracleQuery)
const setExchangeRatesState = useStore((s) => s.setExchangeRatesState) const setExchangeRatesState = useStore((s) => s.setExchangeRatesState)
@ -42,7 +41,7 @@ export const useMarsOracle = () => {
[QUERY_KEYS.MARS_ORACLE], [QUERY_KEYS.MARS_ORACLE],
async () => { async () => {
return await request( return await request(
hiveUrl!, hiveUrl,
gql` gql`
query MarsOracle { query MarsOracle {
oracle: wasm { oracle: wasm {
@ -59,7 +58,7 @@ export const useMarsOracle = () => {
) )
}, },
{ {
enabled: !!hiveUrl && !!oracleAddress && basePriceState === State.READY, enabled: !!hiveUrl && !!oracleAddress,
staleTime: 30000, staleTime: 30000,
refetchInterval: 30000, refetchInterval: 30000,
onError: () => setExchangeRatesState(State.ERROR), onError: () => setExchangeRatesState(State.ERROR),

View File

@ -7,44 +7,34 @@ import useStore from 'store'
import { State } from 'types/enums' import { State } from 'types/enums'
import { QUERY_KEYS } from 'types/enums/queryKeys' import { QUERY_KEYS } from 'types/enums/queryKeys'
const poolsEndpoint = 'osmosis/gamm/v1beta1/pools/' const poolsEndpoint = `${process.env.NEXT_PUBLIC_OSMOSIS_REST}osmosis/gamm/v1beta1/pools/`
export const useSpotPrice = (symbol: string) => { export const useMarsPrice = () => {
const networkConfig = useStore((s) => s.networkConfig) const networkConfig = useStore((s) => s.networkConfig)
const baseCurrency = networkConfig.assets.base
const displayCurrency = networkConfig.displayCurrency const displayCurrency = networkConfig.displayCurrency
const exchangeRates = useStore((s) => s.exchangeRates) const exchangeRates = useStore((s) => s.exchangeRates)
const assetPricesUSD = useStore((s) => s.assetPricesUSD) const assetPricesUSD = useStore((s) => s.assetPricesUSD)
const exchangeRatesState = useStore((s) => s.assetPricesUSDState) const exchangeRatesState = useStore((s) => s.assetPricesUSDState)
const basePriceState = useStore((s) => s.assetPricesUSDState) const asset = useAsset({ symbol: 'MARS' })
const asset = useAsset({ symbol }) const marsOsmosDenom = 'ibc/573FCD90FACEE750F55A8864EF7D38265F07E5A9273FA0E8DAFD39951332B580'
const lcd = networkConfig.restUrl ?? '' const marsPoolId = 907
const poolBase = asset?.poolBase
? exchangeRates?.find((ratesAsset) => ratesAsset.denom === asset.poolBase)
: true
useQuery<PoolResponse>( useQuery<PoolResponse>(
[QUERY_KEYS.SPOT_PRICE, asset?.poolId], [QUERY_KEYS.SPOT_PRICE, marsPoolId],
async () => { async () => {
return fetch(`${lcd}${poolsEndpoint}${asset?.poolId}`).then(async (response) => { return fetch(`${poolsEndpoint}${marsPoolId}`).then(async (response) => {
const data = await response.json() const data = await response.json()
return data return data
}) })
}, },
{ {
enabled: enabled: !!asset && exchangeRatesState === State.READY,
!!asset &&
!!asset.poolId &&
!!poolBase &&
basePriceState === State.READY &&
exchangeRatesState === State.READY,
staleTime: 30000, staleTime: 30000,
refetchInterval: 30000, refetchInterval: 30000,
onSuccess: (data) => { onSuccess: (data) => {
if (!asset || !assetPricesUSD) return if (!asset || !assetPricesUSD) return
const poolDataAssets = data.pool.pool_assets const poolDataAssets = data.pool.pool_assets
const assetFirst = poolDataAssets[0].token.denom === asset.denom const assetFirst = poolDataAssets[0].token.denom === marsOsmosDenom
const primaryAsset = poolDataAssets[assetFirst ? 0 : 1] const primaryAsset = poolDataAssets[assetFirst ? 0 : 1]
const secondaryAsset = poolDataAssets[assetFirst ? 1 : 0] const secondaryAsset = poolDataAssets[assetFirst ? 1 : 0]
@ -74,28 +64,23 @@ export const useSpotPrice = (symbol: string) => {
amount: rate.times(secondaryRate).toString(), amount: rate.times(secondaryRate).toString(),
} }
if (typeof poolBase === 'object') { useStore.setState({
const baseRate = Number(rate.toString()) * Number(poolBase.amount) exchangeRates: updateExchangeRate(coinExchangeRate, exchangeRates || []),
coinExchangeRate.amount = baseRate.toString() })
useStore.setState({
exchangeRates: updateExchangeRate(coinExchangeRate, exchangeRates || []), const secondaryAssetPrice = assetPricesUSD.find(
}) (asset) => asset.denom === secondaryAsset.token.denom,
} else {
useStore.setState({
exchangeRates: updateExchangeRate(coinExchangeRate, exchangeRates || []),
})
}
const baseCurrencyPrice = assetPricesUSD.find(
(asset) => asset.denom === baseCurrency.denom,
)?.amount )?.amount
if (!baseCurrencyPrice) return if (!secondaryAssetPrice) return
const assetPriceCoin = { const assetPriceCoin = {
denom: coinExchangeRate.denom, denom: coinExchangeRate.denom,
amount: new BigNumber(coinExchangeRate.amount).times(baseCurrencyPrice).toString(), amount: new BigNumber(coinExchangeRate.amount).times(secondaryAssetPrice).toString(),
} }
useStore.setState({ useStore.setState({
assetPricesUSD: updateAssetPrices(assetPriceCoin, assetPricesUSD || []), assetPricesUSD: updateAssetPrices(assetPriceCoin, assetPricesUSD || []),
marsPriceState: State.READY,
}) })
} }
}, },

View File

@ -6,14 +6,17 @@ import { State } from 'types/enums'
import { QUERY_KEYS } from 'types/enums/queryKeys' import { QUERY_KEYS } from 'types/enums/queryKeys'
export const useRedBank = () => { export const useRedBank = () => {
const hiveUrl = useStore((s) => s.networkConfig.hiveUrl) const networkConfig = useStore((s) => s.networkConfig)
const userWalletAddress = useStore((s) => s.userWalletAddress) const userWalletAddress = useStore((s) => s.userWalletAddress)
const whitelistedAssets = useStore((s) => s.whitelistedAssets) const whitelistedAssets = useStore((s) => s.whitelistedAssets)
const redbankAddress = useStore((s) => s.networkConfig.contracts.redBank)
const incentivesAddress = useStore((s) => s.networkConfig.contracts.incentives)
const processRedBankQuery = useStore((s) => s.processRedBankQuery) const processRedBankQuery = useStore((s) => s.processRedBankQuery)
const setRedBankState = useStore((s) => s.setRedBankState) const setRedBankState = useStore((s) => s.setRedBankState)
const hiveUrl = networkConfig.hiveUrl
const redbankAddress = networkConfig.contracts.redBank
const incentivesAddress = networkConfig.contracts.incentives
const hasMultiAssetIncentives = networkConfig.hasMultiAssetIncentives
useQuery<RedBankData>( useQuery<RedBankData>(
[QUERY_KEYS.REDBANK], [QUERY_KEYS.REDBANK],
async () => async () =>
@ -24,6 +27,7 @@ export const useRedBank = () => {
userWalletAddress, userWalletAddress,
redbankAddress, redbankAddress,
incentivesAddress, incentivesAddress,
!!hasMultiAssetIncentives,
whitelistedAssets, whitelistedAssets,
)} )}
`, `,

View File

@ -10,17 +10,19 @@ export const useUsdPrice = () => {
let usdPriceUrl = useStore((s) => s.networkConfig.usdPriceUrl) let usdPriceUrl = useStore((s) => s.networkConfig.usdPriceUrl)
let hasPriceFeeds = false let hasPriceFeeds = false
const whitelistedAssets = useStore((s) => s.whitelistedAssets) const whitelistedAssets = useStore((s) => s.whitelistedAssets)
const otherAssets = useStore((s) => s.otherAssets)
const assetPricesUSD = useStore((s) => s.assetPricesUSD ?? []) const assetPricesUSD = useStore((s) => s.assetPricesUSD ?? [])
const basePriceState = useStore((s) => s.basePriceState) const basePriceState = useStore((s) => s.basePriceState)
const baseAsset = useStore((s) => s.networkConfig.assets.base) const baseAsset = useStore((s) => s.networkConfig.assets.base)
if (!usdPriceUrl && basePriceState !== State.READY) { const assets = [...whitelistedAssets, ...otherAssets]
useStore.setState({ basePriceState: State.READY })
}
if (usdPriceUrl && whitelistedAssets) { if (!usdPriceUrl && basePriceState !== State.READY)
useStore.setState({ basePriceState: State.READY })
if (usdPriceUrl && assets) {
const pythApiUrl = new URL(usdPriceUrl + 'latest_price_feeds') const pythApiUrl = new URL(usdPriceUrl + 'latest_price_feeds')
whitelistedAssets.forEach((asset) => { assets.forEach((asset) => {
if (asset.priceFeedId) { if (asset.priceFeedId) {
hasPriceFeeds = true hasPriceFeeds = true
pythApiUrl.searchParams.append('ids[]', asset.priceFeedId) pythApiUrl.searchParams.append('ids[]', asset.priceFeedId)
@ -32,20 +34,18 @@ export const useUsdPrice = () => {
useQuery<CoinPriceData[]>( useQuery<CoinPriceData[]>(
[QUERY_KEYS.USD_PRICE], [QUERY_KEYS.USD_PRICE],
async () => { async () => {
if (!usdPriceUrl || !whitelistedAssets || !hasPriceFeeds) return if (!usdPriceUrl || !assets || !hasPriceFeeds) return
const res = await fetch(usdPriceUrl) const res = await fetch(usdPriceUrl)
return res.json() return res.json()
}, },
{ {
enabled: !!usdPriceUrl || !!whitelistedAssets, enabled: !!usdPriceUrl || !!assets,
staleTime: 30000, staleTime: 30000,
refetchInterval: 30000, refetchInterval: 30000,
onSuccess: (data) => { onSuccess: (data) => {
let updatedAssetPricesUSD: Coin[] = [] let updatedAssetPricesUSD: Coin[] = []
data.map((priceData) => { data.map((priceData) => {
const denom = whitelistedAssets.find( const denom = assets.find((asset) => asset?.priceFeedId === priceData.id)?.denom
(asset) => asset?.priceFeedId === priceData.id,
)?.denom
if (denom) { if (denom) {
const amount = new BigNumber(priceData.price.price) const amount = new BigNumber(priceData.price.price)

30
src/images/astro.svg Normal file
View File

@ -0,0 +1,30 @@
<svg viewBox="0 0 400 400" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="200" cy="200" r="146.41" transform="rotate(-30 200 200)" fill="url(#paint0_linear)" />
<g clip-path="url(#clip0)">
<path
d="M219.326 213.744V213.704C208.627 213.49 200.02 204.963 200.02 194.456C200.02 204.94 191.444 213.455 180.777 213.699V213.744C191.444 213.988 200.02 222.502 200.02 232.986C200.016 222.485 208.627 213.957 219.326 213.744Z"
fill="white"
/>
<path
d="M215.362 117.865H185.558C181.715 117.865 178.196 120.008 176.435 123.422L108.567 254.96C106.592 258.792 109.372 263.358 113.687 263.358H147.957C151.836 263.358 155.381 261.175 157.125 257.716L175.354 221.556C177.832 216.639 177.792 210.832 175.243 205.951L162.125 180.821C158.557 173.988 163.522 165.807 171.235 165.816L229.752 165.878C237.465 165.887 242.412 174.077 238.831 180.901L224.067 209.054C222.528 211.984 222.501 215.479 223.992 218.435L243.795 257.721C245.539 261.18 249.084 263.363 252.963 263.363H287.233C291.548 263.363 294.328 258.797 292.353 254.964L224.485 123.422C222.724 120.008 219.201 117.865 215.362 117.865Z"
fill="white"
/>
</g>
<defs>
<linearGradient
id="paint0_linear"
x1="200"
y1="53.5898"
x2="200"
y2="346.41"
gradientUnits="userSpaceOnUse"
>
<stop offset="0.140625" stop-color="#1A9FD5" />
<stop offset="0.71875" stop-color="#5643F2" />
<stop offset="0.993058" stop-color="#2233E2" />
</linearGradient>
<clipPath id="clip0">
<rect width="185.085" height="145.489" fill="white" transform="translate(107.918 117.865)" />
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -14,7 +14,7 @@ export function getCouncilLink(currentNetwork: ChainInfoID, currentProvider?: Wa
case WalletID.Leap: case WalletID.Leap:
return DocURL.COUNCIL_LEAP return DocURL.COUNCIL_LEAP
case WalletID.StationWallet || WalletID.StationWalletMobile: case WalletID.Station:
return DocURL.COUNCIL_STATION return DocURL.COUNCIL_STATION
default: default:

View File

@ -1,17 +1,11 @@
import BN from 'bignumber.js' import BN from 'bignumber.js'
import { isNil } from 'ramda'
export const plus = (a?: BN.Value, b?: BN.Value): string => new BN(a || 0).plus(b || 0).toString() export const plus = (a?: BN.Value, b?: BN.Value): string => new BN(a || 0).plus(b || 0).toString()
export const times = (a?: BN.Value, b?: BN.Value): string => new BN(a || 0).times(b || 0).toString() export const times = (a?: BN.Value, b?: BN.Value): string => new BN(a || 0).times(b || 0).toString()
export const min = (array: BN.Value[]): string =>
BN.min.apply(null, array.filter(isFinite)).toString()
export const ceil = (n: BN.Value): string => new BN(n).integerValue(BN.ROUND_CEIL).toString() export const ceil = (n: BN.Value): string => new BN(n).integerValue(BN.ROUND_CEIL).toString()
export const isFinite = (n?: BN.Value): boolean => !isNil(n) && new BN(n).isFinite()
export const safeGetInputPercentage = (value: number) => { export const safeGetInputPercentage = (value: number) => {
let increasePercentage = 0 let increasePercentage = 0
if (value >= 0) { if (value >= 0) {

View File

@ -1,3 +1,7 @@
import {
NETWORK_CONFIG as neutronMainnetConfig,
VAULT_CONFIGS as neutronMainnetVaultConfig,
} from '../configs/neutron-1'
import { import {
NETWORK_CONFIG as osmosisTestnetConfig, NETWORK_CONFIG as osmosisTestnetConfig,
VAULT_CONFIGS as osmosisTestnetVaultConfig, VAULT_CONFIGS as osmosisTestnetVaultConfig,
@ -15,6 +19,10 @@ export const getNetworkConfig = (network: string): NetworkConfig => {
let networkConfig let networkConfig
switch (network) { switch (network) {
case 'neutron-1':
networkConfig = neutronMainnetConfig
break
case 'osmo-test-5': case 'osmo-test-5':
networkConfig = osmosisTestnetConfig networkConfig = osmosisTestnetConfig
break break
@ -34,6 +42,10 @@ export const getNetworkVaultConfig = (network: string): Vault[] => {
let vaultConfig let vaultConfig
switch (network) { switch (network) {
case 'neutron-1':
vaultConfig = neutronMainnetVaultConfig
break
case 'osmo-test-5': case 'osmo-test-5':
vaultConfig = osmosisTestnetVaultConfig vaultConfig = osmosisTestnetVaultConfig
break break

View File

@ -23,14 +23,16 @@ export const redBankData: RedBankData = {
deposit_enabled: true, deposit_enabled: true,
borrow_enabled: true, borrow_enabled: true,
deposit_cap: '10000000000000', deposit_cap: '10000000000000',
}, incentives: [
OSMOMarketIncentive: { {
denom: 'uosmo', denom: 'ibc/2E7368A14AC9AB7870F32CFEA687551C5064FA861868EDF7437BC877358A81F9',
emission_per_second: '231482', emission_per_second: '231482',
start_time: 1675793700, start_time: 1675793700,
duration: 2592000, duration: 2592000,
index: '0.000000139928505817', index: '0.000000139928505817',
last_updated: 1678369905, last_updated: 1678369905,
},
],
}, },
ATOMMarket: { ATOMMarket: {
denom: 'ibc/27394FB092D2ECCD56123C74F36E4C1F926001CEADA9CA97EA622B25F41E5EB2', denom: 'ibc/27394FB092D2ECCD56123C74F36E4C1F926001CEADA9CA97EA622B25F41E5EB2',
@ -54,14 +56,16 @@ export const redBankData: RedBankData = {
deposit_enabled: true, deposit_enabled: true,
borrow_enabled: true, borrow_enabled: true,
deposit_cap: '350000000000', deposit_cap: '350000000000',
}, incentives: [
ATOMMarketIncentive: { {
denom: 'ibc/27394FB092D2ECCD56123C74F36E4C1F926001CEADA9CA97EA622B25F41E5EB2', denom: 'ibc/2E7368A14AC9AB7870F32CFEA687551C5064FA861868EDF7437BC877358A81F9',
emission_per_second: '106095', emission_per_second: '106095',
start_time: 1675793700, start_time: 1675793700,
duration: 2592000, duration: 2592000,
index: '0.000001514531327288', index: '0.000001514531327288',
last_updated: 1678369638, last_updated: 1678369638,
},
],
}, },
stATOMMarket: { stATOMMarket: {
denom: 'ibc/C140AFD542AE77BD7DCC83F13FDD8C5E5BB8C4929785E6EC2F4C636F98F17901', denom: 'ibc/C140AFD542AE77BD7DCC83F13FDD8C5E5BB8C4929785E6EC2F4C636F98F17901',
@ -85,14 +89,16 @@ export const redBankData: RedBankData = {
deposit_enabled: true, deposit_enabled: true,
borrow_enabled: false, borrow_enabled: false,
deposit_cap: '350000000000', deposit_cap: '350000000000',
}, incentives: [
stATOMMarketIncentive: { {
denom: 'ibc/C140AFD542AE77BD7DCC83F13FDD8C5E5BB8C4929785E6EC2F4C636F98F17901', denom: 'ibc/2E7368A14AC9AB7870F32CFEA687551C5064FA861868EDF7437BC877358A81F9',
emission_per_second: '106095', emission_per_second: '106095',
start_time: 1675793700, start_time: 1675793700,
duration: 2592000, duration: 2592000,
index: '0.000001514531327288', index: '0.000001514531327288',
last_updated: 1678369638, last_updated: 1678369638,
},
],
}, },
axlUSDCMarket: { axlUSDCMarket: {
denom: 'ibc/D189335C6E4A68B513C10AB227BF1C1D38C746766278BA3EEB4FB14124F1D858', denom: 'ibc/D189335C6E4A68B513C10AB227BF1C1D38C746766278BA3EEB4FB14124F1D858',
@ -116,14 +122,16 @@ export const redBankData: RedBankData = {
deposit_enabled: true, deposit_enabled: true,
borrow_enabled: true, borrow_enabled: true,
deposit_cap: '1500000000000', deposit_cap: '1500000000000',
}, incentives: [
axlUSDCMarketIncentive: { {
denom: 'ibc/D189335C6E4A68B513C10AB227BF1C1D38C746766278BA3EEB4FB14124F1D858', denom: 'ibc/2E7368A14AC9AB7870F32CFEA687551C5064FA861868EDF7437BC877358A81F9',
emission_per_second: '48225', emission_per_second: '48225',
start_time: 1675793700, start_time: 1675793700,
duration: 2592000, duration: 2592000,
index: '0.000000143742920378', index: '0.000000143742920378',
last_updated: 1678369620, last_updated: 1678369620,
},
],
}, },
unclaimedRewards: '4679062', unclaimedRewards: '4679062',
}, },

View File

@ -3,6 +3,7 @@ import 'index.scss'
import 'styles/App.scss' import 'styles/App.scss'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query' import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import BigNumber from 'bignumber.js'
import { import {
CommonContainer, CommonContainer,
CosmosWalletConnectProvider, CosmosWalletConnectProvider,
@ -13,6 +14,7 @@ import type { AppProps, NextWebVitalsMetric } from 'next/app'
import Head from 'next/head' import Head from 'next/head'
import { Suspense } from 'react' import { Suspense } from 'react'
BigNumber.config({ EXPONENTIAL_AT: 1e9 })
const queryClient = new QueryClient() const queryClient = new QueryClient()
const App = ({ Component, pageProps }: AppProps) => { const App = ({ Component, pageProps }: AppProps) => {

View File

@ -78,12 +78,7 @@ const RedBank = () => {
) )
useEffect(() => { useEffect(() => {
if ( if (redBankAssets.length === 0 || marketInfo.length === 0 || redBankState === State.READY)
redBankAssets.length === 0 ||
marketInfo.length === 0 ||
userBalancesState !== State.READY ||
redBankState === State.READY
)
return return
setRedBankState(State.READY) setRedBankState(State.READY)
}, [redBankAssets, marketInfo, redBankState, userBalancesState, setRedBankState]) }, [redBankAssets, marketInfo, redBankState, userBalancesState, setRedBankState])

View File

@ -46,7 +46,7 @@ export interface CommonSlice {
slippage: number slippage: number
tutorialSteps: { redbank: number; fields: number } tutorialSteps: { redbank: number; fields: number }
userBalances: Coin[] userBalances: Coin[]
userUnclaimedRewards: string userUnclaimedRewards: Coin[]
userMarsTokenBalances: Coin[] userMarsTokenBalances: Coin[]
userWalletAddress: string userWalletAddress: string
userIcns?: string userIcns?: string

View File

@ -9,6 +9,7 @@ export interface OraclesSlice {
exchangeRatesState: State exchangeRatesState: State
assetPricesUSD?: Coin[] assetPricesUSD?: Coin[]
assetPricesUSDState: State assetPricesUSDState: State
marsPriceState: State
basePriceState: State basePriceState: State
migrationInProgress: boolean migrationInProgress: boolean
pythVaa: VaaInformation pythVaa: VaaInformation

View File

@ -6,7 +6,6 @@ export interface RedBankSlice {
// VARIABLES // VARIABLES
// ------------------ // ------------------
marketAssetLiquidity: Coin[] marketAssetLiquidity: Coin[]
marketIncentiveInfo: MarketIncentive[]
marketInfo: Market[] marketInfo: Market[]
redBankAssets: RedBankAsset[] redBankAssets: RedBankAsset[]
redBankState: State redBankState: State
@ -18,10 +17,10 @@ export interface RedBankSlice {
// ------------------ // ------------------
// GENERAL FUNCTIONS // GENERAL FUNCTIONS
// ------------------ // ------------------
calculateIncentiveAssetInfo: ( calculateIncentiveAssetsInfo: (
incentive?: MarketIncentive | Record<string, any>, incentive?: MarketIncentive | Record<string, any>,
marketTotalLiquidity?: Coin, marketTotalLiquidity?: Coin,
) => IncentiveInfo | undefined ) => IncentiveInfo[] | undefined
computeMarketLiquidity: (denom: string) => number computeMarketLiquidity: (denom: string) => number
findUserDebt: (denom: string) => number findUserDebt: (denom: string) => number
findUserDeposit: (denom: string) => number findUserDeposit: (denom: string) => number

View File

@ -52,7 +52,7 @@ const commonSlice = (
tutorialSteps: { redbank: 1, fields: 1 }, tutorialSteps: { redbank: 1, fields: 1 },
userBalances: [], userBalances: [],
userMarsTokenBalances: [], userMarsTokenBalances: [],
userUnclaimedRewards: '0', userUnclaimedRewards: [],
userWalletAddress: '', userWalletAddress: '',
vaultConfigs: [], vaultConfigs: [],
whitelistedAssets: [], whitelistedAssets: [],
@ -189,7 +189,7 @@ const commonSlice = (
marketDeposits: [], marketDeposits: [],
userBalances: [], userBalances: [],
userMarsTokenBalances: [], userMarsTokenBalances: [],
userUnclaimedRewards: '0', userUnclaimedRewards: [],
}) })
}, },
queryContract: async <T>(contractAddress: string, queryMsg: object, retries = 3) => { queryContract: async <T>(contractAddress: string, queryMsg: object, retries = 3) => {

View File

@ -2,7 +2,7 @@ import { Coin } from '@cosmjs/stargate'
import BigNumber from 'bignumber.js' import BigNumber from 'bignumber.js'
import { updateExchangeRate } from 'functions' import { updateExchangeRate } from 'functions'
import { updateAssetPrices } from 'functions/updateAssetPrices' import { updateAssetPrices } from 'functions/updateAssetPrices'
import { findAssetByDenom, lookup, magnify } from 'libs/parse' import { findAssetByDenom, lookup } from 'libs/parse'
import isEqual from 'lodash.isequal' import isEqual from 'lodash.isequal'
import { OraclesSlice } from 'store/interfaces/oracles.interface' import { OraclesSlice } from 'store/interfaces/oracles.interface'
import { Store } from 'store/interfaces/store.interface' import { Store } from 'store/interfaces/store.interface'
@ -16,6 +16,7 @@ const oraclesSlice = (set: NamedSet<Store>, get: GetState<Store>): OraclesSlice
// ------------------ // ------------------
exchangeRatesState: State.INITIALISING, exchangeRatesState: State.INITIALISING,
assetPricesUSDState: State.INITIALISING, assetPricesUSDState: State.INITIALISING,
marsPriceState: State.INITIALISING,
basePriceState: State.INITIALISING, basePriceState: State.INITIALISING,
migrationInProgress: false, migrationInProgress: false,
pythVaa: { pythVaa: {
@ -98,9 +99,7 @@ const oraclesSlice = (set: NamedSet<Store>, get: GetState<Store>): OraclesSlice
const asset2Price = assetPricesUSD?.find((coin) => coin.denom === denom2)?.amount const asset2Price = assetPricesUSD?.find((coin) => coin.denom === denom2)?.amount
if (asset1Price && asset1 && asset2Price && asset2) { if (asset1Price && asset1 && asset2Price && asset2) {
return new BigNumber(magnify(Number(asset1Price), asset1.decimals)) return new BigNumber(asset1Price).div(asset2Price).toNumber()
.div(magnify(Number(asset2Price), asset2.decimals))
.toNumber()
} }
return 1 return 1
}, },
@ -199,9 +198,11 @@ const oraclesSlice = (set: NamedSet<Store>, get: GetState<Store>): OraclesSlice
const id = asset.id const id = asset.id
const queryResult = pricesQueryResult[`${id}`]?.price ?? '0.00' const queryResult = pricesQueryResult[`${id}`]?.price ?? '0.00'
const isNonUSDOracle = oracleBaseDenom.toLowerCase().indexOf('usd') === -1
// Non-USD denominated oracle prices // Non-USD denominated oracle prices
if (oracleBaseDenom.toLowerCase().indexOf('usd') === -1) { if (isNonUSDOracle) {
if (get().basePriceState !== State.READY) return
const baseCurrencyPrice = assetPricesUSD.find( const baseCurrencyPrice = assetPricesUSD.find(
(assetPrice) => assetPrice.denom === oracleBaseDenom, (assetPrice) => assetPrice.denom === oracleBaseDenom,
) )
@ -225,6 +226,10 @@ const oraclesSlice = (set: NamedSet<Store>, get: GetState<Store>): OraclesSlice
} }
} else { } else {
// USD denominated oracle prices // USD denominated oracle prices
if (asset.denom === get().baseAsset?.denom) {
set({ basePriceState: State.READY })
}
const assetPrice = { const assetPrice = {
denom, denom,
amount: typeof queryResult === 'string' ? queryResult : '0.00', amount: typeof queryResult === 'string' ? queryResult : '0.00',

View File

@ -2,18 +2,17 @@ import { Coin } from '@cosmjs/stargate'
import { MARS_SYMBOL } from 'constants/appConstants' import { MARS_SYMBOL } from 'constants/appConstants'
import { SECONDS_IN_YEAR } from 'constants/timeConstants' import { SECONDS_IN_YEAR } from 'constants/timeConstants'
import { findByDenom } from 'functions' import { findByDenom } from 'functions'
import { lookupDenomBySymbol } from 'libs/parse' import { findAssetByDenom, lookupDenomBySymbol } from 'libs/parse'
import isEqual from 'lodash.isequal' import isEqual from 'lodash.isequal'
import moment from 'moment'
import { RedBankSlice } from 'store/interfaces/redBank.interface' import { RedBankSlice } from 'store/interfaces/redBank.interface'
import { Store } from 'store/interfaces/store.interface' import { Store } from 'store/interfaces/store.interface'
import colors from 'styles/_assets.module.scss'
import { State } from 'types/enums' import { State } from 'types/enums'
import { GetState } from 'zustand' import { GetState } from 'zustand'
import { NamedSet } from 'zustand/middleware' import { NamedSet } from 'zustand/middleware'
const redBankSlice = (set: NamedSet<Store>, get: GetState<Store>): RedBankSlice => ({ const redBankSlice = (set: NamedSet<Store>, get: GetState<Store>): RedBankSlice => ({
marketAssetLiquidity: [], marketAssetLiquidity: [],
marketIncentiveInfo: [],
marketInfo: [], marketInfo: [],
redBankAssets: [], redBankAssets: [],
redBankState: State.INITIALISING, redBankState: State.INITIALISING,
@ -22,30 +21,33 @@ const redBankSlice = (set: NamedSet<Store>, get: GetState<Store>): RedBankSlice
// ------------------ // ------------------
// GENERAL FUNCTIONS // GENERAL FUNCTIONS
// ------------------ // ------------------
calculateIncentiveAssetInfo: ( calculateIncentiveAssetsInfo: (
incentive?: MarketIncentive | Record<string, any>, incentives?: MarketIncentive[] | Record<string, any>,
marketTotalLiquidity?: Coin, marketTotalLiquidity?: Coin,
): IncentiveInfo | undefined => { ): IncentiveInfo[] | undefined => {
const otherAssets = get().otherAssets const assets = [...get().otherAssets, ...get().whitelistedAssets]
const whitelistedAssets = get().whitelistedAssets
const convertToBaseCurrency = get().convertToBaseCurrency const convertToBaseCurrency = get().convertToBaseCurrency
const marsAsset = get().otherAssets?.find((asset) => asset.denom === MARS_SYMBOL) if (!incentives?.length || !marketTotalLiquidity || !assets || !convertToBaseCurrency) return
if (!incentive || !marketTotalLiquidity || !whitelistedAssets || !convertToBaseCurrency) return const incentiveAssetsInfo = incentives.map((incentive: MarketIncentive) => {
const incentiveAsset = findAssetByDenom(incentive.denom, assets)
if (!incentiveAsset) return
const anualEmission = Number(incentive.emission_per_second) * SECONDS_IN_YEAR
const anualEmissionVaule = convertToBaseCurrency({
denom: incentive.denom,
amount: anualEmission.toString(),
})
const liquidityValue = convertToBaseCurrency(marketTotalLiquidity)
const incentiveApr = anualEmissionVaule / liquidityValue
const anualEmission = Number(incentive.emission_per_second) * SECONDS_IN_YEAR return {
const anualEmissionVaule = convertToBaseCurrency({ symbol: incentiveAsset.symbol,
denom: lookupDenomBySymbol(MARS_SYMBOL, otherAssets), color: incentiveAsset.color,
amount: anualEmission.toString(), apy: incentiveApr * 100,
}
}) })
const liquidityValue = convertToBaseCurrency(marketTotalLiquidity)
const incentiveApr = anualEmissionVaule / liquidityValue
return { return incentiveAssetsInfo
symbol: marsAsset?.symbol || MARS_SYMBOL,
color: marsAsset?.color || colors.mars,
apy: incentiveApr * 100,
}
}, },
computeMarketLiquidity: (denom: string) => { computeMarketLiquidity: (denom: string) => {
return Number(get().marketAssetLiquidity.find((asset) => asset.denom === denom)?.amount) || 0 return Number(get().marketAssetLiquidity.find((asset) => asset.denom === denom)?.amount) || 0
@ -87,8 +89,8 @@ const redBankSlice = (set: NamedSet<Store>, get: GetState<Store>): RedBankSlice
const marketLiquidity = (depositLiquidity - debtLiquidity).toString() const marketLiquidity = (depositLiquidity - debtLiquidity).toString()
marketAssetLiquidity.push({ denom: asset.denom, amount: marketLiquidity }) marketAssetLiquidity.push({ denom: asset.denom, amount: marketLiquidity })
const incentiveInfo = get().calculateIncentiveAssetInfo( const incentiveInfo = get().calculateIncentiveAssetsInfo(
findByDenom(get().marketIncentiveInfo, asset.denom), findByDenom(get().marketInfo, asset.denom)?.incentives,
{ denom: asset.denom, amount: depositLiquidity.toString() }, { denom: asset.denom, amount: depositLiquidity.toString() },
) )
@ -134,29 +136,52 @@ const redBankSlice = (set: NamedSet<Store>, get: GetState<Store>): RedBankSlice
processRedBankQuery: (data: RedBankData, whitelistedAssets: Asset[]) => { processRedBankQuery: (data: RedBankData, whitelistedAssets: Asset[]) => {
if (isEqual(data, get().previousRedBankQueryData) && get().marketInfo.length) return if (isEqual(data, get().previousRedBankQueryData) && get().marketInfo.length) return
const userUnclaimedRewards = data.rbwasmkey.unclaimedRewards
const marketInfo: Market[] = [] const marketInfo: Market[] = []
const marketIncentiveInfo: MarketIncentive[] = [] const assets = [...whitelistedAssets, ...get().otherAssets]
const MARS_DENOM = lookupDenomBySymbol(MARS_SYMBOL, assets)
const hasMultiAssetIncentives = get().networkConfig.hasMultiAssetIncentives
whitelistedAssets?.forEach((asset: Asset) => { whitelistedAssets?.forEach((asset: Asset) => {
const denom = asset.denom const denom = asset.denom
const id = asset.id const id = asset.id
const queryResult = data.rbwasmkey const queryResult = data.rbwasmkey
const marketData = { const marketData: Market = {
...queryResult[`${id}Market`], ...queryResult[`${id}Market`],
denom: denom, denom: denom,
incentives: [],
}
if (hasMultiAssetIncentives) {
const marketIncentiveData = queryResult[
`${id}MarketIncentive`
] as MultiAssetMarketIncentive[]
marketIncentiveData.forEach((incentive) => {
marketData.incentives.push({
denom: incentive.denom,
emission_per_second: String(incentive.emission_rate),
})
})
} else {
const marketIncentiveData = {
...queryResult[`${id}MarketIncentive`],
denom: MARS_DENOM,
} as MarketIncentive
const isValid =
marketIncentiveData?.emission_per_second &&
moment(
(marketIncentiveData?.start_time ?? 0) + (marketIncentiveData?.duration ?? 0),
).isBefore(moment.now())
if (isValid) marketData.incentives.push(marketIncentiveData)
} }
marketInfo.push(marketData) marketInfo.push(marketData)
const marketIncentiveData = {
...queryResult[`${id}MarketIncentive`],
denom: denom,
}
marketIncentiveInfo.push(marketIncentiveData)
}) })
const userUnclaimedRewards =
hasMultiAssetIncentives && typeof data.rbwasmkey.unclaimedRewards === 'object'
? data.rbwasmkey.unclaimedRewards
: [{ denom: MARS_DENOM, amount: data.rbwasmkey.unclaimedRewards }]
set({ set({
marketInfo, marketInfo,
marketIncentiveInfo,
previousRedBankQueryData: data, previousRedBankQueryData: data,
userUnclaimedRewards, userUnclaimedRewards,
}) })

View File

@ -7,6 +7,7 @@
atom: $colorTokenATOM; atom: $colorTokenATOM;
axl: $colorTokenAXL; axl: $colorTokenAXL;
usdc: $colorTokenUSDC; usdc: $colorTokenUSDC;
astro: $colorTokenASTRO;
wbtc: $colorTokenWBTC; wbtc: $colorTokenWBTC;
weth: $colorTokenWETH; weth: $colorTokenWETH;
juno: $colorTokenJUNO; juno: $colorTokenJUNO;

View File

@ -39,6 +39,7 @@ $colorTokenStATOM: #e50571;
$colorTokenWBTC: #f09242; $colorTokenWBTC: #f09242;
$colorTokenWETH: #343434; $colorTokenWETH: #343434;
$colorTokenNTRN: #284fe0; $colorTokenNTRN: #284fe0;
$colorTokenASTRO: #2233e2;
$colorGradientOSMO: linear-gradient(to bottom, #3a02e2, #e700ca); $colorGradientOSMO: linear-gradient(to bottom, #3a02e2, #e700ca);
$colorGradientATOM: linear-gradient(to bottom, #2e3148, #6f7390); $colorGradientATOM: linear-gradient(to bottom, #2e3148, #6f7390);

View File

@ -6,6 +6,7 @@ interface Asset {
| 'OSMO' | 'OSMO'
| 'NTRN' | 'NTRN'
| 'ATOM' | 'ATOM'
| 'ASTRO'
| 'AXL' | 'AXL'
| 'JUNO' | 'JUNO'
| 'USDC.axl' | 'USDC.axl'
@ -21,6 +22,7 @@ interface Asset {
| 'axlWBTC' | 'axlWBTC'
| 'axlWETH' | 'axlWETH'
| 'ATOM' | 'ATOM'
| 'ASTRO'
| 'AXL' | 'AXL'
| 'JUNO' | 'JUNO'
| 'stATOM' | 'stATOM'
@ -28,7 +30,6 @@ interface Asset {
contract_addr?: string contract_addr?: string
logo: string logo: string
decimals: number decimals: number
poolId?: number
poolBase?: string poolBase?: string
priceFeedId?: string priceFeedId?: string
} }
@ -56,7 +57,7 @@ interface RedBankAsset extends Asset {
depositBalanceBaseCurrency: number depositBalanceBaseCurrency: number
marketLiquidity: string marketLiquidity: string
isCollateral: boolean isCollateral: boolean
incentiveInfo?: IncentiveInfo incentiveInfo?: IncentiveInfo[]
depositCap: number depositCap: number
depositLiquidity: numnber depositLiquidity: numnber
borrowEnabled: boolean borrowEnabled: boolean

View File

@ -1,6 +1,6 @@
interface HoverItem { interface HoverItem {
color?: string color?: string
name: string name: string
coin: import('@cosmjs/proto-signing').Coin coin: import('@cosmjs/stargate').Coin
negative?: boolean negative?: boolean
} }

View File

@ -24,6 +24,7 @@ interface NetworkConfig {
displayCurrency: displayCurrency displayCurrency: displayCurrency
appUrl: string appUrl: string
isFieldsEnabled: boolean isFieldsEnabled: boolean
hasMultiAssetIncentives?: boolean
} }
interface DisplayCurrency { interface DisplayCurrency {

View File

@ -4,27 +4,29 @@ interface RedBankData {
} }
rbwasmkey: { rbwasmkey: {
OSMOMarket: Market OSMOMarket: Market
OSMOMarketIncentive: MarketIncentive OSMOMarketIncentive: MarketIncentive | MultiAssetMarketIncentive[]
ATOMMarket: Market ATOMMarket: Market
ATOMMarketIncentive: MarketIncentive ATOMMarketIncentive: MarketIncentive | MultiAssetMarketIncentive[]
AXLMarket: Market AXLMarket: Market
AXLMarketIncentive: MarketIncentive AXLMarketIncentive: MarketIncentive | MultiAssetMarketIncentive[]
JUNOMarket: Market JUNOMarket: Market
JUNOMarketIncentive: MarketIncentive JUNOMarketIncentive: MarketIncentive | MultiAssetMarketIncentive[]
ASTROMarket: Market
ASTROMarketIncentive: MarketIncentive | MultiAssetMarketIncentive[]
axlUSDCMarket: Market axlUSDCMarket: Market
axlUSDCMarketIncentive: MarketIncentive axlUSDCMarketIncentive: MarketIncentive | MultiAssetMarketIncentive[]
axlWBTCMarket: Market axlWBTCMarket: Market
axlWBTCMarketIncentive: MarketIncentive axlWBTCMarketIncentive: MarketIncentive | MultiAssetMarketIncentive[]
axlWETHMarket: Market axlWETHMarket: Market
axlWETHMarketIncentive: MarketIncentive axlWETHMarketIncentive: MarketIncentive | MultiAssetMarketIncentive[]
stATOMMarket: Market stATOMMarket: Market
stATOMMarketIncentive: MarketIncentive stATOMMarketIncentive: MarketIncentive | MultiAssetMarketIncentive[]
nUSDCMarket: Market nUSDCMarket: Market
nUSDCMarketIncentive: MarketIncentive nUSDCMarketIncentive: MarketIncentive | MultiAssetMarketIncentive[]
NTRNMarket: Market NTRNMarket: Market
NTRNMarketIncentive: MarketIncentive NTRNMarketIncentive: MarketIncentive | MultiAssetMarketIncentive[]
collateral: UserCollateral[] collateral: UserCollateral[]
unclaimedRewards: string unclaimedRewards: string | Coin[]
} }
} }
@ -45,6 +47,7 @@ interface Market {
deposit_enabled: boolean deposit_enabled: boolean
borrow_enabled: boolean borrow_enabled: boolean
deposit_cap: string deposit_cap: string
incentives: MarketIncentive[]
} }
interface InterestRateModel { interface InterestRateModel {
@ -57,8 +60,13 @@ interface InterestRateModel {
interface MarketIncentive { interface MarketIncentive {
denom: string denom: string
emission_per_second: string emission_per_second: string
index: string index?: string
last_updated: number last_updated?: number
start_time: number start_time?: number
duration: number duration?: number
}
interface MultiAssetMarketIncentive {
denom: string
emission_rate: number
} }

3121
yarn.lock

File diff suppressed because it is too large Load Diff