Skip to main content
Back to Sample Apps

Base Telegram Trading Bot

A user-friendly Telegram bot for trading ERC-20 tokens on Base Mainnet with MEV protection, leveraging QuickNode's Base DeFi Power Bundle

Frontend Framework/Library:
Viem
Language:
TypeScript
Build Tool/Development Server:
Base DeFi Power Bundle
Sample app preview

Overview

This project is a Telegram-based trading bot built on Base Mainnet using the QuickNode Base DeFi Bundle. The bot enables users to create or import wallets, check balances and history, and execute MEV-protected token swaps—all from within Telegram.

This example bot is provided for educational and demonstration purposes only. Use at your own risk. Always verify transactions and conduct proper security reviews before using in production environments.

The demo uses:

Supporting resources:

Getting Started

Install Dependencies

Open the project dictory:

git clone https://github.com/quiknode-labs/qn-guide-examples.git
cd qn-guide-examples/base/telegram-trading-bot

Then, install the dependencies:

npm install
# or
yarn install
# or
pnpm install
# or
bun install

Set Environment Variables

Get a Telegram Bot Token

  • Open Telegram and search for the BotFather (@BotFather)
  • Send the command /newbot
  • Follow the instructions to name your bot
  • Keep the token provided by BotFather handy

Get a QuickNode Base Mainnet Endpoint URL

  • Sign up for a QuickNode account
  • Create a Base Mainnet endpoint
  • Activate the Base DeFi Power Bundle for your endpoint
  • Keep the endpoint URL handy

Create a wallet encryption key to encrypt your private keys

openssl rand -base64 32

Important: This key is used to encrypt and decrypt users' private keys. Without it, or if it's lost, it's impossible to decrypt stored wallets. Store it securely and never share it with anyone.

  • Create a .env file based on the example .env.example file
  • Update the .env file with your QuickNode Base Mainnet endpoint URL, Telegram bot token, and wallet encryption key
  • Leave other variables as they are

Running the Bot

For development:

npm run dev

For production:

npm run start

Usage

After creating your bot with @BotFather, open Telegram and send a message to your bot by searching for the bot username you just created (e.g., @mytradingbot).

Basic Commands

  • /start - Initialize the bot and register
  • /help - Show all available commands
  • /wallet - Display wallet information
  • /balance - Show token balances
  • /history - Display balance history
  • /help - Show all available commands

Wallet Management

  • /create - Create a new wallet
  • /import - Import an existing wallet via private key
  • /export - Export your private key (with security confirmation)

Trading

  • /buy - Buy tokens with ETH
  • /sell - Sell tokens for ETH
  • /settings - Configure trading parameters

Transfers

  • /deposit - Show your wallet address for deposits
  • /withdraw - Withdraw ETH to another address

Security Considerations

  • Private keys are encrypted using AES-256 before storage
  • Sensitive operations require confirmation
  • All transactions use MEV protection to prevent front-running

Architecture

Architecture Diagram

├── README.md                        # Project overview and setup instructions
├── index.ts # Entry point: initializes the bot and registers all commands
├── nodemon.json # Config for automatic reloads during development
├── package.json # Project dependencies and scripts
├── src
│   ├── commands # Telegram command handlers
│   │   ├── balance-history.ts # Handles /history command (uses Blockbook)
│   │   ├── buy.ts # Handles /buy command using ETH as the input token
│   │   ├── deposit.ts # Handles /deposit command to show wallet address
│   │   ├── import-export.ts # Handles /import and /export commands (wallets)
│   │   ├── sell.ts # Handles /sell command using ETH as the output token
│   │   ├── settings.ts # Handles /settings command (slippage, gas, approval prefs)
│   │   ├── start-help.ts # Handles /start and /help commands
│   │   ├── wallet.ts # Handles /wallet command to show wallet info
│   │   └── withdraw.ts # Handles /withdraw command to send ETH out
│   ├── context.ts # Defines and initializes bot session context
│   ├── lib
│   │   ├── database.ts # SQLite setup and queries for users, wallets, txs, settings
│   │   ├── encryption.ts # AES encryption utilities for storing private keys
│   │   ├── history.ts # Functions to fetch balance history from Blockbook
│   │   ├── swap.ts # Handles OpenOcean quote/swap and gas estimation logic
│   │   └── token-wallet.ts # Wallet creation, loading, approval, and transaction signing
│   ├── types
│   │   ├── commands.ts # Type definitions for user interaction/session state
│   │   ├── config.ts # Types for user preferences like slippage, gas priority
│   │   └── wallet.ts # Types for encrypted wallet and related metadata
│   └── utils
│   ├── abis.ts # ABIs for token and router contract interactions
│   ├── constants.ts # App-wide constants (addresses, chain info, etc.)
│   ├── formatters.ts # Helpers to format token amounts, timestamps, and gas
│   ├── keyboardHelper.ts # Inline keyboard generators for Telegram UI
│   └── validators.ts # Input validation (e.g., token address, amount checks)
└── tsconfig.json # TypeScript configuration

Database

This bot uses a local SQLite database (powered by better-sqlite3) to securely manage user sessions, wallets, trading settings, and transaction history. The database is structured as follows:

TablePurpose
usersMaps Telegram users to unique user IDs, stores basic metadata
walletsStores each user’s encrypted private key and wallet address
settingsPersists user-defined trading preferences (slippage, gas priority, etc.)
transactionsRecords details of swap activity, including from/to tokens, gas used, and status

All wallet private keys are encrypted using AES-256-CBC and decrypted only in memory during bot operations. This ensures strong security while allowing persistent wallet access across sessions.

The database is initialized automatically on first run (src/lib/database.ts), so no setup is needed beyond ensuring you have a valid WALLET_ENCRYPTION_KEY in your .env.

Troubleshooting Common Issues

If you encounter the following error when starting the bot:

Error: Could not locate the bindings file.

This indicates that better-sqlite3 native bindings failed to build correctly, often due to mismatched Node.js versions or incomplete dependency compilation.

Rebuild the native bindings from source:

cd node_modules/better-sqlite3
npm run build-release
# or
pnpm run build-release
ls build # Verify that a .node file (e.g., better_sqlite3.node) appears
cd ../..

This command compiles the bindings for your system’s Node.js version, resolving the error.

Alternative Fixes:

Clean and Reinstall Dependencies: If the rebuild fails, clear the node_modules directory and reinstall:

rm -rf node_modules package-lock.json
npm install

# Or, if using pnpm:
rm -rf node_modules pnpm-lock.yaml
pnpm install

Check Node.js Version: Ensure you’re using Node.js 20.x or higher, as better-sqlite3 may not support older versions.

Contributions & Feedback
We'd love to hear your feedback and welcome any contributions to this sample app!
To report issues or share feedback, open a GitHub issue in the qn-guide-examples repository.
To contribute, follow these steps:
  1. Fork the repository
  2. Create a feature branch:
    git checkout -b feature/amazing-feature
  3. Commit your changes:
    git commit -m "Add amazing feature"
  4. Push your branch:
    git push origin feature/amazing-feature
  5. Open a Pull Request.