diff --git a/frontend/src/app/settings/page.tsx b/frontend/src/app/settings/page.tsx
index 00c3b4d..bd6f479 100644
--- a/frontend/src/app/settings/page.tsx
+++ b/frontend/src/app/settings/page.tsx
@@ -1,20 +1,26 @@
 "use client";
 
 import { useState, useEffect } from "react";
-import { Copy, Check, LogOut, Moon, Sun, Bell } from "lucide-react";
+import { Copy, Check, LogOut, Moon, Sun, Bell, Globe } from "lucide-react";
 import { useWallet } from "@/context/wallet-context";
 import { useRouter } from "next/navigation";
 import { shortenPublicKey, formatNetwork } from "@/lib/wallet";
+import toast from "react-hot-toast";
+
+type DisplayCurrency = "USD" | "XLM" | "USDC";
+type AmountFormat = "full" | "compact";
 
 export default function SettingsPage() {
   const router = useRouter();
   const { session, disconnect, isHydrated } = useWallet();
-  const [emailNotifications, setEmailNotifications] = useState(true);
-  const [theme, setTheme] = useState<"light" | "dark">(() => {
+
+  const [browserPush, setBrowserPush] = useState(false);
+  const [theme, setTheme] = useState<"light" | "dark" | "system">(() => {
     if (typeof window !== "undefined") {
       const saved = localStorage.getItem("flowfi-theme") as
         | "light"
         | "dark"
+        | "system"
         | null;
       if (saved) {
         document.documentElement.classList.toggle("dark", saved === "dark");
@@ -23,31 +29,66 @@ export default function SettingsPage() {
     }
     return "dark";
   });
+
+  const [displayCurrency, setDisplayCurrency] = useState<DisplayCurrency>(() => {
+    if (typeof window !== "undefined") {
+      return (localStorage.getItem("flowfi-currency") as DisplayCurrency) || "USD";
+    }
+    return "USD";
+  });
+
+  const [amountFormat, setAmountFormat] = useState<AmountFormat>(() => {
+    if (typeof window !== "undefined") {
+      return (localStorage.getItem("flowfi-amount-format") as AmountFormat) || "full";
+    }
+    return "full";
+  });
+
   const [copied, setCopied] = useState(false);
 
-  const toggleTheme = () => {
-    const next = theme === "dark" ? "light" : "dark";
-    setTheme(next);
-    localStorage.setItem("flowfi-theme", next);
-    document.documentElement.classList.toggle(
-      "dark",
-      next === "dark"
-    );
+  const toggleTheme = (newTheme: "light" | "dark" | "system") => {
+    setTheme(newTheme);
+    localStorage.setItem("flowfi-theme", newTheme);
+    if (newTheme === "system") {
+      const prefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches;
+      document.documentElement.classList.toggle("dark", prefersDark);
+    } else {
+      document.documentElement.classList.toggle("dark", newTheme === "dark");
+    }
   };
 
   const copyAddress = async () => {
     if (session?.publicKey) {
       await navigator.clipboard.writeText(session.publicKey);
       setCopied(true);
+      toast.success("Address copied to clipboard");
       setTimeout(() => setCopied(false), 1500);
     }
   };
 
   const handleDisconnect = () => {
     disconnect();
+    toast.success("Wallet disconnected");
     router.push("/");
   };
 
+  const handleBrowserPushToggle = async () => {
+    if (!browserPush) {
+      try {
+        await Notification.requestPermission();
+        setBrowserPush(Notification.permission === "granted");
+        if (Notification.permission === "granted") {
+          toast.success("Browser notifications enabled");
+        }
+      } catch {
+        toast.error("Failed to enable notifications");
+      }
+    } else {
+      setBrowserPush(false);
+      toast("Browser notifications disabled");
+    }
+  };
+
   if (!isHydrated) {
     return (
       <div className="relative min-h-screen overflow-hidden bg-gradient-to-br from-zinc-950 via-zinc-900 to-black dark:from-white dark:via-gray-100 dark:to-gray-200 transition-colors flex items-center justify-center">
@@ -68,14 +109,14 @@ export default function SettingsPage() {
 
           <div>
             <h1 className="text-3xl font-semibold tracking-tight text-white dark:text-black">
-              Profile Settings
+              Settings
             </h1>
             <p className="text-sm opacity-60 mt-1">
-              Manage your FlowFi experience
+              Manage your FlowFi preferences
             </p>
           </div>
 
-          {/* Email Notifications */}
+          {/* Browser Push Notifications */}
           <div className="flex items-center justify-between group">
             <div className="flex items-center gap-3">
               <div className="p-2 rounded-lg bg-purple-500/20 text-purple-400">
@@ -83,27 +124,25 @@ export default function SettingsPage() {
               </div>
               <div>
                 <p className="font-medium text-white dark:text-black">
-                  Email Notifications
+                  Browser Notifications
                 </p>
                 <p className="text-sm opacity-60">
-                  Get notified about activity
+                  Get notified about stream activity
                 </p>
               </div>
             </div>
 
             <button
-              onClick={() =>
-                setEmailNotifications(!emailNotifications)
-              }
+              onClick={handleBrowserPushToggle}
               className={`relative w-14 h-7 rounded-full transition-all duration-300 ${
-                emailNotifications
+                browserPush
                   ? "bg-gradient-to-r from-purple-500 to-blue-500"
                   : "bg-zinc-600"
               }`}
             >
               <span
                 className={`absolute top-1 left-1 w-5 h-5 bg-white rounded-full shadow-md transform transition duration-300 ${
-                  emailNotifications
+                  browserPush
                     ? "translate-x-7"
                     : "translate-x-0"
                 }`}
@@ -112,27 +151,94 @@ export default function SettingsPage() {
           </div>
 
           {/* Theme Toggle */}
-          <div className="flex items-center justify-between">
+          <div className="space-y-4">
             <div className="flex items-center gap-3">
               <div className="p-2 rounded-lg bg-blue-500/20 text-blue-400">
-                {theme === "dark" ? <Moon size={18} /> : <Sun size={18} />}
+                {theme === "dark" ? <Moon size={18} /> : theme === "light" ? <Sun size={18} /> : <Globe size={18} />}
               </div>
               <div>
                 <p className="font-medium text-white dark:text-black">
                   Appearance
                 </p>
                 <p className="text-sm opacity-60">
-                  Toggle dark & light mode
+                  Choose your theme preference
                 </p>
               </div>
             </div>
 
-            <button
-              onClick={toggleTheme}
-              className="px-4 py-2 text-sm rounded-xl border border-white/10 dark:border-black/10 hover:scale-105 transition-transform text-white dark:text-black"
-            >
-              {theme === "dark" ? "Light Mode" : "Dark Mode"}
-            </button>
+            <div className="flex gap-2">
+              {(["light", "dark", "system"] as const).map((t) => (
+                <button
+                  key={t}
+                  onClick={() => toggleTheme(t)}
+                  className={`px-4 py-2 text-sm rounded-xl border transition-all ${
+                    theme === t
+                      ? "border-purple-500 bg-purple-500/20 text-white"
+                      : "border-white/10 dark:border-black/10 text-white/60 dark:text-black/60 hover:border-white/20"
+                  }`}
+                >
+                  {t.charAt(0).toUpperCase() + t.slice(1)}
+                </button>
+              ))}
+            </div>
+          </div>
+
+          {/* Display Preferences */}
+          <div className="space-y-4">
+            <div className="flex items-center gap-3">
+              <div className="p-2 rounded-lg bg-green-500/20 text-green-400">
+                <Globe size={18} />
+              </div>
+              <div>
+                <p className="font-medium text-white dark:text-black">
+                  Display Preferences
+                </p>
+                <p className="text-sm opacity-60">
+                  Customize how amounts are displayed
+                </p>
+              </div>
+            </div>
+
+            <div className="space-y-3 pl-12">
+              <div>
+                <label className="text-sm text-white/60 dark:text-black/60">Default Token</label>
+                <select
+                  value={displayCurrency}
+                  onChange={(e) => {
+                    const val = e.target.value as DisplayCurrency;
+                    setDisplayCurrency(val);
+                    localStorage.setItem("flowfi-currency", val);
+                  }}
+                  className="mt-1 block w-full px-3 py-2 rounded-lg bg-black/40 dark:bg-white/40 border border-white/10 dark:border-black/10 text-white dark:text-black text-sm"
+                >
+                  <option value="USD">USD</option>
+                  <option value="XLM">XLM</option>
+                  <option value="USDC">USDC</option>
+                </select>
+              </div>
+
+              <div>
+                <label className="text-sm text-white/60 dark:text-black/60">Amount Format</label>
+                <div className="flex gap-2 mt-1">
+                  {(["full", "compact"] as const).map((fmt) => (
+                    <button
+                      key={fmt}
+                      onClick={() => {
+                        setAmountFormat(fmt);
+                        localStorage.setItem("flowfi-amount-format", fmt);
+                      }}
+                      className={`px-3 py-1.5 text-xs rounded-lg border transition-all ${
+                        amountFormat === fmt
+                          ? "border-blue-500 bg-blue-500/20 text-white"
+                          : "border-white/10 text-white/60 hover:border-white/20"
+                      }`}
+                    >
+                      {fmt === "full" ? "Full (1.0000000)" : "Compact (1.0)"}
+                    </button>
+                  ))}
+                </div>
+              </div>
+            </div>
           </div>
 
           {/* Wallet Section */}
@@ -202,4 +308,4 @@ export default function SettingsPage() {
       </div>
     </div>
   );
-}
\ No newline at end of file
+}
diff --git a/frontend/src/components/Dashboard.tsx b/frontend/src/components/Dashboard.tsx
index ec9d035..1d4f862 100644
--- a/frontend/src/components/Dashboard.tsx
+++ b/frontend/src/components/Dashboard.tsx
@@ -4,6 +4,8 @@ import { fetchUserEvents } from '@/lib/dashboard';
 import { useWallet } from '@/context/wallet-context';
 import { BackendStreamEvent } from '@/lib/api-types';
 import { downloadCSV } from '@/utils/csvExport';
+import toast from 'react-hot-toast';
+import { fromStroops } from '@/utils/amount';
 
 interface StreamData extends Record<string, unknown> {
     id: string;
@@ -44,6 +46,7 @@ const Dashboard: React.FC = () => {
             setEvents(data);
         } catch (error) {
             console.error(error);
+            toast.error('Failed to load activity events');
         } finally {
             setIsLoadingEvents(false);
         }
@@ -51,6 +54,7 @@ const Dashboard: React.FC = () => {
 
     const handleExport = () => {
         downloadCSV(mockStreams, 'flowfi-stream-history.csv');
+        toast.success('CSV exported successfully!');
     };
 
     const handleTopUp = (streamId: string) => {
@@ -58,7 +62,7 @@ const Dashboard: React.FC = () => {
         if (amount && parseFloat(amount) > 0) {
             console.log(`Adding ${amount} funds to stream ${streamId}`);
             // TODO: Integrate with Soroban contract's top_up_stream function
-            alert(`Successfully added ${amount} to stream ${streamId}`);
+            toast.success(`Successfully added ${amount} to stream ${streamId}`);
         }
     };
 
@@ -108,14 +112,14 @@ const Dashboard: React.FC = () => {
                                 <tr key={stream.id} className="hover:bg-gray-50 dark:hover:bg-gray-700/50 transition-colors">
                                     <td className="px-6 py-4 whitespace-nowrap text-sm text-gray-900 dark:text-gray-100">{stream.date}</td>
                                     <td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-400 font-mono">{stream.recipient}</td>
-                                    <td className="px-6 py-4 whitespace-nowrap text-sm text-gray-900 dark:text-gray-100 font-semibold">{stream.deposited} {stream.token}</td>
-                                    <td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-400">{stream.withdrawn} {stream.token}</td>
+                                    <td className="px-6 py-4 whitespace-nowrap text-sm text-gray-900 dark:text-gray-100 font-semibold">{fromStroops(BigInt(stream.deposited), 7)} {stream.token}</td>
+                                    <td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-400">{fromStroops(BigInt(stream.withdrawn), 7)} {stream.token}</td>
                                     <td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-400">{stream.token}</td>
                                     <td className="px-6 py-4 whitespace-nowrap text-sm">
                                         <span className={`px-2 inline-flex text-xs leading-5 font-semibold rounded-full
-                        ${stream.status === 'Active' ? 'bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200' :
-                                                stream.status === 'Completed' ? 'bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-200' :
-                                                    'bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-200'}`}>
+                            ${stream.status === 'Active' ? 'bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200' :
+                                            stream.status === 'Completed' ? 'bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-200' :
+                                                'bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-200'}`}>
                                             {stream.status}
                                         </span>
                                     </td>
@@ -135,7 +139,21 @@ const Dashboard: React.FC = () => {
                     </table>
                 </div>
             ) : (
-                <ActivityHistory events={events} isLoading={isLoadingEvents} />
+                <>
+                    {isLoadingEvents ? (
+                        <div className="space-y-4">
+                            {[1, 2, 3].map((i) => (
+                                <div key={i} className="animate-pulse bg-white dark:bg-gray-800 shadow rounded-lg p-6">
+                                    <div className="h-4 bg-gray-200 dark:bg-gray-700 rounded w-1/4 mb-4"></div>
+                                    <div className="h-3 bg-gray-200 dark:bg-gray-700 rounded w-full mb-2"></div>
+                                    <div className="h-3 bg-gray-200 dark:bg-gray-700 rounded w-3/4"></div>
+                                </div>
+                            ))}
+                        </div>
+                    ) : (
+                        <ActivityHistory events={events} isLoading={isLoadingEvents} />
+                    )}
+                </>
             )}
         </div>
     );
diff --git a/frontend/src/components/IncomingStreams.tsx b/frontend/src/components/IncomingStreams.tsx
index 7917645..eedcdeb 100644
--- a/frontend/src/components/IncomingStreams.tsx
+++ b/frontend/src/components/IncomingStreams.tsx
@@ -3,6 +3,8 @@
 import React, { useState } from 'react';
 import type { Stream } from '@/lib/dashboard';
 import { useStreamingAmount } from '@/hooks/useStreamingAmount';
+import toast from 'react-hot-toast';
+import { fromStroops } from '@/utils/amount';
 
 interface IncomingStreamsProps {
     streams: Stream[];
@@ -10,13 +12,9 @@ interface IncomingStreamsProps {
     withdrawingStreamId?: string | null;
 }
 
-function formatTokenAmount(value: number): string {
-    if (!Number.isFinite(value)) return '0.0000';
-
-    return new Intl.NumberFormat('en-US', {
-        minimumFractionDigits: 4,
-        maximumFractionDigits: 4,
-    }).format(value);
+function formatTokenAmount(value: number, decimals: number = 7): string {
+    if (!Number.isFinite(value)) return '0.0000000';
+    return fromStroops(BigInt(Math.floor(value)), decimals);
 }
 
 const ClaimableAmount: React.FC<{ stream: Stream }> = ({ stream }) => {
@@ -62,6 +60,15 @@ const IncomingStreams: React.FC<IncomingStreamsProps> = ({
         setFilter(e.target.value as 'All' | 'Active' | 'Completed' | 'Paused');
     };
 
+    const handleWithdraw = async (stream: Stream) => {
+        try {
+            await onWithdraw(stream);
+            toast.success(`Successfully withdrew from stream #${stream.id}`);
+        } catch (error) {
+            toast.error(`Failed to withdraw from stream #${stream.id}`);
+        }
+    };
+
     return (
         <div className="bg-white/40 dark:bg-slate-900/40 backdrop-blur-md rounded-2xl border border-white/20 dark:border-white/10 shadow-xl overflow-hidden">
             <div className="p-6 border-b border-white/20 dark:border-white/10 flex flex-col md:flex-row md:items-center justify-between gap-4">
@@ -128,7 +135,7 @@ const IncomingStreams: React.FC<IncomingStreamsProps> = ({
                                         <button
                                             disabled={stream.status !== 'Active' || withdrawingStreamId === stream.id}
                                             onClick={() => {
-                                                void onWithdraw(stream);
+                                                void handleWithdraw(stream);
                                             }}
                                             className={`px-4 py-2 rounded-lg transition-all ${stream.status === 'Active'
                                                     ? 'bg-accent text-white hover:bg-accent-hover shadow-lg'
diff --git a/frontend/src/components/TransactionTracker.tsx b/frontend/src/components/TransactionTracker.tsx
new file mode 100644
index 0000000..5b54145
--- /dev/null
+++ b/frontend/src/components/TransactionTracker.tsx
@@ -0,0 +1,152 @@
+"use client";
+
+import { useEffect, useState } from "react";
+import { Loader2, CheckCircle, XCircle, ExternalLink, RefreshCw } from "lucide-react";
+import toast from "react-hot-toast";
+
+export type TransactionStatus =
+  | "idle"
+  | "signing"
+  | "submitted"
+  | "confirming"
+  | "confirmed"
+  | "failed";
+
+interface TransactionTrackerProps {
+  status: TransactionStatus;
+  txHash?: string;
+  error?: string;
+  onRetry?: () => void;
+  streamId?: string;
+  pollInterval?: number;
+}
+
+const STELLAR_EXPERT_BASE =
+  "https://stellar.expert/explorer/testnet/tx";
+
+export default function TransactionTracker({
+  status,
+  txHash,
+  error,
+  onRetry,
+  streamId,
+  pollInterval = 2000,
+}: TransactionTrackerProps) {
+  const [confirming, setConfirming] = useState(false);
+
+  useEffect(() => {
+    if (status !== "submitted" || !streamId) return;
+
+    let cancelled = false;
+    setConfirming(true);
+
+    async function poll() {
+      try {
+        const res = await fetch(`/v1/streams/${streamId}`);
+        if (!res.ok) throw new Error("Failed to fetch stream status");
+
+        const data = await res.json();
+        if (data.confirmed && !cancelled) {
+          toast.success("Transaction confirmed!");
+          setConfirming(false);
+          return;
+        }
+      } catch (err) {
+        if (!cancelled) {
+          console.error("Polling error:", err);
+        }
+      }
+
+      if (!cancelled) {
+        setTimeout(poll, pollInterval);
+      }
+    }
+
+    poll();
+    return () => {
+      cancelled = true;
+    };
+  }, [status, streamId, pollInterval]);
+
+  if (status === "idle" || status === "signing") {
+    return (
+      <div className="flex items-center gap-2 text-sm text-gray-400">
+        {status === "signing" && (
+          <>
+            <Loader2 className="h-4 w-4 animate-spin" />
+            <span>Signing transaction...</span>
+          </>
+        )}
+      </div>
+    );
+  }
+
+  if (status === "submitted") {
+    return (
+      <div className="rounded-xl border border-white/10 bg-white/5 p-4 space-y-3">
+        <div className="flex items-center gap-2 text-yellow-400">
+          <Loader2 className="h-4 w-4 animate-spin" />
+          <span className="font-medium">Transaction Submitted</span>
+        </div>
+
+        {txHash && (
+          <a
+            href={`${STELLAR_EXPERT_BASE}/${txHash}`}
+            target="_blank"
+            rel="noopener noreferrer"
+            className="flex items-center gap-1 text-sm text-blue-400 hover:text-blue-300 transition"
+          >
+            View on Stellar Expert
+            <ExternalLink className="h-3 w-3" />
+          </a>
+        )}
+
+        {confirming && (
+          <p className="text-xs text-gray-400">
+            Waiting for confirmation...
+          </p>
+        )}
+      </div>
+    );
+  }
+
+  if (status === "confirmed") {
+    return (
+      <div className="rounded-xl border border-green-500/20 bg-green-500/10 p-4">
+        <div className="flex items-center gap-2 text-green-400">
+          <CheckCircle className="h-5 w-5" />
+          <span className="font-medium">Transaction Confirmed</span>
+        </div>
+      </div>
+    );
+  }
+
+  if (status === "failed") {
+    return (
+      <div className="rounded-xl border border-red-500/20 bg-red-500/10 p-4 space-y-3">
+        <div className="flex items-center gap-2 text-red-400">
+          <XCircle className="h-5 w-5" />
+          <span className="font-medium">Transaction Failed</span>
+        </div>
+
+        {error && (
+          <p className="text-sm text-red-300 bg-red-500/10 p-2 rounded-lg">
+            {error}
+          </p>
+        )}
+
+        {onRetry && (
+          <button
+            onClick={onRetry}
+            className="flex items-center gap-2 text-sm px-4 py-2 rounded-lg bg-red-500/20 text-red-400 hover:bg-red-500/30 transition"
+          >
+            <RefreshCw className="h-4 w-4" />
+            Retry Transaction
+          </button>
+        )}
+      </div>
+    );
+  }
+
+  return null;
+}
diff --git a/frontend/src/components/dashboard/ActivityHistory.tsx b/frontend/src/components/dashboard/ActivityHistory.tsx
index 480e8eb..0dc05a6 100644
--- a/frontend/src/components/dashboard/ActivityHistory.tsx
+++ b/frontend/src/components/dashboard/ActivityHistory.tsx
@@ -1,5 +1,7 @@
 import React from 'react';
 import { BackendStreamEvent } from '@/lib/api-types';
+import { fromStroops } from '@/utils/amount';
+import TransactionTracker from '@/components/TransactionTracker';
 
 interface ActivityHistoryProps {
     events: BackendStreamEvent[];
@@ -8,7 +10,7 @@ interface ActivityHistoryProps {
 
 export const ActivityHistory: React.FC<ActivityHistoryProps> = ({ events, isLoading }) => {
     const formatEventMessage = (event: BackendStreamEvent) => {
-        const amount = event.amount ? parseFloat(event.amount) / 1e7 : 0;
+        const amount = event.amount ? fromStroops(BigInt(event.amount), 7) : '0';
         const streamId = event.streamId;
 
         switch (event.eventType) {
@@ -29,8 +31,13 @@ export const ActivityHistory: React.FC<ActivityHistoryProps> = ({ events, isLoad
 
     if (isLoading) {
         return (
-            <div className="flex justify-center items-center py-8">
-                <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-accent"></div>
+            <div className="space-y-4">
+                {[1, 2, 3].map((i) => (
+                    <div key={i} className="animate-pulse p-4 bg-white/5 border border-glass-border rounded-xl">
+                        <div className="h-4 bg-gray-200 dark:bg-gray-700 rounded w-3/4 mb-2"></div>
+                        <div className="h-3 bg-gray-200 dark:bg-gray-700 rounded w-1/2"></div>
+                    </div>
+                ))}
             </div>
         );
     }
@@ -58,6 +65,15 @@ export const ActivityHistory: React.FC<ActivityHistoryProps> = ({ events, isLoad
                             {event.eventType}
                         </div>
                     </div>
+                    {(event.txHash || event.transactionStatus) && (
+                        <div className="mt-3">
+                            <TransactionTracker
+                                status={event.transactionStatus || 'confirmed'}
+                                txHash={event.txHash}
+                                streamId={event.streamId}
+                            />
+                        </div>
+                    )}
                 </div>
             ))}
         </div>
diff --git a/frontend/src/components/stream-creation/CancelConfirmModal.tsx b/frontend/src/components/stream-creation/CancelConfirmModal.tsx
index 7b53cf3..ad7d615 100644
--- a/frontend/src/components/stream-creation/CancelConfirmModal.tsx
+++ b/frontend/src/components/stream-creation/CancelConfirmModal.tsx
@@ -10,6 +10,7 @@
 
 import React, { useEffect, useState } from "react";
 import { Button } from "@/components/ui/Button";
+import toast from "react-hot-toast";
 
 interface CancelConfirmModalProps {
   streamId: string;
@@ -47,8 +48,9 @@ export const CancelConfirmModal: React.FC<CancelConfirmModalProps> = ({
     setIsSubmitting(true);
     try {
       await onConfirm(streamId);
+      toast.success(`Stream ${streamId} cancelled successfully`);
     } catch {
-      // Errors are handled upstream (toast in dashboard-view)
+      toast.error("Failed to cancel stream. Please try again.");
       setIsSubmitting(false);
     }
   };
diff --git a/frontend/src/components/stream-creation/StreamCreationWizard.tsx b/frontend/src/components/stream-creation/StreamCreationWizard.tsx
index 2e82018..18de64c 100644
--- a/frontend/src/components/stream-creation/StreamCreationWizard.tsx
+++ b/frontend/src/components/stream-creation/StreamCreationWizard.tsx
@@ -9,6 +9,7 @@ import { ScheduleStep } from "./ScheduleStep";
 import { TemplateStep, type StreamTemplate } from "./TemplateStep";
 import { fetchTokenBalanceDisplay } from "@/lib/soroban";
 import { isValidStellarPublicKey } from "@/lib/stellar";
+import toast from "react-hot-toast";
 
 export interface StreamFormData {
   recipient: string;
@@ -313,9 +314,10 @@ export const StreamCreationWizard: React.FC<StreamCreationWizardProps> = ({
       setIsSubmitting(true);
       try {
         await onSubmit(formData);
+        toast.success("Stream created successfully!");
       } catch (error) {
         console.error("Failed to create stream:", error);
-        // Error handling can be added here (e.g., toast notification)
+        toast.error("Failed to create stream. Please try again.");
         setIsSubmitting(false);
       }
     } else {
diff --git a/frontend/src/components/stream-creation/TopUpModal.tsx b/frontend/src/components/stream-creation/TopUpModal.tsx
index 3065cd5..ad6a0b4 100644
--- a/frontend/src/components/stream-creation/TopUpModal.tsx
+++ b/frontend/src/components/stream-creation/TopUpModal.tsx
@@ -9,6 +9,7 @@
 
 import React, { useRef, useEffect, useState } from "react";
 import { Button } from "@/components/ui/Button";
+import toast from "react-hot-toast";
 
 interface TopUpModalProps {
   streamId: string;
@@ -56,9 +57,9 @@ export const TopUpModal: React.FC<TopUpModalProps> = ({
     setIsSubmitting(true);
     try {
       await onConfirm(streamId, amount);
-      // onConfirm is responsible for closing + toasting on success
+      toast.success(`Successfully added ${amount} ${token} to stream`);
     } catch {
-      // Errors are handled upstream (toast in dashboard-view)
+      toast.error("Failed to top up stream. Please try again.");
       setIsSubmitting(false);
     }
   };
diff --git a/frontend/src/utils/amount.ts b/frontend/src/utils/amount.ts
new file mode 100644
index 0000000..275fa68
--- /dev/null
+++ b/frontend/src/utils/amount.ts
@@ -0,0 +1,95 @@
+/**
+ * Convert raw on-chain amount (stroops/smallest unit) to human-readable string
+ */
+export function fromStroops(amount: bigint, decimals: number): string {
+  if (decimals === 0) return amount.toString();
+
+  const factor = 10n ** BigInt(decimals);
+  const integerPart = amount / factor;
+  const fractionalPart = amount % factor;
+
+  const fractionalStr = fractionalPart.toString().padStart(decimals, "0");
+  const trimmedFractional = fractionalStr.replace(/0+$/, "");
+
+  if (!trimmedFractional) return integerPart.toString();
+  return `${integerPart}.${trimmedFractional}`;
+}
+
+/**
+ * Convert human-readable amount to raw on-chain amount (stroops/smallest unit)
+ */
+export function toStroops(amount: string, decimals: number): bigint {
+  const trimmed = amount.trim();
+  if (!trimmed) return 0n;
+
+  const parts = trimmed.split(".");
+  const integerPart = parts[0] || "0";
+  let fractionalPart = parts[1] || "";
+
+  if (fractionalPart.length > decimals) {
+    fractionalPart = fractionalPart.slice(0, decimals);
+  } else if (fractionalPart.length < decimals) {
+    fractionalPart = fractionalPart.padEnd(decimals, "0");
+  }
+
+  const factor = 10n ** BigInt(decimals);
+  return BigInt(integerPart) * factor + BigInt(fractionalPart);
+}
+
+/**
+ * Format stream rate as human-readable string (e.g., "0.0001 USDC/sec")
+ */
+export function formatStreamRate(
+  ratePerSecond: bigint,
+  decimals: number,
+  tokenSymbol: string = "USDC"
+): string {
+  const perSecond = fromStroops(ratePerSecond, decimals);
+  const perMonth = fromStroops(ratePerSecond * 60n * 60n * 24n * 30n, decimals);
+
+  return `${perSecond} ${tokenSymbol}/sec (${perMonth} ${tokenSymbol}/month)`;
+}
+
+/**
+ * Validate that amount string doesn't exceed decimal precision
+ */
+export function hasValidPrecision(amount: string, decimals: number): boolean {
+  if (!amount) return true;
+
+  const parts = amount.split(".");
+  if (parts.length === 0 || parts.length > 2) return false;
+
+  const fractionalPart = parts[1];
+  if (fractionalPart && fractionalPart.length > decimals) return false;
+
+  return true;
+}
+
+/**
+ * Cache for token decimals to avoid repeated contract calls
+ */
+const tokenDecimalsCache = new Map<string, number>();
+
+/**
+ * Get and cache token decimals for a given token address
+ */
+export function getCachedTokenDecimals(tokenAddress: string): number | undefined {
+  return tokenDecimalsCache.get(tokenAddress);
+}
+
+/**
+ * Set token decimals in cache
+ */
+export function setCachedTokenDecimals(
+  tokenAddress: string,
+  decimals: number
+): void {
+  tokenDecimalsCache.set(tokenAddress, decimals);
+}
+
+/**
+ * Clear token decimals cache
+ */
+export function clearTokenDecimalsCache(): void {
+  tokenDecimalsCache.clear();
+}
