diff --git a/components/RedeemModal.tsx b/components/RedeemModal.tsx new file mode 100644 index 0000000..9f3e41d --- /dev/null +++ b/components/RedeemModal.tsx @@ -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 ( + <> +
+
+ {!submitting ? ( + <> +

Redeem your MNGO

+

Welcome to the DAO, let's build together.

+ + ) : null} + + {submitting ? ( + <> +

Approve the transaction

+

Almost there...

+ + ) : null} +
+ {submitting ? ( +
+ +
+ ) : ( + <> +
+
+ +
+
+
+ {connected ? ( + + ) : ( + +
+ + Connect Wallet +
+
+ )} +
+ + )} +
+ + ) +} + +export default RedeemModal diff --git a/pages/RedeemPage.tsx b/pages/RedeemPage.tsx new file mode 100644 index 0000000..6efd94d --- /dev/null +++ b/pages/RedeemPage.tsx @@ -0,0 +1,13 @@ +import RedeemModal from '../components/RedeemModal' + +const RedeemPage = () => { + return ( +
+
+ +
+
+ ) +} + +export default RedeemPage diff --git a/pages/SalePage.tsx b/pages/SalePage.tsx new file mode 100644 index 0000000..d6e19f0 --- /dev/null +++ b/pages/SalePage.tsx @@ -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 ( + <> + + + +
+
+ +
+
+ + ) +} + +export default SalePage diff --git a/pages/_app.tsx b/pages/_app.tsx index 110f3f6..95dfd78 100644 --- a/pages/_app.tsx +++ b/pages/_app.tsx @@ -33,7 +33,7 @@ function App({ Component, pageProps }) { - + {/* */} diff --git a/pages/index.tsx b/pages/index.tsx index bf6a2e5..444d755 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -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 (
- - - - -
-
- -
-
+ {endIdo?.isAfter() && } + {endIdo?.isBefore() && }
) } diff --git a/stores/useWalletStore.tsx b/stores/useWalletStore.tsx index de63d8e..2f37db6 100644 --- a/stores/useWalletStore.tsx +++ b/stores/useWalletStore.tsx @@ -291,6 +291,74 @@ const useWalletStore = create((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)), }))