Cryptocurrency Listing Monitoring & Alert System
RasadX is a modular Node.js monitoring and notification system that detects newly listed trading pairs across cryptocurrency exchanges and sends real-time alerts through Telegram and Email.
The project is built with a focus on clean architecture, separation of concerns, dependency injection, testability, and extensibility.
- β¨ Features
- ποΈ Architecture
- π How It Works
- π§© Project Structure
- π οΈ Tech Stack
- π§ͺ Testing
- π Getting Started
- π Environment Variables
- β Adding an Exchange
- β Adding a Notification Channel
- π§ Design Principles
- π Future Improvements
β οΈ Disclaimer
- π Monitor cryptocurrency listings
- π¦ Binance integration
- π¦ Bybit integration
- π± Telegram notifications
- π§ Email notifications
- πΎ JSON-based persistent state
- π Automatic retry for temporary API failures
- π§ͺ Unit testing with Vitest
- π§© Modular and extensible architecture
- π Structured logging
- β±οΈ Periodic monitoring
- π‘οΈ Duplicate listing prevention
- π Environment-based configuration
rasadX follows a modular architecture based on separation of responsibilities.
ββββββββββββββββββββ
β index.js β
β Application β
β Entry β
ββββββββββ¬ββββββββββ
β
ββββββββββββββ΄βββββββββββββ
β β
βΌ βΌ
βββββββββββββββββ βββββββββββββββββ
β Binance β β Bybit β
β Adapter β β Adapter β
βββββββββ¬ββββββββ βββββββββ¬ββββββββ
β β
ββββββββββββββ¬βββββββββββββ
βΌ
βββββββββββββββββββ
β ListingMonitor β
β Core Business β
β Logic β
ββββββββββ¬βββββββββ
β
ββββββββββ΄βββββββββ
β β
βΌ βΌ
ββββββββββββββββββ ββββββββββββββββββ
β JsonRepository β β Notifications β
β Persistence β β Layer β
ββββββββββββββββββ βββββββββ¬βββββββββ
β
βββββββββ΄ββββββββ
βΌ βΌ
βββββββββββ βββββββββββ
βTelegram β β Email β
βββββββββββ βββββββββββ
Exchange adapters retrieve the latest market information.
Binance API
β
Binance Adapter
Bybit API
β
Bybit Adapter
Different exchanges return different response formats.
Each adapter converts exchange-specific responses into a common internal structure:
{
symbol: "BTCUSDT",
status: "TRADING",
baseAsset: "BTC",
quoteAsset: "USDT"
}This keeps the monitoring layer independent from exchange-specific API formats.
Previously detected symbols are stored in:
data/symbols.json
Example:
{
"Binance": [
"BTCUSDT",
"ETHUSDT"
],
"Bybit": [
"BTCUSDT",
"SOLUSDT"
]
}If the exchange returns:
Previous:
BTCUSDT
ETHUSDT
Current:
BTCUSDT
ETHUSDT
ABCUSDT
rasadX detects:
π¨ ABCUSDT
as a new listing.
Every newly detected listing is passed to the configured notification services.
New Listing
β
ββββββββββββΊ Telegram
β
ββββββββββββΊ Email
Example:
π¨ NEW LISTING
Exchange: Binance
Symbol: ABCUSDT
Time: 2026-08-12T12:00:00.000Z
rasadX/
β
βββ src/
β β
β βββ exchanges/
β β βββ Binance.js
β β βββ Bybit.js
β β
β βββ repositories/
β β βββ JsonRepository.js
β β
β βββ services/
β β βββ ListingMonitor.js
β β βββ NotificationService.js
β β βββ EmailNotificationService.js
β β
β βββ utils/
β β βββ logger.js
β β βββ retry.js
β β
β βββ index.js
β
βββ tests/
β βββ Binance.test.js
β βββ Bybit.test.js
β βββ EmailNotificationService.test.js
β βββ JsonRepository.test.js
β βββ ListingMonitor.test.js
β βββ NotificationService.test.js
β βββ retry.test.js
β
βββ data/
β βββ symbols.json
β
βββ .env.example
βββ .gitignore
βββ package.json
βββ README.md
- Node.js
- JavaScript
- ES Modules
- Axios
- Binance REST API
- Bybit REST API
- Telegram Bot API
- Nodemailer
- SMTP
- JSON file storage
- Vitest
- Mocking external dependencies
- dotenv
- Structured logging
- Reusable retry mechanism
External APIs can temporarily fail because of:
- Network problems
- Server errors
- Rate limits
- Temporary service unavailability
rasadX includes a reusable retry utility.
Example:
await retry(fetchData, {
retries: 3,
delay: 2000,
shouldRetry: (error) => {
const status = error.response?.status;
return (
!status ||
status === 429 ||
status >= 500
);
}
});The system retries temporary failures while avoiding unnecessary retries for client-side errors.
Request
β
βββ β 500
β
βββ Retry
β
βββ β 500
β
βββ Retry
β
βββ β
Success
rasadX uses Vitest for unit testing.
Tests cover:
- Listing detection
- Duplicate listing prevention
- First-run initialization
- Exchange state isolation
- Multiple notification services
- JSON persistence
- Binance API adapter
- Bybit API adapter
- Telegram notification service
- Email notification service
- Retry behavior
External services are mocked during unit tests.
Therefore, the test suite does not require:
- Real Binance API calls
- Real Bybit API calls
- Real Telegram messages
- A real SMTP server
Run the test suite:
npm testMake sure you have:
- Node.js 20+
- npm
git clone https://github.com/RadinAnsari/rasadX.git
cd rasadXnpm installCreate a .env file:
cp .env.example .envExample:
TELEGRAM_BOT_TOKEN=
TELEGRAM_CHAT_ID=
SMTP_HOST=
SMTP_PORT=465
SMTP_USER=
SMTP_PASSWORD=
EMAIL_FROM=
EMAIL_TO=Never commit .env to Git.
Create:
data/symbols.json
with:
{}The application will populate the exchange state automatically.
npm run appThe application periodically checks the configured exchanges and sends notifications when new listings are detected.
| Variable | Description |
|---|---|
TELEGRAM_BOT_TOKEN |
Telegram bot token |
TELEGRAM_CHAT_ID |
Telegram destination chat |
SMTP_HOST |
SMTP server hostname |
SMTP_PORT |
SMTP server port |
SMTP_USER |
SMTP username |
SMTP_PASSWORD |
SMTP credential / app password |
EMAIL_FROM |
Sender email |
EMAIL_TO |
Destination email |
Sensitive credentials are intentionally stored in environment variables and excluded from version control.
The exchange layer is designed around a simple adapter concept.
For example:
src/exchanges/OKX.js
export class OKX {
constructor() {
this.name = "OKX";
}
async getSymbols() {
// Fetch and normalize OKX symbols
}
}The core ListingMonitor does not need to know the details of the OKX API.
This makes the system easy to extend to additional exchanges.
Notification services follow the same conceptual interface.
For example:
src/services/DiscordNotificationService.js
export class DiscordNotificationService {
async sendNewListing({
exchange,
symbol,
}) {
// Send Discord notification
}
}It can then be added to the notification services array:
const notificationServices = [
telegramNotification,
emailNotification,
discordNotification,
];The core listing detection logic does not need to change.
Exchange communication, business logic, persistence, and notifications are separated.
Exchange
β
ListingMonitor
β
Repository / Notifications
Core services receive their dependencies instead of creating them internally.
new ListingMonitor(
exchange,
repository,
notificationServices
);This makes the business logic easier to test and extend.
Each exchange adapter hides exchange-specific API details.
Binance API βββΊ Binance Adapter βββ
ββββΊ Common Format
Bybit API βββββΊ Bybit Adapter βββββ
Notification providers expose the same conceptual operation:
sendNewListing({
exchange,
symbol
});This allows additional channels to be introduced without changing the core listing detection logic.
External dependencies are injected and mocked during unit tests.
This allows the core business logic to be tested without network access or real credentials.
This project is an educational and software engineering project.
It monitors publicly available exchange market information and sends notifications.
It does not execute trades or provide financial advice.
This project is licensed under the MIT License.
Built with Node.js and JavaScript.