//@ts-ignore
import BrowserOnly from "@docusaurus/BrowserOnly";
import { useWallet } from "@solana/wallet-adapter-react";
import {
useWalletModal
} from "@solana/wallet-adapter-react-ui";
import {
truncatePubkey, useBondingPricing,
useCollective, useEndpoint, useErrorHandler,
usePublicKey,
useSolanaUnixTime,
useStrataSdks,
useUserTokensWithMeta,
useRentExemptAmount
} from "@strata-foundation/react";
import { toNumber } from "@strata-foundation/spl-token-bonding";
import React, { useCallback, useEffect, useMemo, useState } from "react";
//@ts-ignore
import {
Alert, AlertDescription, AlertIcon, AlertTitle, Avatar, Box, Button, SimpleGrid, Stack,
Text, VStack
} from "@chakra-ui/react";
import { NATIVE_MINT } from "@solana/spl-token";
import { ITokenWithMetaAndAccount } from "@strata-foundation/spl-token-collective";
import { truthy } from "@strata-foundation/spl-utils";
import { closeOutWumboSubmit } from "./closeOutWumboSubmit";
import { WalletAdapterNetwork } from "@solana/wallet-adapter-base";
//@ts-ignore
import styles from "./styles.module.css";
const OPEN_COLLECTIVE = "3cYa5WvT2bgXSLxxu9XDJSHV3x5JZGM91Nc3B7jYhBL7";
const MainnetGuard = ({ children = null as any }) => {
const { endpoint, setClusterOrEndpoint } = useEndpoint();
if (endpoint.includes("devnet")) {
return (
Recoup SOL from Wumbo
{
setClusterOrEndpoint(WalletAdapterNetwork.Mainnet);
}}
className="white button button--primary"
>
Switch to Mainnet
);
}
return children;
};
interface ITokenHandlerProps {
token: ITokenWithMetaAndAccount;
setAmountByToken: (arg0: ITokenWithMetaAndAccount, arg1: number) => void;
}
export const TokenHandler = React.memo(
({ token, setAmountByToken }) => {
const { publicKey: tokenBondingKey, targetMint } = token.tokenBonding;
const unixTime = useSolanaUnixTime();
const { pricing, loading: loadingPricing } =
useBondingPricing(tokenBondingKey);
const solAmount = pricing?.swap(
toNumber(token.account.amount, token.mint),
targetMint,
NATIVE_MINT,
true,
unixTime
);
useEffect(() => {
if (solAmount) {
setAmountByToken(token, solAmount);
}
}, [solAmount, setAmountByToken]);
return (
{token.metadata?.data?.name}
{solAmount} SOL
);
}
);
export const Recoup = () => {
const { connected, publicKey } = useWallet();
const { tokenBondingSdk, loading: sdkLoading } = useStrataSdks();
const [txError, setError] = useState();
const { handleErrors } = useErrorHandler();
const [amountsByToken, setAmountsByToken] = useState<{
[key: string]: number;
}>({});
const [status, setStatus] = useState(null);
const [isCalculatingTokens, setIsCalculatingTokens] = useState(true);
const { setVisible } = useWalletModal();
const openCollectiveKey = usePublicKey(OPEN_COLLECTIVE);
const { info: openCollective } = useCollective(openCollectiveKey);
const { amount: rentAmount } = useRentExemptAmount(165)
const {
data: tokens,
loading: loading1,
error,
} = useUserTokensWithMeta(publicKey || undefined);
const setAmountByToken = useCallback(
(token: ITokenWithMetaAndAccount, amount: number) => {
if (token && amount) {
setAmountsByToken((old) => ({
...old,
[token.publicKey.toBase58()]: amount + (rentAmount || 0),
}));
}
},
[]
);
const open = useMemo(
() =>
tokens.find(({ account }) => account.mint.equals(openCollective.mint)),
[tokens]
);
const hasOpenAmount = useMemo(
() => open && toNumber(open.account.amount, open.mint) > 0,
[open]
);
const openCollectiveTokens = useMemo(
() =>
tokens.filter(
(token) =>
!!token.tokenRef &&
token.tokenRef.collective &&
token.tokenRef.collective.equals(openCollectiveKey) &&
toNumber(token.account.amount, token.mint) > 0
),
[tokens]
);
useEffect(() => {
if (
Object.values(amountsByToken).length ===
openCollectiveTokens?.length + (hasOpenAmount ? 1 : 0)
) {
setIsCalculatingTokens(false);
}
}, [amountsByToken, hasOpenAmount, openCollectiveTokens]);
handleErrors(error, txError);
const handleSubmit = useCallback(async () => {
try {
await closeOutWumboSubmit({
tokenBondingSdk,
tokens: openCollectiveTokens.filter(truthy),
expectedOutputAmountByToken: amountsByToken,
setStatus,
});
} catch (err: any) {
console.error(err);
setStatus(null);
setError(err);
}
}, [open, hasOpenAmount, openCollectiveTokens, amountsByToken]);
const loading = sdkLoading || loading1 || isCalculatingTokens;
const connectedLoading = connected && publicKey && loading;
const connectedNotLoading = !loading && connected && publicKey;
const isSuccessful = status == "successful";
const isOrphaned = status == "orphaned";
return (
Recoup SOL from Wumbo
{connectedLoading && Loading... }
{connectedNotLoading &&
!(hasOpenAmount || openCollectiveTokens.length) && (
No tokens relating to Wumbo/OPEN found. Make sure you have the
wallet that you used with Wumbo/OPEN, then refresh this page.
)}
{error && {error.toString()} }
{connectedNotLoading && !isSuccessful && !isOrphaned && (
<>
{hasOpenAmount && (
)}
{openCollectiveTokens.map((token) => (
))}
{Object.values(amountsByToken).reduce(
(acc, amount) => acc + amount,
0
)}{" "}
SOL
Ready to be Recouped. Thanks for giving Wumbo a try. Our team
greatly appreciates you and your early support!
Recoup SOL
>
)}
{connectedNotLoading && isSuccessful && (
SOL Recouped
Thanks for giving Wumbo a try. Our team greatly appreciates you
and your early support!
)}
{connectedNotLoading && isOrphaned && (
Something went wrong
I looks like we were unable to recoup the full amount of SOL, one
or multiple of the transactions may have failed. Please refresh
and try again.
)}
setVisible(true)} colorScheme="orange" variant="outline">{ publicKey ? truncatePubkey(publicKey) : "Select Wallet" }
);
};
export const CloseOutWumbo: React.FC = () => (
...}>
{() => (
)}
);