(null);
const [withdrawAmount, setWithdrawAmount] = useState
(BigInt(0));
@@ -63,7 +64,7 @@ export function WithdrawModal({ position, onClose, refetch }: ModalProps): JSX.E
const withdraw = useCallback(async () => {
if (!account) {
- toast.error('Please connect your wallet');
+ toast.info('No account connected', 'Please connect your wallet to continue.');
return;
}
@@ -101,6 +102,7 @@ export function WithdrawModal({ position, onClose, refetch }: ModalProps): JSX.E
sendTransaction,
position.supplyAssets,
position.supplyShares,
+ toast,
]);
return (
diff --git a/src/hooks/useAuthorizeAgent.ts b/src/hooks/useAuthorizeAgent.ts
index 73b62fda..a776f988 100644
--- a/src/hooks/useAuthorizeAgent.ts
+++ b/src/hooks/useAuthorizeAgent.ts
@@ -1,15 +1,14 @@
import { useState, useCallback } from 'react';
-import { toast } from 'react-toastify';
import { Address, encodeFunctionData, parseSignature } from 'viem';
import { useAccount, useReadContract, useSignTypedData, useSwitchChain } from 'wagmi';
import monarchAgentAbi from '@/abis/monarch-agent-v1';
import morphoAbi from '@/abis/morpho';
+import { useStyledToast } from '@/hooks/useStyledToast';
import { useTransactionWithToast } from '@/hooks/useTransactionWithToast';
import { AGENT_CONTRACT } from '@/utils/monarch-agent';
import { MONARCH_TX_IDENTIFIER, MORPHO } from '@/utils/morpho';
import { SupportedNetworks } from '@/utils/networks';
import { Market } from '@/utils/types';
-
export enum AuthorizeAgentStep {
Idle = 'idle',
Authorize = 'authorize',
@@ -33,6 +32,7 @@ export const useAuthorizeAgent = (
marketCaps: MarketCap[],
onSuccess?: () => void,
) => {
+ const toast = useStyledToast();
const [isConfirming, setIsConfirming] = useState(false);
const [currentStep, setCurrentStep] = useState(AuthorizeAgentStep.Idle);
@@ -128,7 +128,10 @@ export const useAuthorizeAgent = (
});
} catch (error) {
console.log('Failed to sign authorization:', error);
- toast.error('Signature request was rejected or failed. Please try again.');
+ toast.error(
+ 'Signature Request Failed',
+ 'Signature request was rejected or failed. Please try again.',
+ );
return;
}
const signature = parseSignature(signatureRaw);
@@ -197,7 +200,10 @@ export const useAuthorizeAgent = (
} catch (error) {
console.error('Error during agent setup:', error);
onError?.();
- toast.error('An error occurred during agent setup. Please try again.');
+ toast.error(
+ 'Agent Setup Failed',
+ 'An error occurred during agent setup. Please try again.',
+ );
throw error;
} finally {
setIsConfirming(false);
diff --git a/src/hooks/useMultiMarketSupply.ts b/src/hooks/useMultiMarketSupply.ts
index 0747bce8..85090089 100644
--- a/src/hooks/useMultiMarketSupply.ts
+++ b/src/hooks/useMultiMarketSupply.ts
@@ -1,5 +1,4 @@
import { useCallback, useState } from 'react';
-import { toast } from 'react-toastify';
import { Address, encodeFunctionData } from 'viem';
import { useAccount } from 'wagmi';
import morphoBundlerAbi from '@/abis/bundlerV2';
@@ -11,6 +10,7 @@ import { getBundlerV2, MONARCH_TX_IDENTIFIER } from '@/utils/morpho';
import { SupportedNetworks } from '@/utils/networks';
import { Market } from '@/utils/types';
import { useERC20Approval } from './useERC20Approval';
+import { useStyledToast } from './useStyledToast';
export type MarketSupply = {
market: Market;
@@ -26,6 +26,7 @@ export function useMultiMarketSupply(
) {
const [currentStep, setCurrentStep] = useState<'approve' | 'signing' | 'supplying'>('approve');
const [showProcessModal, setShowProcessModal] = useState(false);
+ const toast = useStyledToast();
const { address: account } = useAccount();
const chainId = loanAsset?.network;
@@ -164,9 +165,9 @@ export function useMultiMarketSupply(
console.error('Error in executeSupplyTransaction:', error);
setShowProcessModal(false);
if (error instanceof Error) {
- toast.error('Transaction failed or cancelled');
+ toast.error('Transaction failed', error.message);
} else {
- toast.error('Transaction failed');
+ toast.error('Transaction failed', 'Transaction failed or cancled');
}
throw error; // Re-throw to be caught by approveAndSupply
}
@@ -180,11 +181,12 @@ export function useMultiMarketSupply(
usePermit2Setting,
chainId,
loanAsset,
+ toast,
]);
const approveAndSupply = useCallback(async () => {
if (!account) {
- toast.error('Please connect your wallet');
+ toast.error('No account connected', 'Please connect your wallet to continue.');
return false;
}
@@ -223,7 +225,7 @@ export function useMultiMarketSupply(
setShowProcessModal(false);
if (error instanceof Error) {
if (error.message.includes('User rejected')) {
- toast.error('Approval rejected by user');
+ toast.error('Approval rejected', 'Token approval rejected by the user');
} else {
toast.error('Failed to approve token');
}
@@ -250,6 +252,7 @@ export function useMultiMarketSupply(
approve,
useEth,
executeSupplyTransaction,
+ toast,
]);
return {
diff --git a/src/hooks/useRebalance.ts b/src/hooks/useRebalance.ts
index deea1b36..b59eff91 100644
--- a/src/hooks/useRebalance.ts
+++ b/src/hooks/useRebalance.ts
@@ -1,5 +1,4 @@
import { useState, useCallback } from 'react';
-import { toast } from 'react-toastify';
import { Address, encodeFunctionData, maxUint256, parseSignature } from 'viem';
import { useAccount, useReadContract, useSignTypedData } from 'wagmi';
import morphoBundlerAbi from '@/abis/bundlerV2';
@@ -8,6 +7,7 @@ import { useTransactionWithToast } from '@/hooks/useTransactionWithToast';
import { getBundlerV2, MONARCH_TX_IDENTIFIER, MORPHO } from '@/utils/morpho';
import { GroupedPosition, RebalanceAction } from '@/utils/types';
import { usePermit2 } from './usePermit2';
+import { useStyledToast } from './useStyledToast';
export const useRebalance = (groupedPosition: GroupedPosition, onRebalance?: () => void) => {
const [rebalanceActions, setRebalanceActions] = useState([]);
@@ -19,7 +19,7 @@ export const useRebalance = (groupedPosition: GroupedPosition, onRebalance?: ()
const { address: account } = useAccount();
const { signTypedDataAsync } = useSignTypedData();
const bundlerAddress = getBundlerV2(groupedPosition.chainId);
-
+ const toast = useStyledToast();
const { data: isAuthorized } = useReadContract({
address: MORPHO,
abi: morphoAbi,
@@ -121,7 +121,8 @@ export const useRebalance = (groupedPosition: GroupedPosition, onRebalance?: ()
message: value,
});
} catch (error) {
- toast.error('Signature request was rejected or failed. Please try again.');
+ const errorMessage = 'Signature request was rejected or failed. Please try again.';
+ toast.error('Signature request failed', errorMessage);
return;
}
const signature = parseSignature(signatureRaw);
@@ -306,6 +307,7 @@ export const useRebalance = (groupedPosition: GroupedPosition, onRebalance?: ()
sendTransactionAsync,
groupedPosition.loanAssetAddress,
totalAmount,
+ toast,
]);
return {
diff --git a/src/hooks/useStyledToast.tsx b/src/hooks/useStyledToast.tsx
new file mode 100644
index 00000000..383a8ce7
--- /dev/null
+++ b/src/hooks/useStyledToast.tsx
@@ -0,0 +1,20 @@
+import React, { useCallback } from 'react';
+import { toast, ToastOptions } from 'react-toastify';
+import 'react-toastify/dist/ReactToastify.css';
+import { StyledToast } from '../components/common/StyledToast';
+
+export function useStyledToast() {
+ const success = useCallback((title: string, message?: string, options?: ToastOptions) => {
+ toast.success(, options);
+ }, []);
+
+ const error = useCallback((title: string, message?: string, options?: ToastOptions) => {
+ toast.error(, options);
+ }, []);
+
+ const info = useCallback((title: string, message?: string, options?: ToastOptions) => {
+ toast.info(, options);
+ }, []);
+
+ return { success, error, info };
+}
diff --git a/src/hooks/useTransactionWithToast.tsx b/src/hooks/useTransactionWithToast.tsx
index c6e9937a..bdd7906f 100644
--- a/src/hooks/useTransactionWithToast.tsx
+++ b/src/hooks/useTransactionWithToast.tsx
@@ -2,7 +2,7 @@ import React, { useCallback, useEffect } from 'react';
import { toast } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';
import { useSendTransaction, useWaitForTransactionReceipt } from 'wagmi';
-import { TxHashDisplay } from '../components/TxHashDisplay';
+import { StyledToast, TransactionToast } from '@/components/common/StyledToast';
import { getExplorerTxURL } from '../utils/external';
import { SupportedNetworks } from '../utils/networks';
@@ -45,31 +45,29 @@ export function useTransactionWithToast({
}
}, [hash, chainId]);
- const renderToastContent = useCallback(
- (title: string, description?: string) => (
-
-
{title}
- {description &&
{description}
}
-
-
- ),
- [hash],
- );
-
useEffect(() => {
if (isConfirming) {
- toast.loading(renderToastContent(pendingText, pendingDescription), {
- toastId,
- onClick,
- closeButton: true,
- });
+ toast.loading(
+ ,
+ {
+ toastId,
+ onClick,
+ closeButton: true,
+ },
+ );
}
- }, [isConfirming, pendingText, pendingDescription, toastId, onClick, renderToastContent]);
+ }, [isConfirming, pendingText, pendingDescription, toastId, onClick]);
useEffect(() => {
if (isConfirmed) {
toast.update(toastId, {
- render: renderToastContent(`${successText} 🎉`, successDescription),
+ render: (
+
+ ),
type: 'success',
isLoading: false,
autoClose: 5000,
@@ -82,12 +80,7 @@ export function useTransactionWithToast({
}
if (txError) {
toast.update(toastId, {
- render: (
-
-
{errorText}
-
{txError.message}
-
- ),
+ render: ,
type: 'error',
isLoading: false,
autoClose: 5000,
@@ -103,8 +96,9 @@ export function useTransactionWithToast({
errorText,
toastId,
onClick,
- renderToastContent,
onSuccess,
+ toast,
+ hash,
]);
return { sendTransactionAsync, sendTransaction, isConfirming, isConfirmed };