Fast & Secure DeFi Lending on Stellar
Stellarlend is a decentralized finance (DeFi) lending platform built on the Stellar blockchain. It enables users to borrow and lend digital assets with ultra-low fees, instant settlements, and full transparency—powered by Soroban smart contracts. The platform is designed for both crypto-native users and those new to DeFi, offering an intuitive interface for managing lending and borrowing operations on one of the most efficient blockchain networks.
This frontend application provides a modern, responsive web interface for interacting with the Stellarlend protocol, featuring real-time transaction tracking, interest rate calculations, and comprehensive dashboard analytics.
- Lending & Borrowing: Earn interest by lending assets or borrow against collateral
- Multi-Asset Support: Support for XLM, USDC, BTC, ETH, and other Stellar-based assets
- Real-Time Asset Pricing: Cached price oracle proxy for secure price feeds
- Real-Time Calculations: Dynamic interest rate and payment calculations
- Transaction Management: Track all lending, borrowing, and payment transactions
- Dashboard Analytics: Comprehensive metrics and insights
- Responsive Design: Optimized for desktop, tablet, and mobile devices
- Component Library: Built with Storybook for component development and documentation
- Node.js: v18.0.0 or higher
- Package Manager: npm, yarn, pnpm, or bun
- Git: For version control
git clone <repository-url>
cd Stellarlend-frontendChoose your preferred package manager:
# Using npm
npm install
# Using yarn
yarn install
# Using pnpm (recommended)
pnpm install
# Using bun
bun installCreate a .env.local file in the root directory:
cp .env.example .env.localEdit .env.local with your configuration:
# Stellar Network Configuration
NEXT_PUBLIC_STELLAR_NETWORK=testnet
NEXT_PUBLIC_STELLAR_HORIZON_URL=https://horizon-testnet.stellar.org
STELLAR_HORIZON_URLS=https://horizon-testnet.stellar.org,https://horizon-backup.stellar.org
NEXT_PUBLIC_SOROBAN_RPC_URL=https://soroban-testnet.stellar.org
NEXT_PUBLIC_SOROBAN_CONTRACT_ID=GXXXXXXXXXXXXXXX...YOUR_CONTRACT_ID
SOROBAN_RPC_URL=https://soroban-testnet.stellar.org
# API Configuration (if applicable)
NEXT_PUBLIC_API_URL=http://localhost:3001/api
# Feature Flags
NEXT_PUBLIC_ENABLE_ANALYTICS=false
# Server Logging Configuration
SERVER_LOG_LEVEL=info
# Transaction Rate Limiting
API_RATE_LIMIT_MAX=100
API_RATE_LIMIT_WINDOW_MS=60000
TX_ACCOUNT_RATE_LIMIT_MAX=30
TX_ACCOUNT_RATE_LIMIT_WINDOW_MS=60000
TX_ACCOUNT_RATE_LIMIT_BURST=60The Tx relay routes /api/tx/build and /api/tx/submit are protected by an account-scoped wallet limit. If a wallet exceeds the configured burst or window, the response returns 429 with Retry-After and standard RateLimit-* headers.
Migration note: if you previously used NEXT_PUBLIC_SOROBAN_RPC_URL, rename it to SOROBAN_RPC_URL and restart the dev server or rebuild your deployment. The RPC endpoint now stays server-only so browsers cannot bypass the relay and its rate limits.
Logging is emitted as structured JSON by lib/logger.ts and includes:
timestamplevelroutemethodstatusdurationMsmessagecontext
Sensitive information such as authorization headers, API keys, auth tokens, and Stellar public/secret keys are redacted automatically.
Note: For production, use the Stellar mainnet configuration and secure your environment variables.
# Using npm
npm run dev
# Using yarn
yarn dev
# Using pnpm
pnpm dev
# Using bun
bun devOpen http://localhost:3000 in your browser to see the application.
Stellarlend uses Drizzle ORM with a PostgreSQL database backend to persist accounts, sessions, notifications, transactions, and audit logs.
-
Ensure your
.env.localcontains the database connection URL:DATABASE_URL=postgres://postgres:postgres@localhost:5432/stellarlend
-
Run the migrations to initialize your local database:
# Using npm npm run db:migrate # Using pnpm pnpm db:migrate
npm run build
npm start# Run all tests
npm test
# Run tests in watch mode
npm test -- --watch
# Run tests with coverage
npm test -- --coverage# Start Storybook development server
npm run storybook
# Build Storybook for static hosting
npm run build-storybookStorybook will be available at http://localhost:6006
Stellarlend-frontend/
├── app/ # Next.js App Router pages
│ ├── account/ # User account pages
│ ├── dashboard/ # Dashboard pages
│ ├── lending/ # Lending & borrowing pages
│ └── layout.tsx # Root layout
├── components/ # React components
│ ├── atoms/ # Atomic design: smallest components
│ ├── molecules/ # Composite components
│ ├── organisms/ # Complex components
│ ├── features/ # Feature-specific components
│ │ ├── account/ # Account feature components
│ │ ├── dashboard/ # Dashboard feature components
│ │ └── lending/ # Lending feature components
│ ├── marketing/ # Marketing page components
│ └── shared/ # Shared components
│ ├── ui/ # UI components (buttons, icons, etc.)
│ ├── layout/ # Layout components (navbar, sidebar, etc.)
│ └── common/ # Common utility components
├── constants/ # Application constants
│ └── design-tokens.ts # Design system tokens
├── context/ # React context providers
│ └── SidebarContext.tsx
├── lib/ # Utility libraries
│ ├── auth.ts # Authentication utilities
│ ├── utils/ # Utility functions
│ │ ├── cn.ts # Class name utilities (Tailwind merge)
│ │ └── index.ts # Utils barrel export
│ └── index.ts # Lib barrel export
├── types/ # TypeScript type definitions
│ ├── Transaction.ts # Transaction-related types
│ ├── common.ts # Common utility types
│ └── index.ts # Types barrel export
├── public/ # Static assets
│ ├── icons/ # Icon assets
│ └── images/ # Image assets
├── scripts/ # Build and utility scripts
│ ├── svgToComponent.js # SVG to React component converter
│ └── generate-component.js
├── test/ # Test utilities and helpers
│ ├── test-utils.tsx
│ └── component-helpers.ts
└── stories/ # Storybook stories
We use Plop for component scaffolding:
npm run generate-componentFollow the prompts to create a new component with proper structure, tests, and Storybook stories.
Place SVG files in public/images and run:
npm run svgThis will automatically convert SVGs to React components in components/shared/ui/icons/.
The server-side API surface is documented in two places:
| Resource | Description |
|---|---|
docs/backend-architecture.md |
Architecture overview — lib/ modules, caching model, security, and how to add a new route |
openapi.yaml |
OpenAPI 3.1 spec for all app/api/* routes, params, and response shapes |
| Method | Path | Auth | Description |
|---|---|---|---|
GET |
/api/health |
Public | Platform & Stellar network health |
POST/GET/DELETE |
/api/auth/session |
— | Session lifecycle |
GET |
/api/prices |
Public | Asset spot prices (cached 5 s) |
GET |
/api/markets |
Public | Per-asset supply/borrow APR & utilization (cached 30 s) |
GET |
/api/positions |
Optional | User lending/borrowing positions |
GET/POST |
/api/transactions |
Public | Transaction history and creation |
GET |
/api/transactions/export |
Public | Transactions CSV export |
POST |
/api/quote |
Public | Lending/borrowing quote calculation |
GET |
/api/notifications |
Required | List in-app notifications |
PATCH |
/api/notifications/:id |
Required | Mark notification as read |
- Next.js Documentation - Learn about Next.js features and API
- React Documentation - React library documentation
- TypeScript Documentation - TypeScript language reference
- Tailwind CSS Documentation - Utility-first CSS framework
- Stellar Documentation - Stellar blockchain development guide
- Soroban Documentation - Soroban smart contracts
- Idempotency contract and key lifetime - API replay protection and cache retention guidance
- Storybook - Component development environment
- Vitest - Fast unit test framework
- Playwright - End-to-end testing framework
- Framer Motion - Animation library
- Lucide Icons - Icon library
We welcome contributions! Please see our Contributing Guide for detailed guidelines.
Quick Start:
- Fork the repository and create a feature branch
- Follow the code style - We use ESLint and Prettier (configured with Husky pre-commit hooks)
- Write tests for new features and bug fixes
- Update documentation as needed
- Submit a pull request with a clear description of changes
- Linting: Run
npm run lintbefore committing - Formatting: Prettier is configured to run automatically on commit
- TypeScript: Strict mode enabled - ensure all types are properly defined
We use Conventional Commits. Examples:
feat: add new lending form componentfix: resolve transaction status display issuedocs: update README with setup instructions
For more details, see CONTRIBUTING.md.
Stellarlend uses BullMQ (backed by Redis) to process long-running, asynchronous tasks outside the Next.js API request lifecycle. This guarantees that user-facing API routes remain responsive and non-blocking.
indexer-queue: Periodically indexes on-chain transactions for Stellar accounts.- Consumer worker:
src/jobs/indexer.worker.ts
- Consumer worker:
notifications-queue: Dispatches in-app notifications and manages user notification fan-out.- Consumer worker:
src/jobs/notifications.worker.ts
- Consumer worker:
Set the REDIS_URL environment variable in your production or local configuration to point to your running Redis instance:
REDIS_URL=redis://localhost:6379In production environments, background workers should be run as persistent, standalone processes separate from the web server. You can run them using a process manager like PM2:
# Run Next.js web application
npm start
# Run background workers (using custom scripts or entrypoint)
node dist/jobs/indexer.worker.js
node dist/jobs/notifications.worker.jsWorkers register graceful shutdown handlers for SIGINT and SIGTERM, so queue connections are closed cleanly during deploy rollouts or container termination.
Jobs that exhaust retries are copied into dedicated dead-letter queues for investigation and replay:
indexer-dead-letter-queuenotifications-dead-letter-queue
Each dead-letter payload includes the original job id, input payload, error reason, and failure timestamp.
The easiest way to deploy is using Vercel:
- Push your code to GitHub
- Import the repository in Vercel
- Configure environment variables
- Deploy!
# Build the application
npm run build
# Start production server
npm startFor more deployment options, see the Next.js deployment documentation.
Cron registration is protected by Postgres advisory-lock leader election so only one application replica schedules retention, snapshot, and indexer health-check jobs. See docs/scheduler-leader-election.md and docs/infrastructure/README.md for failover and recovery procedures.
| Command | Description |
|---|---|
npm run dev |
Start development server |
npm run build |
Build for production |
npm start |
Start production server |
npm run lint |
Run ESLint |
npm test |
Run tests with Vitest |
npm run storybook |
Start Storybook |
npm run build-storybook |
Build Storybook for static hosting |
npm run svg |
Convert SVG files to React components |
npm run generate-component |
Generate new component scaffold |
- Never commit
.env.localor any files containing secrets - Use environment variables for all sensitive configuration
- Regularly update dependencies to patch security vulnerabilities
- Review and audit smart contract interactions before production use
[Add your license information here]
For questions, issues, or feature requests:
- Open an issue on GitHub
- Contact the development team
- Check the documentation links above
Built with ❤️ for the Stellar ecosystem