diff --git a/frontend/src/components/dashboard/dashboard-view.tsx b/frontend/src/components/dashboard/dashboard-view.tsx
index 3bbc810..5dac949 100644
--- a/frontend/src/components/dashboard/dashboard-view.tsx
+++ b/frontend/src/components/dashboard/dashboard-view.tsx
@@ -15,7 +15,7 @@ import toast from "react-hot-toast";
* - Error state: "Failed to load streams" with a retry button
*/
-import { Skeleton } from "@/components/ui/Skeleton";
+
import {
getDashboardAnalytics,
fetchDashboardData,
@@ -108,8 +108,10 @@ const SIDEBAR_ITEMS: SidebarItem[] = [
/** Shimmer card used as a placeholder while data loads */
function SkeletonCard({ className = "" }: { className?: string }) {
return (
-
-
+
diff --git a/frontend/src/components/stream-creation/StreamCreationWizard.tsx b/frontend/src/components/stream-creation/StreamCreationWizard.tsx
index 55f85fc..f16e9d9 100644
--- a/frontend/src/components/stream-creation/StreamCreationWizard.tsx
+++ b/frontend/src/components/stream-creation/StreamCreationWizard.tsx
@@ -14,6 +14,7 @@ import { fetchTokenBalanceDisplay } from "@/lib/soroban";
import { isValidStellarPublicKey } from "@/lib/stellar";
import toast from "react-hot-toast";
import { useRouter } from "next/navigation";
+import { getApiBaseUrl } from "@/lib/api/_shared";
export interface StreamFormData {
recipient: string;
@@ -349,18 +350,20 @@ export const StreamCreationWizard: React.FC
= ({
const startTime = Date.now();
const TIMEOUT_MS = 30000; // 30 seconds
const POLL_INTERVAL = 2000; // 2 seconds
+ const baseUrl = getApiBaseUrl();
while (Date.now() - startTime < TIMEOUT_MS) {
try {
- const response = await fetch(`/v1/streams?sender=${senderAddress}`);
- const streams = await response.json();
+ const response = await fetch(`${baseUrl}/v1/streams?sender=${senderAddress}`);
+ const payload = await response.json();
+ const streams = Array.isArray(payload) ? payload : (payload.data ?? []);
// Assuming the latest stream is what we want
if (streams && streams.length > 0) {
// Found!
const newStream = streams[0]; // Simplification
toast.success("Stream indexed and confirmed!");
- router.push(`/app/streams/${newStream.streamId}`); // Updated path to match new structure
+ router.push(`/streams/${newStream.streamId}`); // Updated path to match new structure
return;
}
} catch (e) {
@@ -384,7 +387,7 @@ export const StreamCreationWizard: React.FC = ({
// Step 2: Start Polling for Indexer
setIsPolling(true);
- await startPolling(formData.recipient);
+ await startPolling(walletPublicKey || "");
} catch (error) {
logger.error("Failed to create stream:", error);
diff --git a/frontend/src/hooks/useIncomingStreams.ts b/frontend/src/hooks/useIncomingStreams.ts
index dc36dc3..ace4dbb 100644
--- a/frontend/src/hooks/useIncomingStreams.ts
+++ b/frontend/src/hooks/useIncomingStreams.ts
@@ -49,9 +49,7 @@ export function useWithdrawIncomingStream(
});
},
onMutate: async (stream) => {
- if (!publicKey) {
- return {};
- }
+ if (!publicKey) return { previousStreams: undefined, expectedWithdrawn: stream.withdrawn };
// Cancel any outgoing refetches (so they don't overwrite our optimistic update)
await queryClient.cancelQueries({
@@ -97,11 +95,7 @@ export function useWithdrawIncomingStream(
},
onSuccess: async (result, stream, _variables, context) => {
if (publicKey) {
- const ctx = context as {
- previousStreams?: IncomingStreamRecord[];
- expectedWithdrawn?: number;
- };
- const targetWithdrawn = ctx.expectedWithdrawn ?? stream.withdrawn;
+ const targetWithdrawn = (context as { expectedWithdrawn?: number })?.expectedWithdrawn ?? stream.withdrawn;
// Start polling in the background without blocking the mutation
pollIndexerForWithdraw(
publicKey,
diff --git a/frontend/vitest.config.mts b/frontend/vitest.config.mts
index 2e94271..1e79ea1 100644
--- a/frontend/vitest.config.mts
+++ b/frontend/vitest.config.mts
@@ -3,6 +3,7 @@ import react from '@vitejs/plugin-react';
import path from 'path';
export default defineConfig({
+ // @ts-expect-error type mismatch between vite versions in monorepo
plugins: [react()],
resolve: {
alias: {