MP-1566: Deposit funds modal (#33)
* feat: deposit account modal * style: button default colors to match wireframes * react-query-devtools package added * slider moved to separate component
This commit is contained in:
parent
d3a1e9f3f1
commit
55d0910d10
@ -1,7 +1,6 @@
|
|||||||
import React, { useMemo, useState } from 'react'
|
import React, { useMemo, useState } from 'react'
|
||||||
import { XMarkIcon } from '@heroicons/react/24/solid'
|
import { XMarkIcon } from '@heroicons/react/24/solid'
|
||||||
import { toast } from 'react-toastify'
|
import { toast } from 'react-toastify'
|
||||||
import * as Slider from '@radix-ui/react-slider'
|
|
||||||
|
|
||||||
import Button from 'components/Button'
|
import Button from 'components/Button'
|
||||||
import Container from 'components/Container'
|
import Container from 'components/Container'
|
||||||
@ -17,6 +16,7 @@ import Tooltip from 'components/Tooltip'
|
|||||||
import ContainerSecondary from 'components/ContainerSecondary'
|
import ContainerSecondary from 'components/ContainerSecondary'
|
||||||
import Spinner from 'components/Spinner'
|
import Spinner from 'components/Spinner'
|
||||||
import useCalculateMaxBorrowAmount from 'hooks/useCalculateMaxBorrowAmount'
|
import useCalculateMaxBorrowAmount from 'hooks/useCalculateMaxBorrowAmount'
|
||||||
|
import Slider from 'components/Slider'
|
||||||
|
|
||||||
const BorrowFunds = ({ tokenDenom, onClose }: any) => {
|
const BorrowFunds = ({ tokenDenom, onClose }: any) => {
|
||||||
const [amount, setAmount] = useState(0)
|
const [amount, setAmount] = useState(0)
|
||||||
@ -113,14 +113,10 @@ const BorrowFunds = ({ tokenDenom, onClose }: any) => {
|
|||||||
</div>
|
</div>
|
||||||
</ContainerSecondary>
|
</ContainerSecondary>
|
||||||
<ContainerSecondary>
|
<ContainerSecondary>
|
||||||
<div className="relative mb-4 flex flex-1 items-center">
|
<Slider
|
||||||
<Slider.Root
|
className="mb-6"
|
||||||
className="relative flex h-[20px] w-full cursor-pointer touch-none select-none items-center"
|
value={percentageValue}
|
||||||
value={[percentageValue]}
|
onChange={(value) => {
|
||||||
min={0}
|
|
||||||
max={100}
|
|
||||||
step={1}
|
|
||||||
onValueChange={(value) => {
|
|
||||||
const decimal = value[0] / 100
|
const decimal = value[0] / 100
|
||||||
const tokenDecimals = getTokenDecimals(tokenDenom)
|
const tokenDecimals = getTokenDecimals(tokenDenom)
|
||||||
// limit decimal precision based on token contract decimals
|
// limit decimal precision based on token contract decimals
|
||||||
@ -128,21 +124,8 @@ const BorrowFunds = ({ tokenDenom, onClose }: any) => {
|
|||||||
|
|
||||||
setAmount(newAmount)
|
setAmount(newAmount)
|
||||||
}}
|
}}
|
||||||
>
|
onMaxClick={() => setAmount(maxValue)}
|
||||||
<Slider.Track className="relative h-[6px] grow rounded-full bg-gray-400">
|
/>
|
||||||
<Slider.Range className="absolute h-[100%] rounded-full bg-blue-600" />
|
|
||||||
</Slider.Track>
|
|
||||||
<Slider.Thumb className="flex h-[20px] w-[20px] items-center justify-center rounded-full bg-white !outline-none">
|
|
||||||
<div className="relative top-5 text-xs">{percentageValue.toFixed(0)}%</div>
|
|
||||||
</Slider.Thumb>
|
|
||||||
</Slider.Root>
|
|
||||||
<button
|
|
||||||
className="ml-4 rounded-md bg-blue-600 py-1 px-2 text-xs font-semibold text-white"
|
|
||||||
onClick={() => setAmount(maxValue)}
|
|
||||||
>
|
|
||||||
MAX
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</ContainerSecondary>
|
</ContainerSecondary>
|
||||||
<ContainerSecondary className="flex items-center justify-between">
|
<ContainerSecondary className="flex items-center justify-between">
|
||||||
<div className="flex">
|
<div className="flex">
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import React, { useMemo, useState } from 'react'
|
import React, { useMemo, useState } from 'react'
|
||||||
import { XMarkIcon } from '@heroicons/react/24/solid'
|
import { XMarkIcon } from '@heroicons/react/24/solid'
|
||||||
import { toast } from 'react-toastify'
|
import { toast } from 'react-toastify'
|
||||||
import * as Slider from '@radix-ui/react-slider'
|
|
||||||
|
|
||||||
import Button from 'components/Button'
|
import Button from 'components/Button'
|
||||||
import Container from 'components/Container'
|
import Container from 'components/Container'
|
||||||
@ -13,6 +12,7 @@ import BigNumber from 'bignumber.js'
|
|||||||
import useAllBalances from 'hooks/useAllBalances'
|
import useAllBalances from 'hooks/useAllBalances'
|
||||||
import ContainerSecondary from 'components/ContainerSecondary'
|
import ContainerSecondary from 'components/ContainerSecondary'
|
||||||
import Spinner from 'components/Spinner'
|
import Spinner from 'components/Spinner'
|
||||||
|
import Slider from 'components/Slider'
|
||||||
|
|
||||||
const RepayFunds = ({ tokenDenom, amount: repayAmount, onClose }: any) => {
|
const RepayFunds = ({ tokenDenom, amount: repayAmount, onClose }: any) => {
|
||||||
const [amount, setAmount] = useState(0)
|
const [amount, setAmount] = useState(0)
|
||||||
@ -91,14 +91,10 @@ const RepayFunds = ({ tokenDenom, amount: repayAmount, onClose }: any) => {
|
|||||||
</div>
|
</div>
|
||||||
</ContainerSecondary>
|
</ContainerSecondary>
|
||||||
<ContainerSecondary>
|
<ContainerSecondary>
|
||||||
<div className="relative mb-4 flex flex-1 items-center">
|
<Slider
|
||||||
<Slider.Root
|
className="mb-6"
|
||||||
className="relative flex h-[20px] w-full cursor-pointer touch-none select-none items-center"
|
value={percentageValue}
|
||||||
value={[percentageValue]}
|
onChange={(value) => {
|
||||||
min={0}
|
|
||||||
max={100}
|
|
||||||
step={1}
|
|
||||||
onValueChange={(value) => {
|
|
||||||
const decimal = value[0] / 100
|
const decimal = value[0] / 100
|
||||||
const tokenDecimals = getTokenDecimals(tokenDenom)
|
const tokenDecimals = getTokenDecimals(tokenDenom)
|
||||||
// limit decimal precision based on token contract decimals
|
// limit decimal precision based on token contract decimals
|
||||||
@ -106,21 +102,8 @@ const RepayFunds = ({ tokenDenom, amount: repayAmount, onClose }: any) => {
|
|||||||
|
|
||||||
setAmount(newAmount)
|
setAmount(newAmount)
|
||||||
}}
|
}}
|
||||||
>
|
onMaxClick={() => setAmount(maxValue)}
|
||||||
<Slider.Track className="relative h-[6px] grow rounded-full bg-gray-400">
|
/>
|
||||||
<Slider.Range className="absolute h-[100%] rounded-full bg-blue-600" />
|
|
||||||
</Slider.Track>
|
|
||||||
<Slider.Thumb className="flex h-[20px] w-[20px] items-center justify-center rounded-full bg-white !outline-none">
|
|
||||||
<div className="relative top-5 text-xs">{percentageValue.toFixed(0)}%</div>
|
|
||||||
</Slider.Thumb>
|
|
||||||
</Slider.Root>
|
|
||||||
<button
|
|
||||||
className="ml-4 rounded-md bg-blue-600 py-1 px-2 text-xs font-semibold text-white"
|
|
||||||
onClick={() => setAmount(maxValue)}
|
|
||||||
>
|
|
||||||
MAX
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</ContainerSecondary>
|
</ContainerSecondary>
|
||||||
</div>
|
</div>
|
||||||
<Button className="w-full" onClick={handleSubmit} disabled={isSubmitDisabled}>
|
<Button className="w-full" onClick={handleSubmit} disabled={isSubmitDisabled}>
|
||||||
|
@ -12,7 +12,7 @@ const Button = React.forwardRef<any, Props>(
|
|||||||
<button
|
<button
|
||||||
ref={ref}
|
ref={ref}
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
className={`overflow-hidden text-ellipsis rounded-3xl bg-green-500 py-2 px-5 text-sm font-semibold text-white ${className} ${
|
className={`overflow-hidden text-ellipsis rounded-md bg-blue-500 py-2 px-5 text-sm font-semibold text-white ${className} ${
|
||||||
disabled ? 'opacity-40' : ''
|
disabled ? 'opacity-40' : ''
|
||||||
}`}
|
}`}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
|
@ -1,169 +0,0 @@
|
|||||||
import React, { useEffect, useMemo, useState } from 'react'
|
|
||||||
import * as Slider from '@radix-ui/react-slider'
|
|
||||||
import BigNumber from 'bignumber.js'
|
|
||||||
import { Switch } from '@headlessui/react'
|
|
||||||
import useLocalStorageState from 'use-local-storage-state'
|
|
||||||
|
|
||||||
import Button from '../Button'
|
|
||||||
import useAllowedCoins from 'hooks/useAllowedCoins'
|
|
||||||
import useDepositCreditAccount from 'hooks/useDepositCreditAccount'
|
|
||||||
import useCreditManagerStore from 'stores/useCreditManagerStore'
|
|
||||||
import useAllBalances from 'hooks/useAllBalances'
|
|
||||||
import { getTokenDecimals, getTokenSymbol } from 'utils/tokens'
|
|
||||||
import ContainerSecondary from 'components/ContainerSecondary'
|
|
||||||
|
|
||||||
const FundAccount = () => {
|
|
||||||
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 } = useDepositCreditAccount(
|
|
||||||
selectedAccount || '',
|
|
||||||
selectedToken,
|
|
||||||
BigNumber(amount)
|
|
||||||
.times(10 ** getTokenDecimals(selectedToken))
|
|
||||||
.toNumber()
|
|
||||||
)
|
|
||||||
|
|
||||||
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 (
|
|
||||||
<>
|
|
||||||
<ContainerSecondary className="mb-2 p-3">
|
|
||||||
<p className="mb-6 text-sm">
|
|
||||||
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.
|
|
||||||
</p>
|
|
||||||
{isLoadingAllowedCoins ? (
|
|
||||||
<p>Loading...</p>
|
|
||||||
) : (
|
|
||||||
<>
|
|
||||||
<div className="mb-4 text-sm">
|
|
||||||
<div className="mb-1 flex justify-between">
|
|
||||||
<div>Asset:</div>
|
|
||||||
<select
|
|
||||||
className="bg-transparent"
|
|
||||||
onChange={(e) => {
|
|
||||||
setSelectedToken(e.target.value)
|
|
||||||
|
|
||||||
if (e.target.value !== selectedToken) setAmount(0)
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{allowedCoinsData?.map((entry) => (
|
|
||||||
<option key={entry} value={entry}>
|
|
||||||
{getTokenSymbol(entry)}
|
|
||||||
</option>
|
|
||||||
))}
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<div className="flex justify-between">
|
|
||||||
<div>Amount:</div>
|
|
||||||
<input
|
|
||||||
type="number"
|
|
||||||
className="border border-black/50 bg-transparent px-2"
|
|
||||||
value={amount}
|
|
||||||
onChange={(e) => handleValueChange(e.target.valueAsNumber)}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<p className="text-sm">In wallet: {walletAmount.toLocaleString()}</p>
|
|
||||||
{/* SLIDER - initial implementation to test functionality */}
|
|
||||||
{/* TODO: will need to be revamped later on */}
|
|
||||||
<div className="relative mb-6 flex flex-1 items-center">
|
|
||||||
<Slider.Root
|
|
||||||
className="relative flex h-[20px] w-full cursor-pointer touch-none select-none items-center"
|
|
||||||
value={[percentageValue]}
|
|
||||||
min={0}
|
|
||||||
max={100}
|
|
||||||
step={1}
|
|
||||||
onValueChange={(value) => {
|
|
||||||
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)
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Slider.Track className="relative h-[6px] grow rounded-full bg-gray-400">
|
|
||||||
<Slider.Range className="absolute h-[100%] rounded-full bg-blue-600" />
|
|
||||||
</Slider.Track>
|
|
||||||
<Slider.Thumb className="flex h-[20px] w-[20px] items-center justify-center rounded-full bg-white !outline-none">
|
|
||||||
<div className="relative top-5 text-xs">{percentageValue.toFixed(0)}%</div>
|
|
||||||
</Slider.Thumb>
|
|
||||||
</Slider.Root>
|
|
||||||
<button
|
|
||||||
className="ml-4 rounded-md bg-blue-600 py-1 px-2 text-xs font-semibold text-white"
|
|
||||||
onClick={() => setAmount(maxValue)}
|
|
||||||
>
|
|
||||||
MAX
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</ContainerSecondary>
|
|
||||||
<ContainerSecondary className="mb-2 flex items-center justify-between">
|
|
||||||
<div>
|
|
||||||
<h3 className="font-bold">Lending Assets</h3>
|
|
||||||
<div className="text-sm text-[#585A74]/50">Lend assets from account to earn yield.</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<Switch
|
|
||||||
checked={lendAssets}
|
|
||||||
onChange={setLendAssets}
|
|
||||||
className={`${
|
|
||||||
lendAssets ? 'bg-blue-600' : 'bg-gray-400'
|
|
||||||
} relative inline-flex h-6 w-11 items-center rounded-full`}
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
className={`${
|
|
||||||
lendAssets ? 'translate-x-6' : 'translate-x-1'
|
|
||||||
} inline-block h-4 w-4 transform rounded-full bg-white transition`}
|
|
||||||
/>
|
|
||||||
</Switch>
|
|
||||||
</ContainerSecondary>
|
|
||||||
<Button
|
|
||||||
className="w-full !rounded-lg"
|
|
||||||
onClick={() => mutate()}
|
|
||||||
disabled={amount === 0 || !amount}
|
|
||||||
>
|
|
||||||
Fund
|
|
||||||
</Button>
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default FundAccount
|
|
@ -7,14 +7,14 @@ import useCreditManagerStore from 'stores/useCreditManagerStore'
|
|||||||
import useWalletStore from 'stores/useWalletStore'
|
import useWalletStore from 'stores/useWalletStore'
|
||||||
import useCreditAccountPositions from 'hooks/useCreditAccountPositions'
|
import useCreditAccountPositions from 'hooks/useCreditAccountPositions'
|
||||||
import { getTokenDecimals, getTokenSymbol } from 'utils/tokens'
|
import { getTokenDecimals, getTokenSymbol } from 'utils/tokens'
|
||||||
import FundAccount from './FundAccount'
|
|
||||||
import useTokenPrices from 'hooks/useTokenPrices'
|
import useTokenPrices from 'hooks/useTokenPrices'
|
||||||
import useAccountStats from 'hooks/useAccountStats'
|
import useAccountStats from 'hooks/useAccountStats'
|
||||||
import useMarkets from 'hooks/useMarkets'
|
import useMarkets from 'hooks/useMarkets'
|
||||||
import ContainerSecondary from 'components/ContainerSecondary'
|
import ContainerSecondary from 'components/ContainerSecondary'
|
||||||
|
import FundAccountModal from 'components/FundAccountModal'
|
||||||
|
|
||||||
const CreditManager = () => {
|
const CreditManager = () => {
|
||||||
const [isFund, setIsFund] = useState(false)
|
const [showFundWalletModal, setShowFundWalletModal] = useState(false)
|
||||||
|
|
||||||
const address = useWalletStore((s) => s.address)
|
const address = useWalletStore((s) => s.address)
|
||||||
const selectedAccount = useCreditManagerStore((s) => s.selectedAccount)
|
const selectedAccount = useCreditManagerStore((s) => s.selectedAccount)
|
||||||
@ -48,35 +48,22 @@ const CreditManager = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="absolute inset-0 left-auto w-[400px] border-l border-white/20 bg-background-2 p-2">
|
<div className="absolute inset-0 left-auto w-[400px] border-l border-white/20 bg-background-2 p-2">
|
||||||
<ContainerSecondary className="mb-2">
|
<ContainerSecondary className="mb-2 flex gap-3">
|
||||||
{isFund ? (
|
<Button className="flex-1 rounded-md" onClick={() => setShowFundWalletModal(true)}>
|
||||||
<div className="flex items-center justify-between">
|
|
||||||
<h3 className="font-bold">Fund Account</h3>
|
|
||||||
<Button className="rounded-md" onClick={() => setIsFund(false)}>
|
|
||||||
Cancel
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
) : (
|
|
||||||
<div className="flex gap-3">
|
|
||||||
<Button className="flex-1 rounded-md" onClick={() => setIsFund(true)}>
|
|
||||||
Fund
|
Fund
|
||||||
</Button>
|
</Button>
|
||||||
<Button className="flex-1 rounded-md" onClick={() => alert('TODO')}>
|
<Button
|
||||||
|
className="flex-1 rounded-md"
|
||||||
|
onClick={() => alert('TODO')}
|
||||||
|
disabled={!positionsData || positionsData.coins.length === 0}
|
||||||
|
>
|
||||||
Withdraw
|
Withdraw
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</ContainerSecondary>
|
</ContainerSecondary>
|
||||||
{isFund ? (
|
|
||||||
<FundAccount />
|
|
||||||
) : (
|
|
||||||
<>
|
|
||||||
<ContainerSecondary className="mb-2 text-sm">
|
<ContainerSecondary className="mb-2 text-sm">
|
||||||
<div className="mb-1 flex justify-between">
|
<div className="mb-1 flex justify-between">
|
||||||
<div>Total Position:</div>
|
<div>Total Position:</div>
|
||||||
<div className="font-semibold">
|
<div className="font-semibold">{formatCurrency(accountStats?.totalPosition ?? 0)}</div>
|
||||||
{formatCurrency(accountStats?.totalPosition ?? 0)}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="flex justify-between">
|
<div className="flex justify-between">
|
||||||
<div>Total Liabilities:</div>
|
<div>Total Liabilities:</div>
|
||||||
@ -135,8 +122,11 @@ const CreditManager = () => {
|
|||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</ContainerSecondary>
|
</ContainerSecondary>
|
||||||
</>
|
<FundAccountModal
|
||||||
)}
|
key={`fundModal_${selectedAccount}`}
|
||||||
|
show={showFundWalletModal}
|
||||||
|
onClose={() => setShowFundWalletModal(false)}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
220
components/FundAccountModal.tsx
Normal file
220
components/FundAccountModal.tsx
Normal file
@ -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 (
|
||||||
|
<Transition appear show={show} as={React.Fragment}>
|
||||||
|
<Dialog as="div" className="relative z-10" onClose={onClose}>
|
||||||
|
<Transition.Child
|
||||||
|
as={React.Fragment}
|
||||||
|
enter="ease-out duration-300"
|
||||||
|
enterFrom="opacity-0"
|
||||||
|
enterTo="opacity-100"
|
||||||
|
leave="ease-in duration-200"
|
||||||
|
leaveFrom="opacity-100"
|
||||||
|
leaveTo="opacity-0"
|
||||||
|
>
|
||||||
|
<div className="fixed inset-0 bg-black bg-opacity-80" />
|
||||||
|
</Transition.Child>
|
||||||
|
|
||||||
|
<div className="fixed inset-0 overflow-y-auto">
|
||||||
|
<div className="flex min-h-full items-center justify-center p-4">
|
||||||
|
<Transition.Child
|
||||||
|
as={React.Fragment}
|
||||||
|
enter="ease-out duration-300"
|
||||||
|
enterFrom="opacity-0 scale-95"
|
||||||
|
enterTo="opacity-100 scale-100"
|
||||||
|
leave="ease-in duration-200"
|
||||||
|
leaveFrom="opacity-100 scale-100"
|
||||||
|
leaveTo="opacity-0 scale-95"
|
||||||
|
>
|
||||||
|
<Dialog.Panel className="flex min-h-[520px] w-full max-w-3xl transform overflow-hidden rounded-2xl bg-[#585A74] align-middle shadow-xl transition-all">
|
||||||
|
{isLoading && (
|
||||||
|
<div className="absolute inset-0 z-40 grid place-items-center bg-black/50">
|
||||||
|
<Spinner />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<div className="flex flex-1 flex-col items-start justify-between bg-[#4A4C60] p-6">
|
||||||
|
<div>
|
||||||
|
<p className="text-bold mb-3 text-xs uppercase text-white/50">About</p>
|
||||||
|
<h4 className="mb-4 text-xl leading-8">
|
||||||
|
Bringing the next generation of video creation to the Metaverse.
|
||||||
|
<br />
|
||||||
|
Powered by deep-learning.
|
||||||
|
</h4>
|
||||||
|
</div>
|
||||||
|
<Image src="/logo.svg" alt="mars" width={150} height={50} />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex flex-1 flex-col p-4">
|
||||||
|
<Dialog.Title as="h3" className="mb-4 text-center font-medium">
|
||||||
|
Fund Account {selectedAccount}
|
||||||
|
</Dialog.Title>
|
||||||
|
<ContainerSecondary className="mb-2 p-3">
|
||||||
|
<p className="mb-6 text-sm text-[#585A74]/50">
|
||||||
|
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.
|
||||||
|
</p>
|
||||||
|
{isLoadingAllowedCoins ? (
|
||||||
|
<p>Loading...</p>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<div className="mb-2 rounded-md border border-[#585A74] text-sm">
|
||||||
|
<div className="mb-1 flex justify-between border-b border-[#585A74] p-2">
|
||||||
|
<div className="font-bold">Asset:</div>
|
||||||
|
<select
|
||||||
|
className="bg-transparent outline-0"
|
||||||
|
onChange={(e) => {
|
||||||
|
setSelectedToken(e.target.value)
|
||||||
|
|
||||||
|
if (e.target.value !== selectedToken) setAmount(0)
|
||||||
|
}}
|
||||||
|
value={selectedToken}
|
||||||
|
>
|
||||||
|
{allowedCoinsData?.map((entry) => (
|
||||||
|
<option key={entry} value={entry}>
|
||||||
|
{getTokenSymbol(entry)}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div className="flex justify-between p-2">
|
||||||
|
<div className="font-bold">Amount:</div>
|
||||||
|
<input
|
||||||
|
type="number"
|
||||||
|
className="bg-transparent text-right outline-0"
|
||||||
|
value={amount}
|
||||||
|
min="0"
|
||||||
|
onChange={(e) => handleValueChange(e.target.valueAsNumber)}
|
||||||
|
onBlur={(e) => {
|
||||||
|
if (e.target.value === '') setAmount(0)
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p className="mb-2 text-sm">In wallet: {walletAmount.toLocaleString()}</p>
|
||||||
|
<Slider
|
||||||
|
className="mb-6"
|
||||||
|
value={percentageValue}
|
||||||
|
onChange={(value) => {
|
||||||
|
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)}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</ContainerSecondary>
|
||||||
|
<ContainerSecondary className="mb-2 flex items-center justify-between">
|
||||||
|
<div>
|
||||||
|
<h3 className="font-bold">Lending Assets</h3>
|
||||||
|
<div className="text-sm text-[#585A74]/50">
|
||||||
|
Lend assets from account to earn yield.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Switch
|
||||||
|
checked={lendAssets}
|
||||||
|
onChange={setLendAssets}
|
||||||
|
className={`${
|
||||||
|
lendAssets ? 'bg-blue-600' : 'bg-gray-400'
|
||||||
|
} relative inline-flex h-6 w-11 items-center rounded-full`}
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
className={`${
|
||||||
|
lendAssets ? 'translate-x-6' : 'translate-x-1'
|
||||||
|
} inline-block h-4 w-4 transform rounded-full bg-white transition`}
|
||||||
|
/>
|
||||||
|
</Switch>
|
||||||
|
</ContainerSecondary>
|
||||||
|
<Button
|
||||||
|
className="mt-auto w-full"
|
||||||
|
onClick={() => mutate()}
|
||||||
|
disabled={amount === 0 || !amount}
|
||||||
|
>
|
||||||
|
Fund Account
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</Dialog.Panel>
|
||||||
|
</Transition.Child>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Dialog>
|
||||||
|
</Transition>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default FundAccountModal
|
39
components/Slider.tsx
Normal file
39
components/Slider.tsx
Normal file
@ -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 (
|
||||||
|
<div className={`relative flex flex-1 items-center ${className || ''}`}>
|
||||||
|
<RadixSlider.Root
|
||||||
|
className="relative flex h-[20px] w-full cursor-pointer touch-none select-none items-center"
|
||||||
|
value={[value]}
|
||||||
|
min={0}
|
||||||
|
max={100}
|
||||||
|
step={1}
|
||||||
|
onValueChange={(value) => onChange(value)}
|
||||||
|
>
|
||||||
|
<RadixSlider.Track className="relative h-[6px] grow rounded-full bg-gray-400">
|
||||||
|
<RadixSlider.Range className="absolute h-[100%] rounded-full bg-blue-600" />
|
||||||
|
</RadixSlider.Track>
|
||||||
|
<RadixSlider.Thumb className="flex h-[20px] w-[20px] items-center justify-center rounded-full bg-white !outline-none">
|
||||||
|
<div className="relative top-5 text-xs">{value.toFixed(0)}%</div>
|
||||||
|
</RadixSlider.Thumb>
|
||||||
|
</RadixSlider.Root>
|
||||||
|
<button
|
||||||
|
className="ml-4 rounded-md bg-blue-600 py-1 px-2 text-xs font-semibold text-white"
|
||||||
|
onClick={onMaxClick}
|
||||||
|
>
|
||||||
|
MAX
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Slider
|
@ -18,7 +18,7 @@ const WalletPopover = ({ children }: { children: React.ReactNode }) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Popover className="relative">
|
<Popover className="relative">
|
||||||
<Popover.Button as={Button} className="w-[200px]">
|
<Popover.Button as={Button} className="w-[200px] !rounded-3xl !bg-green-500">
|
||||||
{children}
|
{children}
|
||||||
</Popover.Button>
|
</Popover.Button>
|
||||||
|
|
||||||
@ -79,7 +79,10 @@ const Wallet = () => {
|
|||||||
{address ? (
|
{address ? (
|
||||||
<WalletPopover>{formatWalletAddress(address)}</WalletPopover>
|
<WalletPopover>{formatWalletAddress(address)}</WalletPopover>
|
||||||
) : (
|
) : (
|
||||||
<Button className="w-[200px]" onClick={() => setShowConnectModal(true)}>
|
<Button
|
||||||
|
className="w-[200px] !rounded-3xl !bg-green-500"
|
||||||
|
onClick={() => setShowConnectModal(true)}
|
||||||
|
>
|
||||||
Connect Wallet
|
Connect Wallet
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { SigningCosmWasmClient } from '@cosmjs/cosmwasm-stargate'
|
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 { useEffect, useState } from 'react'
|
||||||
import { toast } from 'react-toastify'
|
import { toast } from 'react-toastify'
|
||||||
|
|
||||||
@ -9,7 +9,14 @@ import { contractAddresses } from 'config/contracts'
|
|||||||
import { hardcodedFee } from 'utils/contants'
|
import { hardcodedFee } from 'utils/contants'
|
||||||
import { queryKeys } from 'types/query-keys-factory'
|
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<SigningCosmWasmClient>()
|
const [signingClient, setSigningClient] = useState<SigningCosmWasmClient>()
|
||||||
const address = useWalletStore((s) => s.address)
|
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.tokenBalance(address, denom))
|
||||||
queryClient.invalidateQueries(queryKeys.creditAccountsPositions(accountId))
|
queryClient.invalidateQueries(queryKeys.creditAccountsPositions(accountId))
|
||||||
|
|
||||||
toast.success('Deposited Successfully')
|
options?.onSuccess && options.onSuccess()
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
"@radix-ui/react-slider": "^1.0.0",
|
"@radix-ui/react-slider": "^1.0.0",
|
||||||
"@sentry/nextjs": "^7.12.1",
|
"@sentry/nextjs": "^7.12.1",
|
||||||
"@tanstack/react-query": "^4.3.4",
|
"@tanstack/react-query": "^4.3.4",
|
||||||
|
"@tanstack/react-query-devtools": "^4.12.0",
|
||||||
"@tanstack/react-table": "^8.5.15",
|
"@tanstack/react-table": "^8.5.15",
|
||||||
"@tippyjs/react": "^4.2.6",
|
"@tippyjs/react": "^4.2.6",
|
||||||
"bech32": "^2.0.0",
|
"bech32": "^2.0.0",
|
||||||
|
@ -5,6 +5,7 @@ import { ToastContainer, Zoom } from 'react-toastify'
|
|||||||
import 'react-toastify/dist/ReactToastify.min.css'
|
import 'react-toastify/dist/ReactToastify.min.css'
|
||||||
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
|
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
|
||||||
import detectEthereumProvider from '@metamask/detect-provider'
|
import detectEthereumProvider from '@metamask/detect-provider'
|
||||||
|
import { ReactQueryDevtools } from '@tanstack/react-query-devtools'
|
||||||
|
|
||||||
import '../styles/globals.css'
|
import '../styles/globals.css'
|
||||||
import Layout from 'components/Layout'
|
import Layout from 'components/Layout'
|
||||||
@ -41,7 +42,10 @@ function MyApp({ Component, pageProps }: AppProps) {
|
|||||||
<link rel="icon" href="/favicon.svg" />
|
<link rel="icon" href="/favicon.svg" />
|
||||||
</Head>
|
</Head>
|
||||||
<QueryClientProvider client={queryClient}>
|
<QueryClientProvider client={queryClient}>
|
||||||
<Layout>{address ? <Component {...pageProps} /> : <div>No wallet connected</div>}</Layout>
|
<ReactQueryDevtools initialIsOpen={false} />
|
||||||
|
<Layout>
|
||||||
|
<Component {...pageProps} />
|
||||||
|
</Layout>
|
||||||
<ToastContainer
|
<ToastContainer
|
||||||
autoClose={1500}
|
autoClose={1500}
|
||||||
closeButton={false}
|
closeButton={false}
|
||||||
|
40
yarn.lock
40
yarn.lock
@ -2140,11 +2140,27 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
tslib "^2.4.0"
|
tslib "^2.4.0"
|
||||||
|
|
||||||
|
"@tanstack/match-sorter-utils@^8.1.1":
|
||||||
|
version "8.5.14"
|
||||||
|
resolved "https://registry.yarnpkg.com/@tanstack/match-sorter-utils/-/match-sorter-utils-8.5.14.tgz#12efcd536abe491d09521e0242bc4d51442f8a8a"
|
||||||
|
integrity sha512-lVNhzTcOJ2bZ4IU+PeCPQ36vowBHvviJb2ZfdRFX5uhy7G0jM8N34zAMbmS5ZmVH8D2B7oU82OWo0e/5ZFzQrw==
|
||||||
|
dependencies:
|
||||||
|
remove-accents "0.4.2"
|
||||||
|
|
||||||
"@tanstack/query-core@4.3.4":
|
"@tanstack/query-core@4.3.4":
|
||||||
version "4.3.4"
|
version "4.3.4"
|
||||||
resolved "https://registry.yarnpkg.com/@tanstack/query-core/-/query-core-4.3.4.tgz#b93da17232fda91ec08ef14d2ca1d8326fc599f2"
|
resolved "https://registry.yarnpkg.com/@tanstack/query-core/-/query-core-4.3.4.tgz#b93da17232fda91ec08ef14d2ca1d8326fc599f2"
|
||||||
integrity sha512-NLAe3j5Vk1yYEtoPP5fPGPjRzkZPx67KUM3f14L3InziJZJ0wVecCh7uKfgYkbRKJSeq6PlbND7iuCGdTplN6Q==
|
integrity sha512-NLAe3j5Vk1yYEtoPP5fPGPjRzkZPx67KUM3f14L3InziJZJ0wVecCh7uKfgYkbRKJSeq6PlbND7iuCGdTplN6Q==
|
||||||
|
|
||||||
|
"@tanstack/react-query-devtools@^4.12.0":
|
||||||
|
version "4.12.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@tanstack/react-query-devtools/-/react-query-devtools-4.12.0.tgz#18f341185f0a5580fc8b2daf8197389108be7131"
|
||||||
|
integrity sha512-gUV+aKpwgP7Cfp2+vwgu6krXCytncGWjTqFcnzC1l2INOf8dRi8/GEupYF7npxD9ky72FTuxc5+TI/lC8eB0Eg==
|
||||||
|
dependencies:
|
||||||
|
"@tanstack/match-sorter-utils" "^8.1.1"
|
||||||
|
superjson "^1.10.0"
|
||||||
|
use-sync-external-store "^1.2.0"
|
||||||
|
|
||||||
"@tanstack/react-query@^4.3.4":
|
"@tanstack/react-query@^4.3.4":
|
||||||
version "4.3.4"
|
version "4.3.4"
|
||||||
resolved "https://registry.yarnpkg.com/@tanstack/react-query/-/react-query-4.3.4.tgz#91a4232a967de04a0662d63d53b18ecc3e11c7e2"
|
resolved "https://registry.yarnpkg.com/@tanstack/react-query/-/react-query-4.3.4.tgz#91a4232a967de04a0662d63d53b18ecc3e11c7e2"
|
||||||
@ -3006,6 +3022,13 @@ cookie@^0.4.1:
|
|||||||
resolved "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz"
|
resolved "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz"
|
||||||
integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==
|
integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==
|
||||||
|
|
||||||
|
copy-anything@^3.0.2:
|
||||||
|
version "3.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/copy-anything/-/copy-anything-3.0.2.tgz#7189171ff5e1893b2287e8bf574b8cd448ed50b1"
|
||||||
|
integrity sha512-CzATjGXzUQ0EvuvgOCI6A4BGOo2bcVx8B+eC2nF862iv9fopnPQwlrbACakNCHRIJbCSBj+J/9JeDf60k64MkA==
|
||||||
|
dependencies:
|
||||||
|
is-what "^4.1.6"
|
||||||
|
|
||||||
copy-descriptor@^0.1.0:
|
copy-descriptor@^0.1.0:
|
||||||
version "0.1.1"
|
version "0.1.1"
|
||||||
resolved "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz"
|
resolved "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz"
|
||||||
@ -4375,6 +4398,11 @@ is-weakref@^1.0.2:
|
|||||||
dependencies:
|
dependencies:
|
||||||
call-bind "^1.0.2"
|
call-bind "^1.0.2"
|
||||||
|
|
||||||
|
is-what@^4.1.6:
|
||||||
|
version "4.1.7"
|
||||||
|
resolved "https://registry.yarnpkg.com/is-what/-/is-what-4.1.7.tgz#c41dc1d2d2d6a9285c624c2505f61849c8b1f9cc"
|
||||||
|
integrity sha512-DBVOQNiPKnGMxRMLIYSwERAS5MVY1B7xYiGnpgctsOFvVDz9f9PFXXxMcTOHuoqYp4NK9qFYQaIC1NRRxLMpBQ==
|
||||||
|
|
||||||
is-windows@^1.0.2:
|
is-windows@^1.0.2:
|
||||||
version "1.0.2"
|
version "1.0.2"
|
||||||
resolved "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz"
|
resolved "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz"
|
||||||
@ -5514,6 +5542,11 @@ regjsparser@^0.9.1:
|
|||||||
dependencies:
|
dependencies:
|
||||||
jsesc "~0.5.0"
|
jsesc "~0.5.0"
|
||||||
|
|
||||||
|
remove-accents@0.4.2:
|
||||||
|
version "0.4.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/remove-accents/-/remove-accents-0.4.2.tgz#0a43d3aaae1e80db919e07ae254b285d9e1c7bb5"
|
||||||
|
integrity sha512-7pXIJqJOq5tFgG1A2Zxti3Ht8jJF337m4sowbuHsW30ZnkQFnDzy9qBNhgzX8ZLW4+UBcXiiR7SwR6pokHsxiA==
|
||||||
|
|
||||||
repeat-element@^1.1.2:
|
repeat-element@^1.1.2:
|
||||||
version "1.1.4"
|
version "1.1.4"
|
||||||
resolved "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz"
|
resolved "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz"
|
||||||
@ -5949,6 +5982,13 @@ sucrase@^3.20.0:
|
|||||||
pirates "^4.0.1"
|
pirates "^4.0.1"
|
||||||
ts-interface-checker "^0.1.9"
|
ts-interface-checker "^0.1.9"
|
||||||
|
|
||||||
|
superjson@^1.10.0:
|
||||||
|
version "1.11.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/superjson/-/superjson-1.11.0.tgz#f6e2ae0d8fbac61c3fca09ab6739ac9678414d1b"
|
||||||
|
integrity sha512-6PfAg1FKhqkwWvPb2uXhH4MkMttdc17eJ91+Aoz4s1XUEDZFmLfFx/xVA3wgkPxAGy5dpozgGdK6V/n20Wj9yg==
|
||||||
|
dependencies:
|
||||||
|
copy-anything "^3.0.2"
|
||||||
|
|
||||||
supports-color@^5.3.0:
|
supports-color@^5.3.0:
|
||||||
version "5.5.0"
|
version "5.5.0"
|
||||||
resolved "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz"
|
resolved "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz"
|
||||||
|
Loading…
Reference in New Issue
Block a user