mirror of
https://github.com/cerc-io/mars-interface.git
synced 2025-01-05 11:06:48 +00:00
commit
79db46721f
28
README.md
28
README.md
@ -2,11 +2,11 @@
|
|||||||
|
|
||||||
![mars-banner-1200w](https://marsprotocol.io/banner.png)
|
![mars-banner-1200w](https://marsprotocol.io/banner.png)
|
||||||
|
|
||||||
## Web App
|
## 1. Web App
|
||||||
|
|
||||||
This project is a [NextJS](https://nextjs.org/). React application.
|
This project is a [NextJS](https://nextjs.org/). React application.
|
||||||
|
|
||||||
The project utilises [React hooks](https://reactjs.org/docs/hooks-intro.html), functional components, Zustand for state management, and useQuery for general data fetching and management.
|
The project utilises [React hooks](https://reactjs.org/docs/hooks-intro.html), functional components, [Zustand](https://github.com/pmndrs/zustand) for state management, and [useQuery](https://github.com/TanStack/query) for general data fetching and management.
|
||||||
|
|
||||||
Typescript is added and utilised (but optional if you want to create .jsx or .tsx files).
|
Typescript is added and utilised (but optional if you want to create .jsx or .tsx files).
|
||||||
|
|
||||||
@ -14,7 +14,7 @@ SCSS with [CSS modules](https://create-react-app.dev/docs/adding-a-css-modules-s
|
|||||||
|
|
||||||
Sentry is used for front end error logging/exception & bug reporting.
|
Sentry is used for front end error logging/exception & bug reporting.
|
||||||
|
|
||||||
## Deployment
|
## 2. Deployment
|
||||||
|
|
||||||
Start web server
|
Start web server
|
||||||
|
|
||||||
@ -22,16 +22,18 @@ Start web server
|
|||||||
yarn && yarn dev
|
yarn && yarn dev
|
||||||
```
|
```
|
||||||
|
|
||||||
### Contributing
|
## 3. Text and translations
|
||||||
|
|
||||||
We welcome and encourage contributions! Please create a pull request with as much information about the work you did and what your motivation/intention was.
|
This repository makes use of a [translation repository](https://github.com/mars-protocol/translations). This repository containes all of the translation key values that are used within the UI. The rationale is to have no _hardcoded_ display string values in this repository.
|
||||||
|
|
||||||
## Imports
|
## 4. Development practices
|
||||||
|
|
||||||
|
### 4.1 Imports
|
||||||
|
|
||||||
Local components are imported via index files, which can be automatically generated with `yarn index`. This command targets index.ts files with a specific pattern in order to automate component exports. This results in clean imports throughout the pages:
|
Local components are imported via index files, which can be automatically generated with `yarn index`. This command targets index.ts files with a specific pattern in order to automate component exports. This results in clean imports throughout the pages:
|
||||||
|
|
||||||
```
|
```
|
||||||
import { Button, Card, Titlte } from 'components/common'
|
import { Button, Card, Title } from 'components/common'
|
||||||
```
|
```
|
||||||
|
|
||||||
or
|
or
|
||||||
@ -42,6 +44,16 @@ import { Breakdown, RepayInput } from 'components/fields'
|
|||||||
|
|
||||||
In order for this to work, components are place in a folder with UpperCamelCase with the respective Component.tsx file. The component cannot be exported at default, so rather export the `const` instead.
|
In order for this to work, components are place in a folder with UpperCamelCase with the respective Component.tsx file. The component cannot be exported at default, so rather export the `const` instead.
|
||||||
|
|
||||||
## License
|
### 4.2 Data orchestration
|
||||||
|
|
||||||
|
Data is handled with a combination of container components, useQuery and Zustand. Container components are responsible for syncing the application state with the wallet-provider state. This fire of the required queries in useQuery, which are for many cases also stored in Zustand.
|
||||||
|
|
||||||
|
We aim to have as much as possible available in Zustand, to have one source of truth.
|
||||||
|
|
||||||
|
## 5. Contributing
|
||||||
|
|
||||||
|
We welcome and encourage contributions! Please create a pull request with as much information about the work you did and what your motivation/intention was.
|
||||||
|
|
||||||
|
## 6. License
|
||||||
|
|
||||||
Contents of this repository are open source under the [Mars Protocol Web Application License Agreement](./LICENSE).
|
Contents of this repository are open source under the [Mars Protocol Web Application License Agreement](./LICENSE).
|
||||||
|
76
package.json
76
package.json
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "mars",
|
"name": "mars",
|
||||||
"homepage": "./",
|
"homepage": "./",
|
||||||
"version": "1.0.0",
|
"version": "1.1.0",
|
||||||
"private": false,
|
"private": false,
|
||||||
"license": "SEE LICENSE IN LICENSE FILE",
|
"license": "SEE LICENSE IN LICENSE FILE",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
@ -22,48 +22,48 @@
|
|||||||
"@cosmjs/launchpad": "^0.27.1",
|
"@cosmjs/launchpad": "^0.27.1",
|
||||||
"@cosmjs/proto-signing": "^0.29.5",
|
"@cosmjs/proto-signing": "^0.29.5",
|
||||||
"@cosmjs/stargate": "^0.29.5",
|
"@cosmjs/stargate": "^0.29.5",
|
||||||
"@marsprotocol/wallet-connector": "^0.9.12",
|
"@marsprotocol/wallet-connector": "^1.2.3",
|
||||||
"@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.2",
|
"@ramonak/react-progress-bar": "^5.0.3",
|
||||||
"@sentry/nextjs": "^7.12.1",
|
"@sentry/nextjs": "^7.34.0",
|
||||||
"@tanstack/react-query": "^4.3.4",
|
"@tanstack/react-query": "^4.24.4",
|
||||||
"@tanstack/react-table": "^8.5.13",
|
"@tanstack/react-table": "^8.7.9",
|
||||||
"@testing-library/dom": "^8.17.1",
|
"@testing-library/dom": "^8.20.0",
|
||||||
"@testing-library/jest-dom": "^5.16.5",
|
"@testing-library/jest-dom": "^5.16.5",
|
||||||
"@testing-library/react": "^13.4.0",
|
"@testing-library/react": "^13.4.0",
|
||||||
"@testing-library/user-event": "^14.4.3",
|
"@testing-library/user-event": "^14.4.3",
|
||||||
"@tippyjs/react": "^4.2.6",
|
"@tippyjs/react": "^4.2.6",
|
||||||
"bignumber.js": "^9.1.0",
|
"bignumber.js": "^9.1.1",
|
||||||
"chart.js": "^3.9.1",
|
"chart.js": "^4.2.0",
|
||||||
"classnames": "^2.3.1",
|
"classnames": "^2.3.2",
|
||||||
"create-conical-gradient": "^1.1.0",
|
"create-conical-gradient": "^1.1.0",
|
||||||
"graphql": "^16.6.0",
|
"graphql": "^16.6.0",
|
||||||
"graphql-request": "^5.0.0",
|
"graphql-request": "^5.1.0",
|
||||||
"i18next": "^21.9.1",
|
"i18next": "^22.4.9",
|
||||||
"i18next-browser-languagedetector": "^6.1.5",
|
"i18next-browser-languagedetector": "^7.0.1",
|
||||||
"i18next-http-backend": "^1.4.1",
|
"i18next-http-backend": "^2.1.1",
|
||||||
"lodash.clonedeep": "^4.5.0",
|
"lodash.clonedeep": "^4.5.0",
|
||||||
"lodash.isequal": "^4.5.0",
|
"lodash.isequal": "^4.5.0",
|
||||||
"lodash.throttle": "^4.1.1",
|
"lodash.throttle": "^4.1.1",
|
||||||
"moment": "^2.29.4",
|
"moment": "^2.29.4",
|
||||||
"moment-duration-format": "^2.3.2",
|
"moment-duration-format": "^2.3.2",
|
||||||
"next": "^12.2.5",
|
"next": "^13.1.6",
|
||||||
"numeral": "^2.0.6",
|
"numeral": "^2.0.6",
|
||||||
"ramda": "^0.28.0",
|
"ramda": "^0.28.0",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-chartjs-2": "^4.3.1",
|
"react-chartjs-2": "^5.2.0",
|
||||||
"react-currency-input-field": "^3.6.4",
|
"react-currency-input-field": "^3.6.9",
|
||||||
"react-device-detect": "^2.2.2",
|
"react-device-detect": "^2.2.2",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"react-i18next": "^11.18.5",
|
"react-i18next": "^12.1.4",
|
||||||
"react-spring": "^9.5.5",
|
"react-spring": "^9.6.1",
|
||||||
"react-table": "^7.8.0",
|
"react-table": "^7.8.0",
|
||||||
"react-use-clipboard": "^1.0.8",
|
"react-use-clipboard": "^1.0.9",
|
||||||
"sass": "^1.56.1",
|
"sass": "^1.57.1",
|
||||||
"typescript": "^4.8.2",
|
"typescript": "^4.9.5",
|
||||||
"web-vitals": "^3.0.1",
|
"web-vitals": "^3.1.1",
|
||||||
"zustand": "^4.1.1"
|
"zustand": "^4.3.2"
|
||||||
},
|
},
|
||||||
"browserslist": {
|
"browserslist": {
|
||||||
"production": [
|
"production": [
|
||||||
@ -80,26 +80,26 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/chart.js": "^2.9.37",
|
"@types/chart.js": "^2.9.37",
|
||||||
"@types/classnames": "^2.3.1",
|
"@types/classnames": "^2.3.1",
|
||||||
"@types/jest": "^29.2.3",
|
"@types/jest": "^29.4.0",
|
||||||
"@types/lodash.clonedeep": "^4.5.7",
|
"@types/lodash.clonedeep": "^4.5.7",
|
||||||
"@types/lodash.isequal": "^4.5.6",
|
"@types/lodash.isequal": "^4.5.6",
|
||||||
"@types/lodash.throttle": "^4.1.7",
|
"@types/lodash.throttle": "^4.1.7",
|
||||||
"@types/node": "^18.7.15",
|
"@types/node": "^18.11.18",
|
||||||
"@types/numeral": "^2.0.2",
|
"@types/numeral": "^2.0.2",
|
||||||
"@types/prettier": "^2.7.0",
|
"@types/prettier": "^2.7.2",
|
||||||
"@types/ramda": "^0.28.15",
|
"@types/ramda": "^0.28.22",
|
||||||
"@types/react": "^18.0.18",
|
"@types/react": "^18.0.27",
|
||||||
"@types/react-dom": "^18.0.6",
|
"@types/react-dom": "^18.0.10",
|
||||||
"@types/react-table": "^7.7.12",
|
"@types/react-table": "^7.7.14",
|
||||||
"eslint": "^8.23.0",
|
"eslint": "^8.33.0",
|
||||||
"eslint-config-next": "^12.2.5",
|
"eslint-config-next": "^13.1.6",
|
||||||
"eslint-plugin-simple-import-sort": "^8.0.0",
|
"eslint-plugin-simple-import-sort": "^10.0.0",
|
||||||
"eslint-plugin-unused-imports": "^2.0.0",
|
"eslint-plugin-unused-imports": "^2.0.0",
|
||||||
"jest": "^29.3.1",
|
"jest": "^29.4.1",
|
||||||
"jest-environment-jsdom": "^29.3.1",
|
"jest-environment-jsdom": "^29.4.1",
|
||||||
"prettier": "^2.7.1",
|
"prettier": "^2.8.3",
|
||||||
"pretty-quick": "^3.1.3",
|
"pretty-quick": "^3.1.3",
|
||||||
"vscode-generate-index-standalone": "^1.6.0"
|
"vscode-generate-index-standalone": "^1.7.1"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"npm": "please-use-yarn",
|
"npm": "please-use-yarn",
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import classNames from 'classnames/bind'
|
import classNames from 'classnames'
|
||||||
|
|
||||||
import styles from './Backdrop.module.scss'
|
import styles from './Backdrop.module.scss'
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import classNames from 'classnames/bind'
|
import classNames from 'classnames'
|
||||||
import { AnimatedNumber, DisplayCurrency } from 'components/common'
|
import { AnimatedNumber, DisplayCurrency } from 'components/common'
|
||||||
import { lookup } from 'libs/parse'
|
import { lookup } from 'libs/parse'
|
||||||
|
|
||||||
|
@ -1,4 +1,11 @@
|
|||||||
import { useWallet } from '@marsprotocol/wallet-connector'
|
import { CosmWasmClient } from '@cosmjs/cosmwasm-stargate'
|
||||||
|
import {
|
||||||
|
getChainInfo,
|
||||||
|
getClient,
|
||||||
|
useWallet,
|
||||||
|
useWalletManager,
|
||||||
|
WalletConnectionStatus,
|
||||||
|
} from '@marsprotocol/wallet-connector'
|
||||||
import { useQueryClient } from '@tanstack/react-query'
|
import { useQueryClient } from '@tanstack/react-query'
|
||||||
import { MARS_SYMBOL, USDC_SYMBOL } from 'constants/appConstants'
|
import { MARS_SYMBOL, USDC_SYMBOL } from 'constants/appConstants'
|
||||||
import {
|
import {
|
||||||
@ -9,9 +16,10 @@ import {
|
|||||||
useUserBalance,
|
useUserBalance,
|
||||||
useUserDebt,
|
useUserDebt,
|
||||||
useUserDeposit,
|
useUserDeposit,
|
||||||
|
useUserIcns,
|
||||||
} from 'hooks/queries'
|
} from 'hooks/queries'
|
||||||
import { useSpotPrice } from 'hooks/queries/useSpotPrice'
|
import { useSpotPrice } from 'hooks/queries/useSpotPrice'
|
||||||
import { ReactNode, useEffect } from 'react'
|
import { ReactNode, useEffect, useState } from 'react'
|
||||||
import useStore from 'store'
|
import useStore from 'store'
|
||||||
import { State } from 'types/enums'
|
import { State } from 'types/enums'
|
||||||
import { Network } from 'types/enums/network'
|
import { Network } from 'types/enums/network'
|
||||||
@ -24,9 +32,15 @@ export const CommonContainer = ({ children }: CommonContainerProps) => {
|
|||||||
// ------------------
|
// ------------------
|
||||||
// EXTERNAL HOOKS
|
// EXTERNAL HOOKS
|
||||||
// ---------------
|
// ---------------
|
||||||
const { chainInfo, address, signingCosmWasmClient, name } = useWallet()
|
const { recentWallet, simulate, sign, broadcast } = useWallet()
|
||||||
|
const { status } = useWalletManager()
|
||||||
const queryClient = useQueryClient()
|
const queryClient = useQueryClient()
|
||||||
|
|
||||||
|
const chainInfo = recentWallet?.network ? getChainInfo(recentWallet?.network.chainId) : undefined
|
||||||
|
const address = status !== WalletConnectionStatus.Connected ? '' : recentWallet?.account.address
|
||||||
|
|
||||||
|
const [cosmWasmClient, setCosmWasmClient] = useState<CosmWasmClient | undefined>()
|
||||||
|
|
||||||
// ------------------
|
// ------------------
|
||||||
// STORE STATE
|
// STORE STATE
|
||||||
// ------------------
|
// ------------------
|
||||||
@ -54,7 +68,6 @@ export const CommonContainer = ({ children }: CommonContainerProps) => {
|
|||||||
const setClient = useStore((s) => s.setClient)
|
const setClient = useStore((s) => s.setClient)
|
||||||
const setUserBalancesState = useStore((s) => s.setUserBalancesState)
|
const setUserBalancesState = useStore((s) => s.setUserBalancesState)
|
||||||
const setUserWalletAddress = useStore((s) => s.setUserWalletAddress)
|
const setUserWalletAddress = useStore((s) => s.setUserWalletAddress)
|
||||||
const setUserWalletName = useStore((s) => s.setUserWalletName)
|
|
||||||
|
|
||||||
// ------------------
|
// ------------------
|
||||||
// SETTERS
|
// SETTERS
|
||||||
@ -75,21 +88,11 @@ export const CommonContainer = ({ children }: CommonContainerProps) => {
|
|||||||
setUserWalletAddress(address || '')
|
setUserWalletAddress(address || '')
|
||||||
}, [setUserWalletAddress, address])
|
}, [setUserWalletAddress, address])
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (!name) return
|
|
||||||
setUserWalletName(name)
|
|
||||||
}, [setUserWalletName, name])
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!rpc || !chainID) return
|
if (!rpc || !chainID) return
|
||||||
setLcdClient(rpc, chainID)
|
setLcdClient(rpc, chainID)
|
||||||
}, [rpc, chainID, setLcdClient])
|
}, [rpc, chainID, setLcdClient])
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (!signingCosmWasmClient) return
|
|
||||||
setClient(signingCosmWasmClient)
|
|
||||||
}, [signingCosmWasmClient, setClient])
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (userDebts && userDeposits && userBalances) {
|
if (userDebts && userDeposits && userBalances) {
|
||||||
setUserBalancesState(State.READY)
|
setUserBalancesState(State.READY)
|
||||||
@ -98,6 +101,28 @@ export const CommonContainer = ({ children }: CommonContainerProps) => {
|
|||||||
}
|
}
|
||||||
}, [userDebts, userDeposits, userBalances, setUserBalancesState])
|
}, [userDebts, userDeposits, userBalances, setUserBalancesState])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!recentWallet) return
|
||||||
|
if (!cosmWasmClient) {
|
||||||
|
const getCosmWasmClient = async () => {
|
||||||
|
const cosmClient = await getClient(recentWallet.network.rpc)
|
||||||
|
setCosmWasmClient(cosmClient)
|
||||||
|
}
|
||||||
|
|
||||||
|
getCosmWasmClient()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const client = {
|
||||||
|
broadcast,
|
||||||
|
cosmWasmClient,
|
||||||
|
recentWallet,
|
||||||
|
sign,
|
||||||
|
simulate,
|
||||||
|
}
|
||||||
|
setClient(client)
|
||||||
|
}, [simulate, sign, recentWallet, cosmWasmClient, broadcast, setClient])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setRedBankAssets()
|
setRedBankAssets()
|
||||||
}, [
|
}, [
|
||||||
@ -126,6 +151,7 @@ export const CommonContainer = ({ children }: CommonContainerProps) => {
|
|||||||
useBlockHeight()
|
useBlockHeight()
|
||||||
useRedBank()
|
useRedBank()
|
||||||
useUserBalance()
|
useUserBalance()
|
||||||
|
useUserIcns()
|
||||||
useUserDeposit()
|
useUserDeposit()
|
||||||
useUserDebt()
|
useUserDebt()
|
||||||
useMarsOracle()
|
useMarsOracle()
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import React, { ReactNode, useEffect } from 'react'
|
import React, { ReactNode, useEffect } from 'react'
|
||||||
import useStore from 'store'
|
import useStore from 'store'
|
||||||
|
import { AccountNftClient, CreditManagerClient } from 'types/classes'
|
||||||
|
|
||||||
interface FieldsContainerProps {
|
interface FieldsContainerProps {
|
||||||
children: ReactNode
|
children: ReactNode
|
||||||
@ -9,15 +10,17 @@ export const FieldsContainer = ({ children }: FieldsContainerProps) => {
|
|||||||
const client = useStore((s) => s.client)
|
const client = useStore((s) => s.client)
|
||||||
const networkConfig = useStore((s) => s.networkConfig)
|
const networkConfig = useStore((s) => s.networkConfig)
|
||||||
const userWalletAddress = useStore((s) => s.userWalletAddress)
|
const userWalletAddress = useStore((s) => s.userWalletAddress)
|
||||||
const setAccountNftClient = useStore((s) => s.setAccountNftClient)
|
|
||||||
const setCreditManagerClient = useStore((s) => s.setCreditManagerClient)
|
|
||||||
const setCreditManagerMsgComposer = useStore((s) => s.setCreditManagerMsgComposer)
|
const setCreditManagerMsgComposer = useStore((s) => s.setCreditManagerMsgComposer)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!client) return
|
if (!client || !networkConfig) return
|
||||||
setAccountNftClient(client)
|
useStore.setState({
|
||||||
setCreditManagerClient(client)
|
creditManagerClient: new CreditManagerClient(networkConfig?.contracts.creditManager, client),
|
||||||
}, [client, setAccountNftClient, setCreditManagerClient])
|
})
|
||||||
|
useStore.setState({
|
||||||
|
accountNftClient: new AccountNftClient(networkConfig?.contracts.accountNft, client),
|
||||||
|
})
|
||||||
|
}, [client, networkConfig])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!userWalletAddress || !networkConfig?.contracts.creditManager) return
|
if (!userWalletAddress || !networkConfig?.contracts.creditManager) return
|
||||||
|
@ -1,152 +1,8 @@
|
|||||||
@import 'src/styles/master';
|
@import 'src/styles/master';
|
||||||
|
|
||||||
.overlay {
|
.loader {
|
||||||
background-color: $alphaBlack60;
|
|
||||||
position: fixed;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
bottom: 0;
|
|
||||||
width: 100vw;
|
|
||||||
height: 100vh;
|
|
||||||
z-index: 50;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
cursor: pointer;
|
|
||||||
margin: 0;
|
|
||||||
|
|
||||||
.loader {
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex: 0 0 100%;
|
flex: 0 0 100%;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
@include margin(4, 0);
|
@include margin(4, 0);
|
||||||
}
|
|
||||||
|
|
||||||
.button {
|
|
||||||
@include margin(4, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
.content {
|
|
||||||
@include layoutTile;
|
|
||||||
width: rem-calc(540);
|
|
||||||
max-width: 100vw;
|
|
||||||
transform: translateX(-50%);
|
|
||||||
position: absolute;
|
|
||||||
left: 50%;
|
|
||||||
@include padding(4);
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
outline: none;
|
|
||||||
cursor: auto;
|
|
||||||
|
|
||||||
.header {
|
|
||||||
@include typoXXLcaps;
|
|
||||||
text-align: center;
|
|
||||||
color: $fontColorLightPrimary;
|
|
||||||
font-weight: $fontWeightRegular;
|
|
||||||
@include margin(0, 0, 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
.enableContent {
|
|
||||||
display: flex;
|
|
||||||
flex: 0 0 100%;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text {
|
|
||||||
@include typoM;
|
|
||||||
text-align: center;
|
|
||||||
color: $fontColorLightSecondary;
|
|
||||||
width: 100%;
|
|
||||||
display: block;
|
|
||||||
|
|
||||||
button {
|
|
||||||
@include typoM;
|
|
||||||
appearance: none;
|
|
||||||
font-weight: $fontWeightSemibold;
|
|
||||||
color: $colorPrimary;
|
|
||||||
background-color: transparent;
|
|
||||||
border: none;
|
|
||||||
text-decoration: none;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
text-decoration: underline;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.list {
|
|
||||||
@include padding(2, 0);
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: space(4);
|
|
||||||
.wallet,
|
|
||||||
button,
|
|
||||||
a {
|
|
||||||
background: transparent;
|
|
||||||
@include padding(2);
|
|
||||||
box-shadow: none;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
appearance: none;
|
|
||||||
border: none;
|
|
||||||
width: 100%;
|
|
||||||
text-decoration: none;
|
|
||||||
border-radius: space(2);
|
|
||||||
cursor: pointer;
|
|
||||||
|
|
||||||
&.disabled {
|
|
||||||
pointer-events: none;
|
|
||||||
img,
|
|
||||||
.info .name {
|
|
||||||
opacity: 0.5;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background-color: $alphaWhite10;
|
|
||||||
}
|
|
||||||
|
|
||||||
img {
|
|
||||||
height: space(15);
|
|
||||||
width: space(15);
|
|
||||||
}
|
|
||||||
|
|
||||||
.info {
|
|
||||||
font-weight: $fontWeightRegular;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
margin-left: space(5);
|
|
||||||
|
|
||||||
.name {
|
|
||||||
@include typoLcaps;
|
|
||||||
color: $fontColorLightPrimary;
|
|
||||||
}
|
|
||||||
|
|
||||||
.description {
|
|
||||||
@include margin(1, 0, 0);
|
|
||||||
color: $fontColorLightTertiary;
|
|
||||||
text-align: left;
|
|
||||||
@include typoM;
|
|
||||||
|
|
||||||
&.capitalize {
|
|
||||||
text-transform: capitalize;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
canvas {
|
|
||||||
max-width: 90vw;
|
|
||||||
max-height: 90vw;
|
|
||||||
height: rem-calc(320);
|
|
||||||
width: rem-calc(320);
|
|
||||||
border: space(3) solid $colorWhite;
|
|
||||||
margin: 0 auto;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,6 @@
|
|||||||
import { ChainInfoID, WalletManagerProvider, WalletType } from '@marsprotocol/wallet-connector'
|
import { ChainInfoID, WalletID, WalletManagerProvider } from '@marsprotocol/wallet-connector'
|
||||||
import { CircularProgress, SVG } from 'components/common'
|
import { CircularProgress, SVG } from 'components/common'
|
||||||
import buttonStyles from 'components/common/Button/Button.module.scss'
|
import { useEffect, useState } from 'react'
|
||||||
import { NETWORK_CONFIG } from 'configs/osmo-test-4'
|
|
||||||
import { SESSION_WALLET_KEY } from 'constants/appConstants'
|
|
||||||
import KeplrImage from 'images/keplr-wallet-extension.png'
|
|
||||||
import WalletConnectImage from 'images/walletconnect-keplr.png'
|
|
||||||
import { FC } from 'react'
|
|
||||||
import { Trans, useTranslation } from 'react-i18next'
|
|
||||||
import useStore from 'store'
|
|
||||||
|
|
||||||
import styles from './CosmosWalletConnectProvider.module.scss'
|
import styles from './CosmosWalletConnectProvider.module.scss'
|
||||||
|
|
||||||
@ -15,66 +8,48 @@ type Props = {
|
|||||||
children?: React.ReactNode
|
children?: React.ReactNode
|
||||||
}
|
}
|
||||||
|
|
||||||
export const CosmosWalletConnectProvider: FC<Props> = ({ children }) => {
|
const defaultChain = ChainInfoID.OsmosisTestnet
|
||||||
const { t } = useTranslation()
|
|
||||||
const chainId = useStore((s) => s.currentNetwork)
|
export const CosmosWalletConnectProvider = ({ children }: Props) => {
|
||||||
|
const [chainInfoOverrides, setChainInfoOverrides] = useState<{ rpc: string; rest: string }>()
|
||||||
|
const [enabledWallets, setEnabledWallets] = useState<WalletID[]>([])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (chainInfoOverrides) return
|
||||||
|
|
||||||
|
const fetchConfig = async () => {
|
||||||
|
const file = await import(
|
||||||
|
`../../../configs/${
|
||||||
|
process.env.NEXT_PUBLIC_NETWORK === 'mainnet' ? 'osmosis-1' : 'osmo-test-4'
|
||||||
|
}.ts`
|
||||||
|
)
|
||||||
|
|
||||||
|
const networkConfig: NetworkConfig = file.NETWORK_CONFIG
|
||||||
|
|
||||||
|
setChainInfoOverrides({
|
||||||
|
rpc: networkConfig.rpcUrl,
|
||||||
|
rest: networkConfig.restUrl,
|
||||||
|
})
|
||||||
|
setEnabledWallets(networkConfig.wallets)
|
||||||
|
}
|
||||||
|
|
||||||
|
fetchConfig()
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!chainInfoOverrides || !enabledWallets?.length) return null
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<WalletManagerProvider
|
<WalletManagerProvider
|
||||||
chainInfoOverrides={{
|
chainInfoOverrides={chainInfoOverrides}
|
||||||
[ChainInfoID.OsmosisTestnet]: {
|
|
||||||
rpc: NETWORK_CONFIG.rpcUrl,
|
|
||||||
rest: NETWORK_CONFIG.restUrl,
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
classNames={{
|
|
||||||
modalContent: styles.content,
|
|
||||||
modalOverlay: styles.overlay,
|
|
||||||
modalHeader: styles.header,
|
|
||||||
modalCloseButton: styles.close,
|
|
||||||
walletList: styles.list,
|
|
||||||
wallet: styles.wallet,
|
|
||||||
walletImage: styles.image,
|
|
||||||
walletInfo: styles.info,
|
|
||||||
walletName: styles.name,
|
|
||||||
walletDescription: styles.description,
|
|
||||||
textContent: styles.text,
|
|
||||||
}}
|
|
||||||
closeIcon={<SVG.Close />}
|
closeIcon={<SVG.Close />}
|
||||||
defaultChainId={chainId}
|
defaultChainId={defaultChain}
|
||||||
enabledWalletTypes={[WalletType.Keplr, WalletType.WalletConnectKeplr]}
|
enabledWallets={enabledWallets}
|
||||||
enablingMeta={{
|
persistent
|
||||||
text: <Trans i18nKey='global.walletResetText' />,
|
|
||||||
textClassName: styles.text,
|
|
||||||
buttonText: <Trans i18nKey='global.walletReset' />,
|
|
||||||
buttonClassName: ` ${buttonStyles.button} ${buttonStyles.primary} ${buttonStyles.small} ${buttonStyles.solid} ${styles.button}`,
|
|
||||||
contentClassName: styles.enableContent,
|
|
||||||
}}
|
|
||||||
enablingStringOverride={t('global.connectingToWallet')}
|
|
||||||
localStorageKey={SESSION_WALLET_KEY}
|
|
||||||
renderLoader={() => (
|
renderLoader={() => (
|
||||||
<div className={styles.loader}>
|
<div className={styles.loader}>
|
||||||
<CircularProgress size={30} />
|
<CircularProgress size={30} />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
walletConnectClientMeta={{
|
|
||||||
name: 'Mars Protocol',
|
|
||||||
description:
|
|
||||||
'Lend, borrow and earn on the galaxy`s most powerful credit protocol or enter the Fields of Mars for advanced DeFi strategies.',
|
|
||||||
url: 'https://marsprotocol.io',
|
|
||||||
icons: ['https://marsprotocol.io/favicon.svg'],
|
|
||||||
}}
|
|
||||||
walletMetaOverride={{
|
|
||||||
[WalletType.Keplr]: {
|
|
||||||
description: <Trans i18nKey='global.keplrBrowserExtension' />,
|
|
||||||
imageUrl: KeplrImage.src,
|
|
||||||
},
|
|
||||||
[WalletType.WalletConnectKeplr]: {
|
|
||||||
name: <Trans i18nKey='global.walletConnect' />,
|
|
||||||
description: <Trans i18nKey='global.walletConnectDescription' />,
|
|
||||||
imageUrl: WalletConnectImage.src,
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
</WalletManagerProvider>
|
</WalletManagerProvider>
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import { useWallet, WalletConnectionStatus } from '@marsprotocol/wallet-connector'
|
import { useWalletManager, WalletConnectionStatus } from '@marsprotocol/wallet-connector'
|
||||||
import { ConnectButton, ConnectedButton } from 'components/common'
|
import { ConnectButton, ConnectedButton } from 'components/common'
|
||||||
|
|
||||||
export const Connect = () => {
|
export const Connect = () => {
|
||||||
const { status } = useWallet()
|
const { status } = useWalletManager()
|
||||||
|
|
||||||
if (status === WalletConnectionStatus.Connected) return <ConnectedButton />
|
if (status === WalletConnectionStatus.Connected) return <ConnectedButton />
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { ChainInfoID, SimpleChainInfoList, useWalletManager } from '@marsprotocol/wallet-connector'
|
import { ChainInfoID, useWallet, useWalletManager } from '@marsprotocol/wallet-connector'
|
||||||
import { AnimatedNumber, Button, CircularProgress, DisplayCurrency, SVG } from 'components/common'
|
import { AnimatedNumber, Button, CircularProgress, DisplayCurrency, SVG } from 'components/common'
|
||||||
import { findByDenom } from 'functions'
|
import { findByDenom } from 'functions'
|
||||||
import { useUserBalance } from 'hooks/queries'
|
import { useUserBalance } from 'hooks/queries'
|
||||||
@ -16,7 +16,8 @@ export const ConnectedButton = () => {
|
|||||||
// ---------------
|
// ---------------
|
||||||
// EXTERNAL HOOKS
|
// EXTERNAL HOOKS
|
||||||
// ---------------
|
// ---------------
|
||||||
const { disconnect } = useWalletManager()
|
const { disconnect } = useWallet()
|
||||||
|
const { disconnect: terminate } = useWalletManager()
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
|
|
||||||
// ---------------
|
// ---------------
|
||||||
@ -25,7 +26,7 @@ export const ConnectedButton = () => {
|
|||||||
const baseCurrency = useStore((s) => s.baseCurrency)
|
const baseCurrency = useStore((s) => s.baseCurrency)
|
||||||
const chainInfo = useStore((s) => s.chainInfo)
|
const chainInfo = useStore((s) => s.chainInfo)
|
||||||
const userWalletAddress = useStore((s) => s.userWalletAddress)
|
const userWalletAddress = useStore((s) => s.userWalletAddress)
|
||||||
const userWalletName = useStore((s) => s.userWalletName)
|
const userIcns = useStore((s) => s.userIcns)
|
||||||
|
|
||||||
// ---------------
|
// ---------------
|
||||||
// LOCAL STATE
|
// LOCAL STATE
|
||||||
@ -34,18 +35,16 @@ export const ConnectedButton = () => {
|
|||||||
successDuration: 1000 * 5,
|
successDuration: 1000 * 5,
|
||||||
})
|
})
|
||||||
const { data, isLoading } = useUserBalance()
|
const { data, isLoading } = useUserBalance()
|
||||||
|
|
||||||
// ---------------
|
// ---------------
|
||||||
// VARIABLES
|
// VARIABLES
|
||||||
// ---------------
|
// ---------------
|
||||||
const baseCurrencyBalance = Number(findByDenom(data || [], baseCurrency.denom || '')?.amount || 0)
|
const baseCurrencyBalance = Number(findByDenom(data || [], baseCurrency.denom || '')?.amount || 0)
|
||||||
const explorerName =
|
const explorerName = chainInfo ? chainInfo.explorerName : ''
|
||||||
chainInfo && SimpleChainInfoList[chainInfo.chainId as ChainInfoID].explorerName
|
|
||||||
|
|
||||||
const [showDetails, setShowDetails] = useState(false)
|
const [showDetails, setShowDetails] = useState(false)
|
||||||
|
|
||||||
const viewOnFinder = useCallback(() => {
|
const viewOnFinder = useCallback(() => {
|
||||||
const explorerUrl = chainInfo && SimpleChainInfoList[chainInfo.chainId as ChainInfoID].explorer
|
const explorerUrl = chainInfo ? chainInfo.explorer : ''
|
||||||
|
|
||||||
window.open(`${explorerUrl}account/${userWalletAddress}`, '_blank')
|
window.open(`${explorerUrl}account/${userWalletAddress}`, '_blank')
|
||||||
}, [chainInfo, userWalletAddress])
|
}, [chainInfo, userWalletAddress])
|
||||||
@ -60,6 +59,11 @@ export const ConnectedButton = () => {
|
|||||||
baseCurrency.decimals,
|
baseCurrency.decimals,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const handleDisconnect = () => {
|
||||||
|
disconnect()
|
||||||
|
terminate()
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.wrapper}>
|
<div className={styles.wrapper}>
|
||||||
{chainInfo?.chainId !== ChainInfoID.Osmosis1 && (
|
{chainInfo?.chainId !== ChainInfoID.Osmosis1 && (
|
||||||
@ -75,18 +79,11 @@ export const ConnectedButton = () => {
|
|||||||
text={
|
text={
|
||||||
<>
|
<>
|
||||||
<span className={styles.address}>
|
<span className={styles.address}>
|
||||||
{userWalletName ? userWalletName : truncate(userWalletAddress, [2, 4])}
|
{userIcns ? userIcns.split('.')[0] : truncate(userWalletAddress, [2, 4])}
|
||||||
</span>
|
</span>
|
||||||
<span className={`${styles.balance} number`}>
|
<span className={`${styles.balance} number`}>
|
||||||
{!isLoading ? (
|
{!isLoading ? (
|
||||||
`${formatValue(
|
`${formatValue(currentBalanceAmount, 2, 2, true, false, ` ${baseCurrency.symbol}`)}`
|
||||||
currentBalanceAmount,
|
|
||||||
2,
|
|
||||||
2,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
` ${chainInfo?.stakeCurrency?.coinDenom}`,
|
|
||||||
)}`
|
|
||||||
) : (
|
) : (
|
||||||
<CircularProgress className={styles.circularProgress} size={12} />
|
<CircularProgress className={styles.circularProgress} size={12} />
|
||||||
)}
|
)}
|
||||||
@ -99,26 +96,28 @@ export const ConnectedButton = () => {
|
|||||||
<div className={styles.details}>
|
<div className={styles.details}>
|
||||||
<div className={styles.detailsHeader}>
|
<div className={styles.detailsHeader}>
|
||||||
<div className={styles.detailsBalance}>
|
<div className={styles.detailsBalance}>
|
||||||
<div className={styles.detailsDenom}>{chainInfo?.stakeCurrency?.coinDenom}</div>
|
<div className={styles.detailsDenom}>{baseCurrency.symbol}</div>
|
||||||
<div className={`${styles.detailsBalanceAmount}`}>
|
<div className={`${styles.detailsBalanceAmount}`}>
|
||||||
<AnimatedNumber amount={currentBalanceAmount} abbreviated={false} />
|
<AnimatedNumber amount={currentBalanceAmount} abbreviated={false} />
|
||||||
<DisplayCurrency
|
<DisplayCurrency
|
||||||
className='s faded'
|
className='s faded'
|
||||||
coin={{
|
coin={{
|
||||||
amount: baseCurrencyBalance.toString(),
|
amount: baseCurrencyBalance.toString(),
|
||||||
denom: baseCurrency.denom,
|
denom: baseCurrency.symbol,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className={styles.detailsButton}>
|
<div className={styles.detailsButton}>
|
||||||
<Button color='secondary' onClick={disconnect} text={t('common.disconnect')} />
|
<Button
|
||||||
|
color='secondary'
|
||||||
|
onClick={handleDisconnect}
|
||||||
|
text={t('common.disconnect')}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className={styles.detailsBody}>
|
<div className={styles.detailsBody}>
|
||||||
<p className={styles.addressLabel}>
|
<p className={styles.addressLabel}>{userIcns ? userIcns : t('common.yourAddress')}</p>
|
||||||
{userWalletName ? `‘${userWalletName}’` : t('common.yourAddress')}
|
|
||||||
</p>
|
|
||||||
<p className={styles.address}>{userWalletAddress}</p>
|
<p className={styles.address}>{userWalletAddress}</p>
|
||||||
<p className={styles.addressMobile}>{truncate(userWalletAddress, [14, 14])}</p>
|
<p className={styles.addressMobile}>{truncate(userWalletAddress, [14, 14])}</p>
|
||||||
<div className={styles.buttons}>
|
<div className={styles.buttons}>
|
||||||
|
@ -63,7 +63,6 @@
|
|||||||
|
|
||||||
.active {
|
.active {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
pointer-events: none;
|
|
||||||
|
|
||||||
&:before {
|
&:before {
|
||||||
content: '';
|
content: '';
|
||||||
@ -74,6 +73,10 @@
|
|||||||
background-color: $fontColorLightPrimary;
|
background-color: $fontColorLightPrimary;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.unclickable {
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,21 +20,28 @@ export const Header = () => {
|
|||||||
<SVG.Logo />
|
<SVG.Logo />
|
||||||
</div>
|
</div>
|
||||||
<div className={styles.navbar}>
|
<div className={styles.navbar}>
|
||||||
<Link href='/redbank' passHref>
|
<Link
|
||||||
<a className={classNames(styles.nav, !router.pathname.includes('farm') && styles.active)}>
|
passHref
|
||||||
|
href='/redbank'
|
||||||
|
className={classNames(
|
||||||
|
styles.nav,
|
||||||
|
!router.pathname.includes('farm') && styles.active,
|
||||||
|
router.pathname === '/redbank' && styles.unclickable,
|
||||||
|
)}
|
||||||
|
>
|
||||||
{t('global.redBank')}
|
{t('global.redBank')}
|
||||||
</a>
|
|
||||||
</Link>
|
</Link>
|
||||||
<Link href='/farm' passHref>
|
<Link
|
||||||
<a
|
passHref
|
||||||
|
href='/farm'
|
||||||
className={classNames(
|
className={classNames(
|
||||||
!FIELDS_FEATURE && styles.disabled,
|
!FIELDS_FEATURE && styles.disabled,
|
||||||
styles.nav,
|
styles.nav,
|
||||||
router.pathname.includes('farm') && styles.active,
|
router.pathname.includes('farm') && styles.active,
|
||||||
|
router.pathname === '/farm' && styles.unclickable,
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{t('global.fields')}
|
{t('global.fields')}
|
||||||
</a>
|
|
||||||
</Link>
|
</Link>
|
||||||
<a className={styles.nav} href={networkConfig?.councilUrl} target='_blank' rel='noreferrer'>
|
<a className={styles.nav} href={networkConfig?.councilUrl} target='_blank' rel='noreferrer'>
|
||||||
{t('global.council')}
|
{t('global.council')}
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import { ExecuteResult } from '@cosmjs/cosmwasm-stargate'
|
import { ChainInfoID, SimpleChainInfoList, TxBroadcastResult } from '@marsprotocol/wallet-connector'
|
||||||
import { ChainInfoID, SimpleChainInfoList } from '@marsprotocol/wallet-connector'
|
|
||||||
import { useQueryClient } from '@tanstack/react-query'
|
import { useQueryClient } from '@tanstack/react-query'
|
||||||
import classNames from 'classnames'
|
import classNames from 'classnames'
|
||||||
import { AnimatedNumber, Button, DisplayCurrency, SVG, Tooltip, TxLink } from 'components/common'
|
import { AnimatedNumber, Button, DisplayCurrency, SVG, Tooltip, TxLink } from 'components/common'
|
||||||
@ -38,7 +37,7 @@ export const IncentivesButton = () => {
|
|||||||
const [showDetails, setShowDetails] = useState(false)
|
const [showDetails, setShowDetails] = useState(false)
|
||||||
const [disabled, setDisabled] = useState(true)
|
const [disabled, setDisabled] = useState(true)
|
||||||
const [submitted, setSubmitted] = useState(false)
|
const [submitted, setSubmitted] = useState(false)
|
||||||
const [response, setResponse] = useState<ExecuteResult>()
|
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)
|
||||||
|
|
||||||
@ -77,7 +76,7 @@ export const IncentivesButton = () => {
|
|||||||
setSubmitted(false)
|
setSubmitted(false)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (response?.transactionHash) {
|
if (response?.hash) {
|
||||||
setDisabled(true)
|
setDisabled(true)
|
||||||
setSubmitted(false)
|
setSubmitted(false)
|
||||||
return
|
return
|
||||||
@ -156,8 +155,8 @@ export const IncentivesButton = () => {
|
|||||||
<div className={`${styles.container} ${styles.info}`}>
|
<div className={`${styles.container} ${styles.info}`}>
|
||||||
<p className='m'>{t('incentives.successfullyClaimed')}</p>
|
<p className='m'>{t('incentives.successfullyClaimed')}</p>
|
||||||
<TxLink
|
<TxLink
|
||||||
hash={response?.transactionHash || ''}
|
hash={response?.hash || ''}
|
||||||
link={`${explorerUrl}txs/${response?.transactionHash}`}
|
link={`${explorerUrl}txs/${response?.hash}`}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { useWallet, WalletConnectionStatus } from '@marsprotocol/wallet-connector'
|
import { useWalletManager, WalletConnectionStatus } from '@marsprotocol/wallet-connector'
|
||||||
import BigNumber from 'bignumber.js'
|
import BigNumber from 'bignumber.js'
|
||||||
import classNames from 'classnames/bind'
|
import classNames from 'classnames'
|
||||||
import { Button, NumberInput, SVG, Toggle, Tooltip } from 'components/common'
|
import { Button, NumberInput, SVG, Toggle, Tooltip } from 'components/common'
|
||||||
import React, { useState } from 'react'
|
import React, { useState } from 'react'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
@ -19,11 +19,11 @@ export const Settings = () => {
|
|||||||
const [inputRef, setInputRef] = useState<React.RefObject<HTMLInputElement>>()
|
const [inputRef, setInputRef] = useState<React.RefObject<HTMLInputElement>>()
|
||||||
const [isCustom, setIsCustom] = useState(false)
|
const [isCustom, setIsCustom] = useState(false)
|
||||||
const enableAnimations = useStore((s) => s.enableAnimations)
|
const enableAnimations = useStore((s) => s.enableAnimations)
|
||||||
const { status } = useWallet()
|
const { status } = useWalletManager()
|
||||||
|
|
||||||
const onInputChange = (value: number) => {
|
const onInputChange = (value: number) => {
|
||||||
setCustomSlippage(value.toString())
|
setCustomSlippage(value.toString())
|
||||||
if (value.toString() === '') {
|
if (!value.toString()) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import classNames from 'classnames/bind'
|
import classNames from 'classnames'
|
||||||
import { ReactNode } from 'react'
|
import { ReactNode } from 'react'
|
||||||
|
|
||||||
import styles from './Highlight.module.scss'
|
import styles from './Highlight.module.scss'
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { useWallet, WalletConnectionStatus } from '@marsprotocol/wallet-connector'
|
import { useWalletManager, WalletConnectionStatus } from '@marsprotocol/wallet-connector'
|
||||||
import classNames from 'classnames'
|
import classNames from 'classnames'
|
||||||
import { Footer, Header, MobileNav } from 'components/common'
|
import { Footer, Header, MobileNav } from 'components/common'
|
||||||
import { FieldsNotConnected } from 'components/fields'
|
import { FieldsNotConnected } from 'components/fields'
|
||||||
@ -21,13 +21,11 @@ export const Layout = ({ children }: Props) => {
|
|||||||
const enableAnimations = useStore((s) => s.enableAnimations)
|
const enableAnimations = useStore((s) => s.enableAnimations)
|
||||||
const backgroundClasses = classNames('background', !userWalletAddress && 'night')
|
const backgroundClasses = classNames('background', !userWalletAddress && 'night')
|
||||||
const vaultConfigs = useStore((s) => s.vaultConfigs)
|
const vaultConfigs = useStore((s) => s.vaultConfigs)
|
||||||
const wallet = useWallet()
|
const { status } = useWalletManager()
|
||||||
const wasConnectedBefore = !!localStorage.getItem(SESSION_WALLET_KEY)
|
const isConnected = status === WalletConnectionStatus.Connected
|
||||||
const connectionSuccess = !!(
|
const wasConnectedBefore =
|
||||||
(wallet.status === WalletConnectionStatus.Connecting && wasConnectedBefore) ||
|
localStorage.getItem(SESSION_WALLET_KEY) !== null &&
|
||||||
wallet.status === WalletConnectionStatus.Connected
|
localStorage.getItem(SESSION_WALLET_KEY) !== '[]'
|
||||||
)
|
|
||||||
const isConnected = !!userWalletAddress || connectionSuccess
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!userWalletAddress) {
|
if (!userWalletAddress) {
|
||||||
@ -41,7 +39,7 @@ export const Layout = ({ children }: Props) => {
|
|||||||
<Header />
|
<Header />
|
||||||
<div className='appContainer'>
|
<div className='appContainer'>
|
||||||
<div className='widthBox'>
|
<div className='widthBox'>
|
||||||
{isConnected ? (
|
{isConnected || wasConnectedBefore ? (
|
||||||
<div className={'body'}>{children}</div>
|
<div className={'body'}>{children}</div>
|
||||||
) : router.route.includes('farm') ? (
|
) : router.route.includes('farm') ? (
|
||||||
<FieldsNotConnected />
|
<FieldsNotConnected />
|
||||||
|
@ -14,21 +14,25 @@ export const MobileNav = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<nav className={styles.mobileNav}>
|
<nav className={styles.mobileNav}>
|
||||||
<Link href='/redbank' passHref>
|
<Link
|
||||||
<a className={classNames(styles.nav, !router.pathname.includes('farm') && styles.active)}>
|
href='/redbank'
|
||||||
|
passHref
|
||||||
|
className={classNames(styles.nav, !router.pathname.includes('farm') && styles.active)}
|
||||||
|
>
|
||||||
<SVG.RedBankIcon />
|
<SVG.RedBankIcon />
|
||||||
<span>{t('global.redBank')}</span>
|
<span>{t('global.redBank')}</span>
|
||||||
</a>
|
|
||||||
</Link>
|
</Link>
|
||||||
<a className={styles.nav} target='_blank' href={networkConfig?.councilUrl} rel='noreferrer'>
|
<a className={styles.nav} target='_blank' href={networkConfig?.councilUrl} rel='noreferrer'>
|
||||||
<SVG.CouncilIcon />
|
<SVG.CouncilIcon />
|
||||||
<span>{t('global.council')}</span>
|
<span>{t('global.council')}</span>
|
||||||
</a>
|
</a>
|
||||||
<Link href='/farm' passHref>
|
<Link
|
||||||
<a className={classNames(styles.nav, router.pathname.includes('farm') && styles.active)}>
|
href='/farm'
|
||||||
|
passHref
|
||||||
|
className={classNames(styles.nav, router.pathname.includes('farm') && styles.active)}
|
||||||
|
>
|
||||||
<SVG.FieldsIcon />
|
<SVG.FieldsIcon />
|
||||||
<span>{t('global.fields')}</span>
|
<span>{t('global.fields')}</span>
|
||||||
</a>
|
|
||||||
</Link>
|
</Link>
|
||||||
</nav>
|
</nav>
|
||||||
)
|
)
|
||||||
|
@ -110,7 +110,7 @@ export const NumberInput = (props: Props) => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value === '') {
|
if (!value) {
|
||||||
updateValues(value, 0)
|
updateValues(value, 0)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
23
src/components/common/TextTooltip/TextTooltip.tsx
Normal file
23
src/components/common/TextTooltip/TextTooltip.tsx
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import Tippy from '@tippyjs/react'
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
text: string
|
||||||
|
tooltip: string
|
||||||
|
}
|
||||||
|
export const TextTooltip = (props: Props) => {
|
||||||
|
return (
|
||||||
|
<Tippy
|
||||||
|
appendTo={() => document.body}
|
||||||
|
animation={false}
|
||||||
|
render={(attrs) => {
|
||||||
|
return (
|
||||||
|
<div className='tippyContainer' {...attrs}>
|
||||||
|
{props.tooltip}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div>{props.text}</div>
|
||||||
|
</Tippy>
|
||||||
|
)
|
||||||
|
}
|
@ -1,7 +1,6 @@
|
|||||||
@import 'src/styles/master';
|
@import 'src/styles/master';
|
||||||
|
|
||||||
.container {
|
.container {
|
||||||
position: fixed;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@include layoutTooltip;
|
@include layoutTooltip;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import Tippy from '@tippyjs/react'
|
import Tippy from '@tippyjs/react'
|
||||||
import classNames from 'classnames/bind'
|
import classNames from 'classnames'
|
||||||
import { SVG } from 'components/common'
|
import { SVG } from 'components/common'
|
||||||
import { ReactNode } from 'react'
|
import { ReactNode } from 'react'
|
||||||
|
|
||||||
|
@ -1,15 +1,14 @@
|
|||||||
import { ExecuteResult } from '@cosmjs/cosmwasm-stargate'
|
|
||||||
import { decodeTxRaw } from '@cosmjs/proto-signing'
|
|
||||||
import { Coin } from '@cosmjs/stargate'
|
import { Coin } from '@cosmjs/stargate'
|
||||||
import { Card } from 'components/common'
|
import { TxBroadcastResult } from '@marsprotocol/wallet-connector'
|
||||||
import { TxFailedContent, TxSuccessContent } from 'components/common'
|
import { Card, TxFailedContent, TxSuccessContent } from 'components/common'
|
||||||
|
import { getFeeFromResponse } from 'functions'
|
||||||
import { useEffect, useMemo, useState } from 'react'
|
import { useEffect, useMemo, useState } from 'react'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import useStore from 'store'
|
import useStore from 'store'
|
||||||
import { TxStatus } from 'types/enums/RedBankAction'
|
import { TxStatus } from 'types/enums/RedBankAction'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
response?: ExecuteResult
|
response?: TxBroadcastResult
|
||||||
error?: string
|
error?: string
|
||||||
title: string
|
title: string
|
||||||
actions?: FieldsAction[]
|
actions?: FieldsAction[]
|
||||||
@ -33,18 +32,18 @@ export const TxResponse = ({
|
|||||||
const rpc = useStore((s) => s.chainInfo?.rpc)
|
const rpc = useStore((s) => s.chainInfo?.rpc)
|
||||||
const chainID = useStore((s) => s.chainInfo?.chainId)
|
const chainID = useStore((s) => s.chainInfo?.chainId)
|
||||||
const client = useStore((s) => s.client)
|
const client = useStore((s) => s.client)
|
||||||
|
const baseCurrency = useStore((s) => s.baseCurrency)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const getTxInfo = async (hash: string) => {
|
const getTxInfo = async (hash?: string) => {
|
||||||
if (txStatus !== TxStatus.LOADING) return
|
if (txStatus !== TxStatus.LOADING) return
|
||||||
if (!rpc || !chainID) return
|
if (!rpc || !chainID || !hash || !response) return
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const txInfoResponse = await client?.getTx(hash)
|
const coin = getFeeFromResponse(response)
|
||||||
|
|
||||||
if (txInfoResponse) {
|
if (coin) {
|
||||||
const decoded = decodeTxRaw(txInfoResponse?.tx)
|
setTxFee(coin)
|
||||||
setTxFee(decoded.authInfo.fee?.amount[0])
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setTxStatus(TxStatus.SUCCESS)
|
setTxStatus(TxStatus.SUCCESS)
|
||||||
@ -56,8 +55,8 @@ export const TxResponse = ({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getTxInfo(response?.transactionHash || '')
|
getTxInfo(response?.hash || undefined)
|
||||||
}, [client, response, rpc, chainID, checkTxStatus, onSuccess, txStatus])
|
}, [client, response, rpc, chainID, checkTxStatus, onSuccess, txStatus, baseCurrency.denom])
|
||||||
|
|
||||||
// reset scroll
|
// reset scroll
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -79,7 +78,7 @@ export const TxResponse = ({
|
|||||||
{txStatus === TxStatus.FAILURE ? (
|
{txStatus === TxStatus.FAILURE ? (
|
||||||
<TxFailedContent
|
<TxFailedContent
|
||||||
handleClose={handleClose}
|
handleClose={handleClose}
|
||||||
hash={response?.transactionHash || ''}
|
hash={response?.response.transactionHash || ''}
|
||||||
message={error}
|
message={error}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
import { ExecuteResult } from '@cosmjs/cosmwasm-stargate'
|
|
||||||
import { Coin } from '@cosmjs/stargate'
|
import { Coin } from '@cosmjs/stargate'
|
||||||
import { ChainInfoID, SimpleChainInfoList } from '@marsprotocol/wallet-connector'
|
import { ChainInfoID, SimpleChainInfoList, TxBroadcastResult } from '@marsprotocol/wallet-connector'
|
||||||
import { Button, TxFee, TxLink } from 'components/common'
|
import { Button, InfoTitle, TxFee, TxLink } from 'components/common'
|
||||||
import { InfoTitle } from 'components/common'
|
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import useStore from 'store'
|
import useStore from 'store'
|
||||||
import { TxStatus } from 'types/enums/RedBankAction'
|
import { TxStatus } from 'types/enums/RedBankAction'
|
||||||
@ -11,7 +9,7 @@ import styles from './TxSuccessContent.module.scss'
|
|||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
title: string
|
title: string
|
||||||
response?: ExecuteResult
|
response?: TxBroadcastResult | null
|
||||||
txFee?: Coin
|
txFee?: Coin
|
||||||
txStatus: TxStatus
|
txStatus: TxStatus
|
||||||
actions: { label: string; values: string[] }[]
|
actions: { label: string; values: string[] }[]
|
||||||
@ -68,8 +66,8 @@ export const TxSuccessContent = ({
|
|||||||
<div className={styles.item}>
|
<div className={styles.item}>
|
||||||
<div className={styles.label}>{t('common.txHash')}</div>
|
<div className={styles.label}>{t('common.txHash')}</div>
|
||||||
<TxLink
|
<TxLink
|
||||||
hash={response?.transactionHash || ''}
|
hash={response?.response.transactionHash || ''}
|
||||||
link={`${explorerUrl}txs/${response?.transactionHash}`}
|
link={`${explorerUrl}txs/${response?.response.transactionHash}`}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -28,6 +28,7 @@ export { MobileNav } from './MobileNav/MobileNav'
|
|||||||
export { Notification } from './Notification/Notification'
|
export { Notification } from './Notification/Notification'
|
||||||
export { NumberInput } from './NumberInput/NumberInput'
|
export { NumberInput } from './NumberInput/NumberInput'
|
||||||
export { SVG } from './SVG/SVG'
|
export { SVG } from './SVG/SVG'
|
||||||
|
export { TextTooltip } from './TextTooltip/TextTooltip'
|
||||||
export { Title } from './Title/Title'
|
export { Title } from './Title/Title'
|
||||||
export { Toggle } from './Toggle/Toggle'
|
export { Toggle } from './Toggle/Toggle'
|
||||||
export { TokenBalance } from './TokenBalance/TokenBalance'
|
export { TokenBalance } from './TokenBalance/TokenBalance'
|
||||||
|
@ -1,5 +1,17 @@
|
|||||||
@import 'src/styles/master';
|
@import 'src/styles/master';
|
||||||
|
|
||||||
|
$color: ':nth-child(1)';
|
||||||
|
$logo: ':nth-child(2)';
|
||||||
|
$name: ':nth-child(3)';
|
||||||
|
$posValue: ':nth-child(4)';
|
||||||
|
$netValue: ':nth-child(5)';
|
||||||
|
$borrowValue: ':nth-child(6)';
|
||||||
|
$vaultCap: ':nth-child(7)';
|
||||||
|
$apy: ':nth-child(8)';
|
||||||
|
$leverage: ':nth-child(9)';
|
||||||
|
$borrowCapacity: ':nth-child(10)';
|
||||||
|
$actions: ':nth-child(11)';
|
||||||
|
|
||||||
.table {
|
.table {
|
||||||
display: none;
|
display: none;
|
||||||
@include margin(0, 0, 6, 0);
|
@include margin(0, 0, 6, 0);
|
||||||
@ -32,13 +44,11 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Not color indicator
|
&:not(#{$color}) {
|
||||||
&:not(:first-child) {
|
|
||||||
@include padding(4, 2);
|
@include padding(4, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Name
|
&#{$name} {
|
||||||
&:nth-child(3) {
|
|
||||||
@include padding(4, 2, 4, 0);
|
@include padding(4, 2, 4, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -64,24 +74,15 @@
|
|||||||
.td {
|
.td {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
// Logos
|
&#{$logo} {
|
||||||
&:nth-child(2) {
|
|
||||||
width: rem-calc(64);
|
width: rem-calc(64);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Not color indicator
|
&:not(#{$color}) {
|
||||||
&:not(:first-child) {
|
|
||||||
@include padding(0, 2);
|
@include padding(0, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Name
|
&#{$name} {
|
||||||
&:nth-child(3) {
|
|
||||||
text-align: left;
|
|
||||||
@include padding(0, 2, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Leverage
|
|
||||||
&:nth-child(3) {
|
|
||||||
text-align: left;
|
text-align: left;
|
||||||
@include padding(0, 2, 0, 0);
|
@include padding(0, 2, 0, 0);
|
||||||
}
|
}
|
||||||
@ -92,11 +93,9 @@
|
|||||||
.table {
|
.table {
|
||||||
.td,
|
.td,
|
||||||
.th {
|
.th {
|
||||||
// Leverage
|
&#{$vaultCap},
|
||||||
&:nth-child(5),
|
&#{$borrowValue},
|
||||||
&:nth-child(6),
|
&#{$leverage} {
|
||||||
&:nth-child(8),
|
|
||||||
&:nth-child(9) {
|
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -68,7 +68,7 @@ export const ActiveVaultsTable = () => {
|
|||||||
title={t('fields.activeVaults')}
|
title={t('fields.activeVaults')}
|
||||||
hideHeaderBorder
|
hideHeaderBorder
|
||||||
styleOverride={{ marginBottom: 40 }}
|
styleOverride={{ marginBottom: 40 }}
|
||||||
tooltip={<Trans i18nKey='fields.tooltips.activeVaults' />}
|
tooltip={<Trans i18nKey='fields.tooltips.activeVaults.desktop' />}
|
||||||
>
|
>
|
||||||
<table className={styles.table}>
|
<table className={styles.table}>
|
||||||
<thead className={styles.thead}>
|
<thead className={styles.thead}>
|
||||||
|
@ -4,6 +4,11 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
||||||
|
.link {
|
||||||
|
color: unset;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
.grid {
|
.grid {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: rem-calc(64) 1fr 1fr;
|
grid-template-columns: rem-calc(64) 1fr 1fr;
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
|
import Tippy from '@tippyjs/react'
|
||||||
import BigNumber from 'bignumber.js'
|
import BigNumber from 'bignumber.js'
|
||||||
import { BorrowCapacity, Card, DisplayCurrency } from 'components/common'
|
import { AnimatedNumber, Apy, BorrowCapacity, Card, DisplayCurrency } from 'components/common'
|
||||||
import { VaultLogo, VaultName } from 'components/fields'
|
import { VaultLogo, VaultName } from 'components/fields'
|
||||||
import { FIELDS_TUTORIAL_KEY } from 'constants/appConstants'
|
import { FIELDS_TUTORIAL_KEY } from 'constants/appConstants'
|
||||||
import { formatValue } from 'libs/parse'
|
|
||||||
import Link from 'next/link'
|
import Link from 'next/link'
|
||||||
import { Trans, useTranslation } from 'react-i18next'
|
import { Trans, useTranslation } from 'react-i18next'
|
||||||
import useStore from 'store'
|
import useStore from 'store'
|
||||||
@ -45,7 +45,7 @@ export const ActiveVaultsTableMobile = () => {
|
|||||||
<Card
|
<Card
|
||||||
title={t('fields.activeVaults')}
|
title={t('fields.activeVaults')}
|
||||||
styleOverride={{ marginBottom: 40 }}
|
styleOverride={{ marginBottom: 40 }}
|
||||||
tooltip={<Trans i18nKey='fields.tooltips.activeVaults' />}
|
tooltip={<Trans i18nKey='fields.tooltips.activeVaults.mobile' />}
|
||||||
>
|
>
|
||||||
<div className={styles.container}>
|
<div className={styles.container}>
|
||||||
{activeVaults.map((vault, i) => {
|
{activeVaults.map((vault, i) => {
|
||||||
@ -55,24 +55,39 @@ export const ActiveVaultsTableMobile = () => {
|
|||||||
<VaultLogo vault={vault} />
|
<VaultLogo vault={vault} />
|
||||||
</div>
|
</div>
|
||||||
<div className={styles.name}>{getVaultSubText(vault)}</div>
|
<div className={styles.name}>{getVaultSubText(vault)}</div>
|
||||||
|
|
||||||
<div className={styles.position}>
|
<div className={styles.position}>
|
||||||
|
<div className='xl' onClick={(e) => e.preventDefault()}>
|
||||||
|
<span className='faded'>{t('common.apy')} </span>
|
||||||
|
<span>
|
||||||
|
<Tippy
|
||||||
|
content={
|
||||||
|
<Apy
|
||||||
|
apyData={{
|
||||||
|
borrow: vault.position.apy.borrow,
|
||||||
|
total: vault.position.apy.total,
|
||||||
|
}}
|
||||||
|
leverage={vault.position.currentLeverage}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<span className='tooltip xl'>
|
||||||
|
<AnimatedNumber amount={vault.position.apy.net} className='xl' suffix='%' />
|
||||||
|
</span>
|
||||||
|
</Tippy>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div className='s'>
|
||||||
|
<span className='faded'>{t('fields.positionValueShort')} </span>
|
||||||
<DisplayCurrency
|
<DisplayCurrency
|
||||||
coin={{
|
coin={{
|
||||||
denom: baseCurrency.denom,
|
denom: baseCurrency.denom,
|
||||||
amount: vault.position.values.total.toString(),
|
amount: vault.position.values.total.toString(),
|
||||||
}}
|
}}
|
||||||
className={'xl'}
|
className={`s ${styles.inline}`}
|
||||||
/>
|
|
||||||
<div className='s'>
|
|
||||||
<span className='faded'>{t('common.debt')} </span>
|
|
||||||
<DisplayCurrency
|
|
||||||
coin={{
|
|
||||||
denom: baseCurrency.denom,
|
|
||||||
amount: vault.position.values.borrowed.toString(),
|
|
||||||
}}
|
|
||||||
className={styles.inline}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className='s'>
|
<div className='s'>
|
||||||
<span className='faded'>{t('common.net')} </span>
|
<span className='faded'>{t('common.net')} </span>
|
||||||
<DisplayCurrency
|
<DisplayCurrency
|
||||||
@ -84,20 +99,18 @@ export const ActiveVaultsTableMobile = () => {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className='s'>
|
<div className='s'>
|
||||||
<span className='faded'>{t('fields.leverage')} </span>
|
<span className='faded'>{t('common.debt')} </span>
|
||||||
{new BigNumber(vault.position.currentLeverage).toPrecision(3)}
|
<DisplayCurrency
|
||||||
|
coin={{
|
||||||
|
denom: baseCurrency.denom,
|
||||||
|
amount: vault.position.values.borrowed.toString(),
|
||||||
|
}}
|
||||||
|
className={styles.inline}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className='s'>
|
<div className='s'>
|
||||||
<span className='faded'>{t('fields.vaultCap')} </span>
|
<span className='faded'>{t('fields.leverage')} </span>
|
||||||
|
{new BigNumber(vault.position.currentLeverage).toPrecision(3)}
|
||||||
{formatValue(
|
|
||||||
(vault.vaultCap?.max || 0) / 10 ** baseCurrency.decimals,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
true,
|
|
||||||
'',
|
|
||||||
` ${baseCurrency.symbol}`,
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className={styles.borrowCapacity}>
|
<div className={styles.borrowCapacity}>
|
||||||
@ -124,6 +137,7 @@ export const ActiveVaultsTableMobile = () => {
|
|||||||
href={`/farm/vault/${vault.address}/${
|
href={`/farm/vault/${vault.address}/${
|
||||||
vault.position.status === 'active' ? 'edit' : 'close'
|
vault.position.status === 'active' ? 'edit' : 'close'
|
||||||
}`}
|
}`}
|
||||||
|
className={styles.link}
|
||||||
>
|
>
|
||||||
<div>{content}</div>
|
<div>{content}</div>
|
||||||
</Link>
|
</Link>
|
||||||
|
@ -1,20 +1,28 @@
|
|||||||
import { ColumnDef, createColumnHelper } from '@tanstack/react-table'
|
import { ColumnDef, createColumnHelper } from '@tanstack/react-table'
|
||||||
import Tippy from '@tippyjs/react'
|
import Tippy from '@tippyjs/react'
|
||||||
import BigNumber from 'bignumber.js'
|
import BigNumber from 'bignumber.js'
|
||||||
import classNames from 'classnames/bind'
|
import classNames from 'classnames'
|
||||||
import {
|
import {
|
||||||
AnimatedNumber,
|
AnimatedNumber,
|
||||||
|
Apy,
|
||||||
BorrowCapacity,
|
BorrowCapacity,
|
||||||
Button,
|
Button,
|
||||||
DisplayCurrency,
|
DisplayCurrency,
|
||||||
SVG,
|
SVG,
|
||||||
|
TextTooltip,
|
||||||
TokenBalance,
|
TokenBalance,
|
||||||
} from 'components/common'
|
} from 'components/common'
|
||||||
import { VaultLogo, VaultName } from 'components/fields'
|
import { VaultLogo, VaultName } from 'components/fields'
|
||||||
import { VAULT_DEPOSIT_BUFFER } from 'constants/appConstants'
|
import { VAULT_DEPOSIT_BUFFER } from 'constants/appConstants'
|
||||||
import { convertPercentage } from 'functions'
|
import { convertPercentage } from 'functions'
|
||||||
import { getLiqBorrowValue, getMaxBorrowValue } from 'functions/fields'
|
import { getLiqBorrowValue, getMaxBorrowValue } from 'functions/fields'
|
||||||
import { convertApyToDailyApy, formatUnlockDate, formatValue, ltvToLeverage } from 'libs/parse'
|
import {
|
||||||
|
convertApyToDailyApy,
|
||||||
|
formatUnlockDate,
|
||||||
|
formatValue,
|
||||||
|
getTimeAndUnit,
|
||||||
|
ltvToLeverage,
|
||||||
|
} from 'libs/parse'
|
||||||
import { useRouter } from 'next/router'
|
import { useRouter } from 'next/router'
|
||||||
import { ReactNode, useMemo } from 'react'
|
import { ReactNode, useMemo } from 'react'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
@ -43,11 +51,38 @@ export const useActiveVaultsColumns = () => {
|
|||||||
columnHelper.accessor('name', {
|
columnHelper.accessor('name', {
|
||||||
enableSorting: true,
|
enableSorting: true,
|
||||||
header: t('fields.position'),
|
header: t('fields.position'),
|
||||||
cell: ({ row }) => <VaultName vault={row.original} />,
|
cell: ({ row }) => {
|
||||||
|
return (
|
||||||
|
<Tippy
|
||||||
|
appendTo={() => document.body}
|
||||||
|
animation={false}
|
||||||
|
render={(attrs) => {
|
||||||
|
return (
|
||||||
|
<div className='tippyContainer' {...attrs}>
|
||||||
|
{t('fields.tooltips.name', {
|
||||||
|
asset1: row.original.symbols.primary,
|
||||||
|
asset2: row.original.symbols.secondary,
|
||||||
|
...getTimeAndUnit(row.original.lockup),
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<VaultName vault={row.original} />
|
||||||
|
</div>
|
||||||
|
</Tippy>
|
||||||
|
)
|
||||||
|
},
|
||||||
}),
|
}),
|
||||||
columnHelper.accessor('position.values.total', {
|
columnHelper.accessor('position.values.total', {
|
||||||
enableSorting: true,
|
enableSorting: true,
|
||||||
header: t('fields.positionValueShort'),
|
header: () => (
|
||||||
|
<TextTooltip
|
||||||
|
text={t('fields.positionValueShort')}
|
||||||
|
tooltip={t('fields.tooltips.positionValue')}
|
||||||
|
/>
|
||||||
|
),
|
||||||
cell: ({ row }) => {
|
cell: ({ row }) => {
|
||||||
const primaryCoin = {
|
const primaryCoin = {
|
||||||
denom: row.original.denoms.primary,
|
denom: row.original.denoms.primary,
|
||||||
@ -89,7 +124,9 @@ export const useActiveVaultsColumns = () => {
|
|||||||
}),
|
}),
|
||||||
columnHelper.accessor('position.values.primary', {
|
columnHelper.accessor('position.values.primary', {
|
||||||
enableSorting: true,
|
enableSorting: true,
|
||||||
header: t('fields.netValue'),
|
header: () => (
|
||||||
|
<TextTooltip text={t('fields.netValue')} tooltip={t('fields.tooltips.netValue')} />
|
||||||
|
),
|
||||||
cell: ({ row }) => {
|
cell: ({ row }) => {
|
||||||
const position = row.original.position
|
const position = row.original.position
|
||||||
const netValue = position.values.primary + position.values.secondary
|
const netValue = position.values.primary + position.values.secondary
|
||||||
@ -129,7 +166,9 @@ export const useActiveVaultsColumns = () => {
|
|||||||
}),
|
}),
|
||||||
columnHelper.accessor('position.values.borrowed', {
|
columnHelper.accessor('position.values.borrowed', {
|
||||||
enableSorting: true,
|
enableSorting: true,
|
||||||
header: t('common.borrowed'),
|
header: () => (
|
||||||
|
<TextTooltip text={t('common.borrowed')} tooltip={t('fields.tooltips.borrowValue')} />
|
||||||
|
),
|
||||||
cell: (info) => {
|
cell: (info) => {
|
||||||
const borrowAsset = whitelistedAssets.find(
|
const borrowAsset = whitelistedAssets.find(
|
||||||
(asset) => asset.denom === info.row.original.denoms.secondary,
|
(asset) => asset.denom === info.row.original.denoms.secondary,
|
||||||
@ -169,7 +208,9 @@ export const useActiveVaultsColumns = () => {
|
|||||||
}),
|
}),
|
||||||
columnHelper.accessor('vaultCap', {
|
columnHelper.accessor('vaultCap', {
|
||||||
enableSorting: true,
|
enableSorting: true,
|
||||||
header: t('fields.vaultCap'),
|
header: () => (
|
||||||
|
<TextTooltip text={t('fields.vaultCap')} tooltip={t('fields.tooltips.vaultCap')} />
|
||||||
|
),
|
||||||
cell: ({ row }) => {
|
cell: ({ row }) => {
|
||||||
if (!row.original.vaultCap) {
|
if (!row.original.vaultCap) {
|
||||||
return null
|
return null
|
||||||
@ -217,7 +258,9 @@ export const useActiveVaultsColumns = () => {
|
|||||||
columnHelper.accessor('position.apy', {
|
columnHelper.accessor('position.apy', {
|
||||||
id: 'apy',
|
id: 'apy',
|
||||||
enableSorting: true,
|
enableSorting: true,
|
||||||
header: t('common.apy'),
|
header: () => (
|
||||||
|
<TextTooltip text={t('common.apy')} tooltip={t('fields.tooltips.apy.active')} />
|
||||||
|
),
|
||||||
cell: ({ row }) => {
|
cell: ({ row }) => {
|
||||||
switch (row.original.position.status) {
|
switch (row.original.position.status) {
|
||||||
case 'unlocked':
|
case 'unlocked':
|
||||||
@ -228,13 +271,28 @@ export const useActiveVaultsColumns = () => {
|
|||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
case 'active':
|
case 'active':
|
||||||
const apy = new BigNumber(row.original.position.apy).decimalPlaces(2).toNumber()
|
const apy = new BigNumber(row.original.position.apy.net).decimalPlaces(2).toNumber()
|
||||||
|
|
||||||
|
const apyData = {
|
||||||
|
total: row.original.apy || 0,
|
||||||
|
borrow: row.original.position.apy.borrow,
|
||||||
|
}
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
<Tippy
|
||||||
|
appendTo={() => document.body}
|
||||||
|
animation={false}
|
||||||
|
content={
|
||||||
|
<Apy apyData={apyData} leverage={row.original.position.currentLeverage} />
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<span className='tooltip'>
|
||||||
<AnimatedNumber amount={apy} className='m' suffix='%' />
|
<AnimatedNumber amount={apy} className='m' suffix='%' />
|
||||||
<p className='s faded'>
|
<p className='s faded'>
|
||||||
{convertApyToDailyApy(row.original.position.apy)}%/{t('common.day')}
|
{convertApyToDailyApy(row.original.position.apy.net)}%/{t('common.day')}
|
||||||
</p>
|
</p>
|
||||||
|
</span>
|
||||||
|
</Tippy>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
case 'unlocking':
|
case 'unlocking':
|
||||||
@ -242,7 +300,6 @@ export const useActiveVaultsColumns = () => {
|
|||||||
<>
|
<>
|
||||||
<p className='m'>{t('fields.unlocking')}</p>
|
<p className='m'>{t('fields.unlocking')}</p>
|
||||||
<p className='s faded'>
|
<p className='s faded'>
|
||||||
{/* {new Date(row.original.position?.unlockAtTimestamp || 0).} */}
|
|
||||||
{formatUnlockDate(row.original.position?.unlockAtTimestamp || 0)}
|
{formatUnlockDate(row.original.position?.unlockAtTimestamp || 0)}
|
||||||
</p>
|
</p>
|
||||||
</>
|
</>
|
||||||
@ -252,7 +309,9 @@ export const useActiveVaultsColumns = () => {
|
|||||||
}),
|
}),
|
||||||
columnHelper.accessor('ltv', {
|
columnHelper.accessor('ltv', {
|
||||||
enableSorting: true,
|
enableSorting: true,
|
||||||
header: t('fields.leverage'),
|
header: () => (
|
||||||
|
<TextTooltip text={t('fields.leverage')} tooltip={t('fields.tooltips.leverage.active')} />
|
||||||
|
),
|
||||||
cell: ({ row }) => {
|
cell: ({ row }) => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@ -275,7 +334,12 @@ export const useActiveVaultsColumns = () => {
|
|||||||
}),
|
}),
|
||||||
columnHelper.accessor('position.amounts.borrowed', {
|
columnHelper.accessor('position.amounts.borrowed', {
|
||||||
enableSorting: false,
|
enableSorting: false,
|
||||||
header: t('common.borrowingCapacity'),
|
header: () => (
|
||||||
|
<TextTooltip
|
||||||
|
text={t('common.borrowingCapacity')}
|
||||||
|
tooltip={t('fields.tooltips.borrowCapacity')}
|
||||||
|
/>
|
||||||
|
),
|
||||||
cell: ({ row }) => {
|
cell: ({ row }) => {
|
||||||
const maxBorrowValue = getMaxBorrowValue(row.original, row.original.position)
|
const maxBorrowValue = getMaxBorrowValue(row.original, row.original.position)
|
||||||
|
|
||||||
|
@ -47,8 +47,6 @@ $action: ':nth-child(9)';
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$number: 1;
|
|
||||||
|
|
||||||
&:not(#{$color}) {
|
&:not(#{$color}) {
|
||||||
@include padding(4, 2);
|
@include padding(4, 2);
|
||||||
}
|
}
|
||||||
@ -111,7 +109,7 @@ $action: ':nth-child(9)';
|
|||||||
&#{$description} {
|
&#{$description} {
|
||||||
text-align: left;
|
text-align: left;
|
||||||
width: rem-calc(300);
|
width: rem-calc(300);
|
||||||
@include padding(0, 2, 0, 0);
|
@include padding(2, 2, 2, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -53,7 +53,7 @@ export const AvailableVaultsTable = () => {
|
|||||||
title={t('fields.availableVaults')}
|
title={t('fields.availableVaults')}
|
||||||
hideHeaderBorder
|
hideHeaderBorder
|
||||||
styleOverride={{ marginBottom: 40 }}
|
styleOverride={{ marginBottom: 40 }}
|
||||||
tooltip={<Trans i18nKey='fields.tooltips.activeVaults' />}
|
tooltip={<Trans i18nKey='fields.tooltips.availableVaults.desktop' />}
|
||||||
>
|
>
|
||||||
<table className={styles.table}>
|
<table className={styles.table}>
|
||||||
<thead className={styles.thead}>
|
<thead className={styles.thead}>
|
||||||
@ -68,7 +68,7 @@ export const AvailableVaultsTable = () => {
|
|||||||
const wrapperClasses = classes({
|
const wrapperClasses = classes({
|
||||||
wrapper: true,
|
wrapper: true,
|
||||||
left: header.id === 'name' || header.id === 'description',
|
left: header.id === 'name' || header.id === 'description',
|
||||||
center: header.id === 'provider_name',
|
center: header.id === 'provider',
|
||||||
})
|
})
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -4,6 +4,15 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
||||||
|
.inline {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.link {
|
||||||
|
color: unset;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
.grid {
|
.grid {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: rem-calc(64) 1fr 1fr;
|
grid-template-columns: rem-calc(64) 1fr 1fr;
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
|
import Tippy from '@tippyjs/react'
|
||||||
import BigNumber from 'bignumber.js'
|
import BigNumber from 'bignumber.js'
|
||||||
import { AnimatedNumber, Card } from 'components/common'
|
import { AnimatedNumber, Apy, Card, DisplayCurrency } from 'components/common'
|
||||||
import { VaultLogo, VaultName } from 'components/fields'
|
import { VaultLogo, VaultName } from 'components/fields'
|
||||||
import { formatValue, ltvToLeverage } from 'libs/parse'
|
import { getTimeAndUnit, ltvToLeverage } from 'libs/parse'
|
||||||
|
import Link from 'next/link'
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import { Trans, useTranslation } from 'react-i18next'
|
import { Trans, useTranslation } from 'react-i18next'
|
||||||
import useStore from 'store'
|
import useStore from 'store'
|
||||||
@ -12,6 +14,7 @@ export const AvailableVaultsTableMobile = () => {
|
|||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const availableVaults = useStore((s) => s.availableVaults)
|
const availableVaults = useStore((s) => s.availableVaults)
|
||||||
const baseCurrency = useStore((s) => s.baseCurrency)
|
const baseCurrency = useStore((s) => s.baseCurrency)
|
||||||
|
const redBankAssets = useStore((s) => s.redBankAssets)
|
||||||
|
|
||||||
if (!availableVaults?.length) return null
|
if (!availableVaults?.length) return null
|
||||||
|
|
||||||
@ -19,14 +22,25 @@ export const AvailableVaultsTableMobile = () => {
|
|||||||
<Card
|
<Card
|
||||||
title={t('fields.availableVaults')}
|
title={t('fields.availableVaults')}
|
||||||
styleOverride={{ marginBottom: 40 }}
|
styleOverride={{ marginBottom: 40 }}
|
||||||
tooltip={<Trans i18nKey='fields.tooltips.availableVaults' />}
|
tooltip={<Trans i18nKey='fields.tooltips.availableVaults.mobile' />}
|
||||||
>
|
>
|
||||||
<div className={styles.container}>
|
<div className={styles.container}>
|
||||||
{availableVaults.map((vault, i) => {
|
{availableVaults.map((vault, i) => {
|
||||||
const minAPY = new BigNumber(vault.apy || 0).decimalPlaces(2).toNumber()
|
const borrowAsset = redBankAssets.find((asset) => asset.denom === vault.denoms.secondary)
|
||||||
const maxAPY = new BigNumber(minAPY).times(ltvToLeverage(vault.ltv.max)).toNumber()
|
const maxBorrowRate = Number(borrowAsset?.borrowRate ?? 0) * vault.ltv.max
|
||||||
|
const minAPY = new BigNumber(vault.apy || 0).toNumber()
|
||||||
|
|
||||||
const leverage = ltvToLeverage(vault.ltv.max)
|
const leverage = ltvToLeverage(vault.ltv.max)
|
||||||
|
const maxAPY =
|
||||||
|
new BigNumber(minAPY).times(leverage).decimalPlaces(2).toNumber() - maxBorrowRate
|
||||||
|
const apyDataNoLev = { total: vault.apy || 0, borrow: 0 }
|
||||||
|
const apyDataLev = { total: vault.apy || 0, borrow: maxBorrowRate }
|
||||||
return (
|
return (
|
||||||
|
<Link
|
||||||
|
key={`${vault.address}-${i}`}
|
||||||
|
href={`/farm/vault/${vault.address}/create`}
|
||||||
|
className={styles.link}
|
||||||
|
>
|
||||||
<div className={styles.grid} key={`${vault.address}-${i}`}>
|
<div className={styles.grid} key={`${vault.address}-${i}`}>
|
||||||
<div className={styles.logo}>
|
<div className={styles.logo}>
|
||||||
<VaultLogo vault={vault} />
|
<VaultLogo vault={vault} />
|
||||||
@ -35,12 +49,24 @@ export const AvailableVaultsTableMobile = () => {
|
|||||||
<VaultName vault={vault} />
|
<VaultName vault={vault} />
|
||||||
</div>
|
</div>
|
||||||
<div className={styles.stats}>
|
<div className={styles.stats}>
|
||||||
<div className='xl'>
|
<div onClick={(e) => e.preventDefault()} className='xl'>
|
||||||
<span className='faded'>{t('common.apy')} </span>
|
<span className='faded'>{t('common.apy')} </span>
|
||||||
<span>
|
<span>
|
||||||
|
<Tippy content={<Apy apyData={apyDataNoLev} leverage={1} />}>
|
||||||
|
<span className='tooltip xl'>
|
||||||
<AnimatedNumber amount={minAPY} suffix='-' />
|
<AnimatedNumber amount={minAPY} suffix='-' />
|
||||||
|
</span>
|
||||||
|
</Tippy>
|
||||||
|
<Tippy
|
||||||
|
content={
|
||||||
|
<Apy apyData={apyDataLev} leverage={ltvToLeverage(vault.ltv.max)} />
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<span className='tooltip xl'>
|
||||||
<AnimatedNumber amount={maxAPY} suffix='%' />
|
<AnimatedNumber amount={maxAPY} suffix='%' />
|
||||||
</span>
|
</span>
|
||||||
|
</Tippy>
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className='s'>
|
<div className='s'>
|
||||||
<span className='faded'>{t('fields.leverage')} </span>
|
<span className='faded'>{t('fields.leverage')} </span>
|
||||||
@ -49,19 +75,25 @@ export const AvailableVaultsTableMobile = () => {
|
|||||||
<div className='s'>
|
<div className='s'>
|
||||||
<span className='faded'>{t('fields.vaultCap')} </span>
|
<span className='faded'>{t('fields.vaultCap')} </span>
|
||||||
<span>
|
<span>
|
||||||
{formatValue(
|
<DisplayCurrency
|
||||||
(vault.vaultCap?.max || 0) / 10 ** baseCurrency.decimals,
|
coin={{
|
||||||
0,
|
denom: baseCurrency.denom,
|
||||||
0,
|
amount: (vault.vaultCap?.max || 0).toString(),
|
||||||
true,
|
}}
|
||||||
'',
|
className={styles.inline}
|
||||||
' ' + baseCurrency.symbol,
|
/>
|
||||||
)}
|
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className={styles.description}>{vault.description}</div>
|
<div className={styles.description}>
|
||||||
|
{t('fields.tooltips.name', {
|
||||||
|
asset1: vault.symbols.primary,
|
||||||
|
asset2: vault.symbols.secondary,
|
||||||
|
...getTimeAndUnit(vault.lockup),
|
||||||
|
})}
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
</Link>
|
||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
|
@ -4,6 +4,6 @@
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
width: rem-calc(7);
|
width: rem-calc(7);
|
||||||
height: space(16);
|
height: 100%;
|
||||||
margin-left: rem-calc(-7);
|
margin-left: rem-calc(-7);
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,20 @@
|
|||||||
import { ColumnDef, createColumnHelper } from '@tanstack/react-table'
|
import { ColumnDef, createColumnHelper } from '@tanstack/react-table'
|
||||||
import Tippy from '@tippyjs/react'
|
import Tippy from '@tippyjs/react'
|
||||||
import BigNumber from 'bignumber.js'
|
import BigNumber from 'bignumber.js'
|
||||||
import classNames from 'classnames/bind'
|
import classNames from 'classnames'
|
||||||
import { AnimatedNumber, Button, DisplayCurrency, SVG, TokenBalance } from 'components/common'
|
import {
|
||||||
|
AnimatedNumber,
|
||||||
|
Apy,
|
||||||
|
Button,
|
||||||
|
DisplayCurrency,
|
||||||
|
SVG,
|
||||||
|
TextTooltip,
|
||||||
|
TokenBalance,
|
||||||
|
} from 'components/common'
|
||||||
import { VaultLogo, VaultName } from 'components/fields'
|
import { VaultLogo, VaultName } from 'components/fields'
|
||||||
import { VAULT_DEPOSIT_BUFFER } from 'constants/appConstants'
|
import { VAULT_DEPOSIT_BUFFER } from 'constants/appConstants'
|
||||||
import { convertPercentage } from 'functions'
|
import { convertPercentage } from 'functions'
|
||||||
import { convertApyToDailyApy, formatValue, ltvToLeverage } from 'libs/parse'
|
import { convertApyToDailyApy, formatValue, getTimeAndUnit, ltvToLeverage } from 'libs/parse'
|
||||||
import { useRouter } from 'next/router'
|
import { useRouter } from 'next/router'
|
||||||
import { useMemo } from 'react'
|
import { useMemo } from 'react'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
@ -19,6 +27,8 @@ export const useAvailableVaultsColumns = () => {
|
|||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const baseCurrency = useStore((s) => s.baseCurrency)
|
const baseCurrency = useStore((s) => s.baseCurrency)
|
||||||
const columnHelper = createColumnHelper<Vault>()
|
const columnHelper = createColumnHelper<Vault>()
|
||||||
|
const redBankAssets = useStore((s) => s.redBankAssets)
|
||||||
|
|
||||||
const defaultAvailableVaultsColumns: ColumnDef<Vault, any>[] = useMemo(
|
const defaultAvailableVaultsColumns: ColumnDef<Vault, any>[] = useMemo(
|
||||||
() => [
|
() => [
|
||||||
columnHelper.accessor('color', {
|
columnHelper.accessor('color', {
|
||||||
@ -33,12 +43,39 @@ export const useAvailableVaultsColumns = () => {
|
|||||||
}),
|
}),
|
||||||
columnHelper.accessor('name', {
|
columnHelper.accessor('name', {
|
||||||
enableSorting: true,
|
enableSorting: true,
|
||||||
header: t('fields.position'),
|
header: t('fields.name'),
|
||||||
cell: ({ row }) => <VaultName vault={row.original} />,
|
cell: ({ row }) => {
|
||||||
|
return (
|
||||||
|
<Tippy
|
||||||
|
appendTo={() => document.body}
|
||||||
|
animation={false}
|
||||||
|
render={(attrs) => {
|
||||||
|
return (
|
||||||
|
<div className='tippyContainer' {...attrs}>
|
||||||
|
{t('fields.tooltips.name', {
|
||||||
|
asset1: row.original.symbols.primary,
|
||||||
|
asset2: row.original.symbols.secondary,
|
||||||
|
...getTimeAndUnit(row.original.lockup),
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<VaultName vault={row.original} />
|
||||||
|
</div>
|
||||||
|
</Tippy>
|
||||||
|
)
|
||||||
|
},
|
||||||
}),
|
}),
|
||||||
columnHelper.accessor('ltv', {
|
columnHelper.accessor('ltv', {
|
||||||
enableSorting: true,
|
enableSorting: true,
|
||||||
header: t('fields.leverage'),
|
header: () => (
|
||||||
|
<TextTooltip
|
||||||
|
text={t('fields.leverage')}
|
||||||
|
tooltip={t('fields.tooltips.leverage.available')}
|
||||||
|
/>
|
||||||
|
),
|
||||||
cell: ({ row }) => {
|
cell: ({ row }) => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@ -53,16 +90,22 @@ export const useAvailableVaultsColumns = () => {
|
|||||||
columnHelper.accessor('apy', {
|
columnHelper.accessor('apy', {
|
||||||
id: 'apy',
|
id: 'apy',
|
||||||
enableSorting: true,
|
enableSorting: true,
|
||||||
header: t('common.apy'),
|
header: () => (
|
||||||
|
<TextTooltip text={t('common.apy')} tooltip={t('fields.tooltips.apy.available')} />
|
||||||
|
),
|
||||||
cell: ({ row }) => {
|
cell: ({ row }) => {
|
||||||
if (!row.original.apy) {
|
if (!row.original.apy) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
const maxLeverage = ltvToLeverage(row.original.ltv.max)
|
const maxLeverage = ltvToLeverage(row.original.ltv.max)
|
||||||
|
const borrowAsset = redBankAssets.find(
|
||||||
|
(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).decimalPlaces(2).toNumber()
|
||||||
const maxAPY = new BigNumber(minAPY).times(maxLeverage).decimalPlaces(2).toNumber()
|
|
||||||
|
const maxAPY = new BigNumber(minAPY).times(maxLeverage).toNumber() - maxBorrowRate
|
||||||
const minDailyAPY = new BigNumber(convertApyToDailyApy(row.original.apy))
|
const minDailyAPY = new BigNumber(convertApyToDailyApy(row.original.apy))
|
||||||
.decimalPlaces(2)
|
.decimalPlaces(2)
|
||||||
.toNumber()
|
.toNumber()
|
||||||
@ -70,13 +113,27 @@ export const useAvailableVaultsColumns = () => {
|
|||||||
.times(maxLeverage)
|
.times(maxLeverage)
|
||||||
.decimalPlaces(2)
|
.decimalPlaces(2)
|
||||||
.toNumber()
|
.toNumber()
|
||||||
|
const apyDataNoLev = { total: row.original.apy || 0, borrow: 0 }
|
||||||
|
const apyDataLev = { total: row.original.apy || 0, borrow: maxBorrowRate }
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<p className='m'>
|
<Tippy content={<Apy apyData={apyDataNoLev} leverage={1} />}>
|
||||||
|
<span className='tooltip m'>
|
||||||
<AnimatedNumber amount={minAPY} />
|
<AnimatedNumber amount={minAPY} />
|
||||||
|
</span>
|
||||||
|
</Tippy>
|
||||||
<span>-</span>
|
<span>-</span>
|
||||||
|
<Tippy
|
||||||
|
content={
|
||||||
|
<Apy apyData={apyDataLev} leverage={ltvToLeverage(row.original.ltv.max)} />
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<span className='tooltip ,'>
|
||||||
<AnimatedNumber amount={maxAPY} suffix='%' />
|
<AnimatedNumber amount={maxAPY} suffix='%' />
|
||||||
</p>
|
</span>
|
||||||
|
</Tippy>
|
||||||
|
|
||||||
<p className='s faded'>
|
<p className='s faded'>
|
||||||
{minDailyAPY}-{maxDailyAPY}%/
|
{minDailyAPY}-{maxDailyAPY}%/
|
||||||
{t('common.day')}
|
{t('common.day')}
|
||||||
@ -87,7 +144,9 @@ export const useAvailableVaultsColumns = () => {
|
|||||||
}),
|
}),
|
||||||
columnHelper.accessor('vaultCap', {
|
columnHelper.accessor('vaultCap', {
|
||||||
enableSorting: true,
|
enableSorting: true,
|
||||||
header: t('fields.vaultCap'),
|
header: () => (
|
||||||
|
<TextTooltip text={t('fields.vaultCap')} tooltip={t('fields.tooltips.vaultCap')} />
|
||||||
|
),
|
||||||
cell: ({ row }) => {
|
cell: ({ row }) => {
|
||||||
if (!row.original.vaultCap) {
|
if (!row.original.vaultCap) {
|
||||||
return null
|
return null
|
||||||
@ -140,7 +199,25 @@ export const useAvailableVaultsColumns = () => {
|
|||||||
columnHelper.accessor('description', {
|
columnHelper.accessor('description', {
|
||||||
enableSorting: true,
|
enableSorting: true,
|
||||||
header: t('common.description'),
|
header: t('common.description'),
|
||||||
cell: ({ row }) => <p>{row.original.description}</p>,
|
cell: ({ row }) => (
|
||||||
|
<Tippy
|
||||||
|
appendTo={() => document.body}
|
||||||
|
animation={false}
|
||||||
|
render={(attrs) => {
|
||||||
|
return (
|
||||||
|
<div className='tippyContainer' {...attrs}>
|
||||||
|
{t('fields.tooltips.name', {
|
||||||
|
asset1: row.original.symbols.primary,
|
||||||
|
asset2: row.original.symbols.secondary,
|
||||||
|
...getTimeAndUnit(row.original.lockup),
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<p>{row.original.description}</p>
|
||||||
|
</Tippy>
|
||||||
|
),
|
||||||
}),
|
}),
|
||||||
columnHelper.display({
|
columnHelper.display({
|
||||||
id: 'actions',
|
id: 'actions',
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import classNames from 'classnames/bind'
|
import classNames from 'classnames'
|
||||||
import { BreakdownGraph, BreakdownTable } from 'components/fields'
|
import { BreakdownGraph, BreakdownTable } from 'components/fields'
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import Tippy from '@tippyjs/react'
|
import Tippy from '@tippyjs/react'
|
||||||
import classNames from 'classnames/bind'
|
import classNames from 'classnames'
|
||||||
|
|
||||||
import styles from './AssetBar.module.scss'
|
import styles from './AssetBar.module.scss'
|
||||||
|
|
||||||
@ -12,11 +12,11 @@ interface Props {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const AssetBar = (props: Props) => {
|
export const AssetBar = (props: Props) => {
|
||||||
const labelClasses = classNames([
|
const labelClasses = classNames(
|
||||||
styles.label,
|
styles.label,
|
||||||
props.alignRight && styles.alignRight,
|
props.alignRight && styles.alignRight,
|
||||||
props.showLabel ? styles.show : styles.hide,
|
props.showLabel ? styles.show : styles.hide,
|
||||||
])
|
)
|
||||||
return (
|
return (
|
||||||
<Tippy
|
<Tippy
|
||||||
content={
|
content={
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
import classNames from 'classnames/bind'
|
import classNames from 'classnames'
|
||||||
import { DisplayCurrency } from 'components/common'
|
import { DisplayCurrency } from 'components/common'
|
||||||
import { AssetBar } from 'components/fields'
|
import { AssetBar } from 'components/fields'
|
||||||
import { lookup } from 'libs/parse'
|
import { lookup } from 'libs/parse'
|
||||||
import React from 'react'
|
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import useStore from 'store'
|
import useStore from 'store'
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import Tippy from '@tippyjs/react'
|
import Tippy from '@tippyjs/react'
|
||||||
import classNames from 'classnames/bind'
|
import classNames from 'classnames'
|
||||||
import {
|
import {
|
||||||
AnimatedNumber,
|
AnimatedNumber,
|
||||||
Apy,
|
Apy,
|
||||||
|
@ -1,16 +1,13 @@
|
|||||||
import { ExecuteResult } from '@cosmjs/cosmwasm-stargate'
|
|
||||||
import { TxResponse } from 'components/common'
|
import { TxResponse } from 'components/common'
|
||||||
import { useFieldsActionMessages } from 'hooks/data'
|
import { useFieldsActionMessages } from 'hooks/data'
|
||||||
import { useRouter } from 'next/router'
|
import { useRouter } from 'next/router'
|
||||||
import React from 'react'
|
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import useStore from 'store'
|
import useStore from 'store'
|
||||||
|
|
||||||
import styles from './ClosePositionResponse.module.scss'
|
import styles from './ClosePositionResponse.module.scss'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
data?: ExecuteResult
|
data?: ResultData
|
||||||
error: Error | null
|
|
||||||
isLoading: boolean
|
isLoading: boolean
|
||||||
accountId: string
|
accountId: string
|
||||||
}
|
}
|
||||||
@ -20,7 +17,7 @@ export const ClosePositionResponse = (props: Props) => {
|
|||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const getVaults = useStore((s) => s.getVaults)
|
const getVaults = useStore((s) => s.getVaults)
|
||||||
|
|
||||||
const { repayMessage, withdrawMessage } = useFieldsActionMessages(props.data)
|
const { repayMessage, withdrawMessage } = useFieldsActionMessages(props.data?.result)
|
||||||
|
|
||||||
const actions = [
|
const actions = [
|
||||||
...(repayMessage ? [repayMessage] : []),
|
...(repayMessage ? [repayMessage] : []),
|
||||||
@ -30,12 +27,12 @@ export const ClosePositionResponse = (props: Props) => {
|
|||||||
return (
|
return (
|
||||||
<div className={styles.container}>
|
<div className={styles.container}>
|
||||||
<TxResponse
|
<TxResponse
|
||||||
error={props.error?.message}
|
error={props.data?.error}
|
||||||
handleClose={() => router.replace('/farm')}
|
handleClose={() => router.replace('/farm')}
|
||||||
onSuccess={() => {
|
onSuccess={() => {
|
||||||
getVaults({ refetch: true })
|
getVaults({ refetch: true })
|
||||||
}}
|
}}
|
||||||
response={props.data}
|
response={props.data?.result}
|
||||||
title={t('fields.txMessages.close')}
|
title={t('fields.txMessages.close')}
|
||||||
actions={actions}
|
actions={actions}
|
||||||
/>
|
/>
|
||||||
|
@ -1,40 +1,38 @@
|
|||||||
import { ExecuteResult } from '@cosmjs/cosmwasm-stargate'
|
|
||||||
import { TxResponse } from 'components/common'
|
import { TxResponse } from 'components/common'
|
||||||
import { useFieldsActionMessages } from 'hooks/data'
|
import { useFieldsActionMessages } from 'hooks/data'
|
||||||
import { useRouter } from 'next/router'
|
import { useRouter } from 'next/router'
|
||||||
import React from 'react'
|
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import useStore from 'store'
|
import useStore from 'store'
|
||||||
|
|
||||||
import styles from './EditResponse.module.scss'
|
import styles from './EditResponse.module.scss'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
data?: ExecuteResult
|
data?: ResultData
|
||||||
error: Error | null
|
|
||||||
isLoading: boolean
|
isLoading: boolean
|
||||||
activeVault: ActiveVault
|
activeVault: ActiveVault
|
||||||
}
|
}
|
||||||
|
|
||||||
export const EditResponse = (props: Props) => {
|
export const EditResponse = (props: Props) => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const getVaults = useStore((s) => s.getVaults)
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const { depositMessage, borrowMessage, swapMessage } = useFieldsActionMessages(props.data)
|
const getVaults = useStore((s) => s.getVaults)
|
||||||
|
const { depositMessage, borrowMessage, swapMessage } = useFieldsActionMessages(props.data?.result)
|
||||||
|
|
||||||
const actions = [
|
const actions = [
|
||||||
...(depositMessage ? [depositMessage] : []),
|
...(depositMessage ? [depositMessage] : []),
|
||||||
...(borrowMessage ? [borrowMessage] : []),
|
...(borrowMessage ? [borrowMessage] : []),
|
||||||
...(swapMessage ? [swapMessage] : []),
|
...(swapMessage ? [swapMessage] : []),
|
||||||
]
|
]
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.container}>
|
<div className={styles.container}>
|
||||||
<TxResponse
|
<TxResponse
|
||||||
error={props.error?.message}
|
error={props.data?.error}
|
||||||
handleClose={() => router.replace('/farm')}
|
handleClose={() => router.replace('/farm')}
|
||||||
onSuccess={() => {
|
onSuccess={() => {
|
||||||
getVaults({ refetch: true })
|
getVaults({ refetch: true })
|
||||||
}}
|
}}
|
||||||
response={props.data}
|
response={props.data?.result}
|
||||||
title={t('fields.txMessages.edit')}
|
title={t('fields.txMessages.edit')}
|
||||||
actions={actions}
|
actions={actions}
|
||||||
/>
|
/>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import classNames from 'classnames/bind'
|
import classNames from 'classnames'
|
||||||
import { Tutorial } from 'components/common'
|
import { Tutorial } from 'components/common'
|
||||||
import { TokenInput } from 'components/fields'
|
import { TokenInput } from 'components/fields'
|
||||||
import { FIELDS_TUTORIAL_KEY } from 'constants/appConstants'
|
import { FIELDS_TUTORIAL_KEY } from 'constants/appConstants'
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import BigNumber from 'bignumber.js'
|
import BigNumber from 'bignumber.js'
|
||||||
import classNames from 'classnames/bind'
|
import classNames from 'classnames'
|
||||||
import { InputSlider, Tutorial } from 'components/common'
|
import { InputSlider, Tutorial } from 'components/common'
|
||||||
import { FIELDS_TUTORIAL_KEY } from 'constants/appConstants'
|
import { FIELDS_TUTORIAL_KEY } from 'constants/appConstants'
|
||||||
import { formatValue, ltvToLeverage } from 'libs/parse'
|
import { formatValue, ltvToLeverage } from 'libs/parse'
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import classNames from 'classnames/bind'
|
import classNames from 'classnames'
|
||||||
import { Button, SVG, Tutorial } from 'components/common'
|
import { Button, SVG, Tutorial } from 'components/common'
|
||||||
import { TokenInput } from 'components/fields'
|
import { TokenInput } from 'components/fields'
|
||||||
import { FIELDS_TUTORIAL_KEY } from 'constants/appConstants'
|
import { FIELDS_TUTORIAL_KEY } from 'constants/appConstants'
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { Coin } from '@cosmjs/proto-signing'
|
import { Coin } from '@cosmjs/proto-signing'
|
||||||
import classNames from 'classnames/bind'
|
import classNames from 'classnames'
|
||||||
import { Button, DisplayCurrency, NumberInput } from 'components/common'
|
import { Button, DisplayCurrency, NumberInput } from 'components/common'
|
||||||
import { findByDenom } from 'functions'
|
import { findByDenom } from 'functions'
|
||||||
import { useAsset } from 'hooks/data'
|
import { useAsset } from 'hooks/data'
|
||||||
|
@ -1,16 +1,13 @@
|
|||||||
import { ExecuteResult } from '@cosmjs/cosmwasm-stargate'
|
|
||||||
import { TxResponse } from 'components/common'
|
import { TxResponse } from 'components/common'
|
||||||
import { useFieldsActionMessages } from 'hooks/data'
|
import { useFieldsActionMessages } from 'hooks/data'
|
||||||
import { useRouter } from 'next/router'
|
import { useRouter } from 'next/router'
|
||||||
import React from 'react'
|
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import useStore from 'store'
|
import useStore from 'store'
|
||||||
|
|
||||||
import styles from './RepayResponse.module.scss'
|
import styles from './RepayResponse.module.scss'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
data?: ExecuteResult
|
data?: ResultData
|
||||||
error: Error | null
|
|
||||||
isLoading: boolean
|
isLoading: boolean
|
||||||
vault: ActiveVault
|
vault: ActiveVault
|
||||||
}
|
}
|
||||||
@ -19,19 +16,19 @@ export const RepayResponse = (props: Props) => {
|
|||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const getVaults = useStore((s) => s.getVaults)
|
const getVaults = useStore((s) => s.getVaults)
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const { repayMessage } = useFieldsActionMessages(props.data)
|
const { repayMessage } = useFieldsActionMessages(props.data?.result)
|
||||||
|
|
||||||
const actions = [...(repayMessage ? [repayMessage] : [])]
|
const actions = [...(repayMessage ? [repayMessage] : [])]
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.container}>
|
<div className={styles.container}>
|
||||||
<TxResponse
|
<TxResponse
|
||||||
error={props.error?.message}
|
error={props.data?.error}
|
||||||
handleClose={() => router.replace('/farm')}
|
handleClose={() => router.replace('/farm')}
|
||||||
onSuccess={() => {
|
onSuccess={() => {
|
||||||
getVaults({ refetch: true })
|
getVaults({ refetch: true })
|
||||||
}}
|
}}
|
||||||
response={props.data}
|
response={props.data?.result}
|
||||||
title={t('fields.txMessages.repay')}
|
title={t('fields.txMessages.repay')}
|
||||||
actions={actions}
|
actions={actions}
|
||||||
/>
|
/>
|
||||||
|
@ -1,16 +1,13 @@
|
|||||||
import { ExecuteResult } from '@cosmjs/cosmwasm-stargate'
|
|
||||||
import { TxResponse } from 'components/common'
|
import { TxResponse } from 'components/common'
|
||||||
import { useFieldsActionMessages } from 'hooks/data'
|
import { useFieldsActionMessages } from 'hooks/data'
|
||||||
import { useRouter } from 'next/router'
|
import { useRouter } from 'next/router'
|
||||||
import React from 'react'
|
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import useStore from 'store'
|
import useStore from 'store'
|
||||||
|
|
||||||
import styles from './SetUpResponse.module.scss'
|
import styles from './SetUpResponse.module.scss'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
data?: ExecuteResult
|
data?: ResultData
|
||||||
error: Error | null
|
|
||||||
isLoading: boolean
|
isLoading: boolean
|
||||||
accountId: string
|
accountId: string
|
||||||
}
|
}
|
||||||
@ -18,8 +15,8 @@ interface Props {
|
|||||||
export const SetUpResponse = (props: Props) => {
|
export const SetUpResponse = (props: Props) => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const { depositMessage, borrowMessage, swapMessage } = useFieldsActionMessages(props.data)
|
|
||||||
const getVaults = useStore((s) => s.getVaults)
|
const getVaults = useStore((s) => s.getVaults)
|
||||||
|
const { depositMessage, borrowMessage, swapMessage } = useFieldsActionMessages(props.data?.result)
|
||||||
|
|
||||||
const actions = [
|
const actions = [
|
||||||
...(depositMessage ? [depositMessage] : []),
|
...(depositMessage ? [depositMessage] : []),
|
||||||
@ -30,12 +27,12 @@ export const SetUpResponse = (props: Props) => {
|
|||||||
return (
|
return (
|
||||||
<div className={styles.container}>
|
<div className={styles.container}>
|
||||||
<TxResponse
|
<TxResponse
|
||||||
error={props.error?.message}
|
error={props.data?.error}
|
||||||
handleClose={() => router.replace('/farm')}
|
handleClose={() => router.replace('/farm')}
|
||||||
onSuccess={() => {
|
onSuccess={() => {
|
||||||
getVaults({ refetch: true })
|
getVaults({ refetch: true })
|
||||||
}}
|
}}
|
||||||
response={props.data}
|
response={props.data?.result}
|
||||||
title={t('fields.txMessages.setup')}
|
title={t('fields.txMessages.setup')}
|
||||||
actions={actions}
|
actions={actions}
|
||||||
/>
|
/>
|
||||||
|
@ -1,16 +1,13 @@
|
|||||||
import { ExecuteResult } from '@cosmjs/cosmwasm-stargate'
|
|
||||||
import { TxResponse } from 'components/common'
|
import { TxResponse } from 'components/common'
|
||||||
import { useFieldsActionMessages } from 'hooks/data'
|
import { useFieldsActionMessages } from 'hooks/data'
|
||||||
import { useRouter } from 'next/router'
|
import { useRouter } from 'next/router'
|
||||||
import React from 'react'
|
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import useStore from 'store'
|
import useStore from 'store'
|
||||||
|
|
||||||
import styles from './UnlockResponse.module.scss'
|
import styles from './UnlockResponse.module.scss'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
data?: ExecuteResult
|
data?: ResultData
|
||||||
error: Error | null
|
|
||||||
isLoading: boolean
|
isLoading: boolean
|
||||||
activeVault: ActiveVault
|
activeVault: ActiveVault
|
||||||
}
|
}
|
||||||
@ -19,15 +16,15 @@ export const UnlockResponse = (props: Props) => {
|
|||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const getVaults = useStore((s) => s.getVaults)
|
const getVaults = useStore((s) => s.getVaults)
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const { unlockMessages } = useFieldsActionMessages(props.data, props.activeVault)
|
const { unlockMessages } = useFieldsActionMessages(props.data?.result, props.activeVault)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.container}>
|
<div className={styles.container}>
|
||||||
<TxResponse
|
<TxResponse
|
||||||
error={props.error?.message}
|
error={props.data?.error}
|
||||||
handleClose={() => router.replace('/farm')}
|
handleClose={() => router.replace('/farm')}
|
||||||
onSuccess={() => getVaults({ refetch: true })}
|
onSuccess={() => getVaults({ refetch: true })}
|
||||||
response={props.data}
|
response={props.data?.result}
|
||||||
title={t('fields.txMessages.unlock')}
|
title={t('fields.txMessages.unlock')}
|
||||||
actions={unlockMessages}
|
actions={unlockMessages}
|
||||||
/>
|
/>
|
||||||
|
@ -58,7 +58,7 @@ export const ActionsRow = ({ row, type }: Props) => {
|
|||||||
<div className='tippyContainer' {...attrs}>
|
<div className='tippyContainer' {...attrs}>
|
||||||
{t('redbank.toDepositAssetOnChain', {
|
{t('redbank.toDepositAssetOnChain', {
|
||||||
asset: assetSymbol,
|
asset: assetSymbol,
|
||||||
chain: chainInfo?.chainName,
|
chain: chainInfo?.name,
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
@ -27,7 +27,7 @@ export const useBorrowColumns = () => {
|
|||||||
header: '',
|
header: '',
|
||||||
cell: (info) => (
|
cell: (info) => (
|
||||||
<div className={styles.logo}>
|
<div className={styles.logo}>
|
||||||
<Image alt='logo' height='100%' src={info.getValue().src} width='100%' />
|
<Image alt='logo' src={info.getValue().src} width={32} height={32} />
|
||||||
</div>
|
</div>
|
||||||
),
|
),
|
||||||
}),
|
}),
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { ColumnDef, createColumnHelper } from '@tanstack/react-table'
|
import { ColumnDef, createColumnHelper } from '@tanstack/react-table'
|
||||||
import Tippy from '@tippyjs/react'
|
import Tippy from '@tippyjs/react'
|
||||||
import classNames from 'classnames/bind'
|
import classNames from 'classnames'
|
||||||
import { AnimatedNumber, Apr, Button, CellAmount, SVG } from 'components/common'
|
import { AnimatedNumber, Apr, Button, CellAmount, SVG } from 'components/common'
|
||||||
import { convertPercentage } from 'functions'
|
import { convertPercentage } from 'functions'
|
||||||
import { formatValue } from 'libs/parse'
|
import { formatValue } from 'libs/parse'
|
||||||
@ -32,7 +32,7 @@ export const useDepositColumns = () => {
|
|||||||
header: '',
|
header: '',
|
||||||
cell: (info) => (
|
cell: (info) => (
|
||||||
<div className={styles.logo}>
|
<div className={styles.logo}>
|
||||||
<Image alt='logo' height='100%' src={info.getValue().src} width='100%' />
|
<Image alt='logo' src={info.getValue().src} width={32} height={32} />
|
||||||
</div>
|
</div>
|
||||||
),
|
),
|
||||||
}),
|
}),
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { ExecuteResult } from '@cosmjs/cosmwasm-stargate'
|
import { TxBroadcastResult } from '@marsprotocol/wallet-connector'
|
||||||
import { useQueryClient } from '@tanstack/react-query'
|
import { useQueryClient } from '@tanstack/react-query'
|
||||||
import { Action, Notification, TxResponse } from 'components/common'
|
import { Action, Notification, TxResponse } from 'components/common'
|
||||||
import { findByDenom } from 'functions'
|
import { findByDenom } from 'functions'
|
||||||
@ -13,8 +13,7 @@ import { ltvWeightedDepositValue, maintainanceMarginWeightedDepositValue } from
|
|||||||
import { lookup, lookupDecimals } from 'libs/parse'
|
import { lookup, lookupDecimals } from 'libs/parse'
|
||||||
import isEqual from 'lodash.isequal'
|
import isEqual from 'lodash.isequal'
|
||||||
import { useRouter } from 'next/router'
|
import { useRouter } from 'next/router'
|
||||||
import { useMemo, useState } from 'react'
|
import React, { useMemo, useState } from 'react'
|
||||||
import React from 'react'
|
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import useStore from 'store'
|
import useStore from 'store'
|
||||||
import { NotificationType, ViewType } from 'types/enums'
|
import { NotificationType, ViewType } from 'types/enums'
|
||||||
@ -54,7 +53,7 @@ export const RedbankAction = React.memo(
|
|||||||
// ------------------
|
// ------------------
|
||||||
const [amount, setAmount] = useState(0)
|
const [amount, setAmount] = useState(0)
|
||||||
const [submitted, setSubmitted] = useState(false)
|
const [submitted, setSubmitted] = useState(false)
|
||||||
const [response, setResponse] = useState<ExecuteResult>()
|
const [response, setResponse] = useState<TxBroadcastResult>()
|
||||||
const [error, setError] = useState<string>()
|
const [error, setError] = useState<string>()
|
||||||
const [isMax, setIsMax] = useState<boolean>(false)
|
const [isMax, setIsMax] = useState<boolean>(false)
|
||||||
const [capHit, setCapHit] = useState<boolean>(false)
|
const [capHit, setCapHit] = useState<boolean>(false)
|
||||||
@ -126,7 +125,7 @@ export const RedbankAction = React.memo(
|
|||||||
funds:
|
funds:
|
||||||
activeView === ViewType.Deposit || activeView === ViewType.Repay
|
activeView === ViewType.Deposit || activeView === ViewType.Repay
|
||||||
? [{ denom, amount: amount > 0 ? amount.toFixed(0) : '1' }]
|
? [{ denom, amount: amount > 0 ? amount.toFixed(0) : '1' }]
|
||||||
: [],
|
: undefined,
|
||||||
contract: redBankContractAddress,
|
contract: redBankContractAddress,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { ChainInfoID } from '@marsprotocol/wallet-connector'
|
import { ChainInfoID, WalletID } from '@marsprotocol/wallet-connector'
|
||||||
import atom from 'images/atom.svg'
|
import atom from 'images/atom.svg'
|
||||||
import axlusdc from 'images/axlusdc.svg'
|
import axlusdc from 'images/axlusdc.svg'
|
||||||
import juno from 'images/juno.svg'
|
import juno from 'images/juno.svg'
|
||||||
@ -63,9 +63,9 @@ const OTHER_ASSETS: { [denom: string]: OtherAsset } = {
|
|||||||
|
|
||||||
export const NETWORK_CONFIG: NetworkConfig = {
|
export const NETWORK_CONFIG: NetworkConfig = {
|
||||||
name: ChainInfoID.OsmosisTestnet,
|
name: ChainInfoID.OsmosisTestnet,
|
||||||
hiveUrl: 'https://osmosis-delphi-testnet-1.simply-vc.com.mt/XF32UOOU55CX/osmosis-hive/graphql',
|
hiveUrl: 'https://osmosis-delphi-testnet-1.simply-vc.com.mt/XF32UOOU55CX/osmosis-hive/graphql/',
|
||||||
rpcUrl: 'https://osmosis-delphi-testnet-1.simply-vc.com.mt/XF32UOOU55CX/osmosis-rpc',
|
rpcUrl: 'https://osmosis-delphi-testnet-1.simply-vc.com.mt/XF32UOOU55CX/osmosis-rpc/',
|
||||||
restUrl: 'https://osmosis-delphi-testnet-1.simply-vc.com.mt/XF32UOOU55CX/osmosis-lcd',
|
restUrl: 'https://osmosis-delphi-testnet-1.simply-vc.com.mt/XF32UOOU55CX/osmosis-lcd/',
|
||||||
apolloAprUrl: 'https://stats.apollo.farm/api/apr/v1/all',
|
apolloAprUrl: 'https://stats.apollo.farm/api/apr/v1/all',
|
||||||
contracts: {
|
contracts: {
|
||||||
addressProvider: 'osmo17dyy6hyzzy6u5khy5lau7afa2y9kwknu0aprwqn8twndw2qhv8ls6msnjr',
|
addressProvider: 'osmo17dyy6hyzzy6u5khy5lau7afa2y9kwknu0aprwqn8twndw2qhv8ls6msnjr',
|
||||||
@ -76,8 +76,8 @@ export const NETWORK_CONFIG: NetworkConfig = {
|
|||||||
treasury: 'osmo1qv74pu0gjc9vuvkhayuj5j3q8fzmf4pnl643djqpv7enxr925g5q0wf7p3',
|
treasury: 'osmo1qv74pu0gjc9vuvkhayuj5j3q8fzmf4pnl643djqpv7enxr925g5q0wf7p3',
|
||||||
safetyFund: 'osmo1j2mnzs7eqld4umtwky4hyf6f7kqcsg7ragh2l76ev7ucxcjvdjrs3tdezf',
|
safetyFund: 'osmo1j2mnzs7eqld4umtwky4hyf6f7kqcsg7ragh2l76ev7ucxcjvdjrs3tdezf',
|
||||||
protocolRewardsCollector: 'osmo1xl7jguvkg807ya00s0l722nwcappfzyzrac3ug5tnjassnrmnfrs47wguz',
|
protocolRewardsCollector: 'osmo1xl7jguvkg807ya00s0l722nwcappfzyzrac3ug5tnjassnrmnfrs47wguz',
|
||||||
creditManager: 'osmo1prwnxn3vlvh0kqmwxn8whqnavk8ze9hrccwpsapysgpa3pj8r2csy84grp',
|
creditManager: 'osmo169xhpftsee275j3cjudj6qfzdpfp8sdllgeeprud4ynwr4sj6m4qel2ezp',
|
||||||
accountNft: 'osmo1ua5rw84jxg6e7ma4hx7v7yhqcks74cjnx38gpnsvtfzrtxhwcvjqgsxulx',
|
accountNft: 'osmo1xpgx06z2c6zjk49feq75swgv78m6dvht6wramu2gltzjz5j959nq4hggxz',
|
||||||
},
|
},
|
||||||
assets: {
|
assets: {
|
||||||
base: ASSETS.osmo,
|
base: ASSETS.osmo,
|
||||||
@ -85,7 +85,8 @@ export const NETWORK_CONFIG: NetworkConfig = {
|
|||||||
other: [OTHER_ASSETS.mars, OTHER_ASSETS.axlusdc],
|
other: [OTHER_ASSETS.mars, OTHER_ASSETS.axlusdc],
|
||||||
},
|
},
|
||||||
appUrl: 'https://testnet.osmosis.zone',
|
appUrl: 'https://testnet.osmosis.zone',
|
||||||
councilUrl: 'https://testnet.keplr.app/chains/mars-protocol-testnet',
|
councilUrl: 'https://testnet.keplr.app/chains/mars-hub-testnet',
|
||||||
|
wallets: [WalletID.Keplr, WalletID.Leap, WalletID.Cosmostation],
|
||||||
}
|
}
|
||||||
|
|
||||||
export const VAULT_CONFIGS: Vault[] = [
|
export const VAULT_CONFIGS: Vault[] = [
|
||||||
@ -104,7 +105,8 @@ export const VAULT_CONFIGS: Vault[] = [
|
|||||||
color: '#DD5B65',
|
color: '#DD5B65',
|
||||||
lockup: 86400,
|
lockup: 86400,
|
||||||
provider: 'Apollo vault',
|
provider: 'Apollo vault',
|
||||||
description: 'Up to 2× Leveraged Yield Farming with auto compounding of the LP tokens.',
|
description:
|
||||||
|
'Up to 2.67× leveraged yield farming with auto compounding of the OSMO-ATOM LP tokens.',
|
||||||
ltv: {
|
ltv: {
|
||||||
max: 0.625,
|
max: 0.625,
|
||||||
contract: 0.63,
|
contract: 0.63,
|
||||||
@ -126,7 +128,8 @@ export const VAULT_CONFIGS: Vault[] = [
|
|||||||
color: '#DD5B65',
|
color: '#DD5B65',
|
||||||
lockup: 86400 * 14,
|
lockup: 86400 * 14,
|
||||||
provider: 'Apollo vault',
|
provider: 'Apollo vault',
|
||||||
description: 'Up to 2× Leveraged Yield Farming with auto compounding of the LP tokens.',
|
description:
|
||||||
|
'Up to 2.67× leveraged yield farming with auto compounding of the OSMO-ATOM LP tokens.',
|
||||||
ltv: {
|
ltv: {
|
||||||
max: 0.625,
|
max: 0.625,
|
||||||
contract: 0.63,
|
contract: 0.63,
|
||||||
@ -148,7 +151,8 @@ export const VAULT_CONFIGS: Vault[] = [
|
|||||||
color: '#DD5B65',
|
color: '#DD5B65',
|
||||||
lockup: 86400 * 1,
|
lockup: 86400 * 1,
|
||||||
provider: 'Apollo vault',
|
provider: 'Apollo vault',
|
||||||
description: 'Up to 2× Leveraged Yield Farming with auto compounding of the LP tokens.',
|
description:
|
||||||
|
'Up to 1.67× leveraged yield farming with auto compounding of the OSMO-JUNO LP tokens.',
|
||||||
ltv: {
|
ltv: {
|
||||||
max: 0.4,
|
max: 0.4,
|
||||||
contract: 0.4115,
|
contract: 0.4115,
|
||||||
@ -170,7 +174,8 @@ export const VAULT_CONFIGS: Vault[] = [
|
|||||||
color: '#DD5B65',
|
color: '#DD5B65',
|
||||||
lockup: 86400 * 14,
|
lockup: 86400 * 14,
|
||||||
provider: 'Apollo vault',
|
provider: 'Apollo vault',
|
||||||
description: 'Up to 2× Leveraged Yield Farming with auto compounding of the LP tokens.',
|
description:
|
||||||
|
'Up to 1.67× leveraged yield farming with auto compounding of the OSMO-JUNO LP tokens.',
|
||||||
ltv: {
|
ltv: {
|
||||||
max: 0.4,
|
max: 0.4,
|
||||||
contract: 4.115,
|
contract: 4.115,
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { ChainInfoID } from '@marsprotocol/wallet-connector'
|
import { ChainInfoID, WalletID } from '@marsprotocol/wallet-connector'
|
||||||
import atom from 'images/atom.svg'
|
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'
|
||||||
@ -50,9 +50,9 @@ const OTHER_ASSETS: { [denom: string]: OtherAsset } = {
|
|||||||
|
|
||||||
export const NETWORK_CONFIG: NetworkConfig = {
|
export const NETWORK_CONFIG: NetworkConfig = {
|
||||||
name: ChainInfoID.OsmosisTestnet,
|
name: ChainInfoID.OsmosisTestnet,
|
||||||
hiveUrl: 'https://osmosis-delphi-testnet-1.simply-vc.com.mt/XF32UOOU55CX/osmosis-hive/graphql',
|
hiveUrl: 'https://osmosis-delphi-testnet-1.simply-vc.com.mt/XF32UOOU55CX/osmosis-hive/graphql/',
|
||||||
rpcUrl: 'https://osmosis-delphi-testnet-1.simply-vc.com.mt/XF32UOOU55CX/osmosis-rpc',
|
rpcUrl: 'https://osmosis-delphi-testnet-1.simply-vc.com.mt/XF32UOOU55CX/osmosis-rpc/',
|
||||||
restUrl: 'https://osmosis-delphi-testnet-1.simply-vc.com.mt/XF32UOOU55CX/osmosis-lcd',
|
restUrl: 'https://osmosis-delphi-testnet-1.simply-vc.com.mt/XF32UOOU55CX/osmosis-lcd/',
|
||||||
apolloAprUrl: 'https://stats.apollo.farm/api/apr/v1/all',
|
apolloAprUrl: 'https://stats.apollo.farm/api/apr/v1/all',
|
||||||
contracts: {
|
contracts: {
|
||||||
addressProvider: 'osmo17dyy6hyzzy6u5khy5lau7afa2y9kwknu0aprwqn8twndw2qhv8ls6msnjr',
|
addressProvider: 'osmo17dyy6hyzzy6u5khy5lau7afa2y9kwknu0aprwqn8twndw2qhv8ls6msnjr',
|
||||||
@ -72,7 +72,8 @@ export const NETWORK_CONFIG: NetworkConfig = {
|
|||||||
other: [OTHER_ASSETS.mars],
|
other: [OTHER_ASSETS.mars],
|
||||||
},
|
},
|
||||||
appUrl: 'https://testnet.osmosis.zone',
|
appUrl: 'https://testnet.osmosis.zone',
|
||||||
councilUrl: 'https://testnet.keplr.app/chains/mars-protocol-testnet',
|
councilUrl: 'https://council.marsprotocol.io',
|
||||||
|
wallets: [WalletID.Keplr, WalletID.Leap, WalletID.Cosmostation, WalletID.Falcon],
|
||||||
}
|
}
|
||||||
|
|
||||||
export const VAULT_CONFIGS: Vault[] = [
|
export const VAULT_CONFIGS: Vault[] = [
|
||||||
|
@ -11,7 +11,7 @@ export const DEFAULT_SLIPPAGE = 0.01
|
|||||||
|
|
||||||
/* other */
|
/* other */
|
||||||
export const FEE_EST_AMOUNT = '1'
|
export const FEE_EST_AMOUNT = '1'
|
||||||
export const SESSION_WALLET_KEY = 'walletConnection'
|
export const SESSION_WALLET_KEY = 'shuttle'
|
||||||
export const SWAP_THRESHOLD = 10
|
export const SWAP_THRESHOLD = 10
|
||||||
export const VAULT_DEPOSIT_BUFFER = 0.99
|
export const VAULT_DEPOSIT_BUFFER = 0.99
|
||||||
export const GAS_ADJUSTMENT = 1.3
|
export const GAS_ADJUSTMENT = 1.3
|
||||||
|
@ -19,7 +19,11 @@ export const DEFAULT_POSITION: Position = {
|
|||||||
total: 0,
|
total: 0,
|
||||||
net: 0,
|
net: 0,
|
||||||
},
|
},
|
||||||
apy: 0,
|
apy: {
|
||||||
|
borrow: 5.2,
|
||||||
|
net: 7.7,
|
||||||
|
total: 19,
|
||||||
|
},
|
||||||
ltv: 0.5,
|
ltv: 0.5,
|
||||||
currentLeverage: 1,
|
currentLeverage: 1,
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,14 +0,0 @@
|
|||||||
import { ExecuteResult } from '@cosmjs/cosmwasm-stargate'
|
|
||||||
|
|
||||||
export const getAmountFromUnlockRes = (unlockData: ExecuteResult) => {
|
|
||||||
const stringValue = unlockData?.logs[0].events
|
|
||||||
.find((item) => item.type === 'coin_received')
|
|
||||||
?.attributes.find((item) => item.key === 'amount')?.value
|
|
||||||
|
|
||||||
if (!stringValue) return ''
|
|
||||||
|
|
||||||
if (stringValue?.indexOf('ibc/') > 0) {
|
|
||||||
return stringValue.split('ibc/')[0]
|
|
||||||
}
|
|
||||||
return stringValue.split('factory/')[0]
|
|
||||||
}
|
|
@ -1,4 +1,4 @@
|
|||||||
import { findAssetByDenom, formatValue } from 'libs/parse'
|
import { findAssetByDenom, formatValue, lookup } from 'libs/parse'
|
||||||
import { Coin } from 'types/generated/mars-credit-manager/MarsCreditManager.types'
|
import { Coin } from 'types/generated/mars-credit-manager/MarsCreditManager.types'
|
||||||
|
|
||||||
export const getTokenValueFromCoins = (assets: Asset[], coins: Coin[] = []) => {
|
export const getTokenValueFromCoins = (assets: Asset[], coins: Coin[] = []) => {
|
||||||
@ -7,6 +7,15 @@ export const getTokenValueFromCoins = (assets: Asset[], coins: Coin[] = []) => {
|
|||||||
|
|
||||||
if (!asset) return ''
|
if (!asset) return ''
|
||||||
|
|
||||||
return `${formatValue(Number(token.amount) / 10 ** asset.decimals, 2, 2, true)} ${asset.symbol}`
|
const convertedValue = lookup(Number(token.amount), asset.symbol, asset.decimals)
|
||||||
|
|
||||||
|
return formatValue(
|
||||||
|
convertedValue,
|
||||||
|
2,
|
||||||
|
2,
|
||||||
|
true,
|
||||||
|
convertedValue >= 0.01 ? false : '>',
|
||||||
|
` ${asset.symbol}`,
|
||||||
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
// @index(['./*.ts'], f => `export { ${f.name} } from '${f.path}'`)
|
// @index(['./*.ts'], f => `export { ${f.name} } from '${f.path}'`)
|
||||||
export { coinsToActionCoins } from './coinsToActionCoins'
|
export { coinsToActionCoins } from './coinsToActionCoins'
|
||||||
export { getAmountFromUnlockRes } from './getAmountFromUnlockRes'
|
|
||||||
export { getAmountsFromActiveVault } from './getAmountsFromActiveVault'
|
export { getAmountsFromActiveVault } from './getAmountsFromActiveVault'
|
||||||
export { getClosePositionActions } from './getClosePositionActions'
|
export { getClosePositionActions } from './getClosePositionActions'
|
||||||
export { getCoinFromPosition } from './getCoinFromPosition'
|
export { getCoinFromPosition } from './getCoinFromPosition'
|
||||||
|
15
src/functions/getFeeFromResponse.ts
Normal file
15
src/functions/getFeeFromResponse.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import { Coin } from '@cosmjs/launchpad'
|
||||||
|
import { TxBroadcastResult } from '@marsprotocol/wallet-connector'
|
||||||
|
import { extractCoinFromLog } from 'libs/parse'
|
||||||
|
|
||||||
|
export const getFeeFromResponse = (response: TxBroadcastResult): Coin | null => {
|
||||||
|
const stringValue = response?.response.events
|
||||||
|
.filter((msg: Record<string, string>) => msg.type === 'tx')
|
||||||
|
.map((msg: Record<string, string>) => msg.attributes)
|
||||||
|
.flat()
|
||||||
|
.find((msg: Record<string, string>) => msg.key === 'fee')?.value
|
||||||
|
|
||||||
|
if (!stringValue) return null
|
||||||
|
|
||||||
|
return extractCoinFromLog(stringValue)
|
||||||
|
}
|
@ -2,6 +2,7 @@
|
|||||||
export { convertPercentage } from './convertPercentage'
|
export { convertPercentage } from './convertPercentage'
|
||||||
export { findByDenom } from './findByDenom'
|
export { findByDenom } from './findByDenom'
|
||||||
export { formatToValueSymbol } from './formatToValueSymbol'
|
export { formatToValueSymbol } from './formatToValueSymbol'
|
||||||
|
export { getFeeFromResponse } from './getFeeFromResponse'
|
||||||
export { getSwapUrl } from './getSwapUrl'
|
export { getSwapUrl } from './getSwapUrl'
|
||||||
export { updateExchangeRate } from './updateExchangeRate'
|
export { updateExchangeRate } from './updateExchangeRate'
|
||||||
// @endindex
|
// @endindex
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { ExecuteResult } from '@cosmjs/cosmwasm-stargate'
|
import { TxBroadcastResult } from '@marsprotocol/wallet-connector'
|
||||||
import { getAmountFromUnlockRes, getTokenValueFromCoins } from 'functions/fields'
|
import { getTokenValueFromCoins } from 'functions/fields'
|
||||||
import { useUnlockMessages } from 'hooks/queries'
|
import { useUnlockMessages } from 'hooks/queries'
|
||||||
import { extractCoinFromLog, parseActionMessages } from 'libs/parse'
|
import { extractCoinFromLog, parseActionMessages } from 'libs/parse'
|
||||||
import { useCallback, useEffect, useState } from 'react'
|
import { useCallback, useEffect, useState } from 'react'
|
||||||
@ -8,7 +8,7 @@ import useStore from 'store'
|
|||||||
import { Coin } from 'types/generated/mars-credit-manager/MarsCreditManager.types'
|
import { Coin } from 'types/generated/mars-credit-manager/MarsCreditManager.types'
|
||||||
|
|
||||||
export const useFieldsActionMessages = (
|
export const useFieldsActionMessages = (
|
||||||
data?: ExecuteResult,
|
data?: TxBroadcastResult,
|
||||||
vault?: ActiveVault,
|
vault?: ActiveVault,
|
||||||
): {
|
): {
|
||||||
depositMessage?: FieldsAction
|
depositMessage?: FieldsAction
|
||||||
@ -31,11 +31,9 @@ export const useFieldsActionMessages = (
|
|||||||
|
|
||||||
const getDepositedCoins = useCallback((messages: unknown[]): Coin[] => {
|
const getDepositedCoins = useCallback((messages: unknown[]): Coin[] => {
|
||||||
try {
|
try {
|
||||||
return (
|
return (messages.filter((message: any) => message?.action === 'callback/deposit') as any).map(
|
||||||
messages.filter(
|
(msg: any) => extractCoinFromLog(msg.coin_deposited),
|
||||||
(message: any) => message?.action === 'rover/execute/update_credit_account',
|
)
|
||||||
) as any
|
|
||||||
).map((msg: any) => extractCoinFromLog(msg.coin_deposited))
|
|
||||||
} catch {
|
} catch {
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
@ -44,7 +42,7 @@ export const useFieldsActionMessages = (
|
|||||||
const getBorrowedCoins = useCallback((messages: any[]): Coin[] => {
|
const getBorrowedCoins = useCallback((messages: any[]): Coin[] => {
|
||||||
try {
|
try {
|
||||||
return (
|
return (
|
||||||
messages.filter((message: any) => message?.action === 'outposts/red-bank/borrow') as any
|
messages.filter((message: any) => message?.action === 'borrow' && message?.denom) as any
|
||||||
).map((msg: any) => ({ denom: msg.denom, amount: msg.amount }))
|
).map((msg: any) => ({ denom: msg.denom, amount: msg.amount }))
|
||||||
} catch {
|
} catch {
|
||||||
return []
|
return []
|
||||||
@ -53,9 +51,9 @@ export const useFieldsActionMessages = (
|
|||||||
|
|
||||||
const getSwapCoinIn = useCallback((messages: unknown[]): Coin | null => {
|
const getSwapCoinIn = useCallback((messages: unknown[]): Coin | null => {
|
||||||
try {
|
try {
|
||||||
return (
|
return (messages.filter((message: any) => message?.action === 'swap_fn') as any).map(
|
||||||
messages.filter((message: any) => message?.action === 'rover/swapper/swap_fn') as any
|
(msg: any) => ({ denom: msg.denom_in, amount: msg.amount_in }),
|
||||||
).map((msg: any) => ({ denom: msg.denom_in, amount: msg.amount_in }))[0]
|
)[0]
|
||||||
} catch {
|
} catch {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
@ -64,7 +62,7 @@ export const useFieldsActionMessages = (
|
|||||||
const getSwapCoinOut = useCallback((messages: unknown[]): Coin | null => {
|
const getSwapCoinOut = useCallback((messages: unknown[]): Coin | null => {
|
||||||
try {
|
try {
|
||||||
const coinsSwapOutIndex = messages.findIndex(
|
const coinsSwapOutIndex = messages.findIndex(
|
||||||
(message: any) => message?.action === 'rover/swapper/transfer_result',
|
(message: any) => message?.action === 'transfer_result',
|
||||||
) as any
|
) as any
|
||||||
|
|
||||||
const msg: any = messages[coinsSwapOutIndex + 1]
|
const msg: any = messages[coinsSwapOutIndex + 1]
|
||||||
@ -80,8 +78,10 @@ export const useFieldsActionMessages = (
|
|||||||
const getRepayCoin = useCallback((messages: any[]): Coin | null => {
|
const getRepayCoin = useCallback((messages: any[]): Coin | null => {
|
||||||
try {
|
try {
|
||||||
return messages
|
return messages
|
||||||
.filter((message: any) => message?.action === ('outposts/red-bank/repay' as any))
|
.filter((message: any) => message?.action === ('repay' as any) && message?.denom)
|
||||||
.map((msg: any) => ({ denom: msg.denom, amount: msg.amount }))[0]
|
.map((msg: any) => {
|
||||||
|
return { denom: msg.denom, amount: msg.amount }
|
||||||
|
})[0]
|
||||||
} catch {
|
} catch {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
@ -90,9 +90,7 @@ export const useFieldsActionMessages = (
|
|||||||
const getWithdrawnCoins = useCallback((messages: any[]): Coin[] => {
|
const getWithdrawnCoins = useCallback((messages: any[]): Coin[] => {
|
||||||
try {
|
try {
|
||||||
return (
|
return (
|
||||||
messages.filter(
|
messages.filter((message: any) => message?.action === 'callback/withdraw') as any
|
||||||
(message: any) => message?.action === 'rover/credit-manager/callback/withdraw',
|
|
||||||
) as any
|
|
||||||
).map((msg: any) => {
|
).map((msg: any) => {
|
||||||
return extractCoinFromLog(msg.coin_withdrawn)
|
return extractCoinFromLog(msg.coin_withdrawn)
|
||||||
})
|
})
|
||||||
@ -101,6 +99,18 @@ export const useFieldsActionMessages = (
|
|||||||
}
|
}
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
|
const getVaultUnlockAmount = useCallback((messages: any[]): string | null => {
|
||||||
|
try {
|
||||||
|
return (
|
||||||
|
messages.filter((message: any) => message?.action === 'vault/request_unlock') as any
|
||||||
|
).map((msg: any) => {
|
||||||
|
return msg.unlock_amount
|
||||||
|
})[0]
|
||||||
|
} catch {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}, [])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!data) {
|
if (!data) {
|
||||||
return
|
return
|
||||||
@ -117,9 +127,10 @@ export const useFieldsActionMessages = (
|
|||||||
const swapCoinOut = getSwapCoinOut(messages)
|
const swapCoinOut = getSwapCoinOut(messages)
|
||||||
const repayCoin = getRepayCoin(messages)
|
const repayCoin = getRepayCoin(messages)
|
||||||
const withdrawnCoins = getWithdrawnCoins(messages)
|
const withdrawnCoins = getWithdrawnCoins(messages)
|
||||||
|
const vaultUnlockAmount = getVaultUnlockAmount(messages)
|
||||||
|
|
||||||
if (!vaultTokenAmount) {
|
if (!vaultTokenAmount && vaultUnlockAmount) {
|
||||||
setVaultTokenAmount(getAmountFromUnlockRes(data))
|
setVaultTokenAmount(vaultUnlockAmount)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (depositedCoins.length) {
|
if (depositedCoins.length) {
|
||||||
@ -170,6 +181,7 @@ export const useFieldsActionMessages = (
|
|||||||
getRepayCoin,
|
getRepayCoin,
|
||||||
getWithdrawnCoins,
|
getWithdrawnCoins,
|
||||||
vaultTokenAmount,
|
vaultTokenAmount,
|
||||||
|
getVaultUnlockAmount,
|
||||||
whitelistedAssets,
|
whitelistedAssets,
|
||||||
])
|
])
|
||||||
|
|
||||||
|
@ -1,12 +1,32 @@
|
|||||||
import { StdFee } from '@cosmjs/stargate'
|
import { StdFee } from '@cosmjs/stargate'
|
||||||
import { useMutation } from '@tanstack/react-query'
|
import { useMutation } from '@tanstack/react-query'
|
||||||
|
import { parseActionMessages } from 'libs/parse'
|
||||||
import useStore from 'store'
|
import useStore from 'store'
|
||||||
|
|
||||||
export const useCreateCreditAccount = () => {
|
export const useCreateCreditAccount = () => {
|
||||||
const creditManagerClient = useStore((s) => s.creditManagerClient)
|
const executeMsg = useStore((s) => s.executeMsg)
|
||||||
|
const networkConfig = useStore((s) => s.networkConfig)
|
||||||
|
|
||||||
return useMutation(async (fee: StdFee) => {
|
return useMutation(async (fee: StdFee) => {
|
||||||
const executeResult = await creditManagerClient?.createCreditAccount(fee)
|
const message = { create_credit_account: {} }
|
||||||
return executeResult?.logs[0].events[2].attributes[6].value
|
|
||||||
|
if (!networkConfig) return null
|
||||||
|
return executeMsg({
|
||||||
|
msg: message,
|
||||||
|
fee,
|
||||||
|
contract: networkConfig.contracts.creditManager,
|
||||||
|
}).then((broadcastResult) => {
|
||||||
|
if (broadcastResult) {
|
||||||
|
try {
|
||||||
|
const messages = parseActionMessages(broadcastResult)
|
||||||
|
|
||||||
|
return (
|
||||||
|
messages?.find(
|
||||||
|
(message: Record<string, string>) => message?.action === 'mint',
|
||||||
|
) as Record<string, string>
|
||||||
|
)['token_id']
|
||||||
|
} catch {}
|
||||||
|
}
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -13,29 +13,33 @@ interface Props {
|
|||||||
|
|
||||||
export const useUpdateAccount = () => {
|
export const useUpdateAccount = () => {
|
||||||
const queryClient = useQueryClient()
|
const queryClient = useQueryClient()
|
||||||
const creditManagerClient = useStore((s) => s.creditManagerClient)
|
const executeMsg = useStore((s) => s.executeMsg)
|
||||||
|
const networkConfig = useStore((s) => s.networkConfig)
|
||||||
const getVaults = useStore((s) => s.getVaults)
|
const getVaults = useStore((s) => s.getVaults)
|
||||||
|
|
||||||
return useMutation(
|
return useMutation(async (props: Props) => {
|
||||||
async (props: Props) => {
|
|
||||||
queryClient.removeQueries([QUERY_KEYS.ESTIMATE_FARM_FEE])
|
queryClient.removeQueries([QUERY_KEYS.ESTIMATE_FARM_FEE])
|
||||||
return creditManagerClient?.updateCreditAccount(
|
const message = {
|
||||||
{
|
update_credit_account: {
|
||||||
accountId: props.accountId,
|
account_id: props.accountId,
|
||||||
actions: props.actions,
|
actions: props.actions,
|
||||||
},
|
},
|
||||||
props.fee,
|
}
|
||||||
undefined,
|
|
||||||
props.funds,
|
if (!networkConfig) return
|
||||||
)
|
|
||||||
},
|
return executeMsg({
|
||||||
{
|
msg: message,
|
||||||
onSuccess: () => {
|
fee: props.fee,
|
||||||
|
contract: networkConfig.contracts.creditManager,
|
||||||
|
funds: props.funds,
|
||||||
|
}).then((broadcastResult) => {
|
||||||
|
if (broadcastResult?.response.code === 0) {
|
||||||
getVaults({ refetch: true })
|
getVaults({ refetch: true })
|
||||||
},
|
return { result: broadcastResult }
|
||||||
onError: (error: Error) => {
|
} else {
|
||||||
return `${error.message}`
|
return { error: broadcastResult?.rawLogs }
|
||||||
},
|
}
|
||||||
},
|
})
|
||||||
)
|
})
|
||||||
}
|
}
|
||||||
|
@ -16,4 +16,5 @@ export { useUnlockMessages } from './useUnlockMessages'
|
|||||||
export { useUserBalance } from './useUserBalance'
|
export { useUserBalance } from './useUserBalance'
|
||||||
export { useUserDebt } from './useUserDebt'
|
export { useUserDebt } from './useUserDebt'
|
||||||
export { useUserDeposit } from './useUserDeposit'
|
export { useUserDeposit } from './useUserDeposit'
|
||||||
|
export { useUserIcns } from './useUserIcns'
|
||||||
// @endindex
|
// @endindex
|
||||||
|
@ -9,7 +9,7 @@ import { Action, Coin } from 'types/generated/mars-credit-manager/MarsCreditMana
|
|||||||
import { useEstimateFarmFee } from './useEstimateFarmFee'
|
import { useEstimateFarmFee } from './useEstimateFarmFee'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
accountId?: string
|
accountId?: null | string
|
||||||
prevPosition?: Position
|
prevPosition?: Position
|
||||||
position: Position
|
position: Position
|
||||||
vault: Vault
|
vault: Vault
|
||||||
|
@ -1,14 +1,13 @@
|
|||||||
import { MsgExecuteContractEncodeObject } from '@cosmjs/cosmwasm-stargate'
|
import { MsgExecuteContract } from '@marsprotocol/wallet-connector'
|
||||||
import { GasPrice } from '@cosmjs/stargate'
|
|
||||||
import { useQuery } from '@tanstack/react-query'
|
import { useQuery } from '@tanstack/react-query'
|
||||||
import BigNumber from 'bignumber.js'
|
import BigNumber from 'bignumber.js'
|
||||||
import { GAS_ADJUSTMENT, GAS_PRICE } from 'constants/appConstants'
|
import { GAS_ADJUSTMENT } from 'constants/appConstants'
|
||||||
import useStore from 'store'
|
import useStore from 'store'
|
||||||
import { QUERY_KEYS } from 'types/enums/queryKeys'
|
import { QUERY_KEYS } from 'types/enums/queryKeys'
|
||||||
import { Action, Coin } from 'types/generated/mars-credit-manager/MarsCreditManager.types'
|
import { Action, Coin } from 'types/generated/mars-credit-manager/MarsCreditManager.types'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
accountId?: string
|
accountId?: null | string
|
||||||
actions?: Action[]
|
actions?: Action[]
|
||||||
funds?: Coin[]
|
funds?: Coin[]
|
||||||
isCreate?: boolean
|
isCreate?: boolean
|
||||||
@ -17,44 +16,48 @@ interface Props {
|
|||||||
|
|
||||||
export const useEstimateFarmFee = (props: Props) => {
|
export const useEstimateFarmFee = (props: Props) => {
|
||||||
const userWalletAddress = useStore((s) => s.userWalletAddress)
|
const userWalletAddress = useStore((s) => s.userWalletAddress)
|
||||||
const creditManagerMsgComposer = useStore((s) => s.creditManagerMsgComposer)
|
|
||||||
const client = useStore((s) => s.client)
|
const client = useStore((s) => s.client)
|
||||||
|
const networkConfig = useStore((s) => s.networkConfig)
|
||||||
|
|
||||||
return useQuery(
|
return useQuery(
|
||||||
[QUERY_KEYS.ESTIMATE_FARM_FEE, props.actions],
|
[QUERY_KEYS.ESTIMATE_FARM_FEE, props.actions],
|
||||||
async () => {
|
async () => {
|
||||||
const gasPrice = GasPrice.fromString(GAS_PRICE)
|
|
||||||
const gasAdjustment = GAS_ADJUSTMENT
|
const gasAdjustment = GAS_ADJUSTMENT
|
||||||
|
|
||||||
if (!creditManagerMsgComposer || !client) return null
|
if (!client) return null
|
||||||
|
|
||||||
let msg: MsgExecuteContractEncodeObject | null = null
|
if (!networkConfig) return null
|
||||||
|
|
||||||
if (props.isCreate) {
|
|
||||||
msg = creditManagerMsgComposer.createCreditAccount()
|
|
||||||
} else if (props.accountId && props.actions?.length) {
|
|
||||||
msg = creditManagerMsgComposer.updateCreditAccount(
|
|
||||||
{
|
|
||||||
accountId: props.accountId,
|
|
||||||
actions: props.actions,
|
|
||||||
},
|
|
||||||
props.funds,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!msg) return null
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const gasUsed = await client.simulate(userWalletAddress, [msg], undefined)
|
const simulateOptions = {
|
||||||
|
messages: [
|
||||||
const fee = new BigNumber(Number(gasPrice.amount))
|
new MsgExecuteContract({
|
||||||
.multipliedBy(gasUsed)
|
sender: userWalletAddress,
|
||||||
.multipliedBy(gasAdjustment)
|
contract: networkConfig.contracts.creditManager,
|
||||||
|
msg: props.isCreate
|
||||||
return {
|
? { create_credit_account: {} }
|
||||||
amount: [{ denom: 'uosmo', amount: fee.toFixed(0) }],
|
: {
|
||||||
gas: new BigNumber(gasUsed).multipliedBy(gasAdjustment).toFixed(0),
|
update_credit_account: {
|
||||||
|
account_id: props.accountId,
|
||||||
|
actions: props.actions,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
funds: props.funds,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
wallet: client.recentWallet,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const result = await client.simulate(simulateOptions)
|
||||||
|
|
||||||
|
return result.success
|
||||||
|
? {
|
||||||
|
amount: result.fee ? result.fee.amount : [],
|
||||||
|
gas: new BigNumber(result.fee ? result.fee.gas : 0)
|
||||||
|
.multipliedBy(gasAdjustment)
|
||||||
|
.toFixed(0),
|
||||||
|
}
|
||||||
|
: null
|
||||||
} catch {
|
} catch {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
@ -63,7 +66,6 @@ export const useEstimateFarmFee = (props: Props) => {
|
|||||||
enabled:
|
enabled:
|
||||||
!props.isLoading &&
|
!props.isLoading &&
|
||||||
!!client &&
|
!!client &&
|
||||||
!!creditManagerMsgComposer &&
|
|
||||||
!!userWalletAddress &&
|
!!userWalletAddress &&
|
||||||
(props.isCreate || (!!props.accountId && !!props.actions?.length)),
|
(props.isCreate || (!!props.accountId && !!props.actions?.length)),
|
||||||
},
|
},
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
import { MsgExecuteContractEncodeObject } from '@cosmjs/cosmwasm-stargate'
|
import { MsgExecuteContractEncodeObject } from '@cosmjs/cosmwasm-stargate'
|
||||||
import { toUtf8 } from '@cosmjs/encoding'
|
|
||||||
import { Coin } from '@cosmjs/proto-signing'
|
import { Coin } from '@cosmjs/proto-signing'
|
||||||
import { GasPrice } from '@cosmjs/stargate'
|
import { MsgExecuteContract } from '@marsprotocol/wallet-connector'
|
||||||
import { useQuery } from '@tanstack/react-query'
|
import { useQuery } from '@tanstack/react-query'
|
||||||
import BigNumber from 'bignumber.js'
|
import BigNumber from 'bignumber.js'
|
||||||
import { GAS_ADJUSTMENT, GAS_PRICE } from 'constants/appConstants'
|
import { GAS_ADJUSTMENT } from 'constants/appConstants'
|
||||||
import useStore from 'store'
|
import useStore from 'store'
|
||||||
import { QUERY_KEYS } from 'types/enums/queryKeys'
|
import { QUERY_KEYS } from 'types/enums/queryKeys'
|
||||||
import { ContractMsg } from 'types/types'
|
import { ContractMsg } from 'types/types'
|
||||||
@ -22,37 +21,35 @@ export const useEstimateFee = (props: Props) => {
|
|||||||
const client = useStore((s) => s.client)
|
const client = useStore((s) => s.client)
|
||||||
|
|
||||||
return useQuery(
|
return useQuery(
|
||||||
[QUERY_KEYS.ESTIMATE_FEE],
|
[QUERY_KEYS.ESTIMATE_FEE, props.msg],
|
||||||
async () => {
|
async () => {
|
||||||
const sender = props.sender ? props.sender : userWalletAddress
|
const sender = props.sender ? props.sender : userWalletAddress
|
||||||
const gasPrice = GasPrice.fromString(GAS_PRICE)
|
|
||||||
const gasAdjustment = GAS_ADJUSTMENT
|
const gasAdjustment = GAS_ADJUSTMENT
|
||||||
|
|
||||||
if (!client) return
|
if (!client || !props.contract || !props.msg) return
|
||||||
|
|
||||||
const msg = props.executeMsg
|
|
||||||
? props.executeMsg
|
|
||||||
: {
|
|
||||||
typeUrl: '/cosmwasm.wasm.v1.MsgExecuteContract',
|
|
||||||
value: {
|
|
||||||
sender: sender,
|
|
||||||
contract: props.contract,
|
|
||||||
msg: toUtf8(JSON.stringify(props.msg)),
|
|
||||||
funds: props.funds,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const gasUsed = await client.simulate(sender, [msg], undefined)
|
const simulateOptions = {
|
||||||
|
messages: [
|
||||||
const fee = new BigNumber(Number(gasPrice.amount))
|
new MsgExecuteContract({
|
||||||
.multipliedBy(gasUsed)
|
sender: sender,
|
||||||
.multipliedBy(gasAdjustment)
|
contract: props.contract,
|
||||||
|
msg: props.msg,
|
||||||
return {
|
funds: props.funds,
|
||||||
amount: [{ denom: 'uosmo', amount: fee.toFixed(0) }],
|
}),
|
||||||
gas: new BigNumber(gasUsed).multipliedBy(gasAdjustment).toFixed(0),
|
],
|
||||||
|
wallet: client.recentWallet,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const result = await client.simulate(simulateOptions)
|
||||||
|
return result.success
|
||||||
|
? {
|
||||||
|
amount: result.fee ? result.fee.amount : [],
|
||||||
|
gas: new BigNumber(result.fee ? result.fee.gas : 0)
|
||||||
|
.multipliedBy(gasAdjustment)
|
||||||
|
.toFixed(0),
|
||||||
|
}
|
||||||
|
: null
|
||||||
} catch {
|
} catch {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
@ -11,13 +11,15 @@ interface Props {
|
|||||||
export const useProvideLiquidity = (props: Props) => {
|
export const useProvideLiquidity = (props: Props) => {
|
||||||
const creditManagerClient = useStore((s) => s.creditManagerClient)
|
const creditManagerClient = useStore((s) => s.creditManagerClient)
|
||||||
|
|
||||||
return useQuery(
|
return useQuery<number>(
|
||||||
[QUERY_KEYS.PROVIDE_LIQUIDITY, props.coins],
|
[QUERY_KEYS.PROVIDE_LIQUIDITY, props.coins],
|
||||||
async () => {
|
async () => {
|
||||||
if (!creditManagerClient || !props.coins.length) return null
|
if (!creditManagerClient || !props.coins.length) return null
|
||||||
return creditManagerClient.estimateProvideLiquidity({
|
return creditManagerClient.query({
|
||||||
coinsIn: props.coins,
|
estimate_provide_liquidity: {
|
||||||
lpTokenOut: props.vault?.denoms.lpToken || '',
|
coins_in: props.coins,
|
||||||
|
lp_token_out: props.vault?.denoms.lpToken || '',
|
||||||
|
},
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -5,7 +5,7 @@ import { useAsset } from 'hooks/data'
|
|||||||
import useStore from 'store'
|
import useStore from 'store'
|
||||||
import { QUERY_KEYS } from 'types/enums/queryKeys'
|
import { QUERY_KEYS } from 'types/enums/queryKeys'
|
||||||
|
|
||||||
const poolsEndpoint = '/osmosis/gamm/v1beta1/pools/'
|
const poolsEndpoint = 'osmosis/gamm/v1beta1/pools/'
|
||||||
|
|
||||||
export const useSpotPrice = (symbol: string) => {
|
export const useSpotPrice = (symbol: string) => {
|
||||||
const displayCurrency = useStore((s) => s.displayCurrency)
|
const displayCurrency = useStore((s) => s.displayCurrency)
|
||||||
|
@ -3,8 +3,8 @@ import { getTokenValueFromCoins } from 'functions/fields'
|
|||||||
import { formatUnlockDate } from 'libs/parse'
|
import { formatUnlockDate } from 'libs/parse'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import useStore from 'store'
|
import useStore from 'store'
|
||||||
|
import { VaultClient } from 'types/classes'
|
||||||
import { QUERY_KEYS } from 'types/enums/queryKeys'
|
import { QUERY_KEYS } from 'types/enums/queryKeys'
|
||||||
import { MarsMockVaultClient } from 'types/generated/mars-mock-vault/MarsMockVault.client'
|
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
vault?: ActiveVault
|
vault?: ActiveVault
|
||||||
@ -23,15 +23,19 @@ export const useUnlockMessages = (props: Props) => {
|
|||||||
async () => {
|
async () => {
|
||||||
if (!client || !userWalletAddress || !props.vault || !creditManagerClient) return null
|
if (!client || !userWalletAddress || !props.vault || !creditManagerClient) return null
|
||||||
|
|
||||||
const vaultClient = new MarsMockVaultClient(client, userWalletAddress, props.vault.address)
|
const vaultClient = new VaultClient(props.vault.address, client)
|
||||||
const lpTokenAmount = await vaultClient.previewRedeem({
|
const lpTokenAmount = await vaultClient.query({
|
||||||
|
preview_redeem: {
|
||||||
amount: props.vaultTokenAmount,
|
amount: props.vaultTokenAmount,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
const lpToken = { denom: props.vault.denoms.lpToken, amount: lpTokenAmount }
|
const lpToken = { denom: props.vault.denoms.lpToken, amount: lpTokenAmount }
|
||||||
|
|
||||||
const coins = await creditManagerClient.estimateWithdrawLiquidity({
|
const coins = await creditManagerClient.query({
|
||||||
lpToken,
|
estimate_withdraw_liquidity: {
|
||||||
|
lp_token: lpToken,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
return [
|
return [
|
||||||
|
@ -3,6 +3,7 @@ import { useQuery } from '@tanstack/react-query'
|
|||||||
import { gql, request } from 'graphql-request'
|
import { gql, request } from 'graphql-request'
|
||||||
import { useMemo } from 'react'
|
import { useMemo } from 'react'
|
||||||
import useStore from 'store'
|
import useStore from 'store'
|
||||||
|
import { QUERY_KEYS } from 'types/enums/queryKeys'
|
||||||
|
|
||||||
export interface UserBalanceData {
|
export interface UserBalanceData {
|
||||||
balance: {
|
balance: {
|
||||||
@ -16,7 +17,7 @@ export const useUserBalance = () => {
|
|||||||
const processUserBalanceQuery = useStore((s) => s.processUserBalanceQuery)
|
const processUserBalanceQuery = useStore((s) => s.processUserBalanceQuery)
|
||||||
|
|
||||||
const result = useQuery<UserBalanceData>(
|
const result = useQuery<UserBalanceData>(
|
||||||
[],
|
[QUERY_KEYS.USER_BALANCE],
|
||||||
async () => {
|
async () => {
|
||||||
return await request(
|
return await request(
|
||||||
hiveUrl!,
|
hiveUrl!,
|
||||||
|
54
src/hooks/queries/useUserIcns.tsx
Normal file
54
src/hooks/queries/useUserIcns.tsx
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
import { useQuery } from '@tanstack/react-query'
|
||||||
|
import { gql, request } from 'graphql-request'
|
||||||
|
import { useMemo } from 'react'
|
||||||
|
import useStore from 'store'
|
||||||
|
import { QUERY_KEYS } from 'types/enums/queryKeys'
|
||||||
|
|
||||||
|
export interface UserIcnsData {
|
||||||
|
wasm: {
|
||||||
|
contractQuery: {
|
||||||
|
names: string[]
|
||||||
|
primary_name: string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useUserIcns = () => {
|
||||||
|
/* only possible to query on mainnet */
|
||||||
|
const hiveUrl = 'https://osmosis-mars-frontend.simply-vc.com.mt/GGSFGSFGFG34/osmosis-hive/graphql'
|
||||||
|
const resolverContract = 'osmo1xk0s8xgktn9x5vwcgtjdxqzadg88fgn33p8u9cnpdxwemvxscvast52cdd'
|
||||||
|
|
||||||
|
const userWalletAddress = useStore((s) => s.userWalletAddress)
|
||||||
|
const setUserIcns = useStore((s) => s.setUserIcns)
|
||||||
|
|
||||||
|
const result = useQuery<UserIcnsData>(
|
||||||
|
[QUERY_KEYS.USER_ICNS],
|
||||||
|
async () => {
|
||||||
|
return await request(
|
||||||
|
hiveUrl!,
|
||||||
|
gql`
|
||||||
|
query UserIcnsQuery {
|
||||||
|
wasm {
|
||||||
|
contractQuery(contractAddress:"${resolverContract}", query: {
|
||||||
|
icns_names:{
|
||||||
|
address: "${userWalletAddress}"
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}`,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
enabled: !!userWalletAddress || false,
|
||||||
|
onSuccess: (data) => {
|
||||||
|
const icns = data.wasm.contractQuery.primary_name
|
||||||
|
if (icns !== '') setUserIcns(icns)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
return {
|
||||||
|
...result,
|
||||||
|
data: useMemo(() => result.data, [result.data]),
|
||||||
|
}
|
||||||
|
}
|
@ -3,6 +3,12 @@ import LanguageDetector from 'i18next-browser-languagedetector'
|
|||||||
import HttpApi from 'i18next-http-backend'
|
import HttpApi from 'i18next-http-backend'
|
||||||
import { initReactI18next } from 'react-i18next'
|
import { initReactI18next } from 'react-i18next'
|
||||||
|
|
||||||
|
declare module 'i18next' {
|
||||||
|
interface CustomTypeOptions {
|
||||||
|
returnNull: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
i18next
|
i18next
|
||||||
.use(HttpApi)
|
.use(HttpApi)
|
||||||
.use(LanguageDetector)
|
.use(LanguageDetector)
|
||||||
@ -11,7 +17,7 @@ i18next
|
|||||||
backend: {
|
backend: {
|
||||||
crossDomain: true,
|
crossDomain: true,
|
||||||
loadPath() {
|
loadPath() {
|
||||||
return 'https://raw.githubusercontent.com/mars-protocol/translations/develop/{{lng}}.json'
|
return 'https://raw.githubusercontent.com/mars-protocol/translations/main/{{lng}}.json'
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
react: {
|
react: {
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 7.9 KiB |
Binary file not shown.
Before Width: | Height: | Size: 1.2 KiB |
@ -1,4 +1,4 @@
|
|||||||
import { ExecuteResult } from '@cosmjs/cosmwasm-stargate'
|
import { TxBroadcastResult } from '@marsprotocol/wallet-connector'
|
||||||
import BigNumber from 'bignumber.js'
|
import BigNumber from 'bignumber.js'
|
||||||
import { DAY_IN_SECONDS, HOUR_IN_SECONDS, MINUTE_IN_SECONDS } from 'constants/timeConstants'
|
import { DAY_IN_SECONDS, HOUR_IN_SECONDS, MINUTE_IN_SECONDS } from 'constants/timeConstants'
|
||||||
import moment from 'moment'
|
import moment from 'moment'
|
||||||
@ -282,21 +282,31 @@ export const extractCoinFromLog = (text: string) => {
|
|||||||
return { amount: arr[0], denom: arr[1] }
|
return { amount: arr[0], denom: arr[1] }
|
||||||
}
|
}
|
||||||
|
|
||||||
export const parseActionMessages = (data: ExecuteResult) => {
|
export const parseActionMessages = (data: TxBroadcastResult) => {
|
||||||
const wasmEvents = data.logs[0].events.find((object) => object.type === 'wasm')
|
const wasmEvents: [] = data.response.events
|
||||||
if (wasmEvents) {
|
.filter((object: Record<string, string>) => object.type === 'wasm')
|
||||||
return wasmEvents.attributes.reduce((prev: {}[], curr) => {
|
.map((event: Record<string, string>) => event?.attributes)
|
||||||
if (curr.key === '_contract_address') {
|
.flat()
|
||||||
|
|
||||||
|
if (wasmEvents.length) {
|
||||||
|
return wasmEvents.reduce((prev: {}[], curr: any) => {
|
||||||
|
if (curr.key === 'action') {
|
||||||
prev.push({ [curr.key]: curr.value })
|
prev.push({ [curr.key]: curr.value })
|
||||||
return prev
|
return prev
|
||||||
} else {
|
} else {
|
||||||
|
if (prev.length) {
|
||||||
Object.assign(prev[prev.length - 1], { [curr.key]: curr.value })
|
Object.assign(prev[prev.length - 1], { [curr.key]: curr.value })
|
||||||
|
}
|
||||||
return prev
|
return prev
|
||||||
}
|
}
|
||||||
}, [])
|
}, [])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const toBase64 = (obj: object) => {
|
||||||
|
return Buffer.from(JSON.stringify(obj)).toString('base64')
|
||||||
|
}
|
||||||
|
|
||||||
export const ltvToLeverage = (ltv: number) => {
|
export const ltvToLeverage = (ltv: number) => {
|
||||||
const leverage = 1 / (1 - ltv)
|
const leverage = 1 / (1 - ltv)
|
||||||
return new BigNumber(leverage).decimalPlaces(2).toNumber()
|
return new BigNumber(leverage).decimalPlaces(2).toNumber()
|
||||||
|
@ -19,7 +19,11 @@ export const position: Position = {
|
|||||||
total: 0,
|
total: 0,
|
||||||
net: 0,
|
net: 0,
|
||||||
},
|
},
|
||||||
apy: 0,
|
apy: {
|
||||||
|
borrow: 5.2,
|
||||||
|
net: 7.7,
|
||||||
|
total: 19,
|
||||||
|
},
|
||||||
ltv: 0.5,
|
ltv: 0.5,
|
||||||
currentLeverage: 1,
|
currentLeverage: 1,
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@ import {
|
|||||||
} from 'components/fields'
|
} from 'components/fields'
|
||||||
import { FIELDS_FEATURE } from 'constants/appConstants'
|
import { FIELDS_FEATURE } from 'constants/appConstants'
|
||||||
import { useRouter } from 'next/router'
|
import { useRouter } from 'next/router'
|
||||||
import React, { useEffect } from 'react'
|
import { useEffect } from 'react'
|
||||||
import useStore from 'store'
|
import useStore from 'store'
|
||||||
|
|
||||||
import styles from './Fields.module.scss'
|
import styles from './Fields.module.scss'
|
||||||
@ -23,7 +23,8 @@ const Fields = () => {
|
|||||||
const userWalletAddress = useStore((s) => s.userWalletAddress)
|
const userWalletAddress = useStore((s) => s.userWalletAddress)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!getVaults || !accountNftClient || !client || !creditManagerClient) return
|
if (!getVaults || !accountNftClient || !client || !creditManagerClient || !userWalletAddress)
|
||||||
|
return
|
||||||
if (userWalletAddress && prefUserWalletAddress !== userWalletAddress) {
|
if (userWalletAddress && prefUserWalletAddress !== userWalletAddress) {
|
||||||
prefUserWalletAddress = userWalletAddress
|
prefUserWalletAddress = userWalletAddress
|
||||||
getVaults({ refetch: true })
|
getVaults({ refetch: true })
|
||||||
|
@ -25,7 +25,9 @@ const CloseVaultPosition = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!closeFee || !closeActions || !activeVault || isLoading || data || error) return
|
if (!closeFee || !closeActions || !activeVault || isLoading || data?.error || data?.result)
|
||||||
|
return
|
||||||
|
|
||||||
mutate({
|
mutate({
|
||||||
accountId: activeVault.position.accountId,
|
accountId: activeVault.position.accountId,
|
||||||
actions: closeActions,
|
actions: closeActions,
|
||||||
@ -46,7 +48,6 @@ const CloseVaultPosition = () => {
|
|||||||
return (
|
return (
|
||||||
<ClosePositionResponse
|
<ClosePositionResponse
|
||||||
data={data}
|
data={data}
|
||||||
error={error}
|
|
||||||
isLoading={isLoading}
|
isLoading={isLoading}
|
||||||
accountId={ref.current.position.accountId}
|
accountId={ref.current.position.accountId}
|
||||||
/>
|
/>
|
||||||
|
@ -4,7 +4,6 @@ import { useCreateCreditAccount, useUpdateAccount } from 'hooks/mutations'
|
|||||||
import { useEditPosition, useEstimateFarmFee } from 'hooks/queries'
|
import { useEditPosition, useEstimateFarmFee } from 'hooks/queries'
|
||||||
import { getTimeAndUnit } from 'libs/parse'
|
import { getTimeAndUnit } from 'libs/parse'
|
||||||
import router from 'next/router'
|
import router from 'next/router'
|
||||||
import React from 'react'
|
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
|
|
||||||
import styles from './SetupPosition.module.scss'
|
import styles from './SetupPosition.module.scss'
|
||||||
@ -22,7 +21,6 @@ const SetupPosition = (props: Props) => {
|
|||||||
data: accountId,
|
data: accountId,
|
||||||
isLoading: isLoadingCreate,
|
isLoading: isLoadingCreate,
|
||||||
} = useCreateCreditAccount()
|
} = useCreateCreditAccount()
|
||||||
|
|
||||||
const {
|
const {
|
||||||
mutate: enterVault,
|
mutate: enterVault,
|
||||||
data: enterVaultData,
|
data: enterVaultData,
|
||||||
@ -57,11 +55,10 @@ const SetupPosition = (props: Props) => {
|
|||||||
enterVault({ accountId, actions: editActions, fee: editFee, funds: editFunds })
|
enterVault({ accountId, actions: editActions, fee: editFee, funds: editFunds })
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isLoadingEnterVault || enterVaultError || enterVaultData) {
|
if (isLoadingEnterVault || enterVaultData) {
|
||||||
return (
|
return (
|
||||||
<SetUpResponse
|
<SetUpResponse
|
||||||
data={enterVaultData}
|
data={enterVaultData}
|
||||||
error={enterVaultError}
|
|
||||||
isLoading={isLoadingEnterVault}
|
isLoading={isLoadingEnterVault}
|
||||||
accountId={accountId || ''}
|
accountId={accountId || ''}
|
||||||
/>
|
/>
|
||||||
|
@ -162,31 +162,18 @@ const EditVault = (props: Props) => {
|
|||||||
|
|
||||||
if (isLoadingEdit || editData || editError) {
|
if (isLoadingEdit || editData || editError) {
|
||||||
return (
|
return (
|
||||||
<EditResponse
|
<EditResponse data={editData} isLoading={isLoadingEdit} activeVault={props.activeVault} />
|
||||||
data={editData}
|
|
||||||
error={editError}
|
|
||||||
isLoading={isLoadingEdit}
|
|
||||||
activeVault={props.activeVault}
|
|
||||||
/>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isLoadingRepay || repayData || repayError) {
|
if (isLoadingRepay || repayData || repayError) {
|
||||||
return (
|
return <RepayResponse data={repayData} isLoading={isLoadingRepay} vault={props.activeVault} />
|
||||||
<RepayResponse
|
|
||||||
data={repayData}
|
|
||||||
error={repayError}
|
|
||||||
isLoading={isLoadingRepay}
|
|
||||||
vault={props.activeVault}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isLoadingUnlock || unlockData || unlockError) {
|
if (isLoadingUnlock || unlockData || unlockError) {
|
||||||
return (
|
return (
|
||||||
<UnlockResponse
|
<UnlockResponse
|
||||||
data={unlockData}
|
data={unlockData}
|
||||||
error={unlockError}
|
|
||||||
isLoading={isLoadingUnlock}
|
isLoading={isLoadingUnlock}
|
||||||
activeVault={props.activeVault}
|
activeVault={props.activeVault}
|
||||||
/>
|
/>
|
||||||
|
@ -49,14 +49,7 @@ const RepayVault = (props: Props) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (isLoadingRepay || repayData || repayError) {
|
if (isLoadingRepay || repayData || repayError) {
|
||||||
return (
|
return <RepayResponse data={repayData} isLoading={isLoadingRepay} vault={props.activeVault} />
|
||||||
<RepayResponse
|
|
||||||
data={repayData}
|
|
||||||
error={repayError}
|
|
||||||
isLoading={isLoadingRepay}
|
|
||||||
vault={props.activeVault}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const isSameAmounts = isEqual(prevPosition.amounts, repayPosition.amounts)
|
const isSameAmounts = isEqual(prevPosition.amounts, repayPosition.amounts)
|
||||||
|
@ -5,7 +5,6 @@ import { useActiveVault } from 'hooks/data'
|
|||||||
import { useUpdateAccount } from 'hooks/mutations'
|
import { useUpdateAccount } from 'hooks/mutations'
|
||||||
import { useRequestUnlockPosition } from 'hooks/queries/useRequestUnlockPosition'
|
import { useRequestUnlockPosition } from 'hooks/queries/useRequestUnlockPosition'
|
||||||
import { useRouter } from 'next/router'
|
import { useRouter } from 'next/router'
|
||||||
import React from 'react'
|
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
|
|
||||||
import styles from './UnlockDisclaimer.module.scss'
|
import styles from './UnlockDisclaimer.module.scss'
|
||||||
@ -49,12 +48,7 @@ const Unlock = () => {
|
|||||||
|
|
||||||
if (unlockData || unlockError || isLoadingUnlock) {
|
if (unlockData || unlockError || isLoadingUnlock) {
|
||||||
return (
|
return (
|
||||||
<UnlockResponse
|
<UnlockResponse data={unlockData} isLoading={isLoadingUnlock} activeVault={activeVault} />
|
||||||
data={unlockData}
|
|
||||||
error={unlockError}
|
|
||||||
isLoading={isLoadingUnlock}
|
|
||||||
activeVault={activeVault}
|
|
||||||
/>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,11 +1,15 @@
|
|||||||
import { ExecuteResult } from '@cosmjs/cosmwasm-stargate'
|
|
||||||
import { LcdClient } from '@cosmjs/launchpad'
|
import { LcdClient } from '@cosmjs/launchpad'
|
||||||
import { Coin, StdFee } from '@cosmjs/stargate'
|
import { Coin, StdFee } from '@cosmjs/stargate'
|
||||||
import { WalletChainInfo, WalletSigningCosmWasmClient } from '@marsprotocol/wallet-connector'
|
import {
|
||||||
|
SimplifiedChainInfo,
|
||||||
|
TxBroadcastResult,
|
||||||
|
WalletClient,
|
||||||
|
} from '@marsprotocol/wallet-connector'
|
||||||
import { BlockHeightData } from 'hooks/queries/useBlockHeight'
|
import { BlockHeightData } from 'hooks/queries/useBlockHeight'
|
||||||
import { MarketDepositsData } from 'hooks/queries/useMarketDeposits'
|
import { MarketDepositsData } from 'hooks/queries/useMarketDeposits'
|
||||||
import { SafetyFundBalanceData } from 'hooks/queries/useSafetyFundBalance'
|
import { SafetyFundBalanceData } from 'hooks/queries/useSafetyFundBalance'
|
||||||
import { UserBalanceData } from 'hooks/queries/useUserBalance'
|
import { UserBalanceData } from 'hooks/queries/useUserBalance'
|
||||||
|
import { UserIcnsData } from 'hooks/queries/useUserIcns'
|
||||||
import { Network } from 'types/enums/network'
|
import { Network } from 'types/enums/network'
|
||||||
import { ContractMsg } from 'types/types'
|
import { ContractMsg } from 'types/types'
|
||||||
|
|
||||||
@ -22,8 +26,8 @@ export interface CommonSlice {
|
|||||||
decimals: number
|
decimals: number
|
||||||
}
|
}
|
||||||
baseToDisplayCurrencyRatio?: number
|
baseToDisplayCurrencyRatio?: number
|
||||||
chainInfo?: WalletChainInfo
|
chainInfo?: SimplifiedChainInfo
|
||||||
client?: WalletSigningCosmWasmClient
|
client?: WalletClient
|
||||||
currentNetwork: Network
|
currentNetwork: Network
|
||||||
displayCurrency: {
|
displayCurrency: {
|
||||||
denom: string
|
denom: string
|
||||||
@ -51,7 +55,7 @@ export interface CommonSlice {
|
|||||||
userUnclaimedRewards: string
|
userUnclaimedRewards: string
|
||||||
userMarsTokenBalances: Coin[]
|
userMarsTokenBalances: Coin[]
|
||||||
userWalletAddress: string
|
userWalletAddress: string
|
||||||
userWalletName: string
|
userIcns?: string
|
||||||
vaultConfigs: Vault[]
|
vaultConfigs: Vault[]
|
||||||
whitelistedAssets: Asset[]
|
whitelistedAssets: Asset[]
|
||||||
// ------------------
|
// ------------------
|
||||||
@ -65,7 +69,7 @@ export interface CommonSlice {
|
|||||||
contract: string
|
contract: string
|
||||||
fee: StdFee
|
fee: StdFee
|
||||||
sender?: string
|
sender?: string
|
||||||
}) => Promise<ExecuteResult | undefined>
|
}) => Promise<TxBroadcastResult | undefined>
|
||||||
loadNetworkConfig: () => void
|
loadNetworkConfig: () => void
|
||||||
queryContract: <T>(
|
queryContract: <T>(
|
||||||
contractAddress: string,
|
contractAddress: string,
|
||||||
@ -76,22 +80,23 @@ export interface CommonSlice {
|
|||||||
// ------------------
|
// ------------------
|
||||||
// SETTERS
|
// SETTERS
|
||||||
// ------------------
|
// ------------------
|
||||||
setChainInfo: (chainInfo: WalletChainInfo) => void
|
setChainInfo: (chainInfo: SimplifiedChainInfo) => void
|
||||||
setCurrentNetwork: (network: Network) => void
|
setCurrentNetwork: (network: Network) => void
|
||||||
setTutorialStep: (type: 'fields' | 'redbank', step?: number) => void
|
setTutorialStep: (type: 'fields' | 'redbank', step?: number) => void
|
||||||
setLcdClient: (rpc: string, chainID: string) => void
|
setLcdClient: (rpc: string, chainID: string) => void
|
||||||
setNetworkError: (isError: boolean) => void
|
setNetworkError: (isError: boolean) => void
|
||||||
setClient: (client: WalletSigningCosmWasmClient) => void
|
setClient: (client: WalletClient) => void
|
||||||
setQueryError: (name: string, isError: boolean) => void
|
setQueryError: (name: string, isError: boolean) => void
|
||||||
setServerError: (isError: boolean) => void
|
setServerError: (isError: boolean) => void
|
||||||
|
setUserIcns: (icns: string) => void
|
||||||
setUserWalletAddress: (address: string) => void
|
setUserWalletAddress: (address: string) => void
|
||||||
setUserWalletName: (name: string) => void
|
|
||||||
// ------------------
|
// ------------------
|
||||||
// QUERY RELATED
|
// QUERY RELATED
|
||||||
// ------------------
|
// ------------------
|
||||||
previousBlockHeightQueryData?: BlockHeightData
|
previousBlockHeightQueryData?: BlockHeightData
|
||||||
previousSafetyFundBalanceQueryData?: SafetyFundBalanceData
|
previousSafetyFundBalanceQueryData?: SafetyFundBalanceData
|
||||||
previousUserBalanceQueryData?: UserBalanceData
|
previousUserBalanceQueryData?: UserBalanceData
|
||||||
|
previousUserIcnsQueryData?: UserIcnsData
|
||||||
previousUserUnclaimedBalanceQueryData?: number
|
previousUserUnclaimedBalanceQueryData?: number
|
||||||
processMarketDepositsQuery: (data: MarketDepositsData) => void
|
processMarketDepositsQuery: (data: MarketDepositsData) => void
|
||||||
processUserBalanceQuery: (data: UserBalanceData) => void
|
processUserBalanceQuery: (data: UserBalanceData) => void
|
||||||
|
@ -1,16 +1,12 @@
|
|||||||
import { SigningCosmWasmClient } from '@cosmjs/cosmwasm-stargate'
|
import { AccountNftClient, CreditManagerClient } from 'types/classes'
|
||||||
import { MarsAccountNftInterface } from 'types/generated/mars-account-nft/MarsAccountNft.client'
|
|
||||||
import { MarsCreditManagerClient } from 'types/generated/mars-credit-manager/MarsCreditManager.client'
|
|
||||||
import { MarsCreditManagerMessageComposer } from 'types/generated/mars-credit-manager/MarsCreditManager.message-composer'
|
import { MarsCreditManagerMessageComposer } from 'types/generated/mars-credit-manager/MarsCreditManager.message-composer'
|
||||||
|
|
||||||
export interface FieldsSlice {
|
export interface FieldsSlice {
|
||||||
accountNftClient?: MarsAccountNftInterface
|
accountNftClient?: AccountNftClient
|
||||||
creditManagerClient?: MarsCreditManagerClient
|
creditManagerClient?: CreditManagerClient
|
||||||
creditManagerMsgComposer?: MarsCreditManagerMessageComposer
|
creditManagerMsgComposer?: MarsCreditManagerMessageComposer
|
||||||
isRepay: boolean
|
isRepay: boolean
|
||||||
position?: Position
|
position?: Position
|
||||||
setAccountNftClient: (client: SigningCosmWasmClient) => void
|
|
||||||
setCreditManagerClient: (client: SigningCosmWasmClient) => void
|
|
||||||
setCreditManagerMsgComposer: (address: string, contract: string) => void
|
setCreditManagerMsgComposer: (address: string, contract: string) => void
|
||||||
setIsRepay: (isRepay: boolean) => void
|
setIsRepay: (isRepay: boolean) => void
|
||||||
setPosition: (position?: Position) => void
|
setPosition: (position?: Position) => void
|
||||||
|
@ -1,7 +1,11 @@
|
|||||||
import { ExecuteResult } from '@cosmjs/cosmwasm-stargate'
|
|
||||||
import { LcdClient } from '@cosmjs/launchpad'
|
import { LcdClient } from '@cosmjs/launchpad'
|
||||||
import { Coin } from '@cosmjs/stargate'
|
import { Coin } from '@cosmjs/stargate'
|
||||||
import { WalletChainInfo, WalletSigningCosmWasmClient } from '@marsprotocol/wallet-connector'
|
import {
|
||||||
|
MsgExecuteContract,
|
||||||
|
SimplifiedChainInfo,
|
||||||
|
TxBroadcastResult,
|
||||||
|
WalletClient,
|
||||||
|
} from '@marsprotocol/wallet-connector'
|
||||||
import BigNumber from 'bignumber.js'
|
import BigNumber from 'bignumber.js'
|
||||||
import { BlockHeightData } from 'hooks/queries/useBlockHeight'
|
import { BlockHeightData } from 'hooks/queries/useBlockHeight'
|
||||||
import { MarketDepositsData } from 'hooks/queries/useMarketDeposits'
|
import { MarketDepositsData } from 'hooks/queries/useMarketDeposits'
|
||||||
@ -46,7 +50,6 @@ const commonSlice = (
|
|||||||
queryErrors: [],
|
queryErrors: [],
|
||||||
slippage: 0.02,
|
slippage: 0.02,
|
||||||
tutorialSteps: { redbank: 1, fields: 1 },
|
tutorialSteps: { redbank: 1, fields: 1 },
|
||||||
userWalletName: '',
|
|
||||||
userBalances: [],
|
userBalances: [],
|
||||||
userMarsTokenBalances: [],
|
userMarsTokenBalances: [],
|
||||||
userUnclaimedRewards: '0',
|
userUnclaimedRewards: '0',
|
||||||
@ -80,20 +83,30 @@ const commonSlice = (
|
|||||||
|
|
||||||
return new BigNumber(coin.amount).div(exchangeRate).toNumber()
|
return new BigNumber(coin.amount).div(exchangeRate).toNumber()
|
||||||
},
|
},
|
||||||
executeMsg: async (options: StrategyExecuteMsgOptions): Promise<ExecuteResult | undefined> => {
|
executeMsg: async (
|
||||||
|
options: StrategyExecuteMsgOptions,
|
||||||
|
): Promise<TxBroadcastResult | undefined> => {
|
||||||
const client = get().client!
|
const client = get().client!
|
||||||
|
|
||||||
if (!options.sender) options.sender = get().userWalletAddress
|
if (!options.sender) options.sender = get().userWalletAddress
|
||||||
|
|
||||||
|
const broadcastOptions = {
|
||||||
|
messages: [
|
||||||
|
new MsgExecuteContract({
|
||||||
|
sender: options.sender,
|
||||||
|
contract: options.contract,
|
||||||
|
msg: options.msg,
|
||||||
|
funds: options.funds,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
feeAmount: options.fee.amount[0].amount,
|
||||||
|
gasLimit: options.fee.gas,
|
||||||
|
memo: undefined,
|
||||||
|
wallet: client.recentWallet,
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return client.execute(
|
return client.broadcast(broadcastOptions)
|
||||||
options.sender,
|
|
||||||
options.contract,
|
|
||||||
options.msg as Record<string, unknown>,
|
|
||||||
options.fee,
|
|
||||||
undefined,
|
|
||||||
options.funds,
|
|
||||||
)
|
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
},
|
},
|
||||||
loadNetworkConfig: async () => {
|
loadNetworkConfig: async () => {
|
||||||
@ -133,7 +146,7 @@ const commonSlice = (
|
|||||||
lcdClient: new LcdClient(rpc),
|
lcdClient: new LcdClient(rpc),
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
setChainInfo: (chainInfo: WalletChainInfo) => set({ chainInfo }),
|
setChainInfo: (chainInfo: SimplifiedChainInfo) => set({ chainInfo }),
|
||||||
setCurrentNetwork: (network: Network) => set({ currentNetwork: network }),
|
setCurrentNetwork: (network: Network) => set({ currentNetwork: network }),
|
||||||
setNetworkError: (isError: boolean) => {
|
setNetworkError: (isError: boolean) => {
|
||||||
const errors = get().errors
|
const errors = get().errors
|
||||||
@ -142,7 +155,7 @@ const commonSlice = (
|
|||||||
set({ errors })
|
set({ errors })
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
setClient: (client: WalletSigningCosmWasmClient) => set({ client }),
|
setClient: (client: WalletClient) => set({ client }),
|
||||||
setQueryError: (name: string, isError: boolean) => {
|
setQueryError: (name: string, isError: boolean) => {
|
||||||
const errors = get().errors
|
const errors = get().errors
|
||||||
const queryErrors = get().queryErrors
|
const queryErrors = get().queryErrors
|
||||||
@ -171,7 +184,7 @@ const commonSlice = (
|
|||||||
set({ tutorialSteps })
|
set({ tutorialSteps })
|
||||||
},
|
},
|
||||||
setUserWalletAddress: (address: string) => set({ userWalletAddress: address }),
|
setUserWalletAddress: (address: string) => set({ userWalletAddress: address }),
|
||||||
setUserWalletName: (name: string) => set({ userWalletName: name }),
|
setUserIcns: (icns: string) => set({ userIcns: icns }),
|
||||||
// -------------------
|
// -------------------
|
||||||
// QUERY RELATED
|
// QUERY RELATED
|
||||||
// -------------------
|
// -------------------
|
||||||
|
@ -1,38 +1,11 @@
|
|||||||
import { SigningCosmWasmClient } from '@cosmjs/cosmwasm-stargate'
|
|
||||||
import { FieldsSlice } from 'store/interfaces/fields.interface'
|
import { FieldsSlice } from 'store/interfaces/fields.interface'
|
||||||
import { Store } from 'store/interfaces/store.interface'
|
import { Store } from 'store/interfaces/store.interface'
|
||||||
import { MarsAccountNftClient } from 'types/generated/mars-account-nft/MarsAccountNft.client'
|
|
||||||
import { MarsCreditManagerClient } from 'types/generated/mars-credit-manager/MarsCreditManager.client'
|
|
||||||
import { MarsCreditManagerMessageComposer } from 'types/generated/mars-credit-manager/MarsCreditManager.message-composer'
|
import { MarsCreditManagerMessageComposer } from 'types/generated/mars-credit-manager/MarsCreditManager.message-composer'
|
||||||
import { GetState } from 'zustand'
|
import { GetState } from 'zustand'
|
||||||
import { NamedSet } from 'zustand/middleware'
|
import { NamedSet } from 'zustand/middleware'
|
||||||
|
|
||||||
const fieldsSlice = (set: NamedSet<Store>, get: GetState<Store>): FieldsSlice => ({
|
const fieldsSlice = (set: NamedSet<Store>, get: GetState<Store>): FieldsSlice => ({
|
||||||
isRepay: false,
|
isRepay: false,
|
||||||
setAccountNftClient: (client: SigningCosmWasmClient) => {
|
|
||||||
const contracts = get().networkConfig?.contracts
|
|
||||||
const userWalletAddress = get().userWalletAddress
|
|
||||||
|
|
||||||
if (contracts?.accountNft) {
|
|
||||||
set({
|
|
||||||
accountNftClient: new MarsAccountNftClient(client, userWalletAddress, contracts.accountNft),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
setCreditManagerClient: (client: SigningCosmWasmClient) => {
|
|
||||||
const contracts = get().networkConfig?.contracts
|
|
||||||
const userWalletAddress = get().userWalletAddress
|
|
||||||
|
|
||||||
if (contracts?.accountNft && userWalletAddress) {
|
|
||||||
set({
|
|
||||||
creditManagerClient: new MarsCreditManagerClient(
|
|
||||||
client,
|
|
||||||
userWalletAddress,
|
|
||||||
contracts.creditManager,
|
|
||||||
),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
setCreditManagerMsgComposer: (sender: string, contract: string) => {
|
setCreditManagerMsgComposer: (sender: string, contract: string) => {
|
||||||
set({ creditManagerMsgComposer: new MarsCreditManagerMessageComposer(sender, contract) })
|
set({ creditManagerMsgComposer: new MarsCreditManagerMessageComposer(sender, contract) })
|
||||||
},
|
},
|
||||||
|
@ -90,7 +90,7 @@ const oraclesSlice = (set: NamedSet<Store>, get: GetState<Store>): OraclesSlice
|
|||||||
const denom = asset.denom
|
const denom = asset.denom
|
||||||
|
|
||||||
if (denom === get().baseCurrency.denom) {
|
if (denom === get().baseCurrency.denom) {
|
||||||
updateExchangeRate({ denom, amount: '1' }, exchangeRates)
|
exchangeRates.push({ denom, amount: '1' })
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,12 +5,13 @@ import { convertAprToApy, leverageToLtv } from 'libs/parse'
|
|||||||
import moment from 'moment'
|
import moment from 'moment'
|
||||||
import { Store } from 'store/interfaces/store.interface'
|
import { Store } from 'store/interfaces/store.interface'
|
||||||
import { Options, VaultsSlice } from 'store/interfaces/vaults.interface.'
|
import { Options, VaultsSlice } from 'store/interfaces/vaults.interface.'
|
||||||
|
import { VaultClient } from 'types/classes'
|
||||||
import {
|
import {
|
||||||
|
ArrayOfVaultInfoResponse,
|
||||||
LockingVaultAmount,
|
LockingVaultAmount,
|
||||||
Positions,
|
Positions,
|
||||||
} from 'types/generated/mars-credit-manager/MarsCreditManager.types'
|
} from 'types/generated/mars-credit-manager/MarsCreditManager.types'
|
||||||
import { VaultBaseForString } from 'types/generated/mars-mock-credit-manager/MarsMockCreditManager.types'
|
import { VaultBaseForString } from 'types/generated/mars-mock-credit-manager/MarsMockCreditManager.types'
|
||||||
import { MarsMockVaultClient } from 'types/generated/mars-mock-vault/MarsMockVault.client'
|
|
||||||
import { GetState } from 'zustand'
|
import { GetState } from 'zustand'
|
||||||
import { NamedSet } from 'zustand/middleware'
|
import { NamedSet } from 'zustand/middleware'
|
||||||
|
|
||||||
@ -25,12 +26,14 @@ export const vaultsSlice = (set: NamedSet<Store>, get: GetState<Store>): VaultsS
|
|||||||
const nftClient = get().accountNftClient!
|
const nftClient = get().accountNftClient!
|
||||||
const address = get().userWalletAddress
|
const address = get().userWalletAddress
|
||||||
|
|
||||||
const accountIds = await nftClient
|
const accountIds: string[] = await nftClient
|
||||||
.tokens({ owner: address, limit: 100 })
|
.query({ tokens: { owner: address, limit: 100 } })
|
||||||
.then((result) => result.tokens)
|
.then((result: { tokens: string[] }) => result.tokens)
|
||||||
|
|
||||||
const creditManagerClient = get().creditManagerClient
|
const creditManagerClient = get().creditManagerClient
|
||||||
const promises = accountIds?.map((id) => creditManagerClient?.positions({ accountId: id }))
|
const promises = accountIds?.map((id) =>
|
||||||
|
creditManagerClient?.query({ positions: { account_id: id } }),
|
||||||
|
)
|
||||||
|
|
||||||
const newCreditAccounts = await Promise.all(promises).then((result) =>
|
const newCreditAccounts = await Promise.all(promises).then((result) =>
|
||||||
result.map((value) => value as Positions).filter((positions) => positions.vaults.length),
|
result.map((value) => value as Positions).filter((positions) => positions.vaults.length),
|
||||||
@ -58,11 +61,13 @@ export const vaultsSlice = (set: NamedSet<Store>, get: GetState<Store>): VaultsS
|
|||||||
.toString()
|
.toString()
|
||||||
|
|
||||||
return {
|
return {
|
||||||
coins: await creditManagerClient.estimateWithdrawLiquidity({
|
coins: await creditManagerClient.query({
|
||||||
lpToken: {
|
estimate_withdraw_liquidity: {
|
||||||
|
lp_token: {
|
||||||
amount: amount,
|
amount: amount,
|
||||||
denom: lpToken.denom,
|
denom: lpToken.denom,
|
||||||
},
|
},
|
||||||
|
},
|
||||||
}),
|
}),
|
||||||
vaultAddress: lpToken.vaultAddress,
|
vaultAddress: lpToken.vaultAddress,
|
||||||
}
|
}
|
||||||
@ -91,11 +96,14 @@ export const vaultsSlice = (set: NamedSet<Store>, get: GetState<Store>): VaultsS
|
|||||||
?.unlocking[0]?.id
|
?.unlocking[0]?.id
|
||||||
|
|
||||||
if (!client || !vault || isNaN(lockupId)) return null
|
if (!client || !vault || isNaN(lockupId)) return null
|
||||||
|
|
||||||
|
const vaultClient = new VaultClient(vault.address, client)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
unlockAtTimestamp: Math.round(
|
unlockAtTimestamp: Math.round(
|
||||||
Number(
|
Number(
|
||||||
(
|
(
|
||||||
await client.queryContractSmart(vault.address, {
|
await vaultClient.query({
|
||||||
vault_extension: { lockup: { unlocking_position: { lockup_id: lockupId } } },
|
vault_extension: { lockup: { unlocking_position: { lockup_id: lockupId } } },
|
||||||
})
|
})
|
||||||
).release_at?.at_time,
|
).release_at?.at_time,
|
||||||
@ -152,7 +160,9 @@ export const vaultsSlice = (set: NamedSet<Store>, get: GetState<Store>): VaultsS
|
|||||||
let data: VaultCapData[] = []
|
let data: VaultCapData[] = []
|
||||||
|
|
||||||
const getBatch = async (startAfter?: VaultBaseForString): Promise<void> => {
|
const getBatch = async (startAfter?: VaultBaseForString): Promise<void> => {
|
||||||
const batch = await creditManagerClient?.vaultsInfo({ limit: 5, startAfter })
|
const batch: ArrayOfVaultInfoResponse = await creditManagerClient.query({
|
||||||
|
vaults_info: { limit: 5, start_after: startAfter },
|
||||||
|
})
|
||||||
|
|
||||||
const batchProcessed = batch?.map(
|
const batchProcessed = batch?.map(
|
||||||
(vaultInfo) =>
|
(vaultInfo) =>
|
||||||
@ -184,19 +194,20 @@ export const vaultsSlice = (set: NamedSet<Store>, get: GetState<Store>): VaultsS
|
|||||||
|
|
||||||
const creditAccounts = await get().getCreditAccounts(options)
|
const creditAccounts = await get().getCreditAccounts(options)
|
||||||
const client = get().client!
|
const client = get().client!
|
||||||
const userWalletAddress = get().userWalletAddress
|
|
||||||
|
|
||||||
const promises = creditAccounts.map(async (creditAccount) => {
|
const promises = creditAccounts.map(async (creditAccount) => {
|
||||||
const vaultAddress = creditAccount.vaults[0].vault.address
|
const vaultAddress = creditAccount.vaults[0].vault.address
|
||||||
const vault = get().vaultConfigs.find((vault) => vault.address === vaultAddress)
|
const vault = get().vaultConfigs.find((vault) => vault.address === vaultAddress)
|
||||||
|
|
||||||
const vaultClient = new MarsMockVaultClient(client, userWalletAddress, vaultAddress)
|
const vaultClient = new VaultClient(vaultAddress, client)
|
||||||
|
|
||||||
const amounts = getAmountsFromActiveVault(creditAccount.vaults[0].amount)
|
const amounts = getAmountsFromActiveVault(creditAccount.vaults[0].amount)
|
||||||
return {
|
return {
|
||||||
locked: Number(
|
locked: Number(
|
||||||
await vaultClient.previewRedeem({
|
await vaultClient.query({
|
||||||
|
preview_redeem: {
|
||||||
amount: amounts.locked,
|
amount: amounts.locked,
|
||||||
|
},
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
unlocking: amounts.unlocking,
|
unlocking: amounts.unlocking,
|
||||||
@ -206,7 +217,7 @@ export const vaultsSlice = (set: NamedSet<Store>, get: GetState<Store>): VaultsS
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const newLpTokens = await Promise.all(promises)
|
const newLpTokens = (await Promise.all(promises)).filter((lpToken) => !!lpToken.denom)
|
||||||
set({ lpTokens: newLpTokens })
|
set({ lpTokens: newLpTokens })
|
||||||
|
|
||||||
return newLpTokens
|
return newLpTokens
|
||||||
@ -378,7 +389,11 @@ export const vaultsSlice = (set: NamedSet<Store>, get: GetState<Store>): VaultsS
|
|||||||
vault: vaultTokenAmounts.locked,
|
vault: vaultTokenAmounts.locked,
|
||||||
},
|
},
|
||||||
values,
|
values,
|
||||||
apy: apy,
|
apy: {
|
||||||
|
total: curr.apy,
|
||||||
|
borrow: trueBorrowRate,
|
||||||
|
net: apy,
|
||||||
|
},
|
||||||
currentLeverage: leverage,
|
currentLeverage: leverage,
|
||||||
ltv: leverageToLtv(leverage),
|
ltv: leverageToLtv(leverage),
|
||||||
...(unlockTime ? { unlockAtTimestamp: unlockTime } : {}),
|
...(unlockTime ? { unlockAtTimestamp: unlockTime } : {}),
|
||||||
|
@ -49,6 +49,14 @@ a {
|
|||||||
color: $colorPrimaryHighlight;
|
color: $colorPrimaryHighlight;
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&:has(button) {
|
||||||
|
&:hover,
|
||||||
|
&:focus,
|
||||||
|
&:active {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
b,
|
b,
|
||||||
|
@ -1,35 +1,35 @@
|
|||||||
@use 'sass:math';
|
@use 'sass:math';
|
||||||
$rem-base: 16px;
|
$rem-base: 15px;
|
||||||
|
|
||||||
/* Colors */
|
/* Colors */
|
||||||
$colorWhite: #f5f5f5;
|
$colorWhite: #ffffff;
|
||||||
$colorGrey: #bdbdbd;
|
$colorGrey: #3a3c49;
|
||||||
$colorGreyLight: #e0e0e0;
|
$colorGreyLight: #bfbfbf;
|
||||||
$colorGreyHighlight: #efefef;
|
$colorGreyHighlight: #4c4c4c;
|
||||||
$colorGreyMedium: #9e9e9e;
|
$colorGreyMedium: #5f697a;
|
||||||
$colorGreyDark: #616161;
|
$colorGreyDark: #1a1c25;
|
||||||
|
|
||||||
/* CI Colors */
|
/* CI Colors */
|
||||||
$colorPrimary: #0000ff;
|
$colorPrimary: #14a693;
|
||||||
$colorPrimaryHighlight: #6962cc;
|
$colorPrimaryHighlight: #15bfa9;
|
||||||
$colorPrimaryAlpha: rgba(0, 0, 255, 0.05);
|
$colorPrimaryAlpha: rgba(20, 166, 147, 0.15);
|
||||||
$colorSecondary: #212121;
|
$colorSecondary: #524bb1;
|
||||||
$colorSecondaryHighlight: #424242;
|
$colorSecondaryHighlight: #6962cc;
|
||||||
$colorSecondaryDark: #111111;
|
$colorSecondaryDark: #440b37;
|
||||||
$colorSecondaryAlpha: rgba(17, 17, 17, 0.15);
|
$colorSecondaryAlpha: rgba(68, 11, 55, 0.7);
|
||||||
$colorAccent: $colorGreyMedium;
|
$colorAccent: #2c1b2f;
|
||||||
$colorAccentHighlight: $colorGreyMedium;
|
$colorAccentHighlight: #421f32;
|
||||||
$colorAccentDark: $colorGreyDark;
|
$colorAccentDark: #341a2a;
|
||||||
$colorAccentInverted: $colorGreyLight;
|
$colorAccentInverted: #345dff;
|
||||||
|
|
||||||
/* Info Colors */
|
/* Info Colors */
|
||||||
$colorInfoProfit: #c4e7e9;
|
$colorInfoProfit: #41a4a9;
|
||||||
$colorInfoLoss: #c8aaaa;
|
$colorInfoLoss: #f96363;
|
||||||
$colorInfoWarning: #ffb5b5;
|
$colorInfoWarning: #c83333;
|
||||||
$colorInfoVoteAgainst: #6c5a46;
|
$colorInfoVoteAgainst: #eb9e49;
|
||||||
|
|
||||||
/* Token Colors */
|
/* Token Colors */
|
||||||
$colorTokenMARS: #dd5b65;
|
$colorTokenMARS: #a03b45;
|
||||||
$colorTokenOSMO: #9f1ab9;
|
$colorTokenOSMO: #9f1ab9;
|
||||||
$colorTokenATOM: #6f7390;
|
$colorTokenATOM: #6f7390;
|
||||||
$colorTokenAxlUSDC: #478edc;
|
$colorTokenAxlUSDC: #478edc;
|
||||||
@ -60,29 +60,32 @@ $alphaBlack80: rgba(0, 0, 0, 0.8);
|
|||||||
$alphaBlack90: rgba(0, 0, 0, 0.9);
|
$alphaBlack90: rgba(0, 0, 0, 0.9);
|
||||||
|
|
||||||
/* Background Colors */
|
/* Background Colors */
|
||||||
$backgroundBody: $colorGrey;
|
$backgroundBody: #562a3b;
|
||||||
$backgroundBodyDark: $backgroundBody;
|
$backgroundBodyDark: #141621;
|
||||||
$backgroundInTile: transparent;
|
$backgroundInTile: $alphaBlack30;
|
||||||
$backgroundFooter: transparent;
|
$backgroundFooter: $alphaBlack20;
|
||||||
|
|
||||||
/* Slider Colors */
|
/* Slider Colors */
|
||||||
$sliderThumb: $colorGreyDark;
|
$sliderThumb: $colorWhite;
|
||||||
$sliderMark: $colorGreyDark;
|
$sliderMark: $colorGreyLight;
|
||||||
|
|
||||||
/* Tooltip Colors */
|
/* Tooltip Colors */
|
||||||
$tooltipIconColor: $alphaBlack60;
|
$tooltipIconColor: $alphaWhite20;
|
||||||
|
$tableSort: $alphaWhite20;
|
||||||
|
$tableSortActive: $colorWhite;
|
||||||
|
$tableHeader: $alphaWhite50;
|
||||||
|
|
||||||
/* Table Colors */
|
/* Table Colors */
|
||||||
$tableBorder: $alphaBlack30;
|
$tableBorder: $alphaWhite10;
|
||||||
$tableBorderEnd: $alphaBlack80;
|
$tableBorderEnd: $alphaWhite80;
|
||||||
$tableSort: $alphaBlack20;
|
$tableSort: $alphaWhite20;
|
||||||
$tableSortActive: $alphaBlack90;
|
$tableSortActive: $colorWhite;
|
||||||
$tableHeader: $alphaBlack40;
|
$tableHeader: $alphaWhite40;
|
||||||
$tableLabel: $colorSecondaryDark;
|
$tableLabel: $alphaWhite60;
|
||||||
|
|
||||||
/* Graph Colors */
|
/* Graph Colors */
|
||||||
$graphLiquidationsLine: $alphaBlack70;
|
$graphLiquidationsLine: $alphaWhite70;
|
||||||
$graphAxis: $alphaBlack40;
|
$graphAxis: $alphaWhite40;
|
||||||
|
|
||||||
/* Shadows */
|
/* Shadows */
|
||||||
$shadowInset: inset 0px 2px 2px rgba(0, 0, 0, 0.25);
|
$shadowInset: inset 0px 2px 2px rgba(0, 0, 0, 0.25);
|
||||||
@ -93,40 +96,43 @@ $shadowInset: inset 0px 2px 2px rgba(0, 0, 0, 0.25);
|
|||||||
|
|
||||||
/* Devider */
|
/* Devider */
|
||||||
@mixin devider10 {
|
@mixin devider10 {
|
||||||
border-bottom: 1px solid $alphaBlack10;
|
border-bottom: 1px solid $alphaWhite10;
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin devider20 {
|
@mixin devider20 {
|
||||||
border-bottom: 1px solid $alphaBlack20;
|
border-bottom: 1px solid $alphaWhite20;
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin devider40 {
|
@mixin devider40 {
|
||||||
border-bottom: 1px solid $alphaBlack40;
|
border-bottom: 1px solid $alphaWhite40;
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin devider60 {
|
@mixin devider60 {
|
||||||
border-bottom: 1px solid $alphaBlack60;
|
border-bottom: 1px solid $alphaWhite60;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Backgrounds */
|
/* Backgrounds */
|
||||||
@mixin bgBody {
|
@mixin bgBody {
|
||||||
background-color: $backgroundBody;
|
background-color: $backgroundBody;
|
||||||
}
|
background-size: 100% auto;
|
||||||
|
background-image: url('../images/bg.svg');
|
||||||
@mixin bgTableHover {
|
background-position: center top;
|
||||||
background-color: transparent;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin bgBodyDark {
|
@mixin bgBodyDark {
|
||||||
background-color: $backgroundBodyDark;
|
background-color: $backgroundBodyDark;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@mixin bgTableHover {
|
||||||
|
background-color: rgba($colorPrimary, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
@mixin bgProposalActive {
|
@mixin bgProposalActive {
|
||||||
background: linear-gradient(90deg, #10aa93 2.6%, #248aa9 97.92%);
|
background: linear-gradient(90deg, #10aa93 2.6%, #248aa9 97.92%);
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin bgProposalHover {
|
@mixin bgProposalHover {
|
||||||
background-color: $colorGreyMedium;
|
background-color: #05252f;
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin bgTile($deg: 99.79) {
|
@mixin bgTile($deg: 99.79) {
|
||||||
@ -138,7 +144,7 @@ $shadowInset: inset 0px 2px 2px rgba(0, 0, 0, 0.25);
|
|||||||
}
|
}
|
||||||
|
|
||||||
@mixin bgInTile {
|
@mixin bgInTile {
|
||||||
background: $backgroundInTile;
|
background: $alphaBlack30;
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin bgOverlay {
|
@mixin bgOverlay {
|
||||||
@ -155,11 +161,11 @@ $shadowInset: inset 0px 2px 2px rgba(0, 0, 0, 0.25);
|
|||||||
}
|
}
|
||||||
|
|
||||||
@mixin bgTileDevider {
|
@mixin bgTileDevider {
|
||||||
background-color: $alphaBlack60;
|
background-color: $alphaWhite60;
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin bgDevider {
|
@mixin bgDevider {
|
||||||
background-color: $alphaBlack20;
|
background-color: $alphaWhite20;
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin bgInput {
|
@mixin bgInput {
|
||||||
@ -168,60 +174,68 @@ $shadowInset: inset 0px 2px 2px rgba(0, 0, 0, 0.25);
|
|||||||
|
|
||||||
@mixin bgPrimary {
|
@mixin bgPrimary {
|
||||||
background-color: $colorPrimary;
|
background-color: $colorPrimary;
|
||||||
color: $colorWhite;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin bgSecondary {
|
@mixin bgSecondary {
|
||||||
background-color: $colorSecondary;
|
background-color: $colorSecondary;
|
||||||
color: $colorWhite;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin bgTertiary {
|
@mixin bgTertiary {
|
||||||
background-color: $alphaBlack60;
|
background-color: rgba(82, 75, 177, 0.5);
|
||||||
color: $colorWhite;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin bgLimit {
|
@mixin bgLimit {
|
||||||
background: $colorPrimary;
|
background: linear-gradient(
|
||||||
|
to right,
|
||||||
|
#15bfa9 20.9%,
|
||||||
|
#5e4bb1 49.68%,
|
||||||
|
#382685 82.55%,
|
||||||
|
#c83333 100%
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin bgLimitOpacity {
|
@mixin bgLimitOpacity {
|
||||||
background: $colorPrimary;
|
background: linear-gradient(
|
||||||
|
to right,
|
||||||
|
#15bfa830 20.9%,
|
||||||
|
#5e4bb130 49.68%,
|
||||||
|
#38268530 82.55%,
|
||||||
|
#c8333330 100%
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin bgHatched {
|
@mixin bgHatched {
|
||||||
background-image: linear-gradient(
|
background-image: linear-gradient(
|
||||||
135deg,
|
135deg,
|
||||||
#1a1c25 33.33%,
|
transparent 33.33%,
|
||||||
rgba(255, 255, 255, 0.2) 33.33%,
|
#826d6b 33.33%,
|
||||||
rgba(255, 255, 255, 0.2) 50%,
|
#826d6b 50%,
|
||||||
#1a1c25 50%,
|
transparent 50%,
|
||||||
#1a1c25 83.33%,
|
transparent 83.33%,
|
||||||
rgba(255, 255, 255, 0.2) 83.33%,
|
#826d6b 83.33%,
|
||||||
rgba(255, 255, 255, 0.2) 100%
|
#826d6b 100%
|
||||||
);
|
);
|
||||||
background-size: 5px 5px;
|
background-size: 5px 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* GLOWS */
|
|
||||||
/* GLOWS */
|
/* GLOWS */
|
||||||
@mixin glowXS {
|
@mixin glowXS {
|
||||||
display: none;
|
filter: blur(1px);
|
||||||
}
|
}
|
||||||
@mixin glowS {
|
@mixin glowS {
|
||||||
display: none;
|
filter: blur(3px);
|
||||||
}
|
}
|
||||||
@mixin glowM {
|
@mixin glowM {
|
||||||
display: none;
|
filter: blur(4px);
|
||||||
}
|
}
|
||||||
@mixin glowL {
|
@mixin glowL {
|
||||||
display: none;
|
filter: blur(5px);
|
||||||
}
|
}
|
||||||
@mixin glowXL {
|
@mixin glowXL {
|
||||||
display: none;
|
filter: blur(8px);
|
||||||
}
|
}
|
||||||
@mixin glowXXL {
|
@mixin glowXXL {
|
||||||
display: none;
|
filter: blur(24px);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Typography */
|
/* Typography */
|
||||||
@ -229,11 +243,11 @@ $fontWeightLight: 300;
|
|||||||
$fontWeightRegular: 400;
|
$fontWeightRegular: 400;
|
||||||
$fontWeightSemibold: 600;
|
$fontWeightSemibold: 600;
|
||||||
|
|
||||||
$fontColorDarkPrimary: $colorWhite;
|
$fontColorDarkPrimary: $colorSecondaryDark;
|
||||||
$fontColorDarkSecondary: $colorSecondaryDark;
|
$fontColorDarkSecondary: rgba(68, 8, 55, 0.7);
|
||||||
$fontColorLightPrimary: $colorSecondaryDark;
|
$fontColorLightPrimary: $colorWhite;
|
||||||
$fontColorLightSecondary: $alphaBlack30;
|
$fontColorLightSecondary: $alphaWhite60;
|
||||||
$fontColorLightTertiary: $colorSecondaryDark;
|
$fontColorLightTertiary: rgba(255, 255, 255, 0.4);
|
||||||
$fontColorLtv: $colorWhite;
|
$fontColorLtv: $colorWhite;
|
||||||
|
|
||||||
@mixin typoH1 {
|
@mixin typoH1 {
|
||||||
@ -249,6 +263,8 @@ $fontColorLtv: $colorWhite;
|
|||||||
|
|
||||||
@mixin typoH2caps {
|
@mixin typoH2caps {
|
||||||
@include typoH2;
|
@include typoH2;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: rem-calc(9);
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin typoH3 {
|
@mixin typoH3 {
|
||||||
@ -258,6 +274,8 @@ $fontColorLtv: $colorWhite;
|
|||||||
|
|
||||||
@mixin typoH3caps {
|
@mixin typoH3caps {
|
||||||
font-size: rem-calc(30.42);
|
font-size: rem-calc(30.42);
|
||||||
|
line-height: space(10);
|
||||||
|
text-transform: uppercase;
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin typoH4 {
|
@mixin typoH4 {
|
||||||
@ -268,6 +286,8 @@ $fontColorLtv: $colorWhite;
|
|||||||
|
|
||||||
@mixin typoH4caps {
|
@mixin typoH4caps {
|
||||||
@include typoH4;
|
@include typoH4;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: rem-calc(3);
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin typoXXL {
|
@mixin typoXXL {
|
||||||
@ -277,7 +297,9 @@ $fontColorLtv: $colorWhite;
|
|||||||
|
|
||||||
@mixin typoXXLcaps {
|
@mixin typoXXLcaps {
|
||||||
@include typoXXL;
|
@include typoXXL;
|
||||||
font-weight: $fontWeightLight;
|
font-weight: $fontWeightRegular;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: rem-calc(3);
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin typoXL {
|
@mixin typoXL {
|
||||||
@ -287,6 +309,8 @@ $fontColorLtv: $colorWhite;
|
|||||||
|
|
||||||
@mixin typoXLcaps {
|
@mixin typoXLcaps {
|
||||||
@include typoXL;
|
@include typoXL;
|
||||||
|
letter-spacing: rem-calc(5);
|
||||||
|
text-transform: uppercase;
|
||||||
font-weight: $fontWeightLight;
|
font-weight: $fontWeightLight;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -298,6 +322,8 @@ $fontColorLtv: $colorWhite;
|
|||||||
@mixin typoLcaps {
|
@mixin typoLcaps {
|
||||||
@include typoL;
|
@include typoL;
|
||||||
font-weight: $fontWeightSemibold;
|
font-weight: $fontWeightSemibold;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: rem-calc(3);
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin typoM {
|
@mixin typoM {
|
||||||
@ -307,6 +333,7 @@ $fontColorLtv: $colorWhite;
|
|||||||
|
|
||||||
@mixin typoMcaps {
|
@mixin typoMcaps {
|
||||||
@include typoM;
|
@include typoM;
|
||||||
|
text-transform: uppercase;
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin typoS {
|
@mixin typoS {
|
||||||
@ -317,6 +344,8 @@ $fontColorLtv: $colorWhite;
|
|||||||
@mixin typoScaps {
|
@mixin typoScaps {
|
||||||
@include typoS;
|
@include typoS;
|
||||||
font-weight: $fontWeightSemibold;
|
font-weight: $fontWeightSemibold;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: rem-calc(3);
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin typoXS {
|
@mixin typoXS {
|
||||||
@ -327,6 +356,8 @@ $fontColorLtv: $colorWhite;
|
|||||||
@mixin typoXScaps {
|
@mixin typoXScaps {
|
||||||
@include typoXS;
|
@include typoXS;
|
||||||
font-weight: $fontWeightSemibold;
|
font-weight: $fontWeightSemibold;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: rem-calc(3);
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin typoXXS {
|
@mixin typoXXS {
|
||||||
@ -337,6 +368,8 @@ $fontColorLtv: $colorWhite;
|
|||||||
@mixin typoXXScaps {
|
@mixin typoXXScaps {
|
||||||
@include typoXXS;
|
@include typoXXS;
|
||||||
font-weight: $fontWeightSemibold;
|
font-weight: $fontWeightSemibold;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: rem-calc(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin typoXXXS {
|
@mixin typoXXXS {
|
||||||
@ -347,15 +380,20 @@ $fontColorLtv: $colorWhite;
|
|||||||
@mixin typoXXXScaps {
|
@mixin typoXXXScaps {
|
||||||
@include typoXXXS;
|
@include typoXXXS;
|
||||||
font-weight: $fontWeightSemibold;
|
font-weight: $fontWeightSemibold;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: rem-calc(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin typoButton {
|
@mixin typoButton {
|
||||||
|
font-family: Inter, sans-serif;
|
||||||
@include typoS;
|
@include typoS;
|
||||||
font-weight: $fontWeightSemibold;
|
font-weight: $fontWeightSemibold;
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin typoNav {
|
@mixin typoNav {
|
||||||
@include typoL;
|
@include typoL;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: rem-calc(5);
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin typoNetwork {
|
@mixin typoNetwork {
|
||||||
@ -429,70 +467,100 @@ $spacingBase: 4;
|
|||||||
|
|
||||||
/* LAYOUTS */
|
/* LAYOUTS */
|
||||||
@mixin layoutTile {
|
@mixin layoutTile {
|
||||||
padding: space(1);
|
@include bgTile;
|
||||||
background: $colorGreyHighlight;
|
border: rem-calc(7) solid $colorAccentHighlight;
|
||||||
border: 2px solid $colorWhite;
|
border-radius: $borderRadiusXL;
|
||||||
box-shadow: 0 0 0 3px $colorGreyHighlight, 12px 12px 0 0 rgb(0 0 0 / 50%) !important;
|
|
||||||
height: fit-content;
|
height: fit-content;
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin layoutTooltip {
|
@mixin layoutTooltip {
|
||||||
padding: space(3);
|
@include padding(2, 4);
|
||||||
background: $colorGreyLight;
|
@include bgTooltip;
|
||||||
border: 1px solid $colorSecondaryDark;
|
@include typoS;
|
||||||
|
box-shadow: 0 rem-calc(3) rem-calc(4) rgba(0, 0, 0, 0.14),
|
||||||
|
0 rem-calc(3) rem-calc(3) rgba(0, 0, 0, 0.12), 0 rem-calc(1) rem-calc(8) rgba(0, 0, 0, 0.2);
|
||||||
|
border-radius: $borderRadiusL;
|
||||||
|
max-width: rem-calc(350);
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin layoutPopover {
|
@mixin layoutPopover {
|
||||||
padding: space(3);
|
@include bgPopover;
|
||||||
background: $colorGreyLight;
|
box-shadow: 0 rem-calc(2) rem-calc(2) rgba(0, 0, 0, 0.14),
|
||||||
border: 1px solid $colorSecondaryDark;
|
0 rem-calc(1) rem-calc(5) rgba(0, 0, 0, 0.2);
|
||||||
|
border-radius: $borderRadiusL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin layoutIncentiveButton {
|
@mixin layoutIncentiveButton {
|
||||||
|
--border-width: 3px;
|
||||||
|
background-color: #946582;
|
||||||
|
position: relative;
|
||||||
|
border: none;
|
||||||
|
margin: rem-calc(3) rem-calc(11) 0 0;
|
||||||
|
height: rem-calc(28);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
border: none;
|
||||||
|
background-color: darken(#946582, 10%);
|
||||||
|
}
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
border-radius: $borderRadiusXXL;
|
||||||
|
position: absolute;
|
||||||
|
content: '';
|
||||||
|
top: calc(-1 * var(--border-width));
|
||||||
|
left: calc(-1 * var(--border-width));
|
||||||
|
z-index: -1;
|
||||||
|
width: calc(100% + var(--border-width) * 2);
|
||||||
|
height: calc(100% + var(--border-width) * 2);
|
||||||
|
background: linear-gradient(
|
||||||
|
90deg,
|
||||||
|
rgba(105, 98, 204, 0.8) 0%,
|
||||||
|
rgba(105, 98, 204, 1) 40%,
|
||||||
|
rgba(255, 255, 255, 1) 50%,
|
||||||
|
rgba(105, 98, 204, 1) 60%,
|
||||||
|
rgba(105, 98, 204, 0.8) 100%
|
||||||
|
);
|
||||||
|
background-size: 300% 300%;
|
||||||
|
background-position: 0 50%;
|
||||||
|
animation: moveGradient 6s alternate infinite;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin layoutLogo {
|
@mixin layoutLogo {
|
||||||
> svg {
|
> svg {
|
||||||
width: rem-calc(57);
|
width: rem-calc(50);
|
||||||
height: rem-calc(57);
|
height: rem-calc(50);
|
||||||
|
|
||||||
path {
|
|
||||||
stroke: $fontColorLightPrimary;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin layoutGlobal {
|
@mixin layoutGlobal {
|
||||||
opacity: 1 !important;
|
|
||||||
box-shadow: none !important;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Buttons */
|
/* Buttons */
|
||||||
$buttonBorder: $alphaBlack40;
|
$buttonBorder: $alphaWhite40;
|
||||||
$buttonBorderHover: $colorSecondaryDark;
|
$buttonBorderHover: $colorWhite;
|
||||||
|
|
||||||
@mixin buttonS {
|
@mixin buttonS {
|
||||||
@include typoS;
|
@include typoS;
|
||||||
@include padding(1.5, 5);
|
@include padding(1.5, 5);
|
||||||
height: rem-calc(32);
|
min-height: rem-calc(32);
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin buttonM {
|
@mixin buttonM {
|
||||||
@include typoM;
|
@include typoM;
|
||||||
@include padding(2.5, 6);
|
@include padding(2.5, 6);
|
||||||
height: rem-calc(40);
|
min-height: rem-calc(40);
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin buttonL {
|
@mixin buttonL {
|
||||||
@include typoL;
|
@include typoL;
|
||||||
@include padding(2.5, 6);
|
@include padding(2.5, 6);
|
||||||
height: rem-calc(56);
|
min-height: rem-calc(56);
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin buttonSolidPrimary {
|
@mixin buttonSolidPrimary {
|
||||||
&.primary {
|
&.primary {
|
||||||
background-color: $colorPrimary;
|
background-color: $colorPrimary;
|
||||||
color: $colorWhite;
|
|
||||||
|
|
||||||
&:hover,
|
&:hover,
|
||||||
&:focus {
|
&:focus {
|
||||||
@ -508,7 +576,6 @@ $buttonBorderHover: $colorSecondaryDark;
|
|||||||
@mixin buttonSolidSecondary {
|
@mixin buttonSolidSecondary {
|
||||||
&.secondary {
|
&.secondary {
|
||||||
background-color: $colorSecondary;
|
background-color: $colorSecondary;
|
||||||
color: $colorWhite;
|
|
||||||
|
|
||||||
&:hover,
|
&:hover,
|
||||||
&:focus {
|
&:focus {
|
||||||
@ -523,33 +590,34 @@ $buttonBorderHover: $colorSecondaryDark;
|
|||||||
|
|
||||||
@mixin buttonSolidTertiary {
|
@mixin buttonSolidTertiary {
|
||||||
&.tertiary {
|
&.tertiary {
|
||||||
background-color: $colorSecondaryDark;
|
background-color: $colorSecondaryAlpha;
|
||||||
color: $colorWhite;
|
border: 1px solid $alphaWhite60;
|
||||||
border: 1px solid $alphaBlack30;
|
|
||||||
|
|
||||||
&:hover,
|
&:hover,
|
||||||
&:focus {
|
&:focus {
|
||||||
border: 1px solid $alphaBlack20;
|
border: 1px solid $fontColorLightPrimary;
|
||||||
|
background-color: $colorSecondaryDark;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:active {
|
&:active {
|
||||||
|
border: 1px solid $fontColorLightPrimary;
|
||||||
background-color: lighten($colorSecondaryDark, 10%);
|
background-color: lighten($colorSecondaryDark, 10%);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Border Radius */
|
/* Border Radius */
|
||||||
$borderRadiusXXXS: 0;
|
$borderRadiusXXXS: rem-calc(3);
|
||||||
$borderRadiusXXS: 0;
|
$borderRadiusXXS: rem-calc(4);
|
||||||
$borderRadiusXS: 0;
|
$borderRadiusXS: rem-calc(5);
|
||||||
$borderRadiusS: 0;
|
$borderRadiusS: rem-calc(8);
|
||||||
$borderRadiusM: 0;
|
$borderRadiusM: rem-calc(9);
|
||||||
$borderRadiusL: 0;
|
$borderRadiusL: rem-calc(12);
|
||||||
$borderRadiusXL: 0;
|
$borderRadiusXL: rem-calc(16);
|
||||||
$borderRadiusXXL: 0;
|
$borderRadiusXXL: rem-calc(20);
|
||||||
$borderRadiusXXXL: 0;
|
$borderRadiusXXXL: rem-calc(30);
|
||||||
$borderRadiusXXXXL: 0;
|
$borderRadiusXXXXL: rem-calc(100);
|
||||||
$borderRadiusRound: 0;
|
$borderRadiusRound: 50%;
|
||||||
|
|
||||||
/* Dimensions */
|
/* Dimensions */
|
||||||
$headerHeight: rem-calc(86);
|
$headerHeight: rem-calc(86);
|
||||||
|
@ -1,6 +1,62 @@
|
|||||||
|
import { Coin } from '@cosmjs/stargate'
|
||||||
|
import { WalletClient } from '@marsprotocol/wallet-connector'
|
||||||
|
import {
|
||||||
|
ArrayOfCoin,
|
||||||
|
QueryMsg as CreditQueryMsg,
|
||||||
|
} from 'types/generated/mars-credit-manager/MarsCreditManager.types'
|
||||||
|
|
||||||
|
import { QueryMsg as AccountQueryMsg } from './generated/mars-account-nft/MarsAccountNft.types'
|
||||||
|
import { QueryMsg as VaultQueryMsg } from './generated/mars-mock-vault/MarsMockVault.types'
|
||||||
|
|
||||||
export class SetupError extends Error {
|
export class SetupError extends Error {
|
||||||
constructor(name: string, message: string) {
|
constructor(name: string, message: string) {
|
||||||
super(message)
|
super(message)
|
||||||
this.name = name
|
this.name = name
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class CreditManagerClient {
|
||||||
|
address: string
|
||||||
|
client: WalletClient
|
||||||
|
|
||||||
|
constructor(address: string, client: WalletClient) {
|
||||||
|
this.address = address
|
||||||
|
this.client = client
|
||||||
|
}
|
||||||
|
|
||||||
|
query(message: CreditQueryMsg) {
|
||||||
|
return this.client.cosmWasmClient.queryContractSmart(this.address, message)
|
||||||
|
}
|
||||||
|
|
||||||
|
estimateWithdrawLiquidity({ lpToken }: { lpToken: Coin }) {
|
||||||
|
return Promise<ArrayOfCoin>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class AccountNftClient {
|
||||||
|
address: string
|
||||||
|
client: WalletClient
|
||||||
|
|
||||||
|
constructor(address: string, client: WalletClient) {
|
||||||
|
this.address = address
|
||||||
|
this.client = client
|
||||||
|
}
|
||||||
|
|
||||||
|
query(message: AccountQueryMsg) {
|
||||||
|
return this.client.cosmWasmClient.queryContractSmart(this.address, message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class VaultClient {
|
||||||
|
address: string
|
||||||
|
client: WalletClient
|
||||||
|
|
||||||
|
constructor(address: string, client: WalletClient) {
|
||||||
|
this.address = address
|
||||||
|
this.client = client
|
||||||
|
}
|
||||||
|
|
||||||
|
query(message: VaultQueryMsg) {
|
||||||
|
return this.client.cosmWasmClient.queryContractSmart(this.address, message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -7,6 +7,7 @@ export enum QUERY_KEYS {
|
|||||||
USER_BALANCE = 'userBalance',
|
USER_BALANCE = 'userBalance',
|
||||||
USER_DEBT = 'userDebt',
|
USER_DEBT = 'userDebt',
|
||||||
USER_DEPOSIT = 'userDeposits',
|
USER_DEPOSIT = 'userDeposits',
|
||||||
|
USER_ICNS = 'userIcns',
|
||||||
ATOM_PRICE = 'atomPrice',
|
ATOM_PRICE = 'atomPrice',
|
||||||
SAFETY_FUND_BALANCE = 'safetyFundBalance',
|
SAFETY_FUND_BALANCE = 'safetyFundBalance',
|
||||||
MARKET_DEPOSITS = 'marketDeposits',
|
MARKET_DEPOSITS = 'marketDeposits',
|
||||||
|
@ -13,11 +13,11 @@ import {
|
|||||||
ApprovalResponse,
|
ApprovalResponse,
|
||||||
ApprovalsResponse,
|
ApprovalsResponse,
|
||||||
Binary,
|
Binary,
|
||||||
ConfigBaseForString,
|
|
||||||
ConfigUpdates,
|
|
||||||
ContractInfoResponse,
|
ContractInfoResponse,
|
||||||
Expiration,
|
Expiration,
|
||||||
MinterResponse,
|
MinterResponse,
|
||||||
|
NftConfigBaseForString,
|
||||||
|
NftConfigUpdates,
|
||||||
NftInfoResponseForEmpty,
|
NftInfoResponseForEmpty,
|
||||||
NumTokensResponse,
|
NumTokensResponse,
|
||||||
OperatorsResponse,
|
OperatorsResponse,
|
||||||
@ -27,7 +27,7 @@ import {
|
|||||||
} from './MarsAccountNft.types'
|
} from './MarsAccountNft.types'
|
||||||
export interface MarsAccountNftReadOnlyInterface {
|
export interface MarsAccountNftReadOnlyInterface {
|
||||||
contractAddress: string
|
contractAddress: string
|
||||||
config: () => Promise<ConfigBaseForString>
|
config: () => Promise<NftConfigBaseForString>
|
||||||
nextId: () => Promise<Uint64>
|
nextId: () => Promise<Uint64>
|
||||||
ownerOf: ({
|
ownerOf: ({
|
||||||
includeExpired,
|
includeExpired,
|
||||||
@ -113,7 +113,7 @@ export class MarsAccountNftQueryClient implements MarsAccountNftReadOnlyInterfac
|
|||||||
this.minter = this.minter.bind(this)
|
this.minter = this.minter.bind(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
config = async (): Promise<ConfigBaseForString> => {
|
config = async (): Promise<NftConfigBaseForString> => {
|
||||||
return this.client.queryContractSmart(this.contractAddress, {
|
return this.client.queryContractSmart(this.contractAddress, {
|
||||||
config: {},
|
config: {},
|
||||||
})
|
})
|
||||||
@ -263,7 +263,7 @@ export interface MarsAccountNftInterface extends MarsAccountNftReadOnlyInterface
|
|||||||
{
|
{
|
||||||
updates,
|
updates,
|
||||||
}: {
|
}: {
|
||||||
updates: ConfigUpdates
|
updates: NftConfigUpdates
|
||||||
},
|
},
|
||||||
fee?: number | StdFee | 'auto',
|
fee?: number | StdFee | 'auto',
|
||||||
memo?: string,
|
memo?: string,
|
||||||
@ -398,7 +398,7 @@ export class MarsAccountNftClient
|
|||||||
{
|
{
|
||||||
updates,
|
updates,
|
||||||
}: {
|
}: {
|
||||||
updates: ConfigUpdates
|
updates: NftConfigUpdates
|
||||||
},
|
},
|
||||||
fee: number | StdFee | 'auto' = 'auto',
|
fee: number | StdFee | 'auto' = 'auto',
|
||||||
memo?: string,
|
memo?: string,
|
||||||
|
@ -10,7 +10,7 @@ import { toUtf8 } from '@cosmjs/encoding'
|
|||||||
import { MsgExecuteContract } from 'cosmjs-types/cosmwasm/wasm/v1/tx'
|
import { MsgExecuteContract } from 'cosmjs-types/cosmwasm/wasm/v1/tx'
|
||||||
import { MsgExecuteContractEncodeObject } from 'cosmwasm'
|
import { MsgExecuteContractEncodeObject } from 'cosmwasm'
|
||||||
|
|
||||||
import { Binary, ConfigUpdates, Expiration } from './MarsAccountNft.types'
|
import { Binary, Expiration, NftConfigUpdates } from './MarsAccountNft.types'
|
||||||
export interface MarsAccountNftMessage {
|
export interface MarsAccountNftMessage {
|
||||||
contractAddress: string
|
contractAddress: string
|
||||||
sender: string
|
sender: string
|
||||||
@ -18,7 +18,7 @@ export interface MarsAccountNftMessage {
|
|||||||
{
|
{
|
||||||
updates,
|
updates,
|
||||||
}: {
|
}: {
|
||||||
updates: ConfigUpdates
|
updates: NftConfigUpdates
|
||||||
},
|
},
|
||||||
funds?: Coin[],
|
funds?: Coin[],
|
||||||
) => MsgExecuteContractEncodeObject
|
) => MsgExecuteContractEncodeObject
|
||||||
@ -125,7 +125,7 @@ export class MarsAccountNftMessageComposer implements MarsAccountNftMessage {
|
|||||||
{
|
{
|
||||||
updates,
|
updates,
|
||||||
}: {
|
}: {
|
||||||
updates: ConfigUpdates
|
updates: NftConfigUpdates
|
||||||
},
|
},
|
||||||
funds?: Coin[],
|
funds?: Coin[],
|
||||||
): MsgExecuteContractEncodeObject => {
|
): MsgExecuteContractEncodeObject => {
|
||||||
|
@ -15,11 +15,11 @@ import {
|
|||||||
ApprovalResponse,
|
ApprovalResponse,
|
||||||
ApprovalsResponse,
|
ApprovalsResponse,
|
||||||
Binary,
|
Binary,
|
||||||
ConfigBaseForString,
|
|
||||||
ConfigUpdates,
|
|
||||||
ContractInfoResponse,
|
ContractInfoResponse,
|
||||||
Expiration,
|
Expiration,
|
||||||
MinterResponse,
|
MinterResponse,
|
||||||
|
NftConfigBaseForString,
|
||||||
|
NftConfigUpdates,
|
||||||
NftInfoResponseForEmpty,
|
NftInfoResponseForEmpty,
|
||||||
NumTokensResponse,
|
NumTokensResponse,
|
||||||
OperatorsResponse,
|
OperatorsResponse,
|
||||||
@ -329,12 +329,12 @@ export function useMarsAccountNftNextIdQuery<TData = Uint64>({
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
export interface MarsAccountNftConfigQuery<TData>
|
export interface MarsAccountNftConfigQuery<TData>
|
||||||
extends MarsAccountNftReactQuery<ConfigBaseForString, TData> {}
|
extends MarsAccountNftReactQuery<NftConfigBaseForString, TData> {}
|
||||||
export function useMarsAccountNftConfigQuery<TData = ConfigBaseForString>({
|
export function useMarsAccountNftConfigQuery<TData = NftConfigBaseForString>({
|
||||||
client,
|
client,
|
||||||
options,
|
options,
|
||||||
}: MarsAccountNftConfigQuery<TData>) {
|
}: MarsAccountNftConfigQuery<TData>) {
|
||||||
return useQuery<ConfigBaseForString, Error, TData>(
|
return useQuery<NftConfigBaseForString, Error, TData>(
|
||||||
marsAccountNftQueryKeys.config(client?.contractAddress),
|
marsAccountNftQueryKeys.config(client?.contractAddress),
|
||||||
() => (client ? client.config() : Promise.reject(new Error('Invalid client'))),
|
() => (client ? client.config() : Promise.reject(new Error('Invalid client'))),
|
||||||
{ ...options, enabled: !!client && (options?.enabled != undefined ? options.enabled : true) },
|
{ ...options, enabled: !!client && (options?.enabled != undefined ? options.enabled : true) },
|
||||||
@ -545,7 +545,7 @@ export function useMarsAccountNftAcceptMinterRoleMutation(
|
|||||||
export interface MarsAccountNftUpdateConfigMutation {
|
export interface MarsAccountNftUpdateConfigMutation {
|
||||||
client: MarsAccountNftClient
|
client: MarsAccountNftClient
|
||||||
msg: {
|
msg: {
|
||||||
updates: ConfigUpdates
|
updates: NftConfigUpdates
|
||||||
}
|
}
|
||||||
args?: {
|
args?: {
|
||||||
fee?: number | StdFee | 'auto'
|
fee?: number | StdFee | 'auto'
|
||||||
|
@ -15,7 +15,7 @@ export interface InstantiateMsg {
|
|||||||
export type ExecuteMsg =
|
export type ExecuteMsg =
|
||||||
| {
|
| {
|
||||||
update_config: {
|
update_config: {
|
||||||
updates: ConfigUpdates
|
updates: NftConfigUpdates
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
| {
|
| {
|
||||||
@ -81,7 +81,7 @@ export type Expiration =
|
|||||||
}
|
}
|
||||||
export type Timestamp = Uint64
|
export type Timestamp = Uint64
|
||||||
export type Uint64 = string
|
export type Uint64 = string
|
||||||
export interface ConfigUpdates {
|
export interface NftConfigUpdates {
|
||||||
max_value_for_burn?: Uint128 | null
|
max_value_for_burn?: Uint128 | null
|
||||||
proposed_new_minter?: string | null
|
proposed_new_minter?: string | null
|
||||||
}
|
}
|
||||||
@ -183,7 +183,7 @@ export interface ApprovalResponse {
|
|||||||
export interface ApprovalsResponse {
|
export interface ApprovalsResponse {
|
||||||
approvals: Approval[]
|
approvals: Approval[]
|
||||||
}
|
}
|
||||||
export interface ConfigBaseForString {
|
export interface NftConfigBaseForString {
|
||||||
max_value_for_burn: Uint128
|
max_value_for_burn: Uint128
|
||||||
proposed_new_minter?: string | null
|
proposed_new_minter?: string | null
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@ import {
|
|||||||
ArrayOfCoin,
|
ArrayOfCoin,
|
||||||
ArrayOfCoinBalanceResponseItem,
|
ArrayOfCoinBalanceResponseItem,
|
||||||
ArrayOfDebtShares,
|
ArrayOfDebtShares,
|
||||||
|
ArrayOfLentShares,
|
||||||
ArrayOfSharesResponseItem,
|
ArrayOfSharesResponseItem,
|
||||||
ArrayOfString,
|
ArrayOfString,
|
||||||
ArrayOfVaultInfoResponse,
|
ArrayOfVaultInfoResponse,
|
||||||
@ -23,6 +24,8 @@ import {
|
|||||||
ConfigUpdates,
|
ConfigUpdates,
|
||||||
DebtShares,
|
DebtShares,
|
||||||
HealthResponse,
|
HealthResponse,
|
||||||
|
LentShares,
|
||||||
|
NftConfigUpdates,
|
||||||
Positions,
|
Positions,
|
||||||
Uint128,
|
Uint128,
|
||||||
VaultBaseForString,
|
VaultBaseForString,
|
||||||
@ -68,6 +71,21 @@ export interface MarsCreditManagerReadOnlyInterface {
|
|||||||
limit?: number
|
limit?: number
|
||||||
startAfter?: string
|
startAfter?: string
|
||||||
}) => Promise<ArrayOfDebtShares>
|
}) => Promise<ArrayOfDebtShares>
|
||||||
|
allLentShares: ({
|
||||||
|
limit,
|
||||||
|
startAfter,
|
||||||
|
}: {
|
||||||
|
limit?: number
|
||||||
|
startAfter?: string[][]
|
||||||
|
}) => Promise<ArrayOfSharesResponseItem>
|
||||||
|
totalLentShares: () => Promise<LentShares>
|
||||||
|
allTotalLentShares: ({
|
||||||
|
limit,
|
||||||
|
startAfter,
|
||||||
|
}: {
|
||||||
|
limit?: number
|
||||||
|
startAfter?: string
|
||||||
|
}) => Promise<ArrayOfLentShares>
|
||||||
allVaultPositions: ({
|
allVaultPositions: ({
|
||||||
limit,
|
limit,
|
||||||
startAfter,
|
startAfter,
|
||||||
@ -108,6 +126,9 @@ export class MarsCreditManagerQueryClient implements MarsCreditManagerReadOnlyIn
|
|||||||
this.allDebtShares = this.allDebtShares.bind(this)
|
this.allDebtShares = this.allDebtShares.bind(this)
|
||||||
this.totalDebtShares = this.totalDebtShares.bind(this)
|
this.totalDebtShares = this.totalDebtShares.bind(this)
|
||||||
this.allTotalDebtShares = this.allTotalDebtShares.bind(this)
|
this.allTotalDebtShares = this.allTotalDebtShares.bind(this)
|
||||||
|
this.allLentShares = this.allLentShares.bind(this)
|
||||||
|
this.totalLentShares = this.totalLentShares.bind(this)
|
||||||
|
this.allTotalLentShares = this.allTotalLentShares.bind(this)
|
||||||
this.allVaultPositions = this.allVaultPositions.bind(this)
|
this.allVaultPositions = this.allVaultPositions.bind(this)
|
||||||
this.totalVaultCoinBalance = this.totalVaultCoinBalance.bind(this)
|
this.totalVaultCoinBalance = this.totalVaultCoinBalance.bind(this)
|
||||||
this.allTotalVaultCoinBalances = this.allTotalVaultCoinBalances.bind(this)
|
this.allTotalVaultCoinBalances = this.allTotalVaultCoinBalances.bind(this)
|
||||||
@ -209,6 +230,39 @@ export class MarsCreditManagerQueryClient implements MarsCreditManagerReadOnlyIn
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
allLentShares = async ({
|
||||||
|
limit,
|
||||||
|
startAfter,
|
||||||
|
}: {
|
||||||
|
limit?: number
|
||||||
|
startAfter?: string[][]
|
||||||
|
}): Promise<ArrayOfSharesResponseItem> => {
|
||||||
|
return this.client.queryContractSmart(this.contractAddress, {
|
||||||
|
all_lent_shares: {
|
||||||
|
limit,
|
||||||
|
start_after: startAfter,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
totalLentShares = async (): Promise<LentShares> => {
|
||||||
|
return this.client.queryContractSmart(this.contractAddress, {
|
||||||
|
total_lent_shares: {},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
allTotalLentShares = async ({
|
||||||
|
limit,
|
||||||
|
startAfter,
|
||||||
|
}: {
|
||||||
|
limit?: number
|
||||||
|
startAfter?: string
|
||||||
|
}): Promise<ArrayOfLentShares> => {
|
||||||
|
return this.client.queryContractSmart(this.contractAddress, {
|
||||||
|
all_total_lent_shares: {
|
||||||
|
limit,
|
||||||
|
start_after: startAfter,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
allVaultPositions = async ({
|
allVaultPositions = async ({
|
||||||
limit,
|
limit,
|
||||||
startAfter,
|
startAfter,
|
||||||
@ -288,9 +342,9 @@ export interface MarsCreditManagerInterface extends MarsCreditManagerReadOnlyInt
|
|||||||
) => Promise<ExecuteResult>
|
) => Promise<ExecuteResult>
|
||||||
updateConfig: (
|
updateConfig: (
|
||||||
{
|
{
|
||||||
newConfig,
|
updates,
|
||||||
}: {
|
}: {
|
||||||
newConfig: ConfigUpdates
|
updates: ConfigUpdates
|
||||||
},
|
},
|
||||||
fee?: number | StdFee | 'auto',
|
fee?: number | StdFee | 'auto',
|
||||||
memo?: string,
|
memo?: string,
|
||||||
@ -301,6 +355,16 @@ export interface MarsCreditManagerInterface extends MarsCreditManagerReadOnlyInt
|
|||||||
memo?: string,
|
memo?: string,
|
||||||
funds?: Coin[],
|
funds?: Coin[],
|
||||||
) => Promise<ExecuteResult>
|
) => Promise<ExecuteResult>
|
||||||
|
updateNftConfig: (
|
||||||
|
{
|
||||||
|
updates,
|
||||||
|
}: {
|
||||||
|
updates: NftConfigUpdates
|
||||||
|
},
|
||||||
|
fee?: number | StdFee | 'auto',
|
||||||
|
memo?: string,
|
||||||
|
funds?: Coin[],
|
||||||
|
) => Promise<ExecuteResult>
|
||||||
callback: (
|
callback: (
|
||||||
fee?: number | StdFee | 'auto',
|
fee?: number | StdFee | 'auto',
|
||||||
memo?: string,
|
memo?: string,
|
||||||
@ -324,6 +388,7 @@ export class MarsCreditManagerClient
|
|||||||
this.updateCreditAccount = this.updateCreditAccount.bind(this)
|
this.updateCreditAccount = this.updateCreditAccount.bind(this)
|
||||||
this.updateConfig = this.updateConfig.bind(this)
|
this.updateConfig = this.updateConfig.bind(this)
|
||||||
this.updateOwner = this.updateOwner.bind(this)
|
this.updateOwner = this.updateOwner.bind(this)
|
||||||
|
this.updateNftConfig = this.updateNftConfig.bind(this)
|
||||||
this.callback = this.callback.bind(this)
|
this.callback = this.callback.bind(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -371,9 +436,9 @@ export class MarsCreditManagerClient
|
|||||||
}
|
}
|
||||||
updateConfig = async (
|
updateConfig = async (
|
||||||
{
|
{
|
||||||
newConfig,
|
updates,
|
||||||
}: {
|
}: {
|
||||||
newConfig: ConfigUpdates
|
updates: ConfigUpdates
|
||||||
},
|
},
|
||||||
fee: number | StdFee | 'auto' = 'auto',
|
fee: number | StdFee | 'auto' = 'auto',
|
||||||
memo?: string,
|
memo?: string,
|
||||||
@ -384,7 +449,7 @@ export class MarsCreditManagerClient
|
|||||||
this.contractAddress,
|
this.contractAddress,
|
||||||
{
|
{
|
||||||
update_config: {
|
update_config: {
|
||||||
new_config: newConfig,
|
updates,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
fee,
|
fee,
|
||||||
@ -408,6 +473,29 @@ export class MarsCreditManagerClient
|
|||||||
funds,
|
funds,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
updateNftConfig = async (
|
||||||
|
{
|
||||||
|
updates,
|
||||||
|
}: {
|
||||||
|
updates: NftConfigUpdates
|
||||||
|
},
|
||||||
|
fee: number | StdFee | 'auto' = 'auto',
|
||||||
|
memo?: string,
|
||||||
|
funds?: Coin[],
|
||||||
|
): Promise<ExecuteResult> => {
|
||||||
|
return await this.client.execute(
|
||||||
|
this.sender,
|
||||||
|
this.contractAddress,
|
||||||
|
{
|
||||||
|
update_nft_config: {
|
||||||
|
updates,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
fee,
|
||||||
|
memo,
|
||||||
|
funds,
|
||||||
|
)
|
||||||
|
}
|
||||||
callback = async (
|
callback = async (
|
||||||
fee: number | StdFee | 'auto' = 'auto',
|
fee: number | StdFee | 'auto' = 'auto',
|
||||||
memo?: string,
|
memo?: string,
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user