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

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:
- grammY Telegram Bot Framework
- better-sqlite3 for secure local storage
- viem for transaction signing and wallet management
- QuickNode Base DeFi Bundle, including:
- Gas Estimation API
- OpenOcean v4 Lightning Swap API
- MEV Protection & Gas Recovery
- Base Blockbook JSON-RPC
Supporting resources:
- Written Guide - Build a MEV-Protected Telegram Trading Bot on Base
- Video Guide - How to Create a Telegram Trading Bot on BASE
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
├── 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:
Table | Purpose |
---|---|
users | Maps Telegram users to unique user IDs, stores basic metadata |
wallets | Stores each user’s encrypted private key and wallet address |
settings | Persists user-defined trading preferences (slippage, gas priority, etc.) |
transactions | Records 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.
Recommended Fix: Manual Rebuild
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.
- Fork the repository
- Create a feature branch:git checkout -b feature/amazing-feature
- Commit your changes:git commit -m "Add amazing feature"
- Push your branch:git push origin feature/amazing-feature
- Open a Pull Request.