diff --git a/backend/src/index.ts b/backend/src/index.ts index f7a15ec..c58acbe 100644 --- a/backend/src/index.ts +++ b/backend/src/index.ts @@ -158,6 +158,12 @@ app.get("/api/assets", (_req: Request, res: Response) => { }); }); +app.get("/api/config", (_req: Request, res: Response) => { + res.json({ + allowedAssets: ALLOWED_ASSETS, + }); +}); + app.get("/api/streams", (req: Request, res: Response) => { const parsedQuery = listStreamsQuerySchema.safeParse(req.query); if (!parsedQuery.success) { diff --git a/frontend/src/components/CreateStreamForm.tsx b/frontend/src/components/CreateStreamForm.tsx index 2b0e230..f26945d 100644 --- a/frontend/src/components/CreateStreamForm.tsx +++ b/frontend/src/components/CreateStreamForm.tsx @@ -1,4 +1,5 @@ -import { useState, FormEvent } from "react"; +import { useState, useEffect, FormEvent } from "react"; +import { getConfig } from "../services/api"; // Form Draft Autosave [Verified]: Survives refresh, clears on submit/discard, aligns with fields. import { useDraftAutosave } from "../hooks/useDraftAutosave"; import { CreateStreamPayload } from "../types/stream"; @@ -105,7 +106,8 @@ const INITIAL_VALUES: FormValues = { startInMinutes: "0", }; -const allowedAssets = ["USDC", "XLM", "BTC"]; // example allowed assets +// Initial fallback if fetch hasn't completed or failed +const DEFAULT_ALLOWED_ASSETS = ["USDC", "XLM"]; export function CreateStreamForm({ onCreate, @@ -116,6 +118,33 @@ export function CreateStreamForm({ "stellar-stream:create-draft", INITIAL_VALUES ); + const [allowedAssets, setAllowedAssets] = useState([]); + const [configFetchFailed, setConfigFetchFailed] = useState(false); + + useEffect(() => { + async function fetchConfig() { + try { + const config = await getConfig(); + setAllowedAssets(config.allowedAssets); + + // Handle defaulting logic + const currentAsset = values.assetCode; + const isCurrentValid = config.allowedAssets.includes(currentAsset); + + if (!isCurrentValid) { + if (config.allowedAssets.includes("USDC")) { + setValues(prev => ({ ...prev, assetCode: "USDC" })); + } else if (config.allowedAssets.length > 0) { + setValues(prev => ({ ...prev, assetCode: config.allowedAssets[0] })); + } + } + } catch (err) { + console.error("Failed to fetch config:", err); + setConfigFetchFailed(true); + } + } + fetchConfig(); + }, []); // Only fetch once on mount const [touched, setTouched] = useState< Partial> >({}); @@ -250,21 +279,35 @@ export function CreateStreamForm({ * - + {!configFetchFailed && allowedAssets.length > 0 ? ( + + ) : ( + + )} {errors.assetCode && ( {errors.assetCode} diff --git a/frontend/src/services/api.ts b/frontend/src/services/api.ts index e34334e..815ad56 100644 --- a/frontend/src/services/api.ts +++ b/frontend/src/services/api.ts @@ -176,3 +176,12 @@ export async function getStream(streamId: string): Promise { const body = await parseResponse<{ data: Stream }>(response); return body.data; } + +export interface AppConfig { + allowedAssets: string[]; +} + +export async function getConfig(): Promise { + const response = await fetch(`${API_BASE}/config`); + return parseResponse(response); +} diff --git a/package-lock.json b/package-lock.json index 41c24fc..90fbdc4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,7 +1,7 @@ { "name": "stellar-stream", "version": "1.0.0", - + "lockfileVersion": 3, "requires": true, "packages": { "": {