179 lines
6.1 KiB
TypeScript
179 lines
6.1 KiB
TypeScript
import { useCallback, useMemo, useState } from 'react'
|
|
import StakeForm from '@components/StakeForm'
|
|
import mangoStore from '@store/mangoStore'
|
|
import { getStakableTokensDataForTokenName } from 'utils/tokens'
|
|
import { ArrowLeftIcon, XMarkIcon } from '@heroicons/react/20/solid'
|
|
import DespositForm from './DepositForm'
|
|
import { EnterBottomExitBottom } from './shared/Transitions'
|
|
import TokenSelect from './TokenSelect'
|
|
import { IconButton } from './shared/Button'
|
|
import HeroTokenButton from './HeroTokenButton'
|
|
import useStakeableTokens, { StakeableToken } from 'hooks/useStakeableTokens'
|
|
import { useTheme } from 'next-themes'
|
|
|
|
const set = mangoStore.getState().set
|
|
|
|
export const YIELD_BUTTON_CLASSES = `flex items-center justify-center rounded-xl raised-button-neutral group after:rounded-xl h-32 px-6 md:px-6 w-full after:border after:border-th-bkg-3 focus:outline-none disabled:cursor-not-allowed disabled:opacity-50`
|
|
|
|
export const SOL_YIELD = [
|
|
'bSOL',
|
|
'MSOL',
|
|
'JitoSOL',
|
|
'JSOL',
|
|
'INF',
|
|
'hubSOL',
|
|
'digitSOL',
|
|
'dualSOL',
|
|
'mangoSOL',
|
|
'compassSOL',
|
|
]
|
|
|
|
const Stake = () => {
|
|
const { theme } = useTheme()
|
|
const [showTokenSelect, setShowTokenSelect] = useState(false)
|
|
const selectedToken = mangoStore((s) => s.selectedToken)
|
|
const { stakeableTokens } = useStakeableTokens()
|
|
|
|
const handleTokenSelect = useCallback((token: string) => {
|
|
set((state) => {
|
|
state.selectedToken = token
|
|
})
|
|
setShowTokenSelect(false)
|
|
}, [])
|
|
|
|
const selectableTokens = useMemo(() => {
|
|
return stakeableTokens.sort((a: StakeableToken, b: StakeableToken) => {
|
|
const aApy = a.estNetApy
|
|
const bApy = b.estNetApy
|
|
return bApy - aApy
|
|
})
|
|
}, [stakeableTokens])
|
|
|
|
// const swapUrl = `https://app.mango.markets/swap?in=USDC&out=${selectedToken}&walletSwap=true`
|
|
|
|
return (
|
|
<>
|
|
<div className="relative overflow-hidden">
|
|
<EnterBottomExitBottom
|
|
className="absolute bottom-0 left-0 z-20 h-full w-full overflow-hidden rounded-2xl border-2 border-th-fgd-1 bg-th-bkg-1 px-3 py-6 pb-0"
|
|
show={showTokenSelect}
|
|
>
|
|
<div className="mb-4 flex items-center justify-between">
|
|
<div className="h-10 w-10" />
|
|
<h2>Select token to Boost!</h2>
|
|
<IconButton
|
|
onClick={() => setShowTokenSelect(false)}
|
|
hideBg
|
|
size="medium"
|
|
>
|
|
<XMarkIcon className="h-6 w-6" />
|
|
</IconButton>
|
|
</div>
|
|
<div className="mb-2 flex justify-between px-3">
|
|
<p className="text-sm text-th-fgd-4">Token</p>
|
|
<p className="text-sm text-th-fgd-4">Wallet Balance</p>
|
|
</div>
|
|
<div className="h-full max-h-[500px] overflow-auto pb-10">
|
|
{selectableTokens.map((token) => (
|
|
<TokenSelect
|
|
key={token.token.symbol}
|
|
onClick={() => handleTokenSelect(token.token.symbol)}
|
|
tokenInfo={token}
|
|
clientContext={
|
|
getStakableTokensDataForTokenName(token.token.symbol)
|
|
.clientContext
|
|
}
|
|
/>
|
|
))}
|
|
</div>
|
|
</EnterBottomExitBottom>
|
|
<div
|
|
className={`rounded-2xl border-2 border-th-fgd-1 bg-th-bkg-1 p-6 text-th-fgd-1 md:p-8`}
|
|
>
|
|
{selectableTokens.length ? (
|
|
!selectedToken ? (
|
|
<>
|
|
<div className="flex flex-col items-center">
|
|
<div className="w-full pb-6 text-center md:pb-8">
|
|
<h1 className="mb-1">Welcome yield fan 👋</h1>
|
|
<p>
|
|
It's time to leverage up your liquid staking yield.
|
|
</p>
|
|
</div>
|
|
<div
|
|
className={`bg-x-repeat h-2 w-full ${
|
|
theme === 'Light'
|
|
? `bg-[url('/images/zigzag-repeat.svg')]`
|
|
: `bg-[url('/images/zigzag-repeat-dark.svg')]`
|
|
} bg-contain opacity-20`}
|
|
/>
|
|
</div>
|
|
<div className="space-y-3 pt-6 md:pt-8">
|
|
<h2 className="text-center text-lg font-normal">
|
|
Select to earn leveraged yield
|
|
</h2>
|
|
{selectableTokens.map((token) => {
|
|
const { symbol } = token.token
|
|
return (
|
|
<HeroTokenButton
|
|
key={symbol}
|
|
onClick={() =>
|
|
set((state) => {
|
|
state.selectedToken = symbol
|
|
})
|
|
}
|
|
tokenInfo={token}
|
|
/>
|
|
)
|
|
})}
|
|
</div>
|
|
</>
|
|
) : (
|
|
<>
|
|
<div className="mb-6 flex items-center space-x-3">
|
|
<IconButton
|
|
onClick={() =>
|
|
set((state) => {
|
|
state.selectedToken = ''
|
|
})
|
|
}
|
|
size="small"
|
|
isPrimary
|
|
>
|
|
<ArrowLeftIcon className="h-5 w-5" />
|
|
</IconButton>
|
|
<h2>Add {selectedToken}</h2>
|
|
</div>
|
|
{selectedToken === 'USDC' ? (
|
|
<DespositForm
|
|
token="USDC"
|
|
clientContext={
|
|
getStakableTokensDataForTokenName('USDC').clientContext
|
|
}
|
|
/>
|
|
) : (
|
|
<StakeForm
|
|
token={selectedToken}
|
|
clientContext={
|
|
getStakableTokensDataForTokenName(selectedToken)
|
|
?.clientContext
|
|
}
|
|
/>
|
|
)}
|
|
</>
|
|
)
|
|
) : (
|
|
<div className="p-10">
|
|
<p className="text-center text-th-fgd-4">
|
|
No positions to remove
|
|
</p>
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
</>
|
|
)
|
|
}
|
|
|
|
export default Stake
|