Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Crypto Wallet Tracker - Bug Fixed #12

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
121 changes: 68 additions & 53 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,67 +1,82 @@
<h1 align="center">
Crypto Wallet Transactions Tracker Bot
</h1>

</p>
<p align="center">
<img src="https://img.shields.io/github/stars/cankatx/crypto-wallet-tracker">
<img src="https://img.shields.io/github/forks/cankatx/crypto-wallet-tracker">
<br>
<img src="https://img.shields.io/github/languages/top/cankatx/crypto-wallet-tracker">
<img src="https://img.shields.io/github/last-commit/cankatx/crypto-wallet-tracker">
<br>
<img src="https://img.shields.io/github/issues/cankatx/crypto-wallet-tracker">
<img src="https://img.shields.io/github/issues-closed/cankatx/crypto-wallet-tracker">
<br>
</p>

This is a Telegram bot that tracks the transactions of added Ethereum (ETH) and Binance Coin (BNB) wallets and sends notifications whenever a new transaction occurs. The bot uses the Etherscan and BSCscan APIs to gather information about transactions, and CoinGecko to fetch the current prices of ETH and BNB.

You can contact me for any inquiry; <br>
[![Telegram](https://img.shields.io/badge/Telegram-2CA5E0?style=for-the-badge&logo=telegram&logoColor=white)](https://t.me/cankat)

## Commands

- `/start` shows a welcome message and instructions on how to use the bot.
- `/add` adds a new wallet to track transactions for. The wallet address must be provided in the correct format (starting with '0x' for ETH wallets and 'bnb' for BNB wallets), otherwise the bot will prompt the user to correct it. The added wallets are saved in a JSON file for persistence.
- `/remove` removes a wallet from the list of tracked wallets. The user must provide the wallet address in the correct format.
- `/list` shows the list of currently tracked wallets.
# Crypto Wallet Tracker Bot

## Introduction

The Crypto Wallet Tracker Bot is a Telegram bot that allows users to monitor their Ethereum (ETH) and Binance Smart Chain (BNB) wallet transactions in real-time. Users can add their wallet addresses to the bot, and it will send them notifications whenever incoming or outgoing transactions occur on their wallets.

## Features

- Logging: the bot prompts every transaction and errors.
- Format check: the bot checks that the wallet address provided by the user is in the correct format before adding it to the list of tracked wallets.
- **Real-time Transaction Monitoring**: The bot continuously monitors user-specified wallet addresses and sends notifications for incoming and outgoing transactions.
- **Supports Ethereum and Binance Smart Chain**: Users can monitor wallets on both Ethereum and Binance Smart Chain blockchains.
- **Telegram Integration**: Notifications are sent directly to users via Telegram, making it convenient to stay updated on wallet activities.

## Requirements
## Installation

To run the bot, you'll need to have Python 3.6 or later installed on your system, along with the following Python libraries:
To use the Crypto Wallet Tracker Bot, follow these steps:

- `requests` (for making HTTP requests to the APIs)
- `web3` (for interacting with the Ethereum blockchain)
1. Clone the repository:

You'll also need to obtain API keys for Etherscan and BSCscan, as well as a Telegram bot token. These can be obtained by following the instructions on the respective websites.
```bash
git clone https://github.com/your-username/crypto-wallet-tracker-bot.git
```

## Installation
2. Install the required dependencies:

```bash
pip install -r requirements.txt
```

3. Create a `.env` file and add your Telegram bot token:

```bash
TELEGRAM_BOT_TOKEN=<your_telegram_bot_token>
TELEGRAM_CHAT_ID=<your_telegram_chat_id>
```

4. Obtain API keys from Etherscan and BscScan for Ethereum and Binance Smart Chain respectively, and replace `<your_etherscan_api_key>` and `<your_bscscan_api_key>` in the code with your actual API keys.

5. Run the bot:

```bash
python bot.py
```

## Changes and Fixes

- **Improved Code Readability**: Refactored the code to improve readability and maintainability.
- **Added Environment Variables**: Utilized environment variables for sensitive information such as API keys and Telegram bot token.
- **Enhanced Error Handling**: Implemented better error handling mechanisms to gracefully handle exceptions and errors.
- **Updated Dependency Management**: Included `python-dotenv` for managing environment variables more effectively.
- **Fixed API Key Handling**: Revised the code to properly handle API keys for different blockchains.

## Usage

1. Start the bot by sending the `/start` command to initiate the bot and get instructions on how to use it.

2. Add a wallet to monitor using the `/add <blockchain> <wallet_address>` command. For example:

```
/add ETH 0x123456789abcdef
```

Replace `ETH` with the blockchain (either `ETH` for Ethereum or `BNB` for Binance Smart Chain), and `0x123456789abcdef` with the wallet address you want to monitor.

3. Remove a wallet from monitoring using the `/remove <blockchain> <wallet_address>` command. For example:

```
/remove ETH 0x123456789abcdef
```

1. Clone this repository: `git clone https://github.com/cankatx/crypto-wallet-tracker.git`
2. Install the required packages: `pip install -r requirements.txt`
3. Replace the following placeholders in the `main.py` file with your API keys and bot token:
Replace `ETH` with the blockchain and `0x123456789abcdef` with the wallet address you want to stop monitoring.

```python
ETHERSCAN_API_KEY = '<your_etherscan_api_key>'
BSCSCAN_API_KEY = '<your_bscscan_api_key>'
TELEGRAM_BOT_TOKEN = '<your_telegram_bot_token>'
TELEGRAM_CHAT_ID = '<your_telegram_chat_id>'
```
4. Start the bot: `python main.py`
4. List all wallets being monitored for a specific blockchain using the `/list <blockchain>` command. For example:

## Screenshots
```
/list ETH
```

<img src="images/image3.png" width="505" height="395" />
<img src="images/image2.png" width="509" height="380" />
<img src="images/image1.png" width="470" height="175" />
</p>
Replace `ETH` with the blockchain you want to list wallets for.

## Disclaimer
## Contributing

This bot is provided for educational purposes only and should not be used as financial advice. The bot does not have access to your wallet.
Contributions are welcome! If you find any bugs or have suggestions for improvements, feel free to open an issue or submit a pull request. Email : [email protected]
Binary file removed images/image1.png
Binary file not shown.
Binary file removed images/image2.png
Binary file not shown.
Binary file removed images/image3.png
Binary file not shown.
76 changes: 48 additions & 28 deletions main.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,25 @@
import requests
import json
import time
import os.path
import os
import re
from web3 import Web3
from dotenv import load_dotenv

# Load environment variables
load_dotenv()

# Update the following variables with your own Telegram bot token
TELEGRAM_BOT_TOKEN = os.getenv('TELEGRAM_BOT_TOKEN')
TELEGRAM_CHAT_ID = os.getenv('TELEGRAM_CHAT_ID')

# Update the following variables with your own Etherscan and BscScan API keys and Telegram bot token
ETHERSCAN_API_KEY = '<your_etherscan_api_key>'
BSCSCAN_API_KEY = '<your_bscscan_api_key>'
TELEGRAM_BOT_TOKEN = '<your_telegram_bot_token>'
TELEGRAM_CHAT_ID = '<your_telegram_chat_id>'

# Define some helper functions
def get_wallet_transactions(wallet_address, blockchain):
def get_wallet_transactions(wallet_address, blockchain, api_key):
if blockchain == 'eth':
url = f'https://api.etherscan.io/api?module=account&action=txlist&address={wallet_address}&sort=desc&apikey={ETHERSCAN_API_KEY}'
url = f'https://api.etherscan.io/api?module=account&action=txlist&address={wallet_address}&sort=desc&apikey={api_key}'
elif blockchain == 'bnb':
url = f'https://api.bscscan.com/api?module=account&action=txlist&address={wallet_address}&sort=desc&apikey={BSCSCAN_API_KEY}'
url = f'https://api.bscscan.com/api?module=account&action=txlist&address={wallet_address}&sort=desc&apikey={api_key}'
else:
raise ValueError('Invalid blockchain specified')

Expand All @@ -25,11 +28,13 @@ def get_wallet_transactions(wallet_address, blockchain):

result = data.get('result', [])
if not isinstance(result, list):
print(f"[{time.strftime('%Y-%m-%d %H:%M:%S')}] Error fetching transactions for {wallet_address} on {blockchain.upper()} blockchain: {data}")
print(
f"[{time.strftime('%Y-%m-%d %H:%M:%S')}] Error fetching transactions for {wallet_address} on {blockchain.upper()} blockchain: {data}")
return []

return result


def send_telegram_notification(message, value, usd_value, tx_hash, blockchain):
if blockchain == 'eth':
etherscan_link = f'<a href="https://etherscan.io/tx/{tx_hash}">Etherscan</a>'
Expand All @@ -39,13 +44,16 @@ def send_telegram_notification(message, value, usd_value, tx_hash, blockchain):
raise ValueError('Invalid blockchain specified')

url = f'https://api.telegram.org/bot{TELEGRAM_BOT_TOKEN}/sendMessage'
payload = {'chat_id': f'{TELEGRAM_CHAT_ID}', 'text': f'{message}: {etherscan_link}\nValue: {value:.6f} {blockchain.upper()} (${usd_value:.2f})',
payload = {'chat_id': f'{TELEGRAM_CHAT_ID}',
'text': f'{message}: {etherscan_link}\nValue: {value:.6f} {blockchain.upper()} (${usd_value:.2f})',
'parse_mode': 'HTML'}
response = requests.post(url, data=payload)
print(f"[{time.strftime('%Y-%m-%d %H:%M:%S')}] Telegram notification sent with message: {message}, value: {value} {blockchain.upper()} (${usd_value:.2f})")
print(
f"[{time.strftime('%Y-%m-%d %H:%M:%S')}] Telegram notification sent with message: {message}, value: {value} {blockchain.upper()} (${usd_value:.2f})")
return response

def monitor_wallets():

def monitor_wallets(eth_api_key, bsc_api_key):
watched_wallets = set()
file_path = "watched_wallets.txt"
if not os.path.exists(file_path):
Expand Down Expand Up @@ -78,24 +86,25 @@ def monitor_wallets():

for wallet in watched_wallets:
blockchain, wallet_address = wallet.split(':')
transactions = get_wallet_transactions(wallet_address, blockchain)
transactions = get_wallet_transactions(wallet_address, blockchain,
eth_api_key if blockchain == 'eth' else bsc_api_key)
for tx in transactions:
tx_hash = tx['hash']
tx_time = int(tx['timeStamp'])

if tx_hash not in latest_tx_hashes and tx_time > last_run_time:
if tx['to'].lower() == wallet_address.lower():
value = float(tx['value']) / 10**18 # Convert from wei to ETH or BNB
usd_value = value * (eth_usd_price if blockchain == 'eth' else bnb_usd_price) # Calculate value in USD
value = float(tx['value']) / 10 ** 18 # Convert from wei to ETH or BNB
usd_value = value * (
eth_usd_price if blockchain == 'eth' else bnb_usd_price) # Calculate value in USD
message = f'🚨 Incoming transaction detected on {wallet_address}'
send_telegram_notification(message, value, usd_value, tx['hash'], blockchain)
#print(f'\n{message}, Value: {value} {blockchain.upper()}, ${usd_value:.2f}\n')
elif tx['from'].lower() == wallet_address.lower():
value = float(tx['value']) / 10**18 # Convert from wei to ETH or BNB
usd_value = value * (eth_usd_price if blockchain == 'eth' else bnb_usd_price) # Calculate value in USD
value = float(tx['value']) / 10 ** 18 # Convert from wei to ETH or BNB
usd_value = value * (
eth_usd_price if blockchain == 'eth' else bnb_usd_price) # Calculate value in USD
message = f'🚨 Outgoing transaction detected on {wallet_address}'
send_telegram_notification(message, value, usd_value, tx['hash'], blockchain)
#print(f'\n{message}, Value: {value} {blockchain.upper()}, ${usd_value:.2f}\n')

latest_tx_hashes[tx_hash] = int(tx['blockNumber'])

Expand All @@ -115,11 +124,13 @@ def monitor_wallets():
# Sleep for 10 seconds before trying again
time.sleep(10)


def add_wallet(wallet_address, blockchain):
file_path = "watched_wallets.txt"
with open(file_path, 'a') as f:
f.write(f'{blockchain}:{wallet_address}\n')


def remove_wallet(wallet_address, blockchain):
file_path = "watched_wallets.txt"
temp_file_path = "temp.txt"
Expand All @@ -129,6 +140,7 @@ def remove_wallet(wallet_address, blockchain):
temp_f.write(line)
os.replace(temp_file_path, file_path)


# Define the command handlers for the Telegram bot
def start(update, context):
message = """
Expand All @@ -150,9 +162,11 @@ def start(update, context):
"""
context.bot.send_message(chat_id=update.message.chat_id, text=message)


def add(update, context):
if len(context.args) < 2:
context.bot.send_message(chat_id=update.message.chat_id, text="Please provide a blockchain and wallet address to add.")
context.bot.send_message(chat_id=update.message.chat_id,
text="Please provide a blockchain and wallet address to add.")
return

blockchain = context.args[0].lower()
Expand All @@ -161,30 +175,35 @@ def add(update, context):
# Check if the wallet address is in the correct format for the specified blockchain
if blockchain == 'eth':
if not re.match(r'^0x[a-fA-F0-9]{40}$', wallet_address):
context.bot.send_message(chat_id=update.message.chat_id, text=f"{wallet_address} is not a valid Ethereum wallet address.")
context.bot.send_message(chat_id=update.message.chat_id,
text=f"{wallet_address} is not a valid Ethereum wallet address.")
return
elif blockchain == 'bnb':
if not re.match(r'^0x[a-fA-F0-9]{40}$', wallet_address):
context.bot.send_message(chat_id=update.message.chat_id, text=f"{wallet_address} is not a valid Binance Smart Chain wallet address.")
context.bot.send_message(chat_id=update.message.chat_id,
text=f"{wallet_address} is not a valid Binance Smart Chain wallet address.")
return
else:
context.bot.send_message(chat_id=update.message.chat_id, text=f"Invalid blockchain specified: {blockchain}")
return

add_wallet(wallet_address, blockchain)
message = f'Added {wallet_address} to the list of watched {blockchain.upper()} wallets.'
context.bot.send_message(chat_id=update.message.chat_id, text=message)


def remove(update, context):
if len(context.args) < 2:
context.bot.send_message(chat_id=update.message.chat_id, text="Please provide a blockchain and wallet address to remove.\nUsage: /remove ETH 0x123456789abcdef")
context.bot.send_message(chat_id=update.message.chat_id,
text="Please provide a blockchain and wallet address to remove.\nUsage: /remove ETH 0x123456789abcdef")
return
blockchain = context.args[0].lower()
wallet_address = context.args[1]
remove_wallet(wallet_address, blockchain)
message = f'Removed {wallet_address} from the list of watched {blockchain.upper()} wallets.'
context.bot.send_message(chat_id=update.message.chat_id, text=message)


def list_wallets(update, context):
with open("watched_wallets.txt", "r") as f:
wallets = [line.strip() for line in f.readlines()]
Expand All @@ -203,17 +222,18 @@ def list_wallets(update, context):
if eth_wallets:
message += "Ethereum Wallets:\n"
for i, wallet in enumerate(eth_wallets):
message += f"{i+1}. {wallet}\n"
message += f"{i + 1}. {wallet}\n"
message += "\n"
if bnb_wallets:
message += "Binance Coin Wallets:\n"
for i, wallet in enumerate(bnb_wallets):
message += f"{i+1}. {wallet}\n"
message += f"{i + 1}. {wallet}\n"
context.bot.send_message(chat_id=update.message.chat_id, text=message)
else:
message = "There are no wallets currently being monitored."
context.bot.send_message(chat_id=update.message.chat_id, text=message)


# Set up the Telegram bot
from telegram.ext import Updater, CommandHandler

Expand All @@ -236,4 +256,4 @@ def list_wallets(update, context):
print(f"[{time.strftime('%Y-%m-%d %H:%M:%S')}] Telegram bot started.")

print(f"[{time.strftime('%Y-%m-%d %H:%M:%S')}] Monitoring wallets...")
monitor_wallets()
monitor_wallets('<your_etherscan_api_key>', '<your_bscscan_api_key>')