Skip to content

Commit b3a7355

Browse files
committed
Unify transaction toast notifications (issue #5)
- Fix error toasts auto-dismissing; now require manual dismissal per acceptance criteria - Add notifyTxSuccessLocal for success states without a real tx hash - Migrate SwapCard.tsx off raw sonner calls to unified TxToasts helpers
1 parent 0f88718 commit b3a7355

3 files changed

Lines changed: 21 additions & 4 deletions

File tree

components/TxToasts.test.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,11 @@ describe('notifyTxError / notifyTxPending', () => {
106106
expect(toastMock.error.mock.calls[0][1].description).toBe('User rejected');
107107
});
108108

109+
it('notifyTxError requires manual dismissal (duration: Infinity)', () => {
110+
notifyTxError('User rejected');
111+
expect(toastMock.error.mock.calls[0][1].duration).toBe(Infinity);
112+
});
113+
109114
it('notifyTxPending shows a loading toast', () => {
110115
notifyTxPending();
111116
expect(toastMock.loading).toHaveBeenCalledTimes(1);

components/TxToasts.tsx

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ export function notifyTx(
4646
}
4747

4848
return toast.error(t('txToasts.failed', 'Transaction failed'), {
49-
description: opts.chain ? undefined : undefined,
49+
duration: Infinity,
5050
});
5151
}
5252

@@ -70,10 +70,22 @@ export function notifyTxSuccess(txHash: Hash, chain?: Chain, onSuccess?: () => v
7070
onSuccess?.();
7171
}
7272

73+
/**
74+
* Convenience: success toast with unified styling but no explorer link,
75+
* for actions that succeed without producing an on-chain tx hash yet.
76+
*/
77+
export function notifyTxSuccessLocal(message: string) {
78+
toast.success(t('txToasts.sent', 'Transaction sent'), {
79+
description: message,
80+
duration: 5000,
81+
});
82+
}
83+
7384
/** Convenience: error toast with a user-safe message. */
7485
export function notifyTxError(message: string) {
7586
toast.error(t('txToasts.failed', 'Transaction failed'), {
7687
description: message || t('txToasts.rejected', 'The transaction was rejected or failed.'),
88+
duration: Infinity,
7789
});
7890
}
7991

components/swap/SwapCard.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { ArrowDownUp, RefreshCw } from 'lucide-react';
55
import { KNOWN_TOKENS } from '@/lib/services/RouteOptimizer';
66
import { useRouteOptimizer } from '@/lib/hooks/useRouteOptimizer';
77
import { SwapRouteDisplay } from './SwapRouteDisplay';
8-
import { toast } from 'sonner';
8+
import { notifyTxError, notifyTxSuccessLocal } from '@/components/TxToasts';
99

1010
export function SwapCard() {
1111
const [tokenInSymbol, setTokenInSymbol] = useState('USDC');
@@ -49,11 +49,11 @@ export function SwapCard() {
4949

5050
const handleExecuteSwap = () => {
5151
if (!route) {
52-
toast.error('No valid route available for swap');
52+
notifyTxError('No valid route available for swap');
5353
return;
5454
}
5555

56-
toast.success(
56+
notifyTxSuccessLocal(
5757
`Swapped ${amountInStr} ${tokenInSymbol} for ~${formatOutput()} ${tokenOutSymbol} via ${
5858
route.hops.length > 1 ? 'multi-hop route' : 'direct route'
5959
}`

0 commit comments

Comments
 (0)