diff --git a/apps/wallet-dashboard/app/(protected)/layout.tsx b/apps/wallet-dashboard/app/(protected)/layout.tsx
index 72fa80c67cc..61dadf84b57 100644
--- a/apps/wallet-dashboard/app/(protected)/layout.tsx
+++ b/apps/wallet-dashboard/app/(protected)/layout.tsx
@@ -2,7 +2,6 @@
// SPDX-License-Identifier: Apache-2.0
'use client';
-import { Notifications } from '@/components/index';
import React, { type PropsWithChildren } from 'react';
import { Sidebar, TopNav } from './components';
@@ -22,7 +21,6 @@ function DashboardLayout({ children }: PropsWithChildren): JSX.Element {
{children}
-
);
}
diff --git a/apps/wallet-dashboard/app/(protected)/vesting/page.tsx b/apps/wallet-dashboard/app/(protected)/vesting/page.tsx
index e29d94a7fef..33572a16dff 100644
--- a/apps/wallet-dashboard/app/(protected)/vesting/page.tsx
+++ b/apps/wallet-dashboard/app/(protected)/vesting/page.tsx
@@ -13,9 +13,8 @@ import {
} from '@/components';
import { UnstakeDialogView } from '@/components/Dialogs/unstake/enums';
import { useUnstakeDialog } from '@/components/Dialogs/unstake/hooks';
-import { useGetSupplyIncreaseVestingObjects, useNotifications } from '@/hooks';
+import { useGetSupplyIncreaseVestingObjects } from '@/hooks';
import { groupTimelockedStakedObjects, TimelockedStakedObjectsGrouped } from '@/lib/utils';
-import { NotificationType } from '@/stores/notificationStore';
import { useFeature } from '@growthbook/growthbook-react';
import {
Panel,
@@ -56,6 +55,7 @@ import { useRouter } from 'next/navigation';
import { useEffect, useState } from 'react';
import { StakedTimelockObject } from '@/components';
import { IotaSignAndExecuteTransactionOutput } from '@iota/wallet-standard';
+import toast from 'react-hot-toast';
export default function VestingDashboardPage(): JSX.Element {
const [timelockedObjectsToUnstake, setTimelockedObjectsToUnstake] =
@@ -66,7 +66,6 @@ export default function VestingDashboardPage(): JSX.Element {
const router = useRouter();
const { data: system } = useIotaClientQuery('getLatestIotaSystemState');
const [isVestingScheduleDialogOpen, setIsVestingScheduleDialogOpen] = useState(false);
- const { addNotification } = useNotifications();
const { data: activeValidators } = useGetActiveValidatorsInfo();
const { mutateAsync: signAndExecuteTransaction } = useSignAndExecuteTransaction();
const { theme } = useTheme();
@@ -163,7 +162,7 @@ export default function VestingDashboardPage(): JSX.Element {
const handleCollect = () => {
if (!unlockAllSupplyIncreaseVesting?.transactionBlock) {
- addNotification('Failed to create a Transaction', NotificationType.Error);
+ toast.error('Failed to create a Transaction');
return;
}
signAndExecuteTransaction(
@@ -177,10 +176,10 @@ export default function VestingDashboardPage(): JSX.Element {
},
)
.then(() => {
- addNotification('Collect transaction has been sent');
+ toast.success('Collect transaction has been sent');
})
.catch(() => {
- addNotification('Collect transaction was not sent', NotificationType.Error);
+ toast.error('Collect transaction was not sent');
});
};
diff --git a/apps/wallet-dashboard/components/Dialogs/Assets/AssetDialog.tsx b/apps/wallet-dashboard/components/Dialogs/Assets/AssetDialog.tsx
index c71390a33aa..3283ef357de 100644
--- a/apps/wallet-dashboard/components/Dialogs/Assets/AssetDialog.tsx
+++ b/apps/wallet-dashboard/components/Dialogs/Assets/AssetDialog.tsx
@@ -9,10 +9,10 @@ import { createNftSendValidationSchema } from '@iota/core';
import { DetailsView, SendView } from './views';
import { IotaObjectData } from '@iota/iota-sdk/client';
import { AssetsDialogView } from './constants';
-import { useCreateSendAssetTransaction, useNotifications } from '@/hooks';
-import { NotificationType } from '@/stores/notificationStore';
+import { useCreateSendAssetTransaction } from '@/hooks';
import { TransactionDetailsView } from '../SendToken';
import { DialogLayout } from '../layout';
+import toast from 'react-hot-toast';
interface AssetsDialogProps {
onClose: () => void;
@@ -34,7 +34,6 @@ export function AssetDialog({ onClose, asset, refetchAssets }: AssetsDialogProps
const [digest, setDigest] = useState('');
const activeAddress = account?.address ?? '';
const objectId = asset?.objectId ?? '';
- const { addNotification } = useNotifications();
const iotaClient = useIotaClient();
const validationSchema = createNftSendValidationSchema(activeAddress, objectId);
@@ -57,10 +56,10 @@ export function AssetDialog({ onClose, asset, refetchAssets }: AssetsDialogProps
setDigest(tx.digest);
refetchAssets();
- addNotification('Transfer transaction successful', NotificationType.Success);
+ toast.success('Transfer transaction successful');
setView(AssetsDialogView.TransactionDetails);
} catch {
- addNotification('Transfer transaction failed', NotificationType.Error);
+ toast.error('Transfer transaction failed');
}
}
diff --git a/apps/wallet-dashboard/components/Dialogs/SendToken/SendTokenDialog.tsx b/apps/wallet-dashboard/components/Dialogs/SendToken/SendTokenDialog.tsx
index a33f018a09c..2a9f3d1c330 100644
--- a/apps/wallet-dashboard/components/Dialogs/SendToken/SendTokenDialog.tsx
+++ b/apps/wallet-dashboard/components/Dialogs/SendToken/SendTokenDialog.tsx
@@ -4,14 +4,14 @@
import React, { useState } from 'react';
import { EnterValuesFormView, ReviewValuesFormView, TransactionDetailsView } from './views';
import { CoinBalance } from '@iota/iota-sdk/client';
-import { useSendCoinTransaction, useNotifications } from '@/hooks';
-import { NotificationType } from '@/stores/notificationStore';
+import { useSendCoinTransaction } from '@/hooks';
import { CoinFormat, useFormatCoin, useGetAllCoins } from '@iota/core';
import { Dialog, DialogContent, DialogPosition } from '@iota/apps-ui-kit';
import { FormDataValues } from './interfaces';
import { INITIAL_VALUES } from './constants';
import { IOTA_TYPE_ARG } from '@iota/iota-sdk/utils';
import { useTransferTransactionMutation } from '@/hooks';
+import toast from 'react-hot-toast';
interface SendCoinDialogProps {
coin: CoinBalance;
@@ -37,7 +37,6 @@ function SendTokenDialogBody({
const [fullAmount] = useFormatCoin(formData.amount, selectedCoin.coinType, CoinFormat.FULL);
const { data: coinsData } = useGetAllCoins(selectedCoin.coinType, activeAddress);
- const { addNotification } = useNotifications();
const isPayAllIota =
selectedCoin.totalBalance === formData.amount && selectedCoin.coinType === IOTA_TYPE_ARG;
@@ -58,18 +57,18 @@ function SendTokenDialogBody({
async function handleTransfer() {
if (!transaction) {
- addNotification('There was an error with the transaction', NotificationType.Error);
+ toast.error('There was an error with the transaction');
return;
}
transfer(transaction, {
onSuccess: () => {
setStep(FormStep.TransactionDetails);
- addNotification('Transfer transaction has been sent', NotificationType.Success);
+ toast.success('Transfer transaction has been sent');
},
onError: () => {
setOpen(false);
- addNotification('Transfer transaction failed', NotificationType.Error);
+ toast.error('Transfer transaction failed');
},
});
}
diff --git a/apps/wallet-dashboard/components/Dialogs/Staking/views/EnterAmountView.tsx b/apps/wallet-dashboard/components/Dialogs/Staking/views/EnterAmountView.tsx
index b90de664794..58509774bc3 100644
--- a/apps/wallet-dashboard/components/Dialogs/Staking/views/EnterAmountView.tsx
+++ b/apps/wallet-dashboard/components/Dialogs/Staking/views/EnterAmountView.tsx
@@ -6,9 +6,9 @@ import { useFormatCoin, useBalance, CoinFormat, parseAmount, useCoinMetadata } f
import { IOTA_TYPE_ARG } from '@iota/iota-sdk/utils';
import { useFormikContext } from 'formik';
import { useSignAndExecuteTransaction } from '@iota/dapp-kit';
-import { useNewStakeTransaction, useNotifications } from '@/hooks';
-import { NotificationType } from '@/stores/notificationStore';
+import { useNewStakeTransaction } from '@/hooks';
import EnterAmountDialogLayout from './EnterAmountDialogLayout';
+import toast from 'react-hot-toast';
export interface FormValues {
amount: string;
@@ -32,7 +32,6 @@ function EnterAmountView({
senderAddress,
onSuccess,
}: EnterAmountViewProps): JSX.Element {
- const { addNotification } = useNotifications();
const { mutateAsync: signAndExecuteTransaction } = useSignAndExecuteTransaction();
const { values, resetForm } = useFormikContext();
@@ -65,7 +64,7 @@ function EnterAmountView({
function handleStake(): void {
if (!newStakeData?.transaction) {
- addNotification('Stake transaction was not created', NotificationType.Error);
+ toast.error('Stake transaction was not created');
return;
}
signAndExecuteTransaction(
@@ -75,11 +74,11 @@ function EnterAmountView({
{
onSuccess: (tx) => {
onSuccess(tx.digest);
- addNotification('Stake transaction has been sent');
+ toast.success('Stake transaction has been sent');
resetForm();
},
onError: () => {
- addNotification('Stake transaction was not sent', NotificationType.Error);
+ toast.error('Stake transaction was not sent');
},
},
);
diff --git a/apps/wallet-dashboard/components/Dialogs/Staking/views/EnterTimelockedAmountView.tsx b/apps/wallet-dashboard/components/Dialogs/Staking/views/EnterTimelockedAmountView.tsx
index b21a6ad3bd1..b1e206dac35 100644
--- a/apps/wallet-dashboard/components/Dialogs/Staking/views/EnterTimelockedAmountView.tsx
+++ b/apps/wallet-dashboard/components/Dialogs/Staking/views/EnterTimelockedAmountView.tsx
@@ -12,14 +12,10 @@ import {
import { IOTA_TYPE_ARG } from '@iota/iota-sdk/utils';
import { useFormikContext } from 'formik';
import { useSignAndExecuteTransaction } from '@iota/dapp-kit';
-import {
- useGetCurrentEpochStartTimestamp,
- useNewStakeTimelockedTransaction,
- useNotifications,
-} from '@/hooks';
-import { NotificationType } from '@/stores/notificationStore';
+import { useGetCurrentEpochStartTimestamp, useNewStakeTimelockedTransaction } from '@/hooks';
import { prepareObjectsForTimelockedStakingTransaction } from '@/lib/utils';
import EnterAmountDialogLayout from './EnterAmountDialogLayout';
+import toast from 'react-hot-toast';
export interface FormValues {
amount: string;
@@ -44,7 +40,6 @@ function EnterTimelockedAmountView({
handleClose,
onSuccess,
}: EnterTimelockedAmountViewProps): JSX.Element {
- const { addNotification } = useNotifications();
const { mutateAsync: signAndExecuteTransaction } = useSignAndExecuteTransaction();
const { resetForm } = useFormikContext();
@@ -84,11 +79,11 @@ function EnterTimelockedAmountView({
function handleStake(): void {
if (groupedTimelockObjects.length === 0) {
- addNotification('Invalid stake amount. Please try again.', NotificationType.Error);
+ toast.error('Invalid stake amount. Please try again.');
return;
}
if (!newStakeData?.transaction) {
- addNotification('Stake transaction was not created', NotificationType.Error);
+ toast.error('Stake transaction was not created');
return;
}
signAndExecuteTransaction(
@@ -98,11 +93,11 @@ function EnterTimelockedAmountView({
{
onSuccess: (tx) => {
onSuccess?.(tx.digest);
- addNotification('Stake transaction has been sent');
+ toast.success('Stake transaction has been sent');
resetForm();
},
onError: () => {
- addNotification('Stake transaction was not sent', NotificationType.Error);
+ toast.error('Stake transaction was not sent');
},
},
);
diff --git a/apps/wallet-dashboard/components/Dialogs/unstake/views/UnstakeTimelockedObjectsView.tsx b/apps/wallet-dashboard/components/Dialogs/unstake/views/UnstakeTimelockedObjectsView.tsx
index 45e34ee5cf0..7ad5de11f24 100644
--- a/apps/wallet-dashboard/components/Dialogs/unstake/views/UnstakeTimelockedObjectsView.tsx
+++ b/apps/wallet-dashboard/components/Dialogs/unstake/views/UnstakeTimelockedObjectsView.tsx
@@ -4,7 +4,7 @@
import { StakeRewardsPanel, ValidatorStakingData } from '@/components';
import { DialogLayout, DialogLayoutBody, DialogLayoutFooter } from '../../layout';
import { Validator } from '../../Staking/views/Validator';
-import { useNewUnstakeTimelockedTransaction, useNotifications } from '@/hooks';
+import { useNewUnstakeTimelockedTransaction } from '@/hooks';
import {
Collapsible,
TimeUnit,
@@ -24,7 +24,7 @@ import {
} from '@iota/apps-ui-kit';
import { useCurrentAccount, useSignAndExecuteTransaction } from '@iota/dapp-kit';
import { IotaSignAndExecuteTransactionOutput } from '@iota/wallet-standard';
-import { NotificationType } from '@/stores/notificationStore';
+import toast from 'react-hot-toast';
interface UnstakeTimelockedObjectsViewProps {
onClose: () => void;
@@ -39,7 +39,6 @@ export function UnstakeTimelockedObjectsView({
onBack,
onSuccess,
}: UnstakeTimelockedObjectsViewProps) {
- const { addNotification } = useNotifications();
const activeAddress = useCurrentAccount()?.address ?? '';
const { data: activeValidators } = useGetActiveValidatorsInfo();
@@ -71,7 +70,7 @@ export function UnstakeTimelockedObjectsView({
);
function handleCopySuccess() {
- addNotification('Copied to clipboard');
+ toast.success('Copied to clipboard');
}
async function handleUnstake(): Promise {
@@ -83,12 +82,12 @@ export function UnstakeTimelockedObjectsView({
},
{
onSuccess: (tx) => {
- addNotification('Unstake transaction has been sent');
+ toast.success('Unstake transaction has been sent');
onSuccess(tx);
},
},
).catch(() => {
- addNotification('Unstake transaction was not sent', NotificationType.Error);
+ toast.error('Unstake transaction was not sent');
});
}
diff --git a/apps/wallet-dashboard/components/Dialogs/unstake/views/UnstakeView.tsx b/apps/wallet-dashboard/components/Dialogs/unstake/views/UnstakeView.tsx
index 5d07eadcec3..81cad4d6ed6 100644
--- a/apps/wallet-dashboard/components/Dialogs/unstake/views/UnstakeView.tsx
+++ b/apps/wallet-dashboard/components/Dialogs/unstake/views/UnstakeView.tsx
@@ -24,9 +24,9 @@ import { Warning } from '@iota/ui-icons';
import { StakeRewardsPanel, ValidatorStakingData } from '@/components';
import { DialogLayout, DialogLayoutFooter, DialogLayoutBody } from '../../layout';
import { Validator } from '../../Staking/views/Validator';
-import { useNewUnstakeTransaction, useNotifications } from '@/hooks';
+import { useNewUnstakeTransaction } from '@/hooks';
import { IotaSignAndExecuteTransactionOutput } from '@iota/wallet-standard';
-import { NotificationType } from '@/stores/notificationStore';
+import toast from 'react-hot-toast';
interface UnstakeDialogProps {
extendedStake: ExtendedDelegatedStake;
@@ -44,7 +44,6 @@ export function UnstakeView({
showActiveStatus,
}: UnstakeDialogProps): JSX.Element {
const activeAddress = useCurrentAccount()?.address ?? '';
- const { addNotification } = useNotifications();
const { data: unstakeData, isPending: isUnstakeTxPending } = useNewUnstakeTransaction(
activeAddress,
extendedStake.stakedIotaId,
@@ -81,12 +80,12 @@ export function UnstakeView({
},
{
onSuccess: (tx) => {
- addNotification('Unstake transaction has been sent');
+ toast.success('Unstake transaction has been sent');
onSuccess(tx);
},
},
).catch(() => {
- addNotification('Unstake transaction was not sent', NotificationType.Error);
+ toast.error('Unstake transaction was not sent');
});
}
diff --git a/apps/wallet-dashboard/components/Notifications/Notifications.tsx b/apps/wallet-dashboard/components/Notifications/Notifications.tsx
deleted file mode 100644
index 77493b164d9..00000000000
--- a/apps/wallet-dashboard/components/Notifications/Notifications.tsx
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright (c) 2024 IOTA Stiftung
-// SPDX-License-Identifier: Apache-2.0
-
-'use client';
-
-import { useEffect, useState } from 'react';
-
-import {
- NotificationData,
- NotificationType,
- useNotificationStore,
-} from '@/stores/notificationStore';
-
-const ALERT_FADE_OUT_DURATION = 700;
-
-const NOTIFICATION_TYPE_TO_COLOR = {
- [NotificationType.Info]: 'bg-blue-500',
- [NotificationType.Success]: 'bg-green-500',
- [NotificationType.Error]: 'bg-red-500',
- [NotificationType.Warning]: 'bg-yellow-500',
-};
-
-function Notification(props: { notification: NotificationData }): JSX.Element {
- const clearNotification = useNotificationStore((state) => state.clearNotification);
- const [transition, setTransition] = useState('opacity-100');
-
- const { notification } = props;
-
- const bgColor = NOTIFICATION_TYPE_TO_COLOR[notification.type];
-
- useEffect(() => {
- const fadeOutputTimeout = setTimeout(() => {
- setTransition('opacity-0');
- }, notification.duration - ALERT_FADE_OUT_DURATION);
-
- const removeTimeout = setTimeout(() => {
- clearNotification(notification.index);
- }, notification.duration);
-
- return () => {
- clearTimeout(fadeOutputTimeout);
- clearTimeout(removeTimeout);
- };
- }, [notification, clearNotification]);
-
- return (
-
- {notification.message}
-
- );
-}
-
-export default function Notifications(): JSX.Element {
- const notifications = useNotificationStore((state) => state.notifications);
- return (
-
- {notifications.map((notification) => (
-
- ))}
-
- );
-}
diff --git a/apps/wallet-dashboard/components/index.ts b/apps/wallet-dashboard/components/index.ts
index fcccf7b3a95..a20f84675b6 100644
--- a/apps/wallet-dashboard/components/index.ts
+++ b/apps/wallet-dashboard/components/index.ts
@@ -2,7 +2,6 @@
// SPDX-License-Identifier: Apache-2.0
export { default as RouteLink } from './RouteLink';
-export { default as Notifications } from './Notifications/Notifications';
export { default as Box } from './Box';
export { default as AmountBox } from './AmountBox';
export { default as Input } from './Input';
diff --git a/apps/wallet-dashboard/hooks/index.ts b/apps/wallet-dashboard/hooks/index.ts
index 5ad872afeed..b88ba9388b2 100644
--- a/apps/wallet-dashboard/hooks/index.ts
+++ b/apps/wallet-dashboard/hooks/index.ts
@@ -3,7 +3,6 @@
export * from './useNewUnstakeTransaction';
export * from './useNewStakeTransaction';
-export * from './useNotifications';
export * from './useSendCoinTransaction';
export * from './useCreateSendAssetTransaction';
export * from './useGetCurrentEpochStartTimestamp';
diff --git a/apps/wallet-dashboard/hooks/useNotifications.ts b/apps/wallet-dashboard/hooks/useNotifications.ts
deleted file mode 100644
index c5ec455b886..00000000000
--- a/apps/wallet-dashboard/hooks/useNotifications.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-// Copyright (c) 2024 IOTA Stiftung
-// SPDX-License-Identifier: Apache-2.0
-
-import { useNotificationStore } from '@/stores/notificationStore';
-
-export function useNotifications() {
- const addNotification = useNotificationStore((state) => state.addNotification);
- return { addNotification };
-}
diff --git a/apps/wallet-dashboard/stores/notificationStore.ts b/apps/wallet-dashboard/stores/notificationStore.ts
deleted file mode 100644
index 08f48e32d1e..00000000000
--- a/apps/wallet-dashboard/stores/notificationStore.ts
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright (c) 2024 IOTA Stiftung
-// SPDX-License-Identifier: Apache-2.0
-
-import { indexGenerator } from '@/lib/utils';
-import { create } from 'zustand';
-
-const indexGen = indexGenerator(200);
-
-export enum NotificationType {
- Success = 'success',
- Error = 'error',
- Warning = 'warning',
- Info = 'info',
-}
-
-export type NotificationData = {
- index: number;
- message: string;
- type: NotificationType;
- duration: number;
-};
-
-interface NotificationsState {
- notifications: NotificationData[];
- addNotification: (message: string, type?: NotificationType, duration?: number) => void;
- clearNotification: (index: number) => void;
-}
-
-export const useNotificationStore = create()((set) => ({
- notifications: [],
- addNotification: (
- message: string,
- type: NotificationType = NotificationType.Success,
- duration: number = 3000,
- ) =>
- set((state) => {
- const index = indexGen.next().value;
-
- const newNotification: NotificationData = {
- index,
- message,
- type,
- duration,
- };
-
- return {
- notifications: [...state.notifications, newNotification],
- };
- }),
- clearNotification: (index: number) =>
- set((state) => {
- return {
- notifications: [
- ...state.notifications.filter((notification) => notification.index !== index),
- ],
- };
- }),
-}));