add redeem page for when token sale is closed
This commit is contained in:
parent
006db8f8e7
commit
05f3417265
|
@ -0,0 +1,128 @@
|
|||
import { useEffect, useState } from 'react'
|
||||
import { LinkIcon } from '@heroicons/react/solid'
|
||||
import useWalletStore from '../stores/useWalletStore'
|
||||
import Button from './Button'
|
||||
import { ConnectWalletButtonSmall } from './ConnectWalletButton'
|
||||
import Loading from './Loading'
|
||||
import useLargestAccounts from '../hooks/useLargestAccounts'
|
||||
import useVaults from '../hooks/useVaults'
|
||||
|
||||
const RedeemModal = () => {
|
||||
const actions = useWalletStore((s) => s.actions)
|
||||
const connected = useWalletStore((s) => s.connected)
|
||||
const wallet = useWalletStore((s) => s.current)
|
||||
const largestAccounts = useLargestAccounts()
|
||||
const vaults = useVaults()
|
||||
|
||||
const redeemableBalance = largestAccounts.redeemable?.balance || 0
|
||||
const mangoAvailable = vaults.usdc
|
||||
? (redeemableBalance * vaults.mango.balance) / vaults.usdc.balance
|
||||
: 0
|
||||
|
||||
console.log('balance', redeemableBalance, mangoAvailable)
|
||||
|
||||
const [submitting, setSubmitting] = useState(false)
|
||||
const [loading, setLoading] = useState(true)
|
||||
|
||||
const handleConnectDisconnect = () => {
|
||||
if (connected) {
|
||||
wallet.disconnect()
|
||||
} else {
|
||||
wallet.connect()
|
||||
}
|
||||
}
|
||||
|
||||
const handleRedeem = () => {
|
||||
setSubmitting(true)
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
setLoading(true)
|
||||
if (largestAccounts.redeemable) {
|
||||
setLoading(false)
|
||||
}
|
||||
}, [largestAccounts])
|
||||
|
||||
useEffect(() => {
|
||||
if (submitting) {
|
||||
const handleSubmit = async () => {
|
||||
await actions.redeem()
|
||||
setSubmitting(false)
|
||||
}
|
||||
handleSubmit()
|
||||
}
|
||||
}, [submitting])
|
||||
|
||||
const disableFormInputs = !connected || loading
|
||||
const disableSubmit = disableFormInputs || redeemableBalance <= 0
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="bg-bkg-2 border border-bkg-3 col-span-7 p-7 rounded-lg shadow-lg">
|
||||
<div className="pb-4 text-center">
|
||||
{!submitting ? (
|
||||
<>
|
||||
<h2>Redeem your MNGO</h2>
|
||||
<p>Welcome to the DAO, let's build together.</p>
|
||||
</>
|
||||
) : null}
|
||||
|
||||
{submitting ? (
|
||||
<>
|
||||
<h2>Approve the transaction</h2>
|
||||
<p>Almost there...</p>
|
||||
</>
|
||||
) : null}
|
||||
</div>
|
||||
{submitting ? (
|
||||
<div className="flex h-64 items-center justify-center">
|
||||
<Loading className="h-6 w-6 mb-3 text-primary-light" />
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
<div
|
||||
className={`${
|
||||
connected ? 'opacity-100' : 'opacity-30'
|
||||
} pb-6 transiton-all duration-1000 w-full`}
|
||||
>
|
||||
<div>
|
||||
<Button
|
||||
onClick={() => handleRedeem()}
|
||||
className="w-full py-2.5"
|
||||
disabled={disableSubmit}
|
||||
>
|
||||
<div className={`flex items-center justify-center`}>
|
||||
Redeem 🥭
|
||||
</div>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex justify-center">
|
||||
{connected ? (
|
||||
<Button
|
||||
className="rounded-full bg-bkg-4 text-fgd-3 font-normal"
|
||||
onClick={() => handleConnectDisconnect()}
|
||||
secondary
|
||||
>
|
||||
<div className="flex items-center text-sm">
|
||||
<LinkIcon className="h-4 w-4 mr-1" />
|
||||
Disconnect
|
||||
</div>
|
||||
</Button>
|
||||
) : (
|
||||
<ConnectWalletButtonSmall onClick={handleConnectDisconnect}>
|
||||
<div className="flex items-center justify-center text-sm">
|
||||
<LinkIcon className="h-4 w-4 mr-1" />
|
||||
Connect Wallet
|
||||
</div>
|
||||
</ConnectWalletButtonSmall>
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default RedeemModal
|
|
@ -0,0 +1,13 @@
|
|||
import RedeemModal from '../components/RedeemModal'
|
||||
|
||||
const RedeemPage = () => {
|
||||
return (
|
||||
<div className="flex justify-center">
|
||||
<div className="max-w-screen-md grid grid-cols-12 gap-4 w-full">
|
||||
<RedeemModal />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default RedeemPage
|
|
@ -0,0 +1,21 @@
|
|||
import ContributionModal from '../components/ContributionModal'
|
||||
import PoolInfoCards from '../components/PoolInfoCards'
|
||||
import HeroSection from '../components/HeroSection'
|
||||
import LandingContent from '../components/LandingContent'
|
||||
|
||||
const SalePage = () => {
|
||||
return (
|
||||
<>
|
||||
<HeroSection />
|
||||
<PoolInfoCards />
|
||||
<LandingContent />
|
||||
<div className="flex justify-center">
|
||||
<div className="max-w-screen-md grid grid-cols-12 gap-4 w-full">
|
||||
<ContributionModal />
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default SalePage
|
|
@ -33,7 +33,7 @@ function App({ Component, pageProps }) {
|
|||
<meta name="twitter:description" content={description} />
|
||||
<meta name="twitter:image" content="/twitter-image.png" />
|
||||
|
||||
<link rel="manifest" href="/manifest.json"></link>
|
||||
{/* <link rel="manifest" href="/manifest.json"></link> */}
|
||||
</Head>
|
||||
<ThemeProvider defaultTheme="Mango">
|
||||
<Component {...pageProps} />
|
||||
|
|
|
@ -1,24 +1,19 @@
|
|||
import SalePage from './SalePage'
|
||||
import RedeemPage from './RedeemPage'
|
||||
import Notifications from '../components/Notification'
|
||||
import TopBar from '../components/TopBar'
|
||||
import ContributionModal from '../components/ContributionModal'
|
||||
import PoolInfoCards from '../components/PoolInfoCards'
|
||||
import HeroSection from '../components/HeroSection'
|
||||
import LandingContent from '../components/LandingContent'
|
||||
|
||||
import usePool from '../hooks/usePool'
|
||||
|
||||
const Index = () => {
|
||||
const { endIdo } = usePool()
|
||||
|
||||
return (
|
||||
<div className={`bg-bkg-1 text-fgd-1 transition-all`}>
|
||||
<TopBar />
|
||||
<Notifications />
|
||||
|
||||
<HeroSection />
|
||||
<PoolInfoCards />
|
||||
<LandingContent />
|
||||
<div className="flex justify-center">
|
||||
<div className="max-w-screen-md grid grid-cols-12 gap-4 w-full">
|
||||
<ContributionModal />
|
||||
</div>
|
||||
</div>
|
||||
{endIdo?.isAfter() && <SalePage />}
|
||||
{endIdo?.isBefore() && <RedeemPage />}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -291,6 +291,74 @@ const useWalletStore = create<WalletStore>((set, get) => ({
|
|||
await actions.fetchWalletTokenAccounts()
|
||||
actions.fetchUsdcVault()
|
||||
},
|
||||
async redeem() {
|
||||
console.log('redeem')
|
||||
|
||||
const actions = get().actions
|
||||
await actions.fetchWalletTokenAccounts()
|
||||
|
||||
const {
|
||||
program,
|
||||
pool,
|
||||
tokenAccounts,
|
||||
mints,
|
||||
current: wallet,
|
||||
connection: { current: connection },
|
||||
} = get()
|
||||
const redeemable = findLargestBalanceAccountForMint(
|
||||
mints,
|
||||
tokenAccounts,
|
||||
pool.redeemableMint
|
||||
)
|
||||
const watermelon = findLargestBalanceAccountForMint(
|
||||
mints,
|
||||
tokenAccounts,
|
||||
pool.watermelonMint
|
||||
)
|
||||
|
||||
console.log(redeemable, watermelon, 'exchangeRedeemableForMango')
|
||||
|
||||
const [poolSigner] = await anchor.web3.PublicKey.findProgramAddress(
|
||||
[pool.watermelonMint.toBuffer()],
|
||||
program.programId
|
||||
)
|
||||
|
||||
const transaction = new Transaction()
|
||||
|
||||
let watermelonAccount = watermelon?.account?.publicKey
|
||||
if (!watermelonAccount) {
|
||||
const [ins, pk] = await createAssociatedTokenAccount(
|
||||
wallet.publicKey,
|
||||
wallet.publicKey,
|
||||
pool.watermelonMint
|
||||
)
|
||||
transaction.add(ins)
|
||||
watermelonAccount = pk
|
||||
}
|
||||
|
||||
transaction.add(
|
||||
program.instruction.exchangeRedeemableForWatermelon(
|
||||
redeemable.account.account.amount,
|
||||
{
|
||||
accounts: {
|
||||
poolAccount: POOL_PK,
|
||||
poolSigner,
|
||||
redeemableMint: pool.redeemableMint,
|
||||
poolWatermelon: pool.poolWatermelon,
|
||||
userAuthority: wallet.publicKey,
|
||||
userWatermelon: watermelonAccount,
|
||||
userRedeemable: redeemable.account.publicKey,
|
||||
tokenProgram: TOKEN_PROGRAM_ID,
|
||||
clock: anchor.web3.SYSVAR_CLOCK_PUBKEY,
|
||||
},
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
await sendTransaction({ transaction, wallet, connection })
|
||||
|
||||
await actions.fetchPool()
|
||||
},
|
||||
},
|
||||
set: (fn) => set(produce(fn)),
|
||||
}))
|
||||
|
|
Loading…
Reference in New Issue