From 152d87f19dedbd972733eeda1172a9c366a6f6b0 Mon Sep 17 00:00:00 2001 From: Yuvraj singh Date: Sun, 7 Sep 2025 00:59:14 +0530 Subject: [PATCH 01/16] Update readme.md --- readme.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/readme.md b/readme.md index ddb056a..9ea4911 100644 --- a/readme.md +++ b/readme.md @@ -4,7 +4,9 @@ A high-performance, real-time trading system built to handle low-latency order e ---- +Screenshot 2025-09-07 at 12 58 00โ€ฏAM +Screenshot 2025-09-07 at 12 57 48โ€ฏAM + ## ๐Ÿš€ Tech Stack From 01340208b42dbdba342c5be61f4c1f1b9f080dc3 Mon Sep 17 00:00:00 2001 From: Yuvraj singh Date: Mon, 17 Nov 2025 21:45:30 +0530 Subject: [PATCH 02/16] Add deployed link to README Added deployed link to the README file. --- readme.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/readme.md b/readme.md index 9ea4911..303feda 100644 --- a/readme.md +++ b/readme.md @@ -1,5 +1,7 @@ # โšก Exchange Platform +DEPLOYED LINK - https://exchange-ruby-iota.vercel.app + A high-performance, real-time trading system built to handle low-latency order execution at scale. The platform combines modular, event-driven architecture with efficient queuing, real-time communication, and scalable infrastructure. From e82752b0357e7cc7d17d1df4b4e5c770b7fb8443 Mon Sep 17 00:00:00 2001 From: yuvrajnode <127673251+yuvrajnode@users.noreply.github.com> Date: Fri, 6 Feb 2026 12:28:22 -0500 Subject: [PATCH 03/16] Add .env.example file --- .env.example | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .env.example diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..fedb6ef --- /dev/null +++ b/.env.example @@ -0,0 +1,3 @@ +BACKPACK_API_URL=https://api.backpack.exchange +PRICE_INDEXER_API_URL=https://price-indexer.workers.madlads.com +BACKPACK_WS_URL=wss://ws.backpack.exchange/ From e669eaed36a002a9708b86b4270be7820c51810c Mon Sep 17 00:00:00 2001 From: Yuvraj singh Date: Thu, 12 Feb 2026 00:13:46 +0530 Subject: [PATCH 04/16] fix: replace deprecated JSDoc type annotation with TypeScript import --- next.config.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/next.config.ts b/next.config.ts index d92ef3c..8078a76 100644 --- a/next.config.ts +++ b/next.config.ts @@ -1,5 +1,6 @@ -/** @type {import('next').NextConfig} */ -const nextConfig = { +import type { NextConfig } from "next"; + +const nextConfig: NextConfig = { images: { remotePatterns: [ { From 3aa0e3339686930112ec334d771c89fee41a955f Mon Sep 17 00:00:00 2001 From: yuvrajnode <1.27673251e+08+yuvrajnode@users.noreply.github.com> Date: Sat, 23 May 2026 03:38:28 +0000 Subject: [PATCH 05/16] Improve project documentation and tech stack overview --- readme.md | 87 ++++++++++++++++++++++++++----------------------------- 1 file changed, 41 insertions(+), 46 deletions(-) diff --git a/readme.md b/readme.md index 303feda..8c2464a 100644 --- a/readme.md +++ b/readme.md @@ -4,96 +4,91 @@ DEPLOYED LINK - https://exchange-ruby-iota.vercel.app A high-performance, real-time trading system built to handle low-latency order execution at scale. The platform combines modular, event-driven architecture with efficient queuing, real-time communication, and scalable infrastructure. - - Screenshot 2025-09-07 at 12 58 00โ€ฏAM Screenshot 2025-09-07 at 12 57 48โ€ฏAM - ## ๐Ÿš€ Tech Stack -### Frontend -- **Next.js & React** โ€“ Dynamic, server-rendered UI -- **Tailwind CSS** โ€“ Fast, responsive styling - -### Backend -- **Node.js & Express** โ€“ High-performance API services -- **PostgreSQL** โ€“ Transactional data storage -- **Time Series DB** โ€“ For high-frequency trade analytics - -### Real-Time Communication -- **WebSockets (Socket.io)** โ€“ Live trade and market updates +This project leverages a robust and modern tech stack to ensure high performance, scalability, and real-time capabilities: -### Queue & Event System -- **Redis** โ€“ Order queuing, Pub/Sub for real-time communication - -### Matching Engine -- **Custom-built in Node.js** โ€“ Fast order matching with event triggers - -### Deployment -- **Railway** โ€“ Cloud deployment +| Category | Technologies | Description | +| :------------------------ | :-------------------------------------------- | :------------------------------------------------ | +| **Frontend** | Next.js, React, Tailwind CSS | Dynamic, server-rendered UI with responsive styling | +| **Backend** | Node.js, Express, PostgreSQL, Time Series DB | High-performance API services and data storage | +| **Real-Time Communication** | WebSockets (Socket.io) | Live trade and market updates | +| **Queue & Event System** | Redis | Order queuing, Pub/Sub for real-time communication | +| **Matching Engine** | Custom-built in Node.js | Fast order matching with event triggers | +| **Deployment** | Railway | Cloud deployment platform | --- ## ๐Ÿง  Architecture & Data Flow +The platform's architecture is designed for efficiency and reliability, ensuring seamless order processing and real-time data distribution. + ### 1. Order Submission -- **User Input**: Traders place buy/sell orders via the frontend. -- **API Request**: Order data is sent to `POST /api/v1/order`. -- **Redis Queue**: API validates and enqueues orders for processing. +- **User Input**: Traders place buy/sell orders via the intuitive frontend interface. +- **API Request**: Order data is securely transmitted to the `POST /api/v1/order` endpoint. +- **Redis Queue**: The API validates incoming orders and enqueues them in Redis for asynchronous processing, decoupling the order intake from the matching engine. ### 2. Order Matching -- **Engine Polling**: A custom-built matching engine polls Redis. -- **Execution**: Orders are matched and trades executed. -- **Event Trigger**: Emits a `trade_created` event via Redis Pub/Sub. +- **Engine Polling**: A custom-built, high-performance matching engine continuously polls the Redis queue for new orders. +- **Execution**: Orders are matched against existing orders in the order book, and trades are executed with millisecond-level precision. +- **Event Trigger**: Upon trade execution, a `trade_created` event is emitted via Redis Pub/Sub, notifying all relevant services and clients. ### 3. Real-Time Distribution & Storage -- **WebSockets**: Broadcast updates to connected clients instantly. -- **PostgreSQL**: Stores all trade records reliably. -- **Time Series DB**: Logs price/volume data for analytics and visualization. +- **WebSockets**: Real-time updates, including trade confirmations and market data, are broadcast instantly to connected clients via WebSockets, ensuring users have the latest information. +- **PostgreSQL**: All trade records and critical transactional data are stored reliably in PostgreSQL, ensuring data integrity and persistence. +- **Time Series DB**: High-frequency price and volume data are logged in a dedicated Time Series Database for advanced analytics, historical charting, and visualization. --- ## โœจ Key Features -- โšก **Real-Time Execution** โ€“ Millisecond-level trade processing -- ๐Ÿ“ˆ **Live Market Updates** โ€“ Instant updates via WebSockets -- ๐Ÿ” **Scalable Design** โ€“ Horizontally scalable with decoupled services -- ๐Ÿงฎ **Efficient Storage** โ€“ Dual-database approach for speed and analytics +- โšก **Real-Time Execution**: Achieve millisecond-level trade processing, crucial for high-frequency trading environments. +- ๐Ÿ“ˆ **Live Market Updates**: Instantaneous market data and trade updates delivered via WebSockets, keeping users informed. +- ๐Ÿ” **Scalable Design**: Horizontally scalable architecture with decoupled services, capable of handling increasing loads and traffic. +- ๐Ÿงฎ **Efficient Storage**: A dual-database approach (PostgreSQL for core trades, Time Series DB for analytics) optimizes both transactional integrity and analytical performance. --- ## ๐Ÿงฉ Challenges & Solutions ### Handling High Throughput -- **Problem**: Concurrent order spikes -- **Solution**: Redis queue decouples order intake from processing +- **Problem**: Managing concurrent order spikes and maintaining system responsiveness under heavy load. +- **Solution**: Implementing a Redis queue to decouple order intake from processing, allowing the system to absorb and process orders efficiently without bottlenecks. ### Ensuring Real-Time Execution -- **Problem**: Trade delay risks -- **Solution**: Optimized matching engine + Redis Pub/Sub + WebSockets +- **Problem**: Minimizing trade delays to provide a competitive trading environment. +- **Solution**: Utilizing an optimized matching engine combined with Redis Pub/Sub and WebSockets for rapid event propagation and instant trade execution. ### Efficient Data Persistence -- **Problem**: High-frequency data impacting performance -- **Solution**: PostgreSQL for core trades, Time Series DB for analytics +- **Problem**: Storing and retrieving high-frequency trading data without impacting overall system performance. +- **Solution**: Employing PostgreSQL for reliable storage of core trade data and a specialized Time Series Database for efficient logging and analysis of market data. --- ## ๐Ÿ“ฆ Setup Instructions +To get the Exchange Platform running locally, follow these steps: + ```bash -# 1. Clone the repo -git clone https://github.com/yourusername/exchange-platform.git -cd exchange-platform +# 1. Clone the repository +git clone https://github.com/yuvrajnode/exchange.git +cd exchange # 2. Install dependencies npm install -# 3. Setup environment variables +# 3. Set up environment variables cp .env.example .env +# Edit the .env file with your database credentials and other configurations -# 4. Start the dev server +# 4. Start the development server npm run dev +``` + +This will start the Next.js development server, and you can access the application in your browser at `http://localhost:3000` (or the port specified in your `.env` file). From 993073c3e3a3b092dd1595e1e821013f00f8462f Mon Sep 17 00:00:00 2001 From: Yuvraj singh Date: Thu, 25 Jun 2026 23:41:20 +0530 Subject: [PATCH 06/16] =?UTF-8?q?chore:=20housekeeping=20=E2=80=94=20ignor?= =?UTF-8?q?e=20.DS=5FStore,=20upgrade=20CI=20to=20Node=2020=20+=20lint,=20?= =?UTF-8?q?improve=20SEO=20metadata?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .DS_Store | Bin 8196 -> 0 bytes .github/workflows/Ci.yml | 16 ++++++++++------ .gitignore | 10 +++++++++- app/layout.tsx | 15 ++++++++++++--- 4 files changed, 31 insertions(+), 10 deletions(-) delete mode 100644 .DS_Store diff --git a/.DS_Store b/.DS_Store deleted file mode 100644 index 0dca4ae052f4a319b1ae4f77ca4c294ca266e0d7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8196 zcmeHMzl#$=7=2^*Vu*q%j^oM|d-0kSBDi-%IIt0}6vVZ(k-mH#q=mYdY8f)&VrwHMY)i zSkiP{_fk9KW@4gZJ;wVRJN+!3lrm*P91sV@0dYVa5C{Gh2e@bJ)~ML`ZB#~aKpgll z9nkNGm|bJyFt=!49URONfEaPwG+wv#1u=G*ILs|F!lrB~(UvNA#89@J^RdfI9Of2n zIg~qmD95ba2}K!p-aj_!P>Dqu#Q|}k>_E(^2$!*syEqKa@6GNbKbB^lPH&v`IM?|0 z_Vcy9_Pfn6J~%Nx8F{}Aw63reXJ@<^VTxYB4)wL1;cMtV|9EuUYFM~WniWc_vjRQ# zrL#gk2N>dE=tT7R)kSLYqP~vwX7hO0>IgCl4a+lp{^-dq5}<}XOfU(2P?zo$5udkx z;du7^uFik%a@6O8dZGE6=p#c)&dfab0S@sXV8_e*Re8RaqpNc*OYi9``&DkJ^Mlq| z!5jgdQo%6vW_8qkO$C*?zNRn3 zAMd|kH{X{N@{1MoJNdruwbiGTf;vA*evgb>{or$~Z?+fXzP^=vpJr<*xQFjtRgSL% z^_(;rMK^!~yxs zW4Goqp+0NJ?7Qr`>Ac*cDdC_~^t?Ha6X*Xh) { return ( - + From 71b7caaa89011b0e612121e81a19099acf011654 Mon Sep 17 00:00:00 2001 From: Yuvraj singh Date: Thu, 25 Jun 2026 23:41:48 +0530 Subject: [PATCH 07/16] =?UTF-8?q?feat(ui):=20add=20futuristic=20design=20s?= =?UTF-8?q?ystem=20=E2=80=94=20glassmorphism,=20neon=20glow,=20gradients,?= =?UTF-8?q?=20custom=20scrollbar?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/globals.css | 114 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 113 insertions(+), 1 deletion(-) diff --git a/app/globals.css b/app/globals.css index 85258ad..a062247 100644 --- a/app/globals.css +++ b/app/globals.css @@ -52,14 +52,126 @@ } } +/* ===== Futuristic theme tokens ===== */ +:root { + --nx-bg: #06080f; + --nx-bg-soft: #0b1020; + --nx-panel: rgba(18, 24, 42, 0.6); + --nx-border: rgba(120, 160, 255, 0.12); + --nx-cyan: #22d3ee; + --nx-violet: #8b5cf6; + --nx-blue: #3b82f6; + --nx-green: #34d399; + --nx-red: #f43f5e; +} + +html { + scroll-behavior: smooth; +} + body { - background: #222223dc; + background: + radial-gradient(1200px 600px at 80% -10%, rgba(139, 92, 246, 0.12), transparent 60%), + radial-gradient(1000px 500px at 0% 0%, rgba(34, 211, 238, 0.1), transparent 55%), + var(--nx-bg); + color: #e5e7eb; + min-height: 100vh; } @layer utilities { .text-balance { text-wrap: balance; } + + /* Gradient brand text */ + .nx-gradient-text { + background: linear-gradient(90deg, var(--nx-cyan), var(--nx-violet) 60%, var(--nx-blue)); + -webkit-background-clip: text; + background-clip: text; + color: transparent; + } + + /* Glassmorphism panel */ + .nx-glass { + background: var(--nx-panel); + backdrop-filter: blur(14px); + -webkit-backdrop-filter: blur(14px); + border: 1px solid var(--nx-border); + } + + /* Subtle neon glow */ + .nx-glow { + box-shadow: 0 0 0 1px rgba(120, 160, 255, 0.08), + 0 8px 40px -12px rgba(59, 130, 246, 0.45); + } + .nx-glow-hover { + transition: box-shadow 0.3s ease, transform 0.3s ease; + } + .nx-glow-hover:hover { + box-shadow: 0 0 0 1px rgba(120, 160, 255, 0.25), + 0 12px 48px -10px rgba(139, 92, 246, 0.5); + transform: translateY(-2px); + } + + /* Grid backdrop */ + .nx-grid-bg { + background-image: + linear-gradient(rgba(120, 160, 255, 0.05) 1px, transparent 1px), + linear-gradient(90deg, rgba(120, 160, 255, 0.05) 1px, transparent 1px); + background-size: 48px 48px; + } + + /* Hide scrollbar but keep scroll */ + .no-scrollbar::-webkit-scrollbar { + display: none; + } + .no-scrollbar { + -ms-overflow-style: none; + scrollbar-width: none; + } + + .animate-aurora { + animation: nx-aurora 12s ease-in-out infinite alternate; + } + .animate-float { + animation: nx-float 6s ease-in-out infinite; + } + .animate-shimmer { + background-size: 200% 100%; + animation: nx-shimmer 2.5s linear infinite; + } +} + +@keyframes nx-aurora { + 0% { transform: translate3d(0, 0, 0) scale(1); opacity: 0.7; } + 100% { transform: translate3d(0, -20px, 0) scale(1.1); opacity: 1; } +} +@keyframes nx-float { + 0%, 100% { transform: translateY(0); } + 50% { transform: translateY(-10px); } +} +@keyframes nx-shimmer { + 0% { background-position: 200% 0; } + 100% { background-position: -200% 0; } +} + +/* Custom scrollbar */ +::-webkit-scrollbar { + width: 10px; + height: 10px; +} +::-webkit-scrollbar-track { + background: transparent; +} +::-webkit-scrollbar-thumb { + background: linear-gradient(var(--nx-violet), var(--nx-cyan)); + border-radius: 9999px; + border: 2px solid transparent; + background-clip: padding-box; +} +::-webkit-scrollbar-thumb:hover { + background: linear-gradient(var(--nx-cyan), var(--nx-violet)); + background-clip: padding-box; } @theme inline { From b14784f422e6aad85c6d2ed49de2e316a6941697 Mon Sep 17 00:00:00 2001 From: Yuvraj singh Date: Thu, 25 Jun 2026 23:43:22 +0530 Subject: [PATCH 08/16] feat(landing): redesign hero, navbar, and features with futuristic UI - Glassmorphism sticky navbar with mobile menu and gradient brand - Hero with gradient headline, glowing CTAs and live stats - Replace ad block with a 4-up animated features grid - Ambient aurora + grid backdrop on home page --- app/page.tsx | 20 +++--- components/Advertisment.tsx | 72 +++++++++++++++------ components/HeroSection.tsx | 79 +++++++++++++++++++---- components/ui/Landing.tsx | 122 ++++++++++++++++++++++++++++-------- 4 files changed, 226 insertions(+), 67 deletions(-) diff --git a/app/page.tsx b/app/page.tsx index 6ce4017..bb15333 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -1,15 +1,15 @@ -"use client"; - - import Landing from "@/components/ui/Landing"; + export default function Home() { - return ( - <> -
- -
- - +
+ {/* Ambient aurora backdrop */} +
+
+
+
+ +
+
); } diff --git a/components/Advertisment.tsx b/components/Advertisment.tsx index 92f746a..0ac2e3b 100644 --- a/components/Advertisment.tsx +++ b/components/Advertisment.tsx @@ -1,21 +1,57 @@ -import Image from "next/image" +"use client"; -export default function Advertisment(){ - return <> -
-
-
advertisement
-
+import { Repeat, ShieldCheck, Activity, Wallet } from "lucide-react"; -

- Turn your money
into real crypto -

-

Buy & Sell

-

Swap Token

-

Real time monetring

-
-
-
+const FEATURES = [ + { + icon: Wallet, + title: "Buy & Sell instantly", + desc: "Turn your money into real crypto with deep liquidity and tight spreads.", + }, + { + icon: Repeat, + title: "Swap any token", + desc: "Move between assets on any chain with a single, seamless transaction.", + }, + { + icon: Activity, + title: "Real-time monitoring", + desc: "Live order books and charts streamed over low-latency WebSockets.", + }, + { + icon: ShieldCheck, + title: "Secure by design", + desc: "Event-driven architecture built to keep your funds and data safe.", + }, +]; - -} \ No newline at end of file +export default function Advertisment() { + return ( +
+
+

+ Everything you need to{" "} + trade smarter +

+

+ A complete toolkit for the modern on-chain trader. +

+
+ +
+ {FEATURES.map(({ icon: Icon, title, desc }) => ( +
+
+ +
+

{title}

+

{desc}

+
+ ))} +
+
+ ); +} diff --git a/components/HeroSection.tsx b/components/HeroSection.tsx index 3c7980e..aba80bf 100644 --- a/components/HeroSection.tsx +++ b/components/HeroSection.tsx @@ -1,15 +1,70 @@ +"use client"; +import { useRouter } from "next/navigation"; +import { ArrowRight, Zap } from "lucide-react"; -export default function Hero(){ - return ( - <> -
-

Exchange you'll love

-

- Exchange make its safe and esty for you to store,buy and sell
stake,crypto on ony blockchain -

- +const STATS = [ + { label: "24h Volume", value: "$2.4B+" }, + { label: "Markets", value: "150+" }, + { label: "Avg. Latency", value: "<5ms" }, + { label: "Active Traders", value: "1.2M" }, +]; + +export default function Hero() { + const router = useRouter(); + + return ( +
+
+ + Real-time order matching ยท Live market data +
+ +

+ The exchange +
+ you'll actually love +

+ +

+ Store, buy, sell and stake crypto across any blockchain โ€” powered by a + low-latency matching engine and real-time WebSocket feeds. +

+ +
+ + +
+ + {/* Stats */} +
+ {STATS.map((stat) => ( +
+
+ {stat.value} +
+
+ {stat.label}
- - ); -} \ No newline at end of file +
+ ))} +
+
+ ); +} diff --git a/components/ui/Landing.tsx b/components/ui/Landing.tsx index 0a61c83..6aa2ce9 100644 --- a/components/ui/Landing.tsx +++ b/components/ui/Landing.tsx @@ -1,30 +1,98 @@ -"use client" -import Image from "next/image" -import { useRouter } from "next/navigation" +"use client"; +import Image from "next/image"; +import { useRouter } from "next/navigation"; +import { useState } from "react"; +import { Menu, X } from "lucide-react"; import Hero from "../HeroSection"; import Advertisment from "../Advertisment"; -export default function Landing(){ - const router = useRouter(); - return <> -
-
- logo -
-
-
    -
  • - router.push("/") - } className="hover:text-gray-300" >Explore
  • -
  • - router.push("/market") - }>Markets
  • -
  • - router.push("/trade/SOL_USDT") - } > Trades
  • -
-
-
- - + +const NAV_LINKS = [ + { label: "Explore", path: "/" }, + { label: "Markets", path: "/market" }, + { label: "Trade", path: "/trade/SOL_USDC" }, +]; + +export default function Landing() { + const router = useRouter(); + const [open, setOpen] = useState(false); + + return ( + <> + {/* Navbar */} +
+ + + {open && ( +
+
    + {NAV_LINKS.map((link) => ( +
  • { + router.push(link.path); + setOpen(false); + }} + className="cursor-pointer rounded-lg px-3 py-2 text-neutral-300 hover:bg-white/5 hover:text-white" + > + {link.label} +
  • + ))} +
+
+ )} +
+ + + + + {/* Footer */} +
+

+ Built with Next.js ยท Real-time data via WebSockets ยท{" "} + Nexus Exchange +

+
-} \ No newline at end of file + ); +} From 0d48bf4bda1135106a9d9075f1995c70db26890d Mon Sep 17 00:00:00 2001 From: Yuvraj singh Date: Thu, 25 Jun 2026 23:43:57 +0530 Subject: [PATCH 09/16] feat(ui): redesign Appbar and core buttons with glass nav + active states - Glass sticky Appbar with gradient brand and active route highlighting - Refined deposit/withdraw buttons with bordered glow and press feedback --- components/ui/Appbar.tsx | 80 +++++++++++++++++++++++------------ components/ui/core/button.tsx | 45 ++++++++++++++------ 2 files changed, 84 insertions(+), 41 deletions(-) diff --git a/components/ui/Appbar.tsx b/components/ui/Appbar.tsx index 33c3196..a293739 100644 --- a/components/ui/Appbar.tsx +++ b/components/ui/Appbar.tsx @@ -1,36 +1,60 @@ "use client"; -import { usePathname } from "next/navigation"; -import { PrimaryButton, SuccessButton } from "@/components/ui//core/button" -import { useRouter } from "next/navigation"; +import { usePathname, useRouter } from "next/navigation"; +import Image from "next/image"; +import { PrimaryButton, SuccessButton } from "@/components/ui/core/button"; -export default function Appbar ({TrueButton} :{TrueButton: number}) { - const route = usePathname(); - const router = useRouter() +export default function Appbar({ TrueButton }: { TrueButton: number }) { + const route = usePathname(); + const router = useRouter(); - return
-
-
-
router.push('/')}> - Exchange -
-
router.push('/market')}> - Markets -
-
router.push('/trade/SOL_USDC')}> - Explore Trade -
-
- {TrueButton==1?( + + +
+ + {TrueButton === 1 ? : null} +
+ ); } -function Button(){ - return
-
- Deposit - Withdraw -
-
-} \ No newline at end of file +function ActionButtons() { + return ( +
+ Deposit + Withdraw +
+ ); +} diff --git a/components/ui/core/button.tsx b/components/ui/core/button.tsx index 020cf3b..3bfb2a9 100644 --- a/components/ui/core/button.tsx +++ b/components/ui/core/button.tsx @@ -1,16 +1,35 @@ - -export const PrimaryButton = ({ children, onClick }: { children: string, onClick?: () => void }) => { - return + ); +}; -} - -export const SuccessButton = ({ children, onClick }: { children: string, onClick?: () => void }) => { - return - -} \ No newline at end of file + ); +}; From ec5df1178c7daac2b3883abcca23d84369149a26 Mon Sep 17 00:00:00 2001 From: Yuvraj singh Date: Thu, 25 Jun 2026 23:45:21 +0530 Subject: [PATCH 10/16] feat(market): apply glassmorphism theme to cards, panels, carousel and skeletons - Glass info cards with hover glow - Gradient section headers for New/Top Gainers/Popular - Themed carousel, market table panel and loading skeletons - Ambient grid + glow backdrop --- app/market/page.tsx | 40 +++++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/app/market/page.tsx b/app/market/page.tsx index 94bf179..6ed0084 100644 --- a/app/market/page.tsx +++ b/app/market/page.tsx @@ -100,10 +100,10 @@ export default function Component() { if (!data) { return ( -
+
{/* Carousel Skeleton */} -
+
@@ -117,7 +117,7 @@ export default function Component() { {/* Three Column Grid Skeleton */}
{[1, 2, 3].map((index) => ( -
+
{[1, 2, 3, 4, 5].map((item) => ( @@ -141,7 +141,7 @@ export default function Component() {
{/* Table Skeleton */} -
+
@@ -218,15 +218,17 @@ export default function Component() { const newEntries = getNewListings(data); const number=0; return ( -
-
+
+
+
+
- +
- window.location.href = "/trade/TATA_INR"} > @@ -253,8 +255,8 @@ const number=0;
- window.location.href = "/trade/TATA_INR"} > @@ -284,23 +286,23 @@ const number=0;
-
-

New

+
+

New

-
-

Top Gainers

+
+

Top Gainers

-
-

Popular

+
+

Popular

-
+
+
Date: Thu, 25 Jun 2026 23:47:25 +0530 Subject: [PATCH 11/16] feat(trade): redesign trading interface with futuristic UI - Rebuild trade page into a responsive 12-col glass grid (chart/book/order) - Rewrite SwapUI: readable inputs, dynamic Buy/Sell submit, gradient tabs, working percent shortcuts - Polish order book with header, mid-price banner and depth bars - Make MarketBar fluid-width and color last price by 24h change --- app/trade/[market]/page.tsx | 60 +++---- components/ui/MarketBar.tsx | 6 +- components/ui/SwapUi.tsx | 303 ++++++++++++++++++---------------- components/ui/depth/Depth.tsx | 17 +- 4 files changed, 200 insertions(+), 186 deletions(-) diff --git a/app/trade/[market]/page.tsx b/app/trade/[market]/page.tsx index 211f04f..5218a46 100644 --- a/app/trade/[market]/page.tsx +++ b/app/trade/[market]/page.tsx @@ -1,52 +1,44 @@ -"use client" -import { useParams } from "next/navigation" +"use client"; +import { useParams } from "next/navigation"; import { Depth } from "@/components/ui/depth/Depth"; import { TradeView } from "@/components/ui/Tradeview"; import Appbar from "@/components/ui/Appbar"; -import {SwapUI} from "@/components/ui/SwapUi"; +import { SwapUI } from "@/components/ui/SwapUi"; import { MarketBar } from "@/components/ui/MarketBar"; - export default function Page() { - const { market } = useParams(); -const number =1; - return ( -
-
- {/* MarketBar at the top */} -
-
+ const { market } = useParams(); + const number = 1; + + return ( +
+
+
+ + + {/* Market summary bar */} +
-
- {/* Left half for TradeView */} -
+ {/* Main trading grid */} +
+ {/* Chart */} +
- {/*
*/} + {/* Order book */} +
+ +
- {/* Right half split between Depth and SwapUI */} -
-
- -
- {/* รท
*/} + {/* Order entry */} +
+
-
- {/* */} -
-
- - {/* SwapUI at the bottom on mobile, right on larger screens */} -
-
); -} \ No newline at end of file +} diff --git a/components/ui/MarketBar.tsx b/components/ui/MarketBar.tsx index 4b10b05..26d0bf1 100644 --- a/components/ui/MarketBar.tsx +++ b/components/ui/MarketBar.tsx @@ -84,13 +84,13 @@ export const MarketBar = ({market}: {market: string}) => { // return
-
+
-

${ticker?.lastPrice}

-

${ticker?.lastPrice}

+

= 0 ? "text-green-500" : "text-red-500"}`}>${ticker?.lastPrice}

+

Last price

24H Change

diff --git a/components/ui/SwapUi.tsx b/components/ui/SwapUi.tsx index 09d49ae..bfee5e4 100644 --- a/components/ui/SwapUi.tsx +++ b/components/ui/SwapUi.tsx @@ -1,6 +1,6 @@ "use client"; -import { useState,useEffect } from "react"; -import Image from "next/image" +import { useState, useEffect } from "react"; +import Image from "next/image"; import { getAllInfo } from "@/app/utils/httpClient"; interface CoinData { @@ -8,152 +8,169 @@ interface CoinData { image: string; } -export function SwapUI({ market }: {market: string}) { - const [amount, setAmount] = useState(''); - const [activeTab, setActiveTab] = useState('buy'); - const [type, setType] = useState('limit'); - const [quantity,setquantity]=useState(''); - const[usdcImage,setimage]=useState(""); - useEffect(() => { - //fetch the Image from getAllInfo - async function fetchImage() { - const data: CoinData[] = await getAllInfo(); - const image= data.find((d: CoinData) => d.symbol.toUpperCase() === market.split('_')[0] )?.image - console.log(image) - setimage(image || "") - } - fetchImage(); - }, [market]); +export function SwapUI({ market }: { market: string }) { + const [amount, setAmount] = useState(""); + const [activeTab, setActiveTab] = useState<"buy" | "sell">("buy"); + const [type, setType] = useState<"limit" | "market">("limit"); + const [quantity, setQuantity] = useState(""); + const [tokenImage, setTokenImage] = useState(""); - return
-
-
- - -
-
-
-
- - -
-
-
-
-
-
-

Available Balance

-

36.94 USDC

-
-
-
-

- Price -

-
+ const base = market.split("_")[0]?.toUpperCase() ?? ""; + const isBuy = activeTab === "buy"; - { - setAmount(e.target.value) - }} /> + useEffect(() => { + async function fetchImage() { + try { + const data: CoinData[] = await getAllInfo(); + const image = data.find( + (d: CoinData) => d.symbol.toUpperCase() === base + )?.image; + setTokenImage(image || ""); + } catch (error) { + console.error("Failed to fetch token image:", error); + } + } + fetchImage(); + }, [base]); -
-
- Market Logo -
-
-
-
-
-
-

- Quantity -

-
- { - setquantity(e.target.value); - }} /> -
-
- / -
-
-
-
-

โ‰ˆ 0.00 USDC

-
-
-
- 25% -
-
- 50% -
-
- 75% -
-
- Max -
-
-
- -
-
-
- - -
-
- - -
-
-
-
-
-
-
-} + return ( +
+ {/* Buy / Sell tabs */} +
+ + +
-function LimitButton({ type, setType }: { type: string, setType: (type: string) => void }) { - return
setType('limit')}> -
- Limit -
-
-} + {/* Order type */} +
+ {(["limit", "market"] as const).map((t) => ( + + ))} +
-function MarketButton({ type, setType }: { type: string, setType: (type: string) => void }) { - return
setType('market')}> -
- Market -
-
-} + {/* Balance */} +
+ Available Balance + 36.94 USDC +
-function BuyButton({ activeTab, setActiveTab }: { activeTab: string, setActiveTab: (tab: string) => void }) { - return
setActiveTab('buy')}> -

- Buy -

-
-} + {/* Price */} +
+ {type === "market" ? "Price (Market)" : "Price"} +
+
+ setAmount(e.target.value)} + /> + + USDC + +
+ + {/* Quantity */} +
Quantity
+
+ setQuantity(e.target.value)} + /> + + {tokenImage ? ( + {base} + ) : ( + {base} + )} + +
+ +
โ‰ˆ 0.00 USDC
-function SellButton({ activeTab, setActiveTab }: { activeTab: string, setActiveTab: (tab: string) => void }) { - return
setActiveTab('sell')}> -

- Sell -

+ {/* Percent shortcuts */} +
+ {["25%", "50%", "75%", "Max"].map((p) => ( + + ))} +
+ + {/* Submit */} + + + {/* Options */} +
+ + +
-} \ No newline at end of file + ); +} diff --git a/components/ui/depth/Depth.tsx b/components/ui/depth/Depth.tsx index 83795af..96ad81a 100644 --- a/components/ui/depth/Depth.tsx +++ b/components/ui/depth/Depth.tsx @@ -75,19 +75,24 @@ export function Depth({market }:{market:string}){ },[market]); - return
+ return
+
Order Book
{asks && } - {price &&
{price}
} + {price && ( +
+ {price} +
+ )} { bids && }
} function TableHeader(){ - return
-
Price(USD)
-
Size
-
Total
+ return
+
Price
+
Size
+
Total
} \ No newline at end of file From c8ff299cda7690a644c4d812671616d78a74368c Mon Sep 17 00:00:00 2001 From: Yuvraj singh Date: Thu, 25 Jun 2026 23:48:16 +0530 Subject: [PATCH 12/16] docs: rewrite README to reflect actual Next.js architecture and futuristic UI --- readme.md | 132 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 68 insertions(+), 64 deletions(-) diff --git a/readme.md b/readme.md index 8c2464a..bd13335 100644 --- a/readme.md +++ b/readme.md @@ -1,94 +1,98 @@ -# โšก Exchange Platform +# โšก Nexus โ€” Real-Time Crypto Exchange -DEPLOYED LINK - https://exchange-ruby-iota.vercel.app +**Live demo โ†’** [exchange-ruby-iota.vercel.app](https://exchange-ruby-iota.vercel.app) -A high-performance, real-time trading system built to handle low-latency order execution at scale. The platform combines modular, event-driven architecture with efficient queuing, real-time communication, and scalable infrastructure. +A futuristic, real-time crypto trading front-end built with **Next.js 15** and **React 19**. Nexus streams live market data over WebSockets, renders interactive candlestick charts and a live order book, and ships a polished glassmorphism UI. -Screenshot 2025-09-07 at 12 58 00โ€ฏAM -Screenshot 2025-09-07 at 12 57 48โ€ฏAM - -## ๐Ÿš€ Tech Stack - -This project leverages a robust and modern tech stack to ensure high performance, scalability, and real-time capabilities: - -| Category | Technologies | Description | -| :------------------------ | :-------------------------------------------- | :------------------------------------------------ | -| **Frontend** | Next.js, React, Tailwind CSS | Dynamic, server-rendered UI with responsive styling | -| **Backend** | Node.js, Express, PostgreSQL, Time Series DB | High-performance API services and data storage | -| **Real-Time Communication** | WebSockets (Socket.io) | Live trade and market updates | -| **Queue & Event System** | Redis | Order queuing, Pub/Sub for real-time communication | -| **Matching Engine** | Custom-built in Node.js | Fast order matching with event triggers | -| **Deployment** | Railway | Cloud deployment platform | +![Markets](https://github.com/user-attachments/assets/fad85667-a4e6-41cc-abee-69e1518931e7) +![Trade](https://github.com/user-attachments/assets/fd768972-2642-48a1-b7e0-a698539ec269) --- -## ๐Ÿง  Architecture & Data Flow - -The platform's architecture is designed for efficiency and reliability, ensuring seamless order processing and real-time data distribution. - -### 1. Order Submission - -- **User Input**: Traders place buy/sell orders via the intuitive frontend interface. -- **API Request**: Order data is securely transmitted to the `POST /api/v1/order` endpoint. -- **Redis Queue**: The API validates incoming orders and enqueues them in Redis for asynchronous processing, decoupling the order intake from the matching engine. +## โœจ Features -### 2. Order Matching - -- **Engine Polling**: A custom-built, high-performance matching engine continuously polls the Redis queue for new orders. -- **Execution**: Orders are matched against existing orders in the order book, and trades are executed with millisecond-level precision. -- **Event Trigger**: Upon trade execution, a `trade_created` event is emitted via Redis Pub/Sub, notifying all relevant services and clients. - -### 3. Real-Time Distribution & Storage - -- **WebSockets**: Real-time updates, including trade confirmations and market data, are broadcast instantly to connected clients via WebSockets, ensuring users have the latest information. -- **PostgreSQL**: All trade records and critical transactional data are stored reliably in PostgreSQL, ensuring data integrity and persistence. -- **Time Series DB**: High-frequency price and volume data are logged in a dedicated Time Series Database for advanced analytics, historical charting, and visualization. +- โšก **Real-time data** โ€” live tickers and order-book depth via a singleton WebSocket manager +- ๐Ÿ“ˆ **Interactive charts** โ€” candlestick + sparkline charts powered by `lightweight-charts` +- ๐Ÿ“Š **Live order book** โ€” animated bid/ask depth bars with running totals +- ๐ŸŽจ **Futuristic UI** โ€” glassmorphism, neon glow, gradient accents and Framer Motion animations +- ๐Ÿ“ฑ **Responsive** โ€” adapts from mobile to ultra-wide trading layouts +- ๐Ÿ”Œ **API proxy layer** โ€” Next.js route handlers proxy market data to avoid CORS --- -## โœจ Key Features +## ๐Ÿงฑ Tech Stack -- โšก **Real-Time Execution**: Achieve millisecond-level trade processing, crucial for high-frequency trading environments. -- ๐Ÿ“ˆ **Live Market Updates**: Instantaneous market data and trade updates delivered via WebSockets, keeping users informed. -- ๐Ÿ” **Scalable Design**: Horizontally scalable architecture with decoupled services, capable of handling increasing loads and traffic. -- ๐Ÿงฎ **Efficient Storage**: A dual-database approach (PostgreSQL for core trades, Time Series DB for analytics) optimizes both transactional integrity and analytical performance. +| Layer | Technology | +| ------------ | -------------------------------------------- | +| Framework | Next.js 15 (App Router), React 19 | +| Language | TypeScript | +| Styling | Tailwind CSS v4, custom design tokens | +| Animation | Framer Motion, tw-animate-css | +| Charts | lightweight-charts | +| Data | Backpack Exchange public API + WebSockets | +| Deployment | Vercel ยท CI via GitHub Actions | --- -## ๐Ÿงฉ Challenges & Solutions +## ๐Ÿ—๏ธ Architecture -### Handling High Throughput -- **Problem**: Managing concurrent order spikes and maintaining system responsiveness under heavy load. -- **Solution**: Implementing a Redis queue to decouple order intake from processing, allowing the system to absorb and process orders efficiently without bottlenecks. - -### Ensuring Real-Time Execution -- **Problem**: Minimizing trade delays to provide a competitive trading environment. -- **Solution**: Utilizing an optimized matching engine combined with Redis Pub/Sub and WebSockets for rapid event propagation and instant trade execution. +```text +Browser โ”€โ”€โ–บ Next.js App Router (pages + API routes) + โ”‚ + โ”œโ”€โ”€ /api/v1/tickers โ”€โ” + โ”œโ”€โ”€ /api/v1/depth โ”œโ”€โ–บ Backpack REST API (proxied) + โ”œโ”€โ”€ /api/v1/klines โ”€โ”˜ + โ”‚ + โ””โ”€โ”€ SignalingManager โ”€โ–บ Backpack WebSocket (live ticker + depth) +``` -### Efficient Data Persistence -- **Problem**: Storing and retrieving high-frequency trading data without impacting overall system performance. -- **Solution**: Employing PostgreSQL for reliable storage of core trade data and a specialized Time Series Database for efficient logging and analysis of market data. +- **`app/api/v1/*`** โ€” server route handlers proxy REST calls (CORS-safe). +- **`SignalingManager`** โ€” one shared `WebSocket`, message buffering, and per-stream callback registration. +- **`ChartManager` / `CombineData`** โ€” chart lifecycle and merge of price + kline data for the markets table. --- -## ๐Ÿ“ฆ Setup Instructions - -To get the Exchange Platform running locally, follow these steps: +## ๐Ÿš€ Getting Started ```bash -# 1. Clone the repository +# 1. Clone git clone https://github.com/yuvrajnode/exchange.git cd exchange -# 2. Install dependencies +# 2. Install npm install -# 3. Set up environment variables +# 3. Configure env (optional โ€” defaults to public Backpack endpoints) cp .env.example .env -# Edit the .env file with your database credentials and other configurations -# 4. Start the development server -npm run dev +# 4. Run +npm run dev # http://localhost:3000 ``` -This will start the Next.js development server, and you can access the application in your browser at `http://localhost:3000` (or the port specified in your `.env` file). +Other scripts: + +```bash +npm run build # production build +npm run start # serve production build +npm run lint # eslint (zero-warning policy) +``` + +--- + +## ๐Ÿ“ Project Structure + +```text +app/ + api/v1/ REST proxy route handlers + market/ markets overview page + trade/[market]/ live trading view + utils/ SignalingManager, ChartManager, http client, types +components/ + ui/ Appbar, SwapUI, MarketBar, Depth, charts, core buttons +``` + +--- + +## ๐Ÿ“ฆ Deployment + +Deployed on **Vercel**. Every push to `main` runs the GitHub Actions CI pipeline (`lint` + `build`) and triggers a Vercel deployment. From 7a72ef582d256c53c2b562638821b6a2b74d01b4 Mon Sep 17 00:00:00 2001 From: Yuvraj singh Date: Thu, 25 Jun 2026 23:59:43 +0530 Subject: [PATCH 13/16] =?UTF-8?q?feat(landing):=20richer=20UX=20=E2=80=94?= =?UTF-8?q?=20scroll=20reveals,=20animated=20hero=20preview,=20live=20mark?= =?UTF-8?q?ets,=20CTA=20band,=20footer?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add reusable Reveal scroll-animation wrapper - Hero: staggered entrance animations, live pulse badge, animated SVG chart preview mock - New live MarketsPreview section pulling real tickers - Scroll-reveal feature cards, CTA band and richer footer with nav links --- components/Advertisment.tsx | 24 +++---- components/HeroSection.tsx | 117 +++++++++++++++++++++++++++--- components/ui/Landing.tsx | 53 ++++++++++++-- components/ui/MarketsPreview.tsx | 120 +++++++++++++++++++++++++++++++ components/ui/Reveal.tsx | 28 ++++++++ 5 files changed, 314 insertions(+), 28 deletions(-) create mode 100644 components/ui/MarketsPreview.tsx create mode 100644 components/ui/Reveal.tsx diff --git a/components/Advertisment.tsx b/components/Advertisment.tsx index 0ac2e3b..c8b641a 100644 --- a/components/Advertisment.tsx +++ b/components/Advertisment.tsx @@ -1,6 +1,7 @@ "use client"; import { Repeat, ShieldCheck, Activity, Wallet } from "lucide-react"; +import Reveal from "./ui/Reveal"; const FEATURES = [ { @@ -28,7 +29,7 @@ const FEATURES = [ export default function Advertisment() { return (
-
+

Everything you need to{" "} trade smarter @@ -36,20 +37,19 @@ export default function Advertisment() {

A complete toolkit for the modern on-chain trader.

-

+
- {FEATURES.map(({ icon: Icon, title, desc }) => ( -
-
- + {FEATURES.map(({ icon: Icon, title, desc }, i) => ( + +
+
+ +
+

{title}

+

{desc}

-

{title}

-

{desc}

-
+ ))}
diff --git a/components/HeroSection.tsx b/components/HeroSection.tsx index aba80bf..c79d4c0 100644 --- a/components/HeroSection.tsx +++ b/components/HeroSection.tsx @@ -1,6 +1,7 @@ "use client"; import { useRouter } from "next/navigation"; +import { motion } from "framer-motion"; import { ArrowRight, Zap } from "lucide-react"; const STATS = [ @@ -10,28 +11,65 @@ const STATS = [ { label: "Active Traders", value: "1.2M" }, ]; +const fadeUp = { + hidden: { opacity: 0, y: 24 }, + show: (i: number) => ({ + opacity: 1, + y: 0, + transition: { duration: 0.6, delay: i * 0.1, ease: [0.21, 0.47, 0.32, 0.98] as [number, number, number, number] }, + }), +}; + export default function Hero() { const router = useRouter(); return (
-
- + + + + + Real-time order matching ยท Live market data -
+ + -

+ The exchange
you'll actually love -

+ -

+ Store, buy, sell and stake crypto across any blockchain โ€” powered by a low-latency matching engine and real-time WebSocket feeds. -

+ -
+ -
+ {/* Stats */} -
+ {STATS.map((stat) => (
))} -
+ + + {/* Product preview mock */} + +
+ + + + nexus ยท SOL / USDC +
+
+ +
+
); } diff --git a/components/ui/Landing.tsx b/components/ui/Landing.tsx index 6aa2ce9..7eb6420 100644 --- a/components/ui/Landing.tsx +++ b/components/ui/Landing.tsx @@ -5,6 +5,7 @@ import { useState } from "react"; import { Menu, X } from "lucide-react"; import Hero from "../HeroSection"; import Advertisment from "../Advertisment"; +import MarketsPreview from "./MarketsPreview"; const NAV_LINKS = [ { label: "Explore", path: "/" }, @@ -84,14 +85,56 @@ export default function Landing() { + + {/* CTA band */} +
+
+
+
+

+ Ready to trade smarter? +

+

+ Jump into live markets with real-time charts and a low-latency + order book. No sign-up required to explore. +

+ +
+
+
+ {/* Footer */} -
-

- Built with Next.js ยท Real-time data via WebSockets ยท{" "} - Nexus Exchange -

+
+
+
+ Nexus logo + + NEXUS + +
+
    + {NAV_LINKS.map((link) => ( +
  • router.push(link.path)} + className="cursor-pointer transition-colors hover:text-white" + > + {link.label} +
  • + ))} +
+

+ ยฉ {new Date().getFullYear()} Nexus ยท Built with Next.js +

+
); diff --git a/components/ui/MarketsPreview.tsx b/components/ui/MarketsPreview.tsx new file mode 100644 index 0000000..22be059 --- /dev/null +++ b/components/ui/MarketsPreview.tsx @@ -0,0 +1,120 @@ +"use client"; + +import { useEffect, useState } from "react"; +import { useRouter } from "next/navigation"; +import { ArrowUpRight, TrendingDown, TrendingUp } from "lucide-react"; +import { getTickers } from "@/app/utils/httpClient"; +import type { Ticker } from "@/app/utils/types"; +import Reveal from "./Reveal"; + +const FEATURED = ["SOL_USDC", "BTC_USDC", "ETH_USDC", "JUP_USDC"]; + +function formatPrice(value: string) { + const n = Number(value); + if (!Number.isFinite(n)) return "โ€”"; + return n.toLocaleString("en-US", { + style: "currency", + currency: "USD", + maximumFractionDigits: n < 1 ? 4 : 2, + }); +} + +export default function MarketsPreview() { + const router = useRouter(); + const [tickers, setTickers] = useState([]); + const [loading, setLoading] = useState(true); + + useEffect(() => { + let active = true; + getTickers() + .then((all) => { + if (!active) return; + const picked = FEATURED.map((s) => + all.find((t) => t.symbol === s) + ).filter(Boolean) as Ticker[]; + setTickers(picked.length ? picked : all.slice(0, 4)); + }) + .catch(() => {}) + .finally(() => active && setLoading(false)); + return () => { + active = false; + }; + }, []); + + return ( +
+ +
+

+ Live markets +

+

+ Real prices, streamed straight from the exchange. +

+
+ +
+ +
+ {(loading ? Array.from({ length: 4 }) : tickers).map((t, i) => { + const ticker = t as Ticker | undefined; + const change = Number(ticker?.priceChangePercent ?? 0) * 100; + const up = change >= 0; + return ( + + + + ); + })} +
+
+ ); +} diff --git a/components/ui/Reveal.tsx b/components/ui/Reveal.tsx new file mode 100644 index 0000000..ca06184 --- /dev/null +++ b/components/ui/Reveal.tsx @@ -0,0 +1,28 @@ +"use client"; + +import { motion } from "framer-motion"; +import type { ReactNode } from "react"; + +export default function Reveal({ + children, + delay = 0, + y = 24, + className, +}: { + children: ReactNode; + delay?: number; + y?: number; + className?: string; +}) { + return ( + + {children} + + ); +} From c844dd93df5b0c401583441e5e0f7593d9ebb270 Mon Sep 17 00:00:00 2001 From: Yuvraj singh Date: Fri, 26 Jun 2026 00:03:40 +0530 Subject: [PATCH 14/16] feat(market): live sparklines, search, favorites tabs and cleaner table - Restore working sparkline charts via lightweight-charts v5 LineSeries API - Add market search box filtering by name/symbol - Functional Spot/Favorites tabs with localStorage-persisted favorites + per-row star toggle - Format price/change cells, empty states, and tidy table styling --- app/market/page.tsx | 251 +++++++++++++++++++++++++++++--------------- 1 file changed, 165 insertions(+), 86 deletions(-) diff --git a/app/market/page.tsx b/app/market/page.tsx index 6ed0084..cb2c5b2 100644 --- a/app/market/page.tsx +++ b/app/market/page.tsx @@ -5,11 +5,14 @@ import { ColorType, createChart, IChartApi, + LineSeries, UTCTimestamp, } from "lightweight-charts"; import { ChevronLeft, ChevronRight, + Search, + Star, TrendingDown, TrendingUp, } from "lucide-react"; @@ -77,6 +80,30 @@ export interface LineCryptoData { export default function Component() { const [data, setData] = useState(null); + const [search, setSearch] = useState(""); + const [tab, setTab] = useState<"spot" | "favorites">("spot"); + const [favorites, setFavorites] = useState(() => { + if (typeof window === "undefined") return []; + try { + return JSON.parse(localStorage.getItem("nx-favorites") || "[]"); + } catch { + return []; + } + }); + + const toggleFavorite = useCallback((symbol: string) => { + setFavorites((prev) => { + const next = prev.includes(symbol) + ? prev.filter((s) => s !== symbol) + : [...prev, symbol]; + try { + localStorage.setItem("nx-favorites", JSON.stringify(next)); + } catch { + /* ignore */ + } + return next; + }); + }, []); useEffect(() => { @@ -303,37 +330,40 @@ const number=0;
-
- - Spot - - - Favorites - +
+
+ {(["spot", "favorites"] as const).map((t) => ( + + ))} +
+
+ + setSearch(e.target.value)} + placeholder="Search marketsโ€ฆ" + className="h-10 w-full rounded-xl border border-white/10 bg-black/30 pl-9 pr-3 text-sm text-white outline-none transition focus:border-cyan-400/60" + /> +
- +
@@ -437,56 +467,89 @@ interface CryptoTableRowProps { volume: number; change: number; klineData: LineCryptoDataPoint[] | undefined; + isFavorite: boolean; + onToggleFavorite: (symbol: string) => void; } -function CryptoTable({ data }: { data: CombinedCryptoData[] | null }) { +function CryptoTable({ + data, + search, + tab, + favorites, + onToggleFavorite, +}: { + data: CombinedCryptoData[] | null; + search: string; + tab: "spot" | "favorites"; + favorites: string[]; + onToggleFavorite: (symbol: string) => void; +}) { if (!data) return null; + + const query = search.trim().toLowerCase(); + const rows = data + .slice() + .sort((a, b) => b.market_cap - a.market_cap) + .filter((item) => !item.symbol.toLowerCase().includes("usdc")) + .filter((item) => + query + ? item.name.toLowerCase().includes(query) || + item.symbol.toLowerCase().includes(query) + : true + ) + .filter((item) => + tab === "favorites" ? favorites.includes(item.symbol.toUpperCase()) : true + ); + return ( - - + + + - - - - - - - {data - ?.sort((a, b) => b.market_cap - a.market_cap) - .slice(0, -5) - .filter((item) => !item.symbol.toLowerCase().includes("usdc")) - .map((item, index) => { - //Now we have to Take each Item and Match the data from the Table and then - // const data = dataKlines?.find((data:any) => data.symbol === item.symbol); - // if (!data) return null; - - return ( - - ); - })} + + {rows.length === 0 ? ( + + + + ) : ( + rows.map((item) => ( + + )) + )}
- Name +
NamePrice + Market Cap Price - โ†“Market Cap - + 24h Volume + 24h Change + Last 7 Days
+ {tab === "favorites" + ? "No favorites yet โ€” tap the โ˜† on any market to add one." + : "No markets match your search."} +
); @@ -501,6 +564,8 @@ function CryptoTableRow({ volume, change, klineData, + isFavorite, + onToggleFavorite, }: CryptoTableRowProps) { function formatNumber(value: number) { if (value >= 1e12) { @@ -527,11 +592,26 @@ function CryptoTableRow({ } > - { + e.stopPropagation(); + onToggleFavorite(symbol.toUpperCase()); + }} + className="mr-3 text-neutral-500 transition-colors hover:text-amber-300" + > + + + - + {symbol} - ${price} + {formatCurrency(price)} 0 ? "text-green-500" : "text-red-500" + className={`text-right py-4 tabular-nums ${ + change >= 0 ? "text-green-500" : "text-red-500" }`} > - {change} % + {change >= 0 ? "+" : ""} + {change?.toFixed(2)}% -
-
- ); + if (!data?.length) + return
; return (
From 29d7f16dae3d3b7674bcf54ab2d49683556dd361 Mon Sep 17 00:00:00 2001 From: Yuvraj singh Date: Fri, 26 Jun 2026 00:05:28 +0530 Subject: [PATCH 15/16] feat(trade): add live Recent Trades panel and refine trading layout - New /api/v1/trades proxy route + getTrades client + Trade type - RecentTrades component polling live trades with buy/sell coloring - Rebalance trading grid: chart / order book / recent trades / order entry --- app/api/v1/trades/route.ts | 23 ++++++++++ app/trade/[market]/page.tsx | 10 ++++- app/utils/httpClient.tsx | 9 +++- app/utils/types.tsx | 11 ++++- components/ui/depth/RecentTrades.tsx | 65 ++++++++++++++++++++++++++++ 5 files changed, 114 insertions(+), 4 deletions(-) create mode 100644 app/api/v1/trades/route.ts create mode 100644 components/ui/depth/RecentTrades.tsx diff --git a/app/api/v1/trades/route.ts b/app/api/v1/trades/route.ts new file mode 100644 index 0000000..bd3ca75 --- /dev/null +++ b/app/api/v1/trades/route.ts @@ -0,0 +1,23 @@ +import { NextResponse } from "next/server"; + +export async function GET(request: Request) { + try { + const { searchParams } = new URL(request.url); + const symbol = searchParams.get("symbol"); + const limit = searchParams.get("limit") ?? "30"; + + const response = await fetch( + `https://api.backpack.exchange/api/v1/trades?symbol=${symbol}&limit=${limit}`, + { headers: { Accept: "application/json" } } + ); + + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + + const data = await response.json(); + return NextResponse.json(data); + } catch (error) { + return NextResponse.json({ error: String(error) }, { status: 500 }); + } +} diff --git a/app/trade/[market]/page.tsx b/app/trade/[market]/page.tsx index 5218a46..7a569ad 100644 --- a/app/trade/[market]/page.tsx +++ b/app/trade/[market]/page.tsx @@ -1,6 +1,7 @@ "use client"; import { useParams } from "next/navigation"; import { Depth } from "@/components/ui/depth/Depth"; +import { RecentTrades } from "@/components/ui/depth/RecentTrades"; import { TradeView } from "@/components/ui/Tradeview"; import Appbar from "@/components/ui/Appbar"; import { SwapUI } from "@/components/ui/SwapUi"; @@ -24,7 +25,7 @@ export default function Page() { {/* Main trading grid */}
{/* Chart */} -
+
@@ -33,8 +34,13 @@ export default function Page() {
+ {/* Recent trades */} +
+ +
+ {/* Order entry */} -
+
diff --git a/app/utils/httpClient.tsx b/app/utils/httpClient.tsx index 15d1fdb..34cd8e5 100644 --- a/app/utils/httpClient.tsx +++ b/app/utils/httpClient.tsx @@ -1,6 +1,6 @@ import axios from "axios"; -import { KLine, Ticker, marketData } from "./types"; +import { KLine, Ticker, Trade, marketData } from "./types"; const API_PREFIX = "/api/v1"; @@ -25,6 +25,13 @@ export async function getTicker(market: string) { return tickers.find((t: Ticker) => t.symbol === market) ?? null; } +export async function getTrades(market: string, limit = 30): Promise { + const response = await api.get("/trades", { + params: { symbol: market, limit }, + }); + return Array.isArray(response.data) ? (response.data as Trade[]) : []; +} + export async function getTickers() { const response = await api.get("/tickers"); diff --git a/app/utils/types.tsx b/app/utils/types.tsx index ca95f11..6c9de47 100644 --- a/app/utils/types.tsx +++ b/app/utils/types.tsx @@ -29,9 +29,18 @@ export interface KLine { } export interface marketData{ - + lastPrice:string, symbol:string, priceChangePercent:string +} + +export interface Trade { + id: number; + price: string; + quantity: string; + quoteQuantity: string; + timestamp: number; + isBuyerMaker: boolean; } \ No newline at end of file diff --git a/components/ui/depth/RecentTrades.tsx b/components/ui/depth/RecentTrades.tsx new file mode 100644 index 0000000..b39a7f3 --- /dev/null +++ b/components/ui/depth/RecentTrades.tsx @@ -0,0 +1,65 @@ +"use client"; + +import { useEffect, useState } from "react"; +import { getTrades } from "@/app/utils/httpClient"; +import type { Trade } from "@/app/utils/types"; + +export function RecentTrades({ market }: { market: string }) { + const [trades, setTrades] = useState([]); + + useEffect(() => { + let active = true; + const load = () => + getTrades(market, 30) + .then((t) => active && setTrades(t.slice().reverse())) + .catch(() => {}); + load(); + const id = setInterval(load, 4000); + return () => { + active = false; + clearInterval(id); + }; + }, [market]); + + return ( +
+
Recent Trades
+
+ Price + Size + Time +
+
+ {trades.length === 0 ? ( +
+ Loading tradesโ€ฆ +
+ ) : ( + trades.map((t) => { + const buy = !t.isBuyerMaker; + return ( +
+ + {Number(t.price).toLocaleString("en-US", { + maximumFractionDigits: 4, + })} + + + {Number(t.quantity).toFixed(2)} + + + {new Date(t.timestamp).toLocaleTimeString("en-US", { + hour12: false, + })} + +
+ ); + }) + )} +
+
+ ); +} From 531d8475a310ff07b887ddc3e5a8a73cbbfaead6 Mon Sep 17 00:00:00 2001 From: Vercel Date: Thu, 16 Jul 2026 19:13:28 +0000 Subject: [PATCH 16/16] Fix React Server Components CVE vulnerabilities Updated dependencies to fix Next.js and React CVE vulnerabilities. The fix-react2shell-next tool automatically updated the following packages to their secure versions: - next - react-server-dom-webpack - react-server-dom-parcel - react-server-dom-turbopack All package.json files have been scanned and vulnerable versions have been patched to the correct fixed versions based on the official React advisory. Co-authored-by: Vercel --- package-lock.json | 80 +++++++++++++++++++++++------------------------ package.json | 2 +- 2 files changed, 41 insertions(+), 41 deletions(-) diff --git a/package-lock.json b/package-lock.json index 79b436c..6d15b49 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,7 +21,7 @@ "framer-motion": "^12.23.24", "lightweight-charts": "^5.0.9", "lucide-react": "^0.554.0", - "next": "^15.5.2", + "next": "15.5.9", "postcss": "^8.5.6", "react": "^19.1.1", "react-dom": "^19.1.1", @@ -1395,9 +1395,9 @@ } }, "node_modules/@next/env": { - "version": "15.5.2", - "resolved": "https://registry.npmjs.org/@next/env/-/env-15.5.2.tgz", - "integrity": "sha512-Qe06ew4zt12LeO6N7j8/nULSOe3fMXE4dM6xgpBQNvdzyK1sv5y4oAP3bq4LamrvGCZtmRYnW8URFCeX5nFgGg==", + "version": "15.5.9", + "resolved": "https://registry.npmjs.org/@next/env/-/env-15.5.9.tgz", + "integrity": "sha512-4GlTZ+EJM7WaW2HEZcyU317tIQDjkQIyENDLxYJfSWlfqguN+dHkZgyQTV/7ykvobU7yEH5gKvreNrH4B6QgIg==", "license": "MIT" }, "node_modules/@next/eslint-plugin-next": { @@ -1411,9 +1411,9 @@ } }, "node_modules/@next/swc-darwin-arm64": { - "version": "15.5.2", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-15.5.2.tgz", - "integrity": "sha512-8bGt577BXGSd4iqFygmzIfTYizHb0LGWqH+qgIF/2EDxS5JsSdERJKA8WgwDyNBZgTIIA4D8qUtoQHmxIIquoQ==", + "version": "15.5.7", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-15.5.7.tgz", + "integrity": "sha512-IZwtxCEpI91HVU/rAUOOobWSZv4P2DeTtNaCdHqLcTJU4wdNXgAySvKa/qJCgR5m6KI8UsKDXtO2B31jcaw1Yw==", "cpu": [ "arm64" ], @@ -1427,9 +1427,9 @@ } }, "node_modules/@next/swc-darwin-x64": { - "version": "15.5.2", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-15.5.2.tgz", - "integrity": "sha512-2DjnmR6JHK4X+dgTXt5/sOCu/7yPtqpYt8s8hLkHFK3MGkka2snTv3yRMdHvuRtJVkPwCGsvBSwmoQCHatauFQ==", + "version": "15.5.7", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-15.5.7.tgz", + "integrity": "sha512-UP6CaDBcqaCBuiq/gfCEJw7sPEoX1aIjZHnBWN9v9qYHQdMKvCKcAVs4OX1vIjeE+tC5EIuwDTVIoXpUes29lg==", "cpu": [ "x64" ], @@ -1443,9 +1443,9 @@ } }, "node_modules/@next/swc-linux-arm64-gnu": { - "version": "15.5.2", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-15.5.2.tgz", - "integrity": "sha512-3j7SWDBS2Wov/L9q0mFJtEvQ5miIqfO4l7d2m9Mo06ddsgUK8gWfHGgbjdFlCp2Ek7MmMQZSxpGFqcC8zGh2AA==", + "version": "15.5.7", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-15.5.7.tgz", + "integrity": "sha512-NCslw3GrNIw7OgmRBxHtdWFQYhexoUCq+0oS2ccjyYLtcn1SzGzeM54jpTFonIMUjNbHmpKpziXnpxhSWLcmBA==", "cpu": [ "arm64" ], @@ -1459,9 +1459,9 @@ } }, "node_modules/@next/swc-linux-arm64-musl": { - "version": "15.5.2", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-15.5.2.tgz", - "integrity": "sha512-s6N8k8dF9YGc5T01UPQ08yxsK6fUow5gG1/axWc1HVVBYQBgOjca4oUZF7s4p+kwhkB1bDSGR8QznWrFZ/Rt5g==", + "version": "15.5.7", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-15.5.7.tgz", + "integrity": "sha512-nfymt+SE5cvtTrG9u1wdoxBr9bVB7mtKTcj0ltRn6gkP/2Nu1zM5ei8rwP9qKQP0Y//umK+TtkKgNtfboBxRrw==", "cpu": [ "arm64" ], @@ -1475,9 +1475,9 @@ } }, "node_modules/@next/swc-linux-x64-gnu": { - "version": "15.5.2", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-15.5.2.tgz", - "integrity": "sha512-o1RV/KOODQh6dM6ZRJGZbc+MOAHww33Vbs5JC9Mp1gDk8cpEO+cYC/l7rweiEalkSm5/1WGa4zY7xrNwObN4+Q==", + "version": "15.5.7", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-15.5.7.tgz", + "integrity": "sha512-hvXcZvCaaEbCZcVzcY7E1uXN9xWZfFvkNHwbe/n4OkRhFWrs1J1QV+4U1BN06tXLdaS4DazEGXwgqnu/VMcmqw==", "cpu": [ "x64" ], @@ -1491,9 +1491,9 @@ } }, "node_modules/@next/swc-linux-x64-musl": { - "version": "15.5.2", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-15.5.2.tgz", - "integrity": "sha512-/VUnh7w8RElYZ0IV83nUcP/J4KJ6LLYliiBIri3p3aW2giF+PAVgZb6mk8jbQSB3WlTai8gEmCAr7kptFa1H6g==", + "version": "15.5.7", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-15.5.7.tgz", + "integrity": "sha512-4IUO539b8FmF0odY6/SqANJdgwn1xs1GkPO5doZugwZ3ETF6JUdckk7RGmsfSf7ws8Qb2YB5It33mvNL/0acqA==", "cpu": [ "x64" ], @@ -1507,9 +1507,9 @@ } }, "node_modules/@next/swc-win32-arm64-msvc": { - "version": "15.5.2", - "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-15.5.2.tgz", - "integrity": "sha512-sMPyTvRcNKXseNQ/7qRfVRLa0VhR0esmQ29DD6pqvG71+JdVnESJaHPA8t7bc67KD5spP3+DOCNLhqlEI2ZgQg==", + "version": "15.5.7", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-15.5.7.tgz", + "integrity": "sha512-CpJVTkYI3ZajQkC5vajM7/ApKJUOlm6uP4BknM3XKvJ7VXAvCqSjSLmM0LKdYzn6nBJVSjdclx8nYJSa3xlTgQ==", "cpu": [ "arm64" ], @@ -1523,9 +1523,9 @@ } }, "node_modules/@next/swc-win32-x64-msvc": { - "version": "15.5.2", - "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-15.5.2.tgz", - "integrity": "sha512-W5VvyZHnxG/2ukhZF/9Ikdra5fdNftxI6ybeVKYvBPDtyx7x4jPPSNduUkfH5fo3zG0JQ0bPxgy41af2JX5D4Q==", + "version": "15.5.7", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-15.5.7.tgz", + "integrity": "sha512-gMzgBX164I6DN+9/PGA+9dQiwmTkE4TloBNx8Kv9UiGARsr9Nba7IpcBRA1iTV9vwlYnrE3Uy6I7Aj6qLjQuqw==", "cpu": [ "x64" ], @@ -5708,12 +5708,12 @@ "license": "MIT" }, "node_modules/next": { - "version": "15.5.2", - "resolved": "https://registry.npmjs.org/next/-/next-15.5.2.tgz", - "integrity": "sha512-H8Otr7abj1glFhbGnvUt3gz++0AF1+QoCXEBmd/6aKbfdFwrn0LpA836Ed5+00va/7HQSDD+mOoVhn3tNy3e/Q==", + "version": "15.5.9", + "resolved": "https://registry.npmjs.org/next/-/next-15.5.9.tgz", + "integrity": "sha512-agNLK89seZEtC5zUHwtut0+tNrc0Xw4FT/Dg+B/VLEo9pAcS9rtTKpek3V6kVcVwsB2YlqMaHdfZL4eLEVYuCg==", "license": "MIT", "dependencies": { - "@next/env": "15.5.2", + "@next/env": "15.5.9", "@swc/helpers": "0.5.15", "caniuse-lite": "^1.0.30001579", "postcss": "8.4.31", @@ -5726,14 +5726,14 @@ "node": "^18.18.0 || ^19.8.0 || >= 20.0.0" }, "optionalDependencies": { - "@next/swc-darwin-arm64": "15.5.2", - "@next/swc-darwin-x64": "15.5.2", - "@next/swc-linux-arm64-gnu": "15.5.2", - "@next/swc-linux-arm64-musl": "15.5.2", - "@next/swc-linux-x64-gnu": "15.5.2", - "@next/swc-linux-x64-musl": "15.5.2", - "@next/swc-win32-arm64-msvc": "15.5.2", - "@next/swc-win32-x64-msvc": "15.5.2", + "@next/swc-darwin-arm64": "15.5.7", + "@next/swc-darwin-x64": "15.5.7", + "@next/swc-linux-arm64-gnu": "15.5.7", + "@next/swc-linux-arm64-musl": "15.5.7", + "@next/swc-linux-x64-gnu": "15.5.7", + "@next/swc-linux-x64-musl": "15.5.7", + "@next/swc-win32-arm64-msvc": "15.5.7", + "@next/swc-win32-x64-msvc": "15.5.7", "sharp": "^0.34.3" }, "peerDependencies": { diff --git a/package.json b/package.json index 33e35bb..f477ed9 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,7 @@ "framer-motion": "^12.23.24", "lightweight-charts": "^5.0.9", "lucide-react": "^0.554.0", - "next": "^15.5.2", + "next": "15.5.9", "postcss": "^8.5.6", "react": "^19.1.1", "react-dom": "^19.1.1",