diff --git a/components/Borrow/BorrowFunds.tsx b/components/Borrow/BorrowFunds.tsx index 34fc749d..c38d7364 100644 --- a/components/Borrow/BorrowFunds.tsx +++ b/components/Borrow/BorrowFunds.tsx @@ -1,7 +1,6 @@ import React, { useMemo, useState } from 'react' import { XMarkIcon } from '@heroicons/react/24/solid' import { toast } from 'react-toastify' -import * as Slider from '@radix-ui/react-slider' import Button from 'components/Button' import Container from 'components/Container' @@ -17,6 +16,7 @@ import Tooltip from 'components/Tooltip' import ContainerSecondary from 'components/ContainerSecondary' import Spinner from 'components/Spinner' import useCalculateMaxBorrowAmount from 'hooks/useCalculateMaxBorrowAmount' +import Slider from 'components/Slider' const BorrowFunds = ({ tokenDenom, onClose }: any) => { const [amount, setAmount] = useState(0) @@ -113,36 +113,19 @@ const BorrowFunds = ({ tokenDenom, onClose }: any) => { -
- { - const decimal = value[0] / 100 - const tokenDecimals = getTokenDecimals(tokenDenom) - // limit decimal precision based on token contract decimals - const newAmount = Number((decimal * maxValue).toFixed(tokenDecimals)) + { + const decimal = value[0] / 100 + const tokenDecimals = getTokenDecimals(tokenDenom) + // limit decimal precision based on token contract decimals + const newAmount = Number((decimal * maxValue).toFixed(tokenDecimals)) - setAmount(newAmount) - }} - > - - - - -
{percentageValue.toFixed(0)}%
-
-
- -
+ setAmount(newAmount) + }} + onMaxClick={() => setAmount(maxValue)} + />
diff --git a/components/Borrow/RepayFunds.tsx b/components/Borrow/RepayFunds.tsx index 82f2cdb4..0861f6ff 100644 --- a/components/Borrow/RepayFunds.tsx +++ b/components/Borrow/RepayFunds.tsx @@ -1,7 +1,6 @@ import React, { useMemo, useState } from 'react' import { XMarkIcon } from '@heroicons/react/24/solid' import { toast } from 'react-toastify' -import * as Slider from '@radix-ui/react-slider' import Button from 'components/Button' import Container from 'components/Container' @@ -13,6 +12,7 @@ import BigNumber from 'bignumber.js' import useAllBalances from 'hooks/useAllBalances' import ContainerSecondary from 'components/ContainerSecondary' import Spinner from 'components/Spinner' +import Slider from 'components/Slider' const RepayFunds = ({ tokenDenom, amount: repayAmount, onClose }: any) => { const [amount, setAmount] = useState(0) @@ -91,36 +91,19 @@ const RepayFunds = ({ tokenDenom, amount: repayAmount, onClose }: any) => {
-
- { - const decimal = value[0] / 100 - const tokenDecimals = getTokenDecimals(tokenDenom) - // limit decimal precision based on token contract decimals - const newAmount = Number((decimal * maxValue).toFixed(tokenDecimals)) + { + const decimal = value[0] / 100 + const tokenDecimals = getTokenDecimals(tokenDenom) + // limit decimal precision based on token contract decimals + const newAmount = Number((decimal * maxValue).toFixed(tokenDecimals)) - setAmount(newAmount) - }} - > - - - - -
{percentageValue.toFixed(0)}%
-
-
- -
+ setAmount(newAmount) + }} + onMaxClick={() => setAmount(maxValue)} + />
- - - )} - - -
-

Lending Assets

-
Lend assets from account to earn yield.
-
- - - - -
- - - ) -} - -export default FundAccount diff --git a/components/CreditManager/index.tsx b/components/CreditManager/index.tsx index 20121620..30d61685 100644 --- a/components/CreditManager/index.tsx +++ b/components/CreditManager/index.tsx @@ -7,14 +7,14 @@ import useCreditManagerStore from 'stores/useCreditManagerStore' import useWalletStore from 'stores/useWalletStore' import useCreditAccountPositions from 'hooks/useCreditAccountPositions' import { getTokenDecimals, getTokenSymbol } from 'utils/tokens' -import FundAccount from './FundAccount' import useTokenPrices from 'hooks/useTokenPrices' import useAccountStats from 'hooks/useAccountStats' import useMarkets from 'hooks/useMarkets' import ContainerSecondary from 'components/ContainerSecondary' +import FundAccountModal from 'components/FundAccountModal' const CreditManager = () => { - const [isFund, setIsFund] = useState(false) + const [showFundWalletModal, setShowFundWalletModal] = useState(false) const address = useWalletStore((s) => s.address) const selectedAccount = useCreditManagerStore((s) => s.selectedAccount) @@ -48,95 +48,85 @@ const CreditManager = () => { return (
- - {isFund ? ( -
-

Fund Account

- -
+ + + + + +
+
Total Position:
+
{formatCurrency(accountStats?.totalPosition ?? 0)}
+
+
+
Total Liabilities:
+
{formatCurrency(accountStats?.totalDebt ?? 0)}
+
+
+ +

Balances

+ {isLoadingPositions ? ( +
Loading...
) : ( -
- - -
+ <> +
+
Asset
+
Value
+
Size
+
APY
+
+ {positionsData?.coins.map((coin) => ( +
+
{getTokenSymbol(coin.denom)}
+
+ {formatCurrency(getTokenTotalUSDValue(coin.amount, coin.denom))} +
+
+ {BigNumber(coin.amount) + .div(10 ** getTokenDecimals(coin.denom)) + .toNumber() + .toLocaleString(undefined, { + maximumFractionDigits: getTokenDecimals(coin.denom), + })} +
+
-
+
+ ))} + {positionsData?.debts.map((coin) => ( +
+
{getTokenSymbol(coin.denom)}
+
+ -{formatCurrency(getTokenTotalUSDValue(coin.amount, coin.denom))} +
+
+ - + {BigNumber(coin.amount) + .div(10 ** getTokenDecimals(coin.denom)) + .toNumber() + .toLocaleString(undefined, { + maximumFractionDigits: 6, + })} +
+
+ -{(Number(marketsData?.[coin.denom].borrow_rate) * 100).toFixed(1)}% +
+
+ ))} + )}
- {isFund ? ( - - ) : ( - <> - -
-
Total Position:
-
- {formatCurrency(accountStats?.totalPosition ?? 0)} -
-
-
-
Total Liabilities:
-
{formatCurrency(accountStats?.totalDebt ?? 0)}
-
-
- -

Balances

- {isLoadingPositions ? ( -
Loading...
- ) : ( - <> -
-
Asset
-
Value
-
Size
-
APY
-
- {positionsData?.coins.map((coin) => ( -
-
{getTokenSymbol(coin.denom)}
-
- {formatCurrency(getTokenTotalUSDValue(coin.amount, coin.denom))} -
-
- {BigNumber(coin.amount) - .div(10 ** getTokenDecimals(coin.denom)) - .toNumber() - .toLocaleString(undefined, { - maximumFractionDigits: getTokenDecimals(coin.denom), - })} -
-
-
-
- ))} - {positionsData?.debts.map((coin) => ( -
-
{getTokenSymbol(coin.denom)}
-
- -{formatCurrency(getTokenTotalUSDValue(coin.amount, coin.denom))} -
-
- - - {BigNumber(coin.amount) - .div(10 ** getTokenDecimals(coin.denom)) - .toNumber() - .toLocaleString(undefined, { - maximumFractionDigits: 6, - })} -
-
- -{(Number(marketsData?.[coin.denom].borrow_rate) * 100).toFixed(1)}% -
-
- ))} - - )} -
- - )} + setShowFundWalletModal(false)} + />
) } diff --git a/components/FundAccountModal.tsx b/components/FundAccountModal.tsx new file mode 100644 index 00000000..35b82303 --- /dev/null +++ b/components/FundAccountModal.tsx @@ -0,0 +1,220 @@ +import React, { useEffect, useMemo, useState } from 'react' +import Image from 'next/image' +import { Transition, Dialog, Switch } from '@headlessui/react' +import BigNumber from 'bignumber.js' +import { toast } from 'react-toastify' +import useLocalStorageState from 'use-local-storage-state' + +import { getTokenDecimals, getTokenSymbol } from 'utils/tokens' +import ContainerSecondary from './ContainerSecondary' +import useCreditManagerStore from 'stores/useCreditManagerStore' +import Button from './Button' +import Spinner from './Spinner' +import useAllBalances from 'hooks/useAllBalances' +import useAllowedCoins from 'hooks/useAllowedCoins' +import useDepositCreditAccount from 'hooks/useDepositCreditAccount' +import Slider from 'components/Slider' + +const FundAccountModal = ({ show, onClose }: any) => { + const [amount, setAmount] = useState(0) + const [selectedToken, setSelectedToken] = useState('') + + const selectedAccount = useCreditManagerStore((s) => s.selectedAccount) + + const [lendAssets, setLendAssets] = useLocalStorageState(`lendAssets_${selectedAccount}`, { + defaultValue: false, + }) + + const { data: balancesData } = useAllBalances() + const { data: allowedCoinsData, isLoading: isLoadingAllowedCoins } = useAllowedCoins() + const { mutate, isLoading } = useDepositCreditAccount( + selectedAccount || '', + selectedToken, + BigNumber(amount) + .times(10 ** getTokenDecimals(selectedToken)) + .toNumber(), + { + onSuccess: () => { + setAmount(0) + toast.success(`${amount} ${getTokenSymbol(selectedToken)} successfully Deposited`) + onClose() + }, + } + ) + + useEffect(() => { + if (allowedCoinsData && allowedCoinsData.length > 0) { + // initialize selected token when allowedCoins fetch data is available + setSelectedToken(allowedCoinsData[0]) + } + }, [allowedCoinsData]) + + const walletAmount = useMemo(() => { + if (!selectedToken) return 0 + + return BigNumber(balancesData?.find((balance) => balance.denom === selectedToken)?.amount ?? 0) + .div(10 ** getTokenDecimals(selectedToken)) + .toNumber() + }, [balancesData, selectedToken]) + + const handleValueChange = (value: number) => { + if (value > walletAmount) { + setAmount(walletAmount) + return + } + + setAmount(value) + } + + const maxValue = walletAmount + const percentageValue = isNaN(amount) ? 0 : (amount * 100) / maxValue + + return ( + + + +
+ + +
+
+ + + {isLoading && ( +
+ +
+ )} + +
+
+

About

+

+ Bringing the next generation of video creation to the Metaverse. +
+ Powered by deep-learning. +

+
+ mars +
+ +
+ + Fund Account {selectedAccount} + + +

+ Transfer assets from your injective wallet to your Mars credit account. If you + don’t have any assets in your injective wallet use the injective bridge to + transfer funds to your injective wallet. +

+ {isLoadingAllowedCoins ? ( +

Loading...

+ ) : ( + <> +
+
+
Asset:
+ +
+
+
Amount:
+ handleValueChange(e.target.valueAsNumber)} + onBlur={(e) => { + if (e.target.value === '') setAmount(0) + }} + /> +
+
+

In wallet: {walletAmount.toLocaleString()}

+ { + const decimal = value[0] / 100 + const tokenDecimals = getTokenDecimals(selectedToken) + // limit decimal precision based on token contract decimals + const newAmount = Number((decimal * maxValue).toFixed(tokenDecimals)) + + setAmount(newAmount) + }} + onMaxClick={() => setAmount(maxValue)} + /> + + )} +
+ +
+

Lending Assets

+
+ Lend assets from account to earn yield. +
+
+ + + + +
+ +
+
+
+
+
+
+
+ ) +} + +export default FundAccountModal diff --git a/components/Slider.tsx b/components/Slider.tsx new file mode 100644 index 00000000..d49f59ce --- /dev/null +++ b/components/Slider.tsx @@ -0,0 +1,39 @@ +import React from 'react' +import * as RadixSlider from '@radix-ui/react-slider' + +type Props = { + className?: string + value: number + onChange: (value: number[]) => void + onMaxClick: () => void +} + +const Slider = ({ className, value, onChange, onMaxClick }: Props) => { + return ( +
+ onChange(value)} + > + + + + +
{value.toFixed(0)}%
+
+
+ +
+ ) +} + +export default Slider diff --git a/components/Wallet.tsx b/components/Wallet.tsx index 3ac5f574..6d1409f8 100644 --- a/components/Wallet.tsx +++ b/components/Wallet.tsx @@ -18,7 +18,7 @@ const WalletPopover = ({ children }: { children: React.ReactNode }) => { return ( - + {children} @@ -79,7 +79,10 @@ const Wallet = () => { {address ? ( {formatWalletAddress(address)} ) : ( - )} diff --git a/hooks/useDepositCreditAccount.tsx b/hooks/useDepositCreditAccount.tsx index 185232ec..4a7224b5 100644 --- a/hooks/useDepositCreditAccount.tsx +++ b/hooks/useDepositCreditAccount.tsx @@ -1,5 +1,5 @@ import { SigningCosmWasmClient } from '@cosmjs/cosmwasm-stargate' -import { useMutation, useQueryClient } from '@tanstack/react-query' +import { useMutation, UseMutationOptions, useQueryClient } from '@tanstack/react-query' import { useEffect, useState } from 'react' import { toast } from 'react-toastify' @@ -9,7 +9,14 @@ import { contractAddresses } from 'config/contracts' import { hardcodedFee } from 'utils/contants' import { queryKeys } from 'types/query-keys-factory' -const useDepositCreditAccount = (accountId: string, denom: string, amount: number) => { +const useDepositCreditAccount = ( + accountId: string, + denom: string, + amount: number, + options?: { + onSuccess?: () => void + } +) => { const [signingClient, setSigningClient] = useState() const address = useWalletStore((s) => s.address) @@ -62,7 +69,7 @@ const useDepositCreditAccount = (accountId: string, denom: string, amount: numbe queryClient.invalidateQueries(queryKeys.tokenBalance(address, denom)) queryClient.invalidateQueries(queryKeys.creditAccountsPositions(accountId)) - toast.success('Deposited Successfully') + options?.onSuccess && options.onSuccess() }, } ) diff --git a/package.json b/package.json index 8fd60356..dc1dce69 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "@radix-ui/react-slider": "^1.0.0", "@sentry/nextjs": "^7.12.1", "@tanstack/react-query": "^4.3.4", + "@tanstack/react-query-devtools": "^4.12.0", "@tanstack/react-table": "^8.5.15", "@tippyjs/react": "^4.2.6", "bech32": "^2.0.0", diff --git a/pages/_app.tsx b/pages/_app.tsx index 3ca80d70..d1cff269 100644 --- a/pages/_app.tsx +++ b/pages/_app.tsx @@ -5,6 +5,7 @@ import { ToastContainer, Zoom } from 'react-toastify' import 'react-toastify/dist/ReactToastify.min.css' import { QueryClient, QueryClientProvider } from '@tanstack/react-query' import detectEthereumProvider from '@metamask/detect-provider' +import { ReactQueryDevtools } from '@tanstack/react-query-devtools' import '../styles/globals.css' import Layout from 'components/Layout' @@ -41,7 +42,10 @@ function MyApp({ Component, pageProps }: AppProps) { - {address ? :
No wallet connected
}
+ + + +