From d88c8614206895a79c92eb5110faf15224e478b3 Mon Sep 17 00:00:00 2001 From: Klesti Selimaj Date: Thu, 12 Feb 2026 14:00:24 +0100 Subject: [PATCH 1/9] Token card twitter author --- src/app/markets/components/PairsCard.tsx | 13 +++++- src/app/markets/components/TokenCard.tsx | 55 ++++++++++++++++++++++-- src/lib/renderUtils.ts | 6 +++ src/modules/tokens/types.ts | 7 +++ 4 files changed, 76 insertions(+), 5 deletions(-) create mode 100644 src/lib/renderUtils.ts diff --git a/src/app/markets/components/PairsCard.tsx b/src/app/markets/components/PairsCard.tsx index ba62ff1..370ef8d 100644 --- a/src/app/markets/components/PairsCard.tsx +++ b/src/app/markets/components/PairsCard.tsx @@ -41,7 +41,18 @@ export default function PairsCard({ title }: { title: string }) { diff --git a/src/app/markets/components/TokenCard.tsx b/src/app/markets/components/TokenCard.tsx index 9ba14dd..642afe8 100644 --- a/src/app/markets/components/TokenCard.tsx +++ b/src/app/markets/components/TokenCard.tsx @@ -1,5 +1,6 @@ import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; +import { humanizeNumber } from "@/lib/renderUtils"; import { cn } from "@/lib/utils"; import { Token, TokenLiveData } from "@/modules/tokens/types"; import { @@ -12,10 +13,13 @@ import { GhostIcon, IconNode, LucideIcon, + UserIcon, UsersIcon, UserStarIcon, ZapIcon, } from "lucide-react"; +import Link from "next/link"; +import { useRouter } from "next/navigation"; export default function TokenCard({ token }: { token: Token }) { const live: TokenLiveData = { @@ -26,8 +30,16 @@ export default function TokenCard({ token }: { token: Token }) { bundleHold: 3, }; + const router = useRouter(); + return ( -
+
router.push(`/token/${token.mint}`)} + onContextMenu={() => + window.open(`/token/${token.mint}`, "_blank", "noopener,noreferrer") + } + >
{token.logoURI ? (

-
+

{token.symbol}

-

+

{ + e.preventDefault(); + e.stopPropagation(); + navigator.clipboard.writeText(token.mint); + }} + > {token.name}

@@ -60,6 +79,28 @@ export default function TokenCard({ token }: { token: Token }) { 10

+
+ {token.twitterPost ? ( + <> + { + e.stopPropagation(); + }} + > + by @{token.twitterPost.author?.username} + +

+ + {humanizeNumber(token.twitterPost.author?.followers)} +

+ + ) : ( + by @username + )} +
@@ -71,7 +112,13 @@ export default function TokenCard({ token }: { token: Token }) {
-
diff --git a/src/lib/renderUtils.ts b/src/lib/renderUtils.ts new file mode 100644 index 0000000..ab706a0 --- /dev/null +++ b/src/lib/renderUtils.ts @@ -0,0 +1,6 @@ +export const humanizeNumber = (num: number) => { + return new Intl.NumberFormat("en", { + notation: "compact", + maximumFractionDigits: 1, + }).format(num); +}; diff --git a/src/modules/tokens/types.ts b/src/modules/tokens/types.ts index 958be07..8a3f3fb 100644 --- a/src/modules/tokens/types.ts +++ b/src/modules/tokens/types.ts @@ -3,6 +3,13 @@ export interface Token { symbol: string; name: string; logoURI?: string; + twitterPost: { + link: string; + author: { + username: string; + followers: number; + }; + }; } export interface TokenLiveData { From f8770477b4a3d4d82c7698ca9cb36e687c70ccdc Mon Sep 17 00:00:00 2001 From: Klesti Selimaj Date: Thu, 12 Feb 2026 14:27:48 +0100 Subject: [PATCH 2/9] Tooltips --- src/app/layout.tsx | 3 +- src/app/markets/components/TokenCard.tsx | 100 ++++++++++++++++------- src/components/ui/tooltip.tsx | 57 +++++++++++++ src/components/utils/MinimalTooltip.tsx | 18 ++++ 4 files changed, 147 insertions(+), 31 deletions(-) create mode 100644 src/components/ui/tooltip.tsx create mode 100644 src/components/utils/MinimalTooltip.tsx diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 8c9b472..98c957c 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -1,6 +1,7 @@ import type { Metadata } from "next"; import { Geist, Geist_Mono } from "next/font/google"; import "./globals.css"; +import { TooltipProvider } from "@/components/ui/tooltip"; const geistSans = Geist({ variable: "--font-geist-sans", @@ -27,7 +28,7 @@ export default function RootLayout({ - {children} + {children} ); diff --git a/src/app/markets/components/TokenCard.tsx b/src/app/markets/components/TokenCard.tsx index 642afe8..6a83fd3 100644 --- a/src/app/markets/components/TokenCard.tsx +++ b/src/app/markets/components/TokenCard.tsx @@ -1,5 +1,11 @@ import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; +import { + Tooltip, + TooltipContent, + TooltipTrigger, +} from "@/components/ui/tooltip"; +import MinimalTooltip from "@/components/utils/MinimalTooltip"; import { humanizeNumber } from "@/lib/renderUtils"; import { cn } from "@/lib/utils"; import { Token, TokenLiveData } from "@/modules/tokens/types"; @@ -35,7 +41,13 @@ export default function TokenCard({ token }: { token: Token }) { return (
router.push(`/token/${token.mint}`)} + onClick={(e) => { + if (e.ctrlKey || e.metaKey) { + window.open(`/token/${token.mint}`, "_blank", "noopener,noreferrer"); + } else { + router.push(`/token/${token.mint}`); + } + }} onContextMenu={() => window.open(`/token/${token.mint}`, "_blank", "noopener,noreferrer") } @@ -70,48 +82,76 @@ export default function TokenCard({ token }: { token: Token }) {

20m

-

- - 10 -

-

- - 10 -

+ +

+ + 10 +

+
+ +

+ + 10 +

+
{token.twitterPost ? ( <> - { - e.stopPropagation(); - }} - > - by @{token.twitterPost.author?.username} - -

- - {humanizeNumber(token.twitterPost.author?.followers)} -

+ + { + e.stopPropagation(); + }} + > + by @{token.twitterPost.author?.username} + + + +

+ + {humanizeNumber(token.twitterPost.author?.followers)} +

+
) : ( by @username )}
- - - - - + + + + + + + + + + + + + + + + + + +
- - + + + + + + + +
From b6627f87aac33744cebfd6f921e5fb78f5e702dc Mon Sep 17 00:00:00 2001 From: Klesti Selimaj Date: Thu, 12 Feb 2026 15:12:37 +0100 Subject: [PATCH 7/9] Improved tooltips --- src/app/markets/components/TokenCard.tsx | 47 ++++++++++++++---------- src/components/utils/MinimalTooltip.tsx | 8 +++- 2 files changed, 34 insertions(+), 21 deletions(-) diff --git a/src/app/markets/components/TokenCard.tsx b/src/app/markets/components/TokenCard.tsx index 53287cb..af1bef3 100644 --- a/src/app/markets/components/TokenCard.tsx +++ b/src/app/markets/components/TokenCard.tsx @@ -107,19 +107,23 @@ export default function TokenCard({ token }: { token: Token }) {
{token.twitterPost ? ( <> - e.stopPropagation()} - > - by @{token.twitterPost.author?.username} - + + e.stopPropagation()} + > + by @{token.twitterPost.author?.username} + + -

- - {humanizeNumber(token.twitterPost.author?.followers)} -

+ +

+ + {humanizeNumber(token.twitterPost.author?.followers)} +

+
) : ( by @username @@ -128,23 +132,23 @@ export default function TokenCard({ token }: { token: Token }) { {/* Badges */}
- + - + - + - + - +
@@ -159,8 +163,13 @@ export default function TokenCard({ token }: { token: Token }) { " >
- - + + + + + + +
- - + + {tokens.map((token) => ( +
+ +
+ ))}
); diff --git a/src/app/markets/components/TokenCard.tsx b/src/app/markets/components/TokenCard.tsx index af1bef3..51e0fdd 100644 --- a/src/app/markets/components/TokenCard.tsx +++ b/src/app/markets/components/TokenCard.tsx @@ -12,7 +12,6 @@ import { CrosshairIcon, EyeIcon, GhostIcon, - IconNode, LucideIcon, UserIcon, UsersIcon, diff --git a/src/app/markets/page.tsx b/src/app/markets/page.tsx index a96ae92..93d6d14 100644 --- a/src/app/markets/page.tsx +++ b/src/app/markets/page.tsx @@ -10,9 +10,57 @@ export default function Markets() {
- - - + + +
From de7e0fd7820c60883302930bd728742e62e468b2 Mon Sep 17 00:00:00 2001 From: Klesti Selimaj Date: Fri, 13 Feb 2026 01:43:39 +0100 Subject: [PATCH 9/9] Landing page --- src/app/page.tsx | 147 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 145 insertions(+), 2 deletions(-) diff --git a/src/app/page.tsx b/src/app/page.tsx index 5776a87..9b5b65d 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -1,3 +1,146 @@ -export default function Home() { - return
hello world
; +import Link from "next/link"; + +export default function Landing() { + return ( +
+ {/* Background gradients */} +
+
+
+
+ + {/* Hero */} +
+
+

+ Trade memecoins
+ + without trading blind + +

+ +

+ Nexa filters noise, intercepts high-rug setups, and executes faster, + so you spend less time guessing and more time surviving. +

+ +
+ + + + + + +
+
+
+ + {/* Live signal strip */} + {/*
+
+ 🟢 12 rugs intercepted today + ⚡ Median execution: 420ms + 📉 Top 10 holder risk flagged + 🔍 Bundler detected pre-launch +
+
*/} + + {/* Why Nexa */} +
+
+
+

Risk-aware by default

+

+ Every trade is evaluated against holder concentration, bundlers, + deployer behavior, and liquidity signals, before execution. +

+
+ +
+

AI where it matters

+

+ No magic predictions. Just automated checks that experienced + traders already do, instantly and consistently. +

+
+ +
+

Built for speed

+

+ Optimized request batching, Solana-native execution, and Jupiter + routing keep latency low even during peak volume. +

+
+
+
+ + {/* Risk interception highlight */} +
+
+

+ Nexa can stop you before you buy a rug +

+

+ When high-risk patterns are detected, Nexa blocks execution by + default and tells you exactly why. If you still want in, that's your + call. But it won't be blind. +

+
+
+ + {/* How it works */} +
+

How it works

+ +
+
+ + 1. Detect + + New pairs, migrations, and liquidity events are tracked in real + time. +
+
+ + 2. Analyze + + Risk signals, holder distribution, and deployer behavior are scored. +
+
+ + 3. Decide + + AI filters or manual overrides determine execution eligibility. +
+
+ + 4. Execute + + Trades are routed through Jupiter with minimal latency. +
+
+
+ + {/* Fees & alignment */} +
+
+

+ Fees that scale with success +

+

+ Nexa charges a small platform fee on executed trades, with optional + AI and quant features available per-use. No subscriptions. No hidden + incentives. +

+
+
+
+ ); }