mirror of
https://github.com/cerc-io/mars-interface.git
synced 2024-11-17 11:19:20 +00:00
feat: updated the wallet connector
This commit is contained in:
parent
6c02a85514
commit
c0b35bf01c
@ -22,7 +22,7 @@
|
||||
"@cosmjs/launchpad": "^0.27.1",
|
||||
"@cosmjs/proto-signing": "^0.29.5",
|
||||
"@cosmjs/stargate": "^0.29.5",
|
||||
"@marsprotocol/wallet-connector": "^1.3.1",
|
||||
"@marsprotocol/wallet-connector": "^1.4.2",
|
||||
"@material-ui/core": "^4.12.4",
|
||||
"@material-ui/icons": "^4.11.3",
|
||||
"@ramonak/react-progress-bar": "^5.0.3",
|
||||
|
@ -1,19 +0,0 @@
|
||||
// This file configures the initialization of Sentry on the browser.
|
||||
// The config you add here will be used whenever a page is visited.
|
||||
// https://docs.sentry.io/platforms/javascript/guides/nextjs/
|
||||
|
||||
import * as Sentry from '@sentry/nextjs'
|
||||
|
||||
const SENTRY_DSN = process.env.SENTRY_DSN || process.env.NEXT_PUBLIC_SENTRY_DSN
|
||||
|
||||
Sentry.init({
|
||||
environment: process.env.NEXT_PUBLIC_SENTRY_ENV,
|
||||
dsn: SENTRY_DSN,
|
||||
// Adjust this value in production, or use tracesSampler for greater control
|
||||
tracesSampleRate: 0.5,
|
||||
// ...
|
||||
// Note: if you want to override the automatic release value, do not set a
|
||||
// `release` value here - use the environment variable `SENTRY_RELEASE`, so
|
||||
// that it will also get attached to your source maps
|
||||
enabled: process.env.NODE_ENV !== 'development',
|
||||
})
|
@ -1,4 +0,0 @@
|
||||
defaults.url=https://sentry.io/
|
||||
defaults.org=delphi-mars
|
||||
defaults.project=mars-dapp
|
||||
cli.executable=../../../.npm/_npx/a8388072043b4cbc/node_modules/@sentry/cli/bin/sentry-cli
|
@ -1,18 +0,0 @@
|
||||
// This file configures the initialization of Sentry on the server.
|
||||
// The config you add here will be used whenever the server handles a request.
|
||||
// https://docs.sentry.io/platforms/javascript/guides/nextjs/
|
||||
|
||||
import * as Sentry from '@sentry/nextjs'
|
||||
|
||||
const SENTRY_DSN = process.env.SENTRY_DSN || process.env.NEXT_PUBLIC_SENTRY_DSN
|
||||
|
||||
Sentry.init({
|
||||
dsn: SENTRY_DSN,
|
||||
// Adjust this value in production, or use tracesSampler for greater control
|
||||
tracesSampleRate: 0.5,
|
||||
// ...
|
||||
// Note: if you want to override the automatic release value, do not set a
|
||||
// `release` value here - use the environment variable `SENTRY_RELEASE`, so
|
||||
// that it will also get attached to your source maps
|
||||
enabled: process.env.NODE_ENV !== 'development',
|
||||
})
|
@ -1,7 +1,6 @@
|
||||
import classNames from 'classnames'
|
||||
import { CircularProgress } from 'components/common'
|
||||
import React from 'react'
|
||||
import { ReactNode } from 'react'
|
||||
import React, { ReactNode } from 'react'
|
||||
|
||||
import styles from './Button.module.scss'
|
||||
|
||||
@ -46,7 +45,7 @@ export const Button = React.forwardRef<any, Props>(
|
||||
styles[size],
|
||||
styles[color],
|
||||
styles[variant],
|
||||
disabled && styles.disabled,
|
||||
(disabled || showProgressIndicator) && styles.disabled,
|
||||
className,
|
||||
)
|
||||
return (
|
||||
|
18
src/components/common/ErrorMessage/ErrorMessage.module.scss
Normal file
18
src/components/common/ErrorMessage/ErrorMessage.module.scss
Normal file
@ -0,0 +1,18 @@
|
||||
@import 'src/styles/master';
|
||||
|
||||
.errorMessage {
|
||||
text-align: left;
|
||||
@include margin(2, 0, -2);
|
||||
display: block;
|
||||
width: 100%;
|
||||
@include typoXS;
|
||||
color: $colorInfoWarning;
|
||||
|
||||
&.center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
&.right {
|
||||
text-align: right;
|
||||
}
|
||||
}
|
14
src/components/common/ErrorMessage/ErrorMessage.tsx
Normal file
14
src/components/common/ErrorMessage/ErrorMessage.tsx
Normal file
@ -0,0 +1,14 @@
|
||||
import classNames from 'classnames'
|
||||
|
||||
import styles from './ErrorMessage.module.scss'
|
||||
|
||||
interface Props {
|
||||
errorMessage?: string
|
||||
alignment?: 'left' | 'center' | 'right'
|
||||
}
|
||||
|
||||
export const ErrorMessage = (props: Props) => {
|
||||
const classes = classNames(styles.errorMessage, props.alignment && styles[props.alignment])
|
||||
|
||||
return props.errorMessage ? <p className={classes}>{props.errorMessage}</p> : null
|
||||
}
|
@ -220,15 +220,6 @@
|
||||
button {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.error {
|
||||
@include margin(2, 0, 0);
|
||||
@include typoS;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
font-weight: $fontWeightSemibold;
|
||||
color: $colorInfoLoss;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,15 @@
|
||||
import { ChainInfoID, SimpleChainInfoList, TxBroadcastResult } from '@marsprotocol/wallet-connector'
|
||||
import { useQueryClient } from '@tanstack/react-query'
|
||||
import classNames from 'classnames'
|
||||
import { AnimatedNumber, Button, DisplayCurrency, SVG, Tooltip, TxLink } from 'components/common'
|
||||
import {
|
||||
AnimatedNumber,
|
||||
Button,
|
||||
DisplayCurrency,
|
||||
ErrorMessage,
|
||||
SVG,
|
||||
Tooltip,
|
||||
TxLink,
|
||||
} from 'components/common'
|
||||
import { MARS_DECIMALS, MARS_SYMBOL } from 'constants/appConstants'
|
||||
import { getClaimUserRewardsMsgOptions } from 'functions/messages'
|
||||
import { useEstimateFee } from 'hooks/queries'
|
||||
@ -36,6 +44,7 @@ export const IncentivesButton = () => {
|
||||
// ---------------
|
||||
const [showDetails, setShowDetails] = useState(false)
|
||||
const [disabled, setDisabled] = useState(true)
|
||||
const [fetching, setFetching] = useState(false)
|
||||
const [submitted, setSubmitted] = useState(false)
|
||||
const [response, setResponse] = useState<TxBroadcastResult>()
|
||||
const [error, setError] = useState<string>()
|
||||
@ -53,6 +62,7 @@ export const IncentivesButton = () => {
|
||||
const onClickAway = useCallback(() => {
|
||||
setShowDetails(false)
|
||||
setResponse(undefined)
|
||||
setError(undefined)
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
@ -64,12 +74,22 @@ export const IncentivesButton = () => {
|
||||
return getClaimUserRewardsMsgOptions()
|
||||
}, [hasUnclaimedRewards])
|
||||
|
||||
const { data: fee } = useEstimateFee({
|
||||
const { data: fee, error: feeError } = useEstimateFee({
|
||||
msg: txMsgOptions?.msg,
|
||||
funds: [],
|
||||
contract: incentivesContractAddress,
|
||||
})
|
||||
|
||||
if (feeError && error !== feeError && !fee) {
|
||||
setError(feeError as string)
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
const isFetching = submitted || (!fee && !response && hasUnclaimedRewards)
|
||||
if (fetching === isFetching) return
|
||||
setFetching(isFetching)
|
||||
}, [submitted, fetching, fee, response, hasUnclaimedRewards])
|
||||
|
||||
useEffect(() => {
|
||||
if (error) {
|
||||
setDisabled(!hasUnclaimedRewards)
|
||||
@ -186,8 +206,8 @@ export const IncentivesButton = () => {
|
||||
)}
|
||||
<div className={styles.claimButton}>
|
||||
<Button
|
||||
disabled={disabled || submitted || (!fee && !response && hasUnclaimedRewards)}
|
||||
showProgressIndicator={(!fee && !response && hasUnclaimedRewards) || submitted}
|
||||
disabled={disabled}
|
||||
showProgressIndicator={fetching}
|
||||
text={
|
||||
Number(unclaimedRewards) > 0 && !disabled
|
||||
? t('incentives.claimRewards')
|
||||
@ -196,7 +216,7 @@ export const IncentivesButton = () => {
|
||||
onClick={() => (submitted ? null : claimRewards())}
|
||||
color='primary'
|
||||
/>
|
||||
{error && <div className={styles.error}>{error}</div>}
|
||||
<ErrorMessage errorMessage={error} alignment='center' />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -153,6 +153,7 @@
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin-bottom: space(3);
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -18,6 +18,7 @@ interface Props {
|
||||
disabled?: boolean
|
||||
amountUntilDepositCap: number
|
||||
activeView: ViewType
|
||||
walletBalance: number
|
||||
inputCallback: (value: number) => void
|
||||
onEnterHandler: () => void
|
||||
setAmountCallback: (value: number) => void
|
||||
@ -33,6 +34,7 @@ export const InputSection = ({
|
||||
disabled,
|
||||
amountUntilDepositCap,
|
||||
activeView,
|
||||
walletBalance,
|
||||
inputCallback,
|
||||
onEnterHandler,
|
||||
setAmountCallback,
|
||||
@ -90,15 +92,14 @@ export const InputSection = ({
|
||||
|
||||
useEffect(
|
||||
() => {
|
||||
if (asset.denom !== baseCurrency.denom || !checkForMaxValue) return
|
||||
if (
|
||||
amount >= maxUsableAmount &&
|
||||
asset.denom === baseCurrency.denom &&
|
||||
!depositWarning &&
|
||||
checkForMaxValue
|
||||
(activeView === ViewType.Repay && walletBalance <= amount) ||
|
||||
(activeView === ViewType.Deposit && amount >= maxUsableAmount)
|
||||
) {
|
||||
setDepositWarning(true)
|
||||
if (!depositWarning) setDepositWarning(true)
|
||||
} else {
|
||||
setDepositWarning(false)
|
||||
if (depositWarning) setDepositWarning(false)
|
||||
}
|
||||
}, // eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
[sliderValue, amount, maxUsableAmount],
|
||||
|
@ -27,7 +27,7 @@
|
||||
opacity: 0.4;
|
||||
|
||||
&.active {
|
||||
filter: grayscale(0);
|
||||
filter: unset;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
@ -37,10 +37,24 @@
|
||||
@include typoXScaps;
|
||||
}
|
||||
|
||||
svg {
|
||||
.icon {
|
||||
width: rem-calc(50);
|
||||
height: rem-calc(50);
|
||||
display: block;
|
||||
|
||||
svg {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
&.redBank {
|
||||
background: url('../../../images/redbank.svg');
|
||||
}
|
||||
|
||||
&.farm {
|
||||
background: url('../../../images/farm.svg');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -20,11 +20,14 @@ export const MobileNav = () => {
|
||||
passHref
|
||||
className={classNames(styles.nav, !router.pathname.includes('farm') && styles.active)}
|
||||
>
|
||||
<SVG.RedBankIcon />
|
||||
<div className={classNames(styles.icon, styles.redBank)} />
|
||||
<span>{t('global.redBank')}</span>
|
||||
</Link>
|
||||
|
||||
<a className={styles.nav} target='_blank' href={networkConfig?.councilUrl} rel='noreferrer'>
|
||||
<div className={styles.icon}>
|
||||
<SVG.CouncilIcon />
|
||||
</div>
|
||||
<span>{t('global.council')}</span>
|
||||
</a>
|
||||
{FIELDS_FEATURE && (
|
||||
@ -33,7 +36,7 @@ export const MobileNav = () => {
|
||||
passHref
|
||||
className={classNames(styles.nav, router.pathname.includes('farm') && styles.active)}
|
||||
>
|
||||
<SVG.FieldsIcon />
|
||||
<div className={classNames(styles.icon, styles.farm)} />
|
||||
<span>{t('global.fields')}</span>
|
||||
</Link>
|
||||
)}
|
||||
|
@ -52,11 +52,14 @@ export const Tutorial = (props: Props) => {
|
||||
}, [tutorialStep, props.step])
|
||||
|
||||
const hideTutorial = () => {
|
||||
localStorage.setItem(
|
||||
props.type === 'fields' ? FIELDS_TUTORIAL_KEY : RED_BANK_TUTORIAL_KEY,
|
||||
'true',
|
||||
)
|
||||
if (props.type === 'fields') {
|
||||
localStorage.setItem(FIELDS_TUTORIAL_KEY, 'true')
|
||||
return
|
||||
}
|
||||
localStorage.setItem(RED_BANK_TUTORIAL_KEY, 'true')
|
||||
useStore.setState({ showRedBankTutorial: false })
|
||||
}
|
||||
|
||||
const handleButtonClick = () => {
|
||||
if (props.step === 3) hideTutorial()
|
||||
setTutorialStep(props.type)
|
||||
|
@ -72,12 +72,6 @@
|
||||
opacity: 0.4;
|
||||
margin-bottom: space(9);
|
||||
}
|
||||
|
||||
.actionButton {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin-bottom: space(3);
|
||||
}
|
||||
}
|
||||
|
||||
.feeTooltipContent {
|
||||
|
@ -8,6 +8,7 @@ import {
|
||||
Card,
|
||||
ConnectButton,
|
||||
DisplayCurrency,
|
||||
ErrorMessage,
|
||||
InputSection,
|
||||
} from 'components/common'
|
||||
import { findByDenom } from 'functions'
|
||||
@ -44,6 +45,7 @@ interface Props {
|
||||
totalBorrowBaseCurrencyAmount: number
|
||||
actionButtonSpec: ModalActionButton
|
||||
submitted: boolean
|
||||
feeError?: string
|
||||
txFee?: Coin
|
||||
activeView: ViewType
|
||||
denom: string
|
||||
@ -64,6 +66,7 @@ export const Action = ({
|
||||
totalBorrowBaseCurrencyAmount,
|
||||
actionButtonSpec,
|
||||
submitted,
|
||||
feeError,
|
||||
txFee,
|
||||
activeView,
|
||||
denom,
|
||||
@ -313,22 +316,22 @@ export const Action = ({
|
||||
|
||||
if (microValue >= maxUsableAmount) microValue = maxUsableAmount
|
||||
setAmountCallback(Number(formatValue(microValue, 0, 0, false, false, false, false, false)))
|
||||
setCapHit(amount > amountUntilDepositCap)
|
||||
setCapHit(amount > amountUntilDepositCap && activeView === ViewType.Deposit)
|
||||
}
|
||||
|
||||
const produceTabActionButton = () => {
|
||||
return (
|
||||
<>
|
||||
<Button
|
||||
color='primary'
|
||||
className={styles.submitButton}
|
||||
disabled={
|
||||
actionButtonSpec.disabled ||
|
||||
(amount > amountUntilDepositCap && activeView === ViewType.Deposit)
|
||||
}
|
||||
disabled={actionButtonSpec.disabled}
|
||||
onClick={() => actionButtonSpec.clickHandler()}
|
||||
showProgressIndicator={actionButtonSpec.fetching}
|
||||
text={actionButtonSpec.text}
|
||||
/>
|
||||
<ErrorMessage errorMessage={feeError} alignment='center' />
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
@ -465,7 +468,7 @@ export const Action = ({
|
||||
actionButton={actionButton}
|
||||
amount={amount}
|
||||
availableText={produceAvailableText()}
|
||||
checkForMaxValue={activeView === ViewType.Deposit}
|
||||
checkForMaxValue={activeView === ViewType.Deposit || activeView === ViewType.Repay}
|
||||
asset={currentAsset}
|
||||
disabled={
|
||||
submitted ||
|
||||
@ -478,6 +481,7 @@ export const Action = ({
|
||||
setAmountCallback={handleInputAmount}
|
||||
amountUntilDepositCap={amountUntilDepositCap}
|
||||
activeView={activeView}
|
||||
walletBalance={walletBalance}
|
||||
/>
|
||||
|
||||
{/* SITUATION COMPARISON */}
|
||||
|
@ -13,6 +13,7 @@ export { CommonContainer } from './Containers/CommonContainer'
|
||||
export { FieldsContainer } from './Containers/FieldsContainer'
|
||||
export { CosmosWalletConnectProvider } from './CosmosWalletConnectProvider/CosmosWalletConnectProvider'
|
||||
export { DisplayCurrency } from './DisplayCurrency/DisplayCurrency'
|
||||
export { ErrorMessage } from './ErrorMessage/ErrorMessage'
|
||||
export { Footer } from './Footer/Footer'
|
||||
export { Connect } from './Header/Connect'
|
||||
export { ConnectButton } from './Header/ConnectButton'
|
||||
|
@ -237,7 +237,7 @@ export const useActiveVaultsColumns = () => {
|
||||
</>
|
||||
)
|
||||
case 'active':
|
||||
const apy = new BigNumber(row.original.position.apy.net).decimalPlaces(2).toNumber()
|
||||
const apy = new BigNumber(row.original.position.apy.net).toNumber()
|
||||
|
||||
const apyData = {
|
||||
total: row.original.apy || 0,
|
||||
|
@ -91,7 +91,7 @@ export const useAvailableVaultsColumns = () => {
|
||||
(asset) => asset.denom === row.original.denoms.secondary,
|
||||
)
|
||||
const maxBorrowRate = Number(borrowAsset?.borrowRate ?? 0) * row.original.ltv.max
|
||||
const minAPY = new BigNumber(row.original.apy).decimalPlaces(2).toNumber()
|
||||
const minAPY = new BigNumber(row.original.apy).toNumber()
|
||||
|
||||
const maxAPY = new BigNumber(minAPY).times(maxLeverage).toNumber() - maxBorrowRate
|
||||
const minDailyAPY = new BigNumber(convertApyToDailyApy(row.original.apy))
|
||||
@ -108,13 +108,22 @@ export const useAvailableVaultsColumns = () => {
|
||||
<>
|
||||
<TextTooltip
|
||||
hideStyling
|
||||
text={<AnimatedNumber amount={minAPY} />}
|
||||
text={
|
||||
<AnimatedNumber
|
||||
amount={Number(formatValue(minAPY, 2, 2, true, false, false, true))}
|
||||
/>
|
||||
}
|
||||
tooltip={<Apy apyData={apyDataNoLev} leverage={1} />}
|
||||
/>
|
||||
<span>-</span>
|
||||
<TextTooltip
|
||||
hideStyling
|
||||
text={<AnimatedNumber amount={maxAPY} suffix='%' />}
|
||||
text={
|
||||
<AnimatedNumber
|
||||
amount={Number(formatValue(maxAPY, 2, 2, true, false, false, true))}
|
||||
suffix='%'
|
||||
/>
|
||||
}
|
||||
tooltip={
|
||||
<Apy apyData={apyDataLev} leverage={ltvToLeverage(row.original.ltv.max)} />
|
||||
}
|
||||
|
@ -216,7 +216,13 @@ export const BreakdownTable = (props: Props) => {
|
||||
<span className='faded'>{t('common.apy')}: </span>
|
||||
<TextTooltip
|
||||
hideStyling
|
||||
text={<AnimatedNumber amount={apy} suffix='%' abbreviated={false} />}
|
||||
text={
|
||||
<AnimatedNumber
|
||||
amount={Number(formatValue(apy, 2, 2, true, false, false, true))}
|
||||
suffix='%'
|
||||
abbreviated={false}
|
||||
/>
|
||||
}
|
||||
tooltip={<Apy apyData={apyData} leverage={currentLeverage} />}
|
||||
/>
|
||||
</div>
|
||||
|
@ -120,7 +120,7 @@ export const RedbankAction = React.memo(
|
||||
}
|
||||
}, [activeView, amount, redBankContractAddress, denom, isMax, userBalances])
|
||||
|
||||
const { data: fee } = useEstimateFee({
|
||||
const { data: fee, error: feeError } = useEstimateFee({
|
||||
msg: txMsgOptions?.msg,
|
||||
funds:
|
||||
activeView === ViewType.Deposit || activeView === ViewType.Repay
|
||||
@ -131,8 +131,8 @@ export const RedbankAction = React.memo(
|
||||
|
||||
const produceActionButtonSpec = (): ModalActionButton => {
|
||||
return {
|
||||
disabled: !Number(amount) || amount === 0 || typeof fee === 'undefined' || submitted,
|
||||
fetching: !!Number(amount) && amount > 0 && typeof fee === 'undefined' && !capHit,
|
||||
disabled: amount === 0 || capHit,
|
||||
fetching: (amount > 0 && typeof fee === 'undefined') || submitted,
|
||||
text: t(`redbank.${activeView.toLowerCase()}`),
|
||||
clickHandler: handleAction,
|
||||
color: 'primary',
|
||||
@ -157,10 +157,14 @@ export const RedbankAction = React.memo(
|
||||
// @ts-ignore
|
||||
funds: txMsgOptions.funds || [],
|
||||
contract: redBankContractAddress,
|
||||
fee,
|
||||
fee: fee,
|
||||
})
|
||||
|
||||
if (res?.response.code !== 0) {
|
||||
setError(res?.rawLogs)
|
||||
} else {
|
||||
setResponse(res)
|
||||
}
|
||||
} catch (error) {
|
||||
const e = error as { message: string }
|
||||
setError(e.message as string)
|
||||
@ -248,6 +252,7 @@ export const RedbankAction = React.memo(
|
||||
) : (
|
||||
<Action
|
||||
actionButtonSpec={produceActionButtonSpec()}
|
||||
feeError={!fee ? (feeError as string) : undefined}
|
||||
activeView={activeView}
|
||||
amount={Number(amount)}
|
||||
borrowAssets={removeZeroBalanceValues(borrowAssets, 'borrowBalance')}
|
||||
|
@ -15,15 +15,6 @@ export const ASSETS: { [denom: string]: Asset } = {
|
||||
hasOraclePrice: true,
|
||||
logo: osmo,
|
||||
},
|
||||
atom: {
|
||||
symbol: 'ATOM',
|
||||
name: 'Atom',
|
||||
denom: 'ibc/27394FB092D2ECCD56123C74F36E4C1F926001CEADA9CA97EA622B25F41E5EB2',
|
||||
color: colors.atom,
|
||||
logo: atom,
|
||||
decimals: 6,
|
||||
hasOraclePrice: true,
|
||||
},
|
||||
axlusdc: {
|
||||
symbol: 'axlUSDC',
|
||||
name: 'Axelar USDC',
|
||||
@ -34,6 +25,15 @@ export const ASSETS: { [denom: string]: Asset } = {
|
||||
hasOraclePrice: true,
|
||||
poolId: 678,
|
||||
},
|
||||
atom: {
|
||||
symbol: 'ATOM',
|
||||
name: 'Atom',
|
||||
denom: 'ibc/27394FB092D2ECCD56123C74F36E4C1F926001CEADA9CA97EA622B25F41E5EB2',
|
||||
color: colors.atom,
|
||||
logo: atom,
|
||||
decimals: 6,
|
||||
hasOraclePrice: true,
|
||||
},
|
||||
}
|
||||
|
||||
const OTHER_ASSETS: { [denom: string]: OtherAsset } = {
|
||||
@ -82,9 +82,9 @@ export const NETWORK_CONFIG: NetworkConfig = {
|
||||
councilUrl: 'https://council.marsprotocol.io',
|
||||
wallets: [
|
||||
WalletID.Keplr,
|
||||
WalletID.StationWallet,
|
||||
WalletID.Leap,
|
||||
WalletID.Cosmostation,
|
||||
WalletID.Falcon,
|
||||
WalletID.KeplrMobile,
|
||||
],
|
||||
}
|
||||
|
@ -42,16 +42,18 @@ export const useEstimateFee = (props: Props) => {
|
||||
}
|
||||
|
||||
const result = await client.simulate(simulateOptions)
|
||||
return result.success
|
||||
? {
|
||||
|
||||
if (result.success) {
|
||||
return {
|
||||
amount: result.fee ? result.fee.amount : [],
|
||||
gas: new BigNumber(result.fee ? result.fee.gas : 0)
|
||||
.multipliedBy(gasAdjustment)
|
||||
.toFixed(0),
|
||||
}
|
||||
: null
|
||||
} catch {
|
||||
return null
|
||||
}
|
||||
throw result.error
|
||||
} catch (e) {
|
||||
throw e
|
||||
}
|
||||
},
|
||||
{
|
||||
|
1
src/images/farm.svg
Normal file
1
src/images/farm.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 18 KiB |
1
src/images/redbank.svg
Normal file
1
src/images/redbank.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 32 KiB |
@ -18,7 +18,7 @@ export default function Document() {
|
||||
<meta content='@mars_protocol' name='twitter:site' />
|
||||
<meta content='@mars_protocol' name='twitter:creator' />
|
||||
<meta content='https://osmosis.marsprotocol.io' property='og:url' />
|
||||
<meta content='Mars Protocol Application - Powered by Osmosis' property='og:title' />
|
||||
<meta content='Mars Protocol - Osmosis Outpost' property='og:title' />
|
||||
<meta
|
||||
content="Lend, borrow and earn on the galaxy's most powerful credit protocol or enter the Fields of Mars for advanced DeFi strategies."
|
||||
property='og:description'
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { Button, Card } from 'components/common'
|
||||
import { ActionsTooltip, Breakdown, PositionInput } from 'components/fields'
|
||||
import { VAULT_DEPOSIT_BUFFER } from 'constants/appConstants'
|
||||
import { DEFAULT_POSITION } from 'constants/defaults'
|
||||
import { useAvailableVault } from 'hooks/data'
|
||||
import cloneDeep from 'lodash.clonedeep'
|
||||
@ -27,11 +28,24 @@ const Create = () => {
|
||||
return
|
||||
}
|
||||
|
||||
const vaultCap = (availableVault.vaultCap?.max || 0) * VAULT_DEPOSIT_BUFFER
|
||||
const isVaultCapReached = availableVault.vaultCap
|
||||
? availableVault.vaultCap.used + position.values.total > vaultCap
|
||||
: false
|
||||
const isDisabled = position.values.total === 0 || isVaultCapReached
|
||||
|
||||
return (
|
||||
<Card
|
||||
title={availableVault.name}
|
||||
onClick={() => router.replace('/farm')}
|
||||
tooltip={'placeholder'}
|
||||
tooltip={
|
||||
<>
|
||||
{t('fields.tooltips.editPosition')}
|
||||
<br />
|
||||
<br />
|
||||
{t('fields.tooltips.apy.available')}
|
||||
</>
|
||||
}
|
||||
>
|
||||
<PositionInput vault={availableVault} position={position} setPosition={setPosition} />
|
||||
<Breakdown vault={availableVault} newPosition={position} isSetUp />
|
||||
@ -41,11 +55,11 @@ const Create = () => {
|
||||
<Button
|
||||
text={t('common.setup')}
|
||||
onClick={() => setPositionInStore(position)}
|
||||
disabled={position.values.total === 0}
|
||||
disabled={isDisabled}
|
||||
className={styles.button}
|
||||
/>
|
||||
</Link>
|
||||
{position.values.total !== 0 && (
|
||||
{!isDisabled && (
|
||||
<ActionsTooltip
|
||||
type='edit'
|
||||
vault={availableVault}
|
||||
|
@ -80,7 +80,7 @@ const SetupPosition = (props: Props) => {
|
||||
<Button
|
||||
prefix={accountId && <SVG.Check />}
|
||||
text={t('fields.setup.step1.button')}
|
||||
disabled={!!accountId || isLoadingCreate || !createFee}
|
||||
disabled={!!accountId || !createFee}
|
||||
showProgressIndicator={isLoadingCreate}
|
||||
onClick={handleCreateCreditAccountClick}
|
||||
className={styles.mintBtn}
|
||||
|
@ -212,7 +212,14 @@ const EditVault = (props: Props) => {
|
||||
<Card
|
||||
title={props.activeVault.name}
|
||||
onClick={() => router.back()}
|
||||
tooltip={t('fields.tooltips.editPosition')}
|
||||
tooltip={
|
||||
<>
|
||||
{t('fields.tooltips.editPosition')}
|
||||
<br />
|
||||
<br />
|
||||
{t('fields.tooltips.apy.available')}
|
||||
</>
|
||||
}
|
||||
actionButtons={actionButtons}
|
||||
>
|
||||
{isRepay ? (
|
||||
|
@ -67,7 +67,14 @@ const RepayVault = (props: Props) => {
|
||||
<Card
|
||||
title={props.activeVault.name}
|
||||
onClick={() => router.back()}
|
||||
tooltip={t('fields.tooltips.editPosition')}
|
||||
tooltip={
|
||||
<>
|
||||
{t('fields.tooltips.editPosition')}
|
||||
<br />
|
||||
<br />
|
||||
{t('fields.tooltips.apy.available')}
|
||||
</>
|
||||
}
|
||||
>
|
||||
<RepayInput
|
||||
vault={props.activeVault}
|
||||
|
@ -10,7 +10,7 @@ import {
|
||||
import { useEffect, useMemo } from 'react'
|
||||
import { Trans, useTranslation } from 'react-i18next'
|
||||
import useStore from 'store'
|
||||
import { NotificationType } from 'types/enums'
|
||||
import { NotificationType, State } from 'types/enums'
|
||||
import { DocURL } from 'types/enums/docURL'
|
||||
|
||||
import styles from './Redbank.module.scss'
|
||||
@ -28,8 +28,10 @@ const RedBank = () => {
|
||||
// STORE STATE
|
||||
// ------------------
|
||||
const marketInfo = useStore((s) => s.marketInfo)
|
||||
const userCollateral = useStore((s) => s.userCollateral)
|
||||
const showTutorial = useStore((s) => s.showRedBankTutorial)
|
||||
const tutorialStep = useStore((s) => s.tutorialSteps['redbank'])
|
||||
const userBalancesState = useStore((s) => s.userBalancesState)
|
||||
const userCollateral = useStore((s) => s.userCollateral)
|
||||
|
||||
const maxBorrowLimit = useMemo(() => {
|
||||
if (!userCollateral || !redBankAssets) return 0
|
||||
@ -69,8 +71,6 @@ const RedBank = () => {
|
||||
|
||||
const showLiquidationWarning = borrowBalance >= maxBorrowLimit && borrowBalance > 0
|
||||
|
||||
const showTutorial = !localStorage.getItem(RED_BANK_TUTORIAL_KEY)
|
||||
|
||||
const depositCard = (
|
||||
<Card
|
||||
hideHeaderBorder
|
||||
@ -92,10 +92,19 @@ const RedBank = () => {
|
||||
)
|
||||
|
||||
useEffect(() => {
|
||||
if (userBalancesState !== State.READY) return
|
||||
|
||||
if (localStorage.getItem(RED_BANK_TUTORIAL_KEY)) {
|
||||
return useStore.setState({ showRedBankTutorial: false })
|
||||
}
|
||||
|
||||
if (Number(balanceSum(redBankAssets, 'depositBalanceBaseCurrency')) > 0) {
|
||||
localStorage.setItem(RED_BANK_TUTORIAL_KEY, 'true')
|
||||
return useStore.setState({ showRedBankTutorial: false })
|
||||
}
|
||||
}, [redBankAssets])
|
||||
|
||||
useStore.setState({ showRedBankTutorial: true })
|
||||
}, [redBankAssets, userBalancesState])
|
||||
|
||||
return (
|
||||
<div className={styles.markets}>
|
||||
|
@ -12,6 +12,7 @@ export interface RedBankSlice {
|
||||
marketInfo: Market[]
|
||||
redBankAssets: RedBankAsset[]
|
||||
redBankState: State
|
||||
showRedBankTutorial: boolean
|
||||
userBalancesState: State
|
||||
userCollateral?: UserCollateral[]
|
||||
userDebts?: Coin[]
|
||||
|
@ -12,6 +12,7 @@ import { DepositAndDebtData } from 'hooks/queries/useDepositAndDebt'
|
||||
import { SafetyFundBalanceData } from 'hooks/queries/useSafetyFundBalance'
|
||||
import { UserBalanceData } from 'hooks/queries/useUserBalance'
|
||||
import isEqual from 'lodash.isequal'
|
||||
import { isMobile } from 'react-device-detect'
|
||||
import { CommonSlice } from 'store/interfaces/common.interface'
|
||||
import { OraclesSlice } from 'store/interfaces/oracles.interface'
|
||||
import { Network } from 'types/enums/network'
|
||||
@ -97,11 +98,14 @@ const commonSlice = (
|
||||
gasLimit: options.fee.gas,
|
||||
memo: undefined,
|
||||
wallet: client.recentWallet,
|
||||
mobile: isMobile,
|
||||
}
|
||||
|
||||
try {
|
||||
return client.broadcast(broadcastOptions)
|
||||
} catch (e) {}
|
||||
} catch (e) {
|
||||
console.error('transaction', e)
|
||||
}
|
||||
},
|
||||
loadNetworkConfig: async () => {
|
||||
try {
|
||||
|
@ -19,6 +19,7 @@ const redBankSlice = (set: NamedSet<Store>, get: GetState<Store>): RedBankSlice
|
||||
marketInfo: [],
|
||||
redBankAssets: [],
|
||||
redBankState: State.INITIALISING,
|
||||
showRedBankTutorial: false,
|
||||
userBalancesState: State.INITIALISING,
|
||||
// ------------------
|
||||
// GENERAL FUNCTIONS
|
||||
|
53
yarn.lock
53
yarn.lock
@ -364,7 +364,7 @@
|
||||
"@cosmjs/math" "^0.29.5"
|
||||
"@cosmjs/utils" "^0.29.5"
|
||||
|
||||
"@cosmjs/cosmwasm-stargate@^0.29.2", "@cosmjs/cosmwasm-stargate@^0.29.5":
|
||||
"@cosmjs/cosmwasm-stargate@^0.29.5":
|
||||
version "0.29.5"
|
||||
resolved "https://registry.yarnpkg.com/@cosmjs/cosmwasm-stargate/-/cosmwasm-stargate-0.29.5.tgz#3f257da682658833e0f4eb9e8ff758e4d927663a"
|
||||
integrity sha512-TNdSvm2tEE3XMCuxHxquzls56t40hC8qnLeYJWHsY2ECZmRK3KrnpRReEr7N7bLtODToK7X/riYrV0JaYxjrYA==
|
||||
@ -419,7 +419,7 @@
|
||||
bech32 "^1.1.4"
|
||||
readonly-date "^1.0.0"
|
||||
|
||||
"@cosmjs/encoding@^0.29.2", "@cosmjs/encoding@^0.29.5":
|
||||
"@cosmjs/encoding@^0.29.5":
|
||||
version "0.29.5"
|
||||
resolved "https://registry.yarnpkg.com/@cosmjs/encoding/-/encoding-0.29.5.tgz#009a4b1c596cdfd326f30ccfa79f5e56daa264f2"
|
||||
integrity sha512-G4rGl/Jg4dMCw5u6PEZHZcoHnUBlukZODHbm/wcL4Uu91fkn5jVo5cXXZcvs4VCkArVGrEj/52eUgTZCmOBGWQ==
|
||||
@ -486,7 +486,7 @@
|
||||
ws "^7"
|
||||
xstream "^11.14.0"
|
||||
|
||||
"@cosmjs/stargate@^0.29.2", "@cosmjs/stargate@^0.29.5":
|
||||
"@cosmjs/stargate@^0.29.5":
|
||||
version "0.29.5"
|
||||
resolved "https://registry.yarnpkg.com/@cosmjs/stargate/-/stargate-0.29.5.tgz#d597af1c85a3c2af7b5bdbec34d5d40692cc09e4"
|
||||
integrity sha512-hjEv8UUlJruLrYGJcUZXM/CziaINOKwfVm2BoSdUnNTMxGvY/jC1ABHKeZUYt9oXHxEJ1n9+pDqzbKc8pT0nBw==
|
||||
@ -537,21 +537,21 @@
|
||||
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.3.6":
|
||||
version "2.3.6"
|
||||
resolved "https://registry.yarnpkg.com/@delphi-labs/shuttle/-/shuttle-2.3.6.tgz#91d047d31e077fe001f155e4abed9faf36a9100c"
|
||||
integrity sha512-dhUphKn/MhUdbKIVmZFL5QvK5CqjJBrQ+io/euncgMwjAQyCOwLReXoncpF8DzwEcADJdFpmHhUurAWlWxG5ZA==
|
||||
"@delphi-labs/shuttle@^2.3.9":
|
||||
version "2.3.10"
|
||||
resolved "https://registry.yarnpkg.com/@delphi-labs/shuttle/-/shuttle-2.3.10.tgz#bd4f0fc48bb0ff13fd3a7e004246e469c5315d6e"
|
||||
integrity sha512-fS7vN7nFkeynbf7p01E8OTF3L+pKPnW2yuTWQTzHLzCSpzSaLkgIPnXxg4/C5/abr4FZ5ZytxpS9TKyj7hP4wA==
|
||||
dependencies:
|
||||
"@cosmjs/amino" "^0.29.5"
|
||||
"@cosmjs/cosmwasm-stargate" "^0.29.2"
|
||||
"@cosmjs/encoding" "^0.29.2"
|
||||
"@cosmjs/cosmwasm-stargate" "^0.29.5"
|
||||
"@cosmjs/encoding" "^0.29.5"
|
||||
"@cosmjs/launchpad" "^0.27.1"
|
||||
"@cosmjs/proto-signing" "^0.29.5"
|
||||
"@cosmjs/stargate" "^0.29.2"
|
||||
"@cosmjs/stargate" "^0.29.5"
|
||||
"@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/cosmos" "^0.11.38"
|
||||
"@keplr-wallet/proto-types" "^0.11.38"
|
||||
"@metamask/eth-sig-util" "^5.0.2"
|
||||
"@walletconnect/client" "^1.8.0"
|
||||
@ -564,6 +564,7 @@
|
||||
long "^5.2.1"
|
||||
secp256k1 "^5.0.0"
|
||||
tslib "^2.4.0"
|
||||
use-local-storage-state "^18.1.2"
|
||||
ws "^8.12.0"
|
||||
zustand "^4.3.1"
|
||||
|
||||
@ -1436,7 +1437,7 @@
|
||||
buffer "^6.0.3"
|
||||
delay "^4.4.0"
|
||||
|
||||
"@keplr-wallet/cosmos@^0.11.34", "@keplr-wallet/cosmos@^0.11.38":
|
||||
"@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==
|
||||
@ -1497,16 +1498,18 @@
|
||||
resolved "https://registry.yarnpkg.com/@kurkle/color/-/color-0.3.2.tgz#5acd38242e8bde4f9986e7913c8fdf49d3aa199f"
|
||||
integrity sha512-fuscdXJ9G1qb7W8VdHi+IwRqij3lBkosAm4ydQtEmbY58OzHXqQhvlxqEkoz0yssNVn38bcpRWgA9PP+OGoisw==
|
||||
|
||||
"@marsprotocol/wallet-connector@^1.3.1":
|
||||
version "1.3.1"
|
||||
resolved "https://registry.yarnpkg.com/@marsprotocol/wallet-connector/-/wallet-connector-1.3.1.tgz#1875c92f87876342469a9190ae5ca44d6c0f552e"
|
||||
integrity sha512-zi6QsPt5/1nvX/4IlpoGubJO2M4/gqlmTd6WdHACeeCOYNV2UtlpNepvjPDIcTJn5Ls0xK8Ig+3JiEtGJeiWpw==
|
||||
"@marsprotocol/wallet-connector@^1.4.2":
|
||||
version "1.4.2"
|
||||
resolved "https://registry.yarnpkg.com/@marsprotocol/wallet-connector/-/wallet-connector-1.4.2.tgz#9dfeaf82242e821d2beef276c23e7f60313ae079"
|
||||
integrity sha512-rHVCbKHvAXHzmU5tZo9mV81Y4WclY6oDtO35nQqlh4X+DtIF/8j71hJRXCpGF+IuN1xwp3I8hcKAIqb08KOa5w==
|
||||
dependencies:
|
||||
"@cosmjs/cosmwasm-stargate" "^0.29.5"
|
||||
"@delphi-labs/shuttle" "^2.3.6"
|
||||
"@cosmjs/encoding" "^0.29.5"
|
||||
"@cosmjs/stargate" "^0.29.5"
|
||||
"@delphi-labs/shuttle" "^2.3.9"
|
||||
"@keplr-wallet/cosmos" "^0.11.38"
|
||||
axios "^1.3.2"
|
||||
react-device-detect "^2.2.2"
|
||||
react-device-detect "^2.2.3"
|
||||
react-modal "^3.16.1"
|
||||
react-qr-code "^2.0.11"
|
||||
webpack "^5.75.0"
|
||||
@ -6706,6 +6709,13 @@ react-device-detect@^2.2.2:
|
||||
dependencies:
|
||||
ua-parser-js "^1.0.2"
|
||||
|
||||
react-device-detect@^2.2.3:
|
||||
version "2.2.3"
|
||||
resolved "https://registry.yarnpkg.com/react-device-detect/-/react-device-detect-2.2.3.tgz#97a7ae767cdd004e7c3578260f48cf70c036e7ca"
|
||||
integrity sha512-buYY3qrCnQVlIFHrC5UcUoAj7iANs/+srdkwsnNjI7anr3Tt7UY6MqNxtMLlr0tMBied0O49UZVK8XKs3ZIiPw==
|
||||
dependencies:
|
||||
ua-parser-js "^1.0.33"
|
||||
|
||||
react-dom@^18.2.0:
|
||||
version "18.2.0"
|
||||
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.2.0.tgz#22aaf38708db2674ed9ada224ca4aa708d821e3d"
|
||||
@ -7639,7 +7649,7 @@ typescript@^4.9.5:
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a"
|
||||
integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==
|
||||
|
||||
ua-parser-js@^1.0.2:
|
||||
ua-parser-js@^1.0.2, ua-parser-js@^1.0.33:
|
||||
version "1.0.33"
|
||||
resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-1.0.33.tgz#f21f01233e90e7ed0f059ceab46eb190ff17f8f4"
|
||||
integrity sha512-RqshF7TPTE0XLYAqmjlu5cLLuGdKrNu9O1KLA/qp39QtbZwuzwv1dT46DZSopoUMsYgXpB3Cv8a03FI8b74oFQ==
|
||||
@ -7687,6 +7697,11 @@ url-parse@^1.5.3:
|
||||
querystringify "^2.1.1"
|
||||
requires-port "^1.0.0"
|
||||
|
||||
use-local-storage-state@^18.1.2:
|
||||
version "18.1.2"
|
||||
resolved "https://registry.yarnpkg.com/use-local-storage-state/-/use-local-storage-state-18.1.2.tgz#f131c0aa3803742ca261c547cdfd9d61e848581d"
|
||||
integrity sha512-V+kYQNC5R0N/JDpsg6b4ED5UaItKJcSvbne68DwJDZWHxGMQBiF41ATktFIOyet3PIq30d2qtzVp/2aB6hQ8Bg==
|
||||
|
||||
use-sync-external-store@1.2.0, use-sync-external-store@^1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz#7dbefd6ef3fe4e767a0cf5d7287aacfb5846928a"
|
||||
|
Loading…
Reference in New Issue
Block a user