Next.js 14 DEX Interface for the Aether-Swap AMM protocol on Stellar.
Organization: Aether-Swap · Author: Alhaji-naira
The Aether-Swap Frontend is a production-grade DEX interface featuring:
- 🔄 Token Swap UI — Constant-product swap with slippage tolerance and price impact
- 💧 Liquidity Provision — Add/remove liquidity with LP share tracking
- 🔗 Freighter Wallet — Stellar browser wallet integration with live connection state
- 📊 Live Pool Stats — 24h volume, reserve balances, and trade count from the backend API
- 🌙 Dark Mode Design — Glassmorphism UI with animated gradients
Aether-Swap-Frontend/
├── package.json
├── next.config.js
├── tailwind.config.ts
├── tsconfig.json
└── src/
├── app/
│ ├── layout.tsx # Root layout with fonts and metadata
│ └── page.tsx # Main DEX dashboard (Swap + Liquidity tabs)
└── lib/
└── freighter.ts # Freighter wallet Zustand store + utilities
The main page renders:
| Component | Responsibility |
|---|---|
<SwapPanel> |
Token input/output, flip direction, slippage, swap CTA |
<LiquidityPanel> |
Add/remove liquidity with mode toggle |
<TokenSelector> |
Dropdown to pick from available Stellar tokens |
<StatCard> |
Summary card for volume, reserves, and trade count |
| Header | Navigation + wallet connect/disconnect button |
Built on Zustand for global state:
| Export | Type | Description |
|---|---|---|
useWalletStore |
Zustand store | connect, disconnect, signTx, all state |
truncateAddress |
util function | Shorten public key for UI display |
explorerUrl |
util function | Generate Stellar Expert link for an account |
watchWallet |
subscription | Listen for account/network changes |
checkFreighterInstalled |
async | Detect if Freighter extension is present |
- Node.js ≥ 20.0.0
- npm ≥ 10
- Freighter browser extension (for wallet features)
cd Aether-Swap-Frontend
npm installCreate .env.local:
NEXT_PUBLIC_API_URL=http://localhost:3001
NEXT_PUBLIC_POOL_ID=CAETHER000000DEMOnpm run devOpen http://localhost:3000 in your browser.
npm run build
npm start| Library | Version | Purpose |
|---|---|---|
| Next.js | 14.2.x | React framework with App Router |
| React | 18.x | UI rendering |
| Tailwind CSS | 3.4.x | Utility-first styling |
| Zustand | 4.x | Lightweight global state management |
@stellar/freighter-api |
2.x | Freighter wallet browser bindings |
@stellar/stellar-sdk |
12.x | XDR building, Horizon queries |
| Framer Motion | 11.x | Page and component animations |
| Lucide React | 0.414 | Icon library |
| Recharts | 2.x | Price/volume charts (extend as needed) |
page.tsx
├── useWalletStore (Zustand) ← freighter.ts
├── fetchStats() ← Aether-Swap Backend API
├── <SwapPanel>
│ └── TokenSelector
└── <LiquidityPanel>
└── mode: add | remove
State is globally reactive via Zustand — wallet connection status is shared across all components without prop drilling.
Edit the TOKENS constant in src/app/page.tsx:
const TOKENS = [
{ symbol: 'XLM', name: 'Stellar Lumens', logo: '⭐' },
{ symbol: 'USDC', name: 'USD Coin', logo: '💵' },
// Add new tokens here
{ symbol: 'yXLM', name: 'Yield XLM', logo: '🌱' },
];In SwapPanel.handleSwap(), replace the mock delay with:
import { TransactionBuilder, Networks, Operation } from '@stellar/stellar-sdk';
import { useWalletStore } from '@/lib/freighter';
// Build XDR → sign with Freighter → submit to Horizon
const xdr = buildSorobanSwapXdr(poolId, tokenIn, amountIn, minAmountOut);
const signedXdr = await useWalletStore.getState().signTx(xdr);
await submitToHorizon(signedXdr);MIT © Aether-Swap