From 8a5ae342450f10c6fa8bc12e8edbf4d8709577a6 Mon Sep 17 00:00:00 2001 From: fortezzalaboratory Date: Thu, 28 May 2026 01:27:40 +0100 Subject: [PATCH 1/6] fix(soroban): map ORDER_EXECUTION_FROZEN to user-facing message Surface a clear explanation when contract execution is paused so users know saved orders will execute once trading resumes. Co-authored-by: Cursor --- apps/web/src/lib/soroban/errors.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apps/web/src/lib/soroban/errors.ts b/apps/web/src/lib/soroban/errors.ts index 42b0fb6..5245b40 100644 --- a/apps/web/src/lib/soroban/errors.ts +++ b/apps/web/src/lib/soroban/errors.ts @@ -24,6 +24,8 @@ const CONTRACT_ERROR_MESSAGES: Record = { POSITION_NOT_FOUND: "Position was not found.", SLIPPAGE_EXCEEDED: "Price moved beyond your slippage limit. Try again.", UNAUTHORIZED: "You are not authorized to perform this action.", + ORDER_EXECUTION_FROZEN: + "Order execution is temporarily paused. Your order has been saved and will execute when trading resumes.", } const FALLBACK_MESSAGE = "Transaction failed. Please try again." From d8316289f50631ba0fd432ad9c2686683f9bee5b Mon Sep 17 00:00:00 2001 From: fortezzalaboratory Date: Thu, 28 May 2026 01:28:01 +0100 Subject: [PATCH 2/6] refactor(soroban): export ORDER_EXECUTION_FROZEN_MESSAGE constant Reuse the same copy for contract error parsing and UI banners. Co-authored-by: Cursor --- apps/web/src/lib/soroban/errors.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/apps/web/src/lib/soroban/errors.ts b/apps/web/src/lib/soroban/errors.ts index 5245b40..c451005 100644 --- a/apps/web/src/lib/soroban/errors.ts +++ b/apps/web/src/lib/soroban/errors.ts @@ -11,6 +11,9 @@ const RPC_ERROR_MESSAGES: Record = { op_underfunded: "Wallet balance is too low for this operation.", } +export const ORDER_EXECUTION_FROZEN_MESSAGE = + "Order execution is temporarily paused. Your order has been saved and will execute when trading resumes." + const CONTRACT_ERROR_MESSAGES: Record = { INSUFFICIENT_COLLATERAL: "Insufficient collateral for this position.", INSUFFICIENT_LIQUIDITY: "Insufficient liquidity for this trade.", @@ -24,8 +27,7 @@ const CONTRACT_ERROR_MESSAGES: Record = { POSITION_NOT_FOUND: "Position was not found.", SLIPPAGE_EXCEEDED: "Price moved beyond your slippage limit. Try again.", UNAUTHORIZED: "You are not authorized to perform this action.", - ORDER_EXECUTION_FROZEN: - "Order execution is temporarily paused. Your order has been saved and will execute when trading resumes.", + ORDER_EXECUTION_FROZEN: ORDER_EXECUTION_FROZEN_MESSAGE, } const FALLBACK_MESSAGE = "Transaction failed. Please try again." From d9064fb69926d539061485cadb4da0620cfba973 Mon Sep 17 00:00:00 2001 From: fortezzalaboratory Date: Thu, 28 May 2026 01:28:01 +0100 Subject: [PATCH 3/6] feat(trade): add frozen order status to Order type Track when limit/trigger orders are frozen on-chain so the UI can warn users execution is paused until conditions improve. Co-authored-by: Cursor --- apps/web/src/features/trade/hooks/useOrders.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/apps/web/src/features/trade/hooks/useOrders.ts b/apps/web/src/features/trade/hooks/useOrders.ts index 4ca81bb..2165ef6 100644 --- a/apps/web/src/features/trade/hooks/useOrders.ts +++ b/apps/web/src/features/trade/hooks/useOrders.ts @@ -9,6 +9,8 @@ export type OrderType = | "StopLoss" | "Swap" +export type OrderStatus = "active" | "frozen" + export type Order = { key: string account: string @@ -21,6 +23,7 @@ export type Order = { acceptablePrice: number orderType: OrderType isLong: boolean + status: OrderStatus createdAt: number // unix timestamp ms // TODO: Add executionFee, swapPath, decreaseSwapType when live } @@ -42,11 +45,16 @@ async function fetchOrders(account: string): Promise> { acceptablePrice: 65_100, orderType: "LimitIncrease", isLong: true, + status: "active", createdAt: Date.now() - 1000 * 60 * 30, }, ] } +export function hasFrozenOrders(orders: Array): boolean { + return orders.some((order) => order.status === "frozen") +} + const DUMMY_ACCOUNT = "GDUMMY...STELLAR" export function useOrders(account = DUMMY_ACCOUNT) { From 59d75eab383a79dee96ed00f3cfd60795b94292d Mon Sep 17 00:00:00 2001 From: fortezzalaboratory Date: Thu, 28 May 2026 01:28:19 +0100 Subject: [PATCH 4/6] feat(trade): add dismissible order execution frozen banner Let users dismiss the paused-execution notice for the session while keeping the shared contract error message in one place. Co-authored-by: Cursor --- .../positions/OrderExecutionFrozenBanner.tsx | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 apps/web/src/features/trade/components/positions/OrderExecutionFrozenBanner.tsx diff --git a/apps/web/src/features/trade/components/positions/OrderExecutionFrozenBanner.tsx b/apps/web/src/features/trade/components/positions/OrderExecutionFrozenBanner.tsx new file mode 100644 index 0000000..11f6389 --- /dev/null +++ b/apps/web/src/features/trade/components/positions/OrderExecutionFrozenBanner.tsx @@ -0,0 +1,38 @@ +import { useState } from "react" +import { ORDER_EXECUTION_FROZEN_MESSAGE } from "@/lib/soroban/errors" + +const SESSION_KEY = "so4-order-execution-frozen-dismissed" + +type Props = { + visible: boolean +} + +export function OrderExecutionFrozenBanner({ visible }: Props) { + const [dismissed, setDismissed] = useState( + () => sessionStorage.getItem(SESSION_KEY) === "1", + ) + + if (!visible || dismissed) return null + + function dismiss() { + sessionStorage.setItem(SESSION_KEY, "1") + setDismissed(true) + } + + return ( +
+ {ORDER_EXECUTION_FROZEN_MESSAGE} + +
+ ) +} From 46e1efcf7a903ec2c2cbff78741a7c6fc88b360f Mon Sep 17 00:00:00 2001 From: fortezzalaboratory Date: Thu, 28 May 2026 01:28:19 +0100 Subject: [PATCH 5/6] feat(trade): show frozen-order banner in BottomTabs Surface the paused-execution notice above positions/orders tabs when any open order is in frozen status. Co-authored-by: Cursor --- .../src/features/trade/components/positions/BottomTabs.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/web/src/features/trade/components/positions/BottomTabs.tsx b/apps/web/src/features/trade/components/positions/BottomTabs.tsx index da65655..45cf4da 100644 --- a/apps/web/src/features/trade/components/positions/BottomTabs.tsx +++ b/apps/web/src/features/trade/components/positions/BottomTabs.tsx @@ -1,6 +1,7 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from "@workspace/ui/components/tabs" import { usePositions } from "../../hooks/usePositions" -import { useOrders } from "../../hooks/useOrders" +import { hasFrozenOrders, useOrders } from "../../hooks/useOrders" +import { OrderExecutionFrozenBanner } from "./OrderExecutionFrozenBanner" import { PositionsList } from "./PositionsList" import { OrdersList } from "./OrdersList" import type { Position } from "../../hooks/usePositions" @@ -17,6 +18,7 @@ export function BottomTabs({ onSelectPosition }: Props) { return ( + Positions {positions.length > 0 && `(${positions.length})`} From 2ea38d0eb02e145a5258891348147da00197d585 Mon Sep 17 00:00:00 2001 From: fortezzalaboratory Date: Thu, 28 May 2026 01:28:19 +0100 Subject: [PATCH 6/6] feat(trade): label frozen orders in the orders table Help users spot which pending orders are waiting for execution to resume. Co-authored-by: Cursor --- .../src/features/trade/components/positions/OrdersList.tsx | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/apps/web/src/features/trade/components/positions/OrdersList.tsx b/apps/web/src/features/trade/components/positions/OrdersList.tsx index fa030d3..c5b413e 100644 --- a/apps/web/src/features/trade/components/positions/OrdersList.tsx +++ b/apps/web/src/features/trade/components/positions/OrdersList.tsx @@ -63,6 +63,11 @@ export function OrdersList() { > {o.isLong ? "Long" : "Short"} + {o.status === "frozen" && ( + + Frozen + + )} {o.orderType}