diff --git a/apps/marginfi-v2-ui/src/components/common/AssetList/AssetRowInputBox.tsx b/apps/marginfi-v2-ui/src/components/common/AssetList/AssetRowInputBox.tsx index c25e5d1329..a2e38e3403 100644 --- a/apps/marginfi-v2-ui/src/components/common/AssetList/AssetRowInputBox.tsx +++ b/apps/marginfi-v2-ui/src/components/common/AssetList/AssetRowInputBox.tsx @@ -1,7 +1,7 @@ import { InputAdornment, TextField } from "@mui/material"; import { FC, MouseEventHandler, useCallback } from "react"; import { NumberFormatValues, NumericFormat } from "react-number-format"; -import { toast } from "react-toastify"; +import { showErrorToast } from "~/utils/toastUtils"; interface AssetRowInputBox { value: number; @@ -28,7 +28,7 @@ const AssetRowInputBox: FC = ({ if (maxValue !== undefined) { setValue(maxValue); } else { - toast.error("Not implemented"); + showErrorToast("Not implemented"); } }, [maxValue, setValue]); diff --git a/apps/marginfi-v2-ui/src/components/common/Staking/StakingCard/StakingCard.tsx b/apps/marginfi-v2-ui/src/components/common/Staking/StakingCard/StakingCard.tsx index 967056c36a..fe7335fc86 100644 --- a/apps/marginfi-v2-ui/src/components/common/Staking/StakingCard/StakingCard.tsx +++ b/apps/marginfi-v2-ui/src/components/common/Staking/StakingCard/StakingCard.tsx @@ -37,7 +37,6 @@ import { SwapMode, useJupiter } from "@jup-ag/react-hook"; import JSBI from "jsbi"; import { StakeData, usePrevious } from "~/utils"; import { createJupiterApiClient } from "@jup-ag/api"; -import { toast } from "react-toastify"; import { SettingsModal } from "./SettingsModal"; import { SettingsIcon } from "./SettingsIcon"; import { LST_MINT, TokenData, TokenDataMap } from "~/store/lstStore"; @@ -46,6 +45,7 @@ import { IconLoader } from "~/components/ui/icons"; import BN from "bn.js"; import debounce from "lodash.debounce"; import { Desktop, Mobile } from "~/mediaQueries"; +import { MultiStepToastHandle, showErrorToast } from "~/utils/toastUtils"; const QUOTE_EXPIRY_MS = 30_000; const DEFAULT_DEPOSIT_OPTION: DepositOption = { type: "native", amount: new BN(0), maxAmount: new BN(0) }; @@ -182,7 +182,7 @@ export const StakingCard: FC = () => { [depositOption, refresh, lastRefreshTimestamp] ); - const showErrotToast = useRef(debounce(() => toast.error("Failed to find route"), 250)); + const showErrotToast = useRef(debounce(() => showErrorToast("Failed to find route"), 250)); const prevError = usePrevious(error); useEffect(() => { @@ -267,6 +267,9 @@ export const StakingCard: FC = () => { setOngoingAction("minting"); + const multiStepToast = new MultiStepToastHandle("Stake", [{ label: "Minting LST" }]); + multiStepToast.start(); + try { if (depositOption.type === "stake") { const { instructions, signers } = await makeDepositStakeToStakePoolIx( @@ -293,6 +296,7 @@ export const StakingCard: FC = () => { } else if (depositOption.type === "token") { const quote = quoteResponseMeta?.original; if (!quote) { + multiStepToast.setFailed("Route not calculated yet"); console.error("Route not calculated yet"); return; } @@ -346,10 +350,10 @@ export const StakingCard: FC = () => { "confirmed" ); } else { - throw new Error("Invalid deposit option"); + multiStepToast.setFailed("Invalid deposit option"); } - toast.success("Minting complete"); + multiStepToast.setSuccessAndNext(); } catch (error: any) { if (error.logs) { console.log("------ Logs 👇 ------"); @@ -360,7 +364,7 @@ export const StakingCard: FC = () => { if (errorMsg) { errorMsg = errorMsg ? errorMsg : "Transaction failed!"; } - toast.error(errorMsg); + multiStepToast.setFailed(errorMsg); } finally { await Promise.all([refresh(), fetchLstState()]); setDepositOption((currentDepositOption) => diff --git a/apps/marginfi-v2-ui/src/components/desktop/DesktopNavbar/DesktopNavbar.tsx b/apps/marginfi-v2-ui/src/components/desktop/DesktopNavbar/DesktopNavbar.tsx index 338b4ba711..c0f566896d 100644 --- a/apps/marginfi-v2-ui/src/components/desktop/DesktopNavbar/DesktopNavbar.tsx +++ b/apps/marginfi-v2-ui/src/components/desktop/DesktopNavbar/DesktopNavbar.tsx @@ -11,7 +11,6 @@ import { useWalletContext } from "~/hooks/useWalletContext"; import { Features, isActive } from "~/utils/featureGates"; import { PublicKey } from "@solana/web3.js"; import { useConnection } from "~/hooks/useConnection"; -import { toast } from "react-toastify"; import { EMISSION_MINT_INFO_MAP } from "../AssetsList/AssetRow"; import { collectRewardsBatch } from "~/utils"; import { IconMrgn } from "~/components/ui/icons"; @@ -301,7 +300,6 @@ const DesktopNavbar: FC = () => { onClick={async () => { if (!wallet || !selectedAccount || bankAddressesWithEmissions.length === 0) return; await collectRewardsBatch(connection, wallet, selectedAccount, bankAddressesWithEmissions); - toast.success("Withdrawal successful"); }} > collect rewards diff --git a/apps/marginfi-v2-ui/src/components/desktop/Earn/index.tsx b/apps/marginfi-v2-ui/src/components/desktop/Earn/index.tsx index cfc62dedb2..0a0351e601 100644 --- a/apps/marginfi-v2-ui/src/components/desktop/Earn/index.tsx +++ b/apps/marginfi-v2-ui/src/components/desktop/Earn/index.tsx @@ -28,11 +28,11 @@ import { } from "@mrgnlabs/mrgn-common"; import { Bank, PriceBias } from "@mrgnlabs/marginfi-client-v2"; import { Countdown } from "~/components/desktop/Countdown"; -import { toast } from "react-toastify"; import BigNumber from "bignumber.js"; import { useWalletContext } from "~/hooks/useWalletContext"; import { useMrgnlendStore } from "~/store"; import { Desktop } from "~/mediaQueries"; +import { MultiStepToastHandle } from "~/utils/toastUtils"; const Earn = () => { const { wallet, isOverride, connected, walletAddress } = useWalletContext(); @@ -181,25 +181,14 @@ const Earn = () => { const closeDeposit = useCallback( async (deposit: Deposit) => { if (!lipAccount) return; - toast.loading(`Closing deposit`, { - toastId: "close-deposit", - }); + const multiStepToast = new MultiStepToastHandle("Close deposit", [{ label: "Closing deposit" }]); + multiStepToast.start(); try { await lipAccount.closePosition(deposit); - toast.update("close-deposit", { - render: `Closing deposit 👍`, - type: toast.TYPE.SUCCESS, - autoClose: 2000, - isLoading: false, - }); + multiStepToast.setSuccessAndNext(); } catch (e) { console.error(e); - toast.update("close-deposit", { - render: `Error closing deposit: ${e}`, - type: toast.TYPE.ERROR, - autoClose: 2000, - isLoading: false, - }); + multiStepToast.setFailed(`Error closing deposit: ${e}`); } setReloading(true); setLipAccount(await lipAccount.reloadAndClone()); diff --git a/apps/marginfi-v2-ui/src/components/mobile/EmissionsBanner.tsx b/apps/marginfi-v2-ui/src/components/mobile/EmissionsBanner.tsx index eb1e1da095..5adae414f8 100644 --- a/apps/marginfi-v2-ui/src/components/mobile/EmissionsBanner.tsx +++ b/apps/marginfi-v2-ui/src/components/mobile/EmissionsBanner.tsx @@ -5,7 +5,6 @@ import { useWalletContext } from "~/hooks/useWalletContext"; import { useMrgnlendStore } from "~/store"; import { collectRewardsBatch } from "~/utils"; import { EMISSION_MINT_INFO_MAP } from "../desktop/AssetsList/AssetRow"; -import { toast } from "react-toastify"; const EmissionsBanner: FC = () => { const { connection } = useConnection(); @@ -33,7 +32,6 @@ const EmissionsBanner: FC = () => { onClick={async () => { if (!wallet || !selectedAccount || bankAddressesWithEmissions.length === 0) return; await collectRewardsBatch(connection, wallet, selectedAccount, bankAddressesWithEmissions); - toast.success("Withdrawal successful"); }} >
Collect LM rewards
diff --git a/apps/marginfi-v2-ui/src/pages/bridge.tsx b/apps/marginfi-v2-ui/src/pages/bridge.tsx index 794095fa4e..92184bcd3c 100644 --- a/apps/marginfi-v2-ui/src/pages/bridge.tsx +++ b/apps/marginfi-v2-ui/src/pages/bridge.tsx @@ -2,7 +2,6 @@ import React from "react"; import Script from "next/script"; -import { toast } from "react-toastify"; import { useHotkeys } from "react-hotkeys-hook"; import config from "~/config"; @@ -11,6 +10,7 @@ import { useUserProfileStore, useUiStore } from "~/store"; import { Desktop } from "~/mediaQueries"; import { useWalletContext } from "~/hooks/useWalletContext"; import { PageHeader } from "~/components/common/PageHeader"; +import { MultiStepToastHandle } from "~/utils/toastUtils"; const tokens = [ "0x0000000000000000000000000000000000000000", // SOL @@ -111,6 +111,7 @@ const BridgePage = () => { }, [walletContextState, handleConnect, walletAddress]); const handleLoadMayanWidget = React.useCallback(() => { + const multiStepToast = new MultiStepToastHandle("Bridge", [{ label: `Cross-chain swap/bridge in progress` }]); const configIndex = isBridgeIn ? 0 : 1; const config = { ...configs[configIndex], @@ -123,27 +124,13 @@ const BridgePage = () => { }; window.MayanSwap.init("swap_widget", config); window.MayanSwap.setSwapInitiateListener((data) => { - toast.loading("Cross-chain swap/bridge in progress", { - toastId: data.hash, - }); + multiStepToast.start(); }); window.MayanSwap.setSwapCompleteListener((data) => { - toast.update(data.hash, { - render: "Cross-chain swap/bridge done", - toastId: data.hash, - type: toast.TYPE.SUCCESS, - autoClose: 5000, - isLoading: false, - }); + multiStepToast.setSuccessAndNext(); }); window.MayanSwap.setSwapRefundListener((data) => { - toast.update(data.hash, { - render: "Cross-chain swap/bridge refunded", - toastId: data.hash, - type: toast.TYPE.WARNING, - autoClose: 5000, - isLoading: false, - }); + multiStepToast.setFailed("Cross-chain swap/bridge refunded"); }); }, [handleConnect, isBridgeIn, walletAddress, walletContextState.disconnect, walletContextState.signTransaction]); diff --git a/apps/marginfi-v2-ui/src/utils/mrgnActions.ts b/apps/marginfi-v2-ui/src/utils/mrgnActions.ts index e885095a19..b74a8e463c 100644 --- a/apps/marginfi-v2-ui/src/utils/mrgnActions.ts +++ b/apps/marginfi-v2-ui/src/utils/mrgnActions.ts @@ -219,10 +219,14 @@ export async function collectRewardsBatch( marginfiAccount: MarginfiAccountWrapper, bankAddresses: PublicKey[] ) { + const multiStepToast = new MultiStepToastHandle("Collect rewards", [{ label: "Collecting rewards" }]); + multiStepToast.start(); + try { const tx = new Transaction(); const ixs = []; const signers = []; + for (const bankAddress of bankAddresses) { const ix = await marginfiAccount.makeWithdrawEmissionsIx(bankAddress); ixs.push(...ix.instructions); @@ -230,9 +234,10 @@ export async function collectRewardsBatch( } tx.add(...ixs); await processTransaction(connection, wallet, tx); + multiStepToast.setSuccessAndNext(); } catch (error: any) { const msg = extractErrorString(error); - showErrorToast(msg); + multiStepToast.setFailed(msg); console.log(`Error while collecting rewards: ${msg}`); console.log(error); return;