From dd025b4d9a9fa01747a7e91887ae55697df34f33 Mon Sep 17 00:00:00 2001 From: lza_menace Date: Wed, 5 Aug 2020 22:52:13 -0700 Subject: [PATCH] move commands into dedicated module --- tipbot/commands/__init__.py | 45 ++++++++++++++++++++++++ tipbot/commands/balance.py | 13 +++++++ tipbot/commands/debug.py | 11 ++++++ tipbot/commands/deposit.py | 13 +++++++ tipbot/commands/help.py | 13 +++++++ tipbot/commands/register.py | 49 ++++++++++++++++++++++++++ tipbot/commands/tip.py | 69 +++++++++++++++++++++++++++++++++++++ tipbot/commands/withdraw.py | 50 +++++++++++++++++++++++++++ 8 files changed, 263 insertions(+) create mode 100644 tipbot/commands/__init__.py create mode 100644 tipbot/commands/balance.py create mode 100644 tipbot/commands/debug.py create mode 100644 tipbot/commands/deposit.py create mode 100644 tipbot/commands/help.py create mode 100644 tipbot/commands/register.py create mode 100644 tipbot/commands/tip.py create mode 100644 tipbot/commands/withdraw.py diff --git a/tipbot/commands/__init__.py b/tipbot/commands/__init__.py new file mode 100644 index 0000000..597ba5c --- /dev/null +++ b/tipbot/commands/__init__.py @@ -0,0 +1,45 @@ +from tipbot.commands.help import help +from tipbot.commands.debug import debug +from tipbot.commands.register import register +from tipbot.commands.tip import tip +from tipbot.commands.withdraw import withdraw +from tipbot.commands.balance import balance +from tipbot.commands.deposit import deposit + + +all_commands = { + 'register': { + 'func': register, + 'example': '/register', + 'help': 'Register your Telegram user ID to this bot to begin sending and receiving tips', + }, + 'tip': { + 'func': tip, + 'example': '/tip ', + 'help': 'Tip a user in Wownero' + }, + 'withdraw': { + 'func': withdraw, + 'example': '/withdraw
', + 'help': 'Send Wownero to a specified Wownero address' + }, + 'balance': { + 'func': balance, + 'example': '/balance', + 'help': 'Show your current balance' + }, + 'deposit': { + 'func': deposit, + 'example': '/deposit', + 'help': 'Show your Wownero wallet address for transferring funds to' + }, + 'help': { + 'func': help, + 'example': '/help', + 'help': 'Show available commands for the bot', + }, + 'debug': { + 'func': debug, + 'admin': True + } +} diff --git a/tipbot/commands/balance.py b/tipbot/commands/balance.py new file mode 100644 index 0000000..68379c4 --- /dev/null +++ b/tipbot/commands/balance.py @@ -0,0 +1,13 @@ +import logging +from tipbot import wownero +from tipbot import db +from tipbot.helpers.decorators import wallet_rpc_required, log_event, registration_required + + +@wallet_rpc_required +@registration_required +@log_event +def balance(update, context): + u = db.User.get(telegram_id=update.message.from_user['id']) + balances = wownero.Wallet().balances(account=u.account_index) + update.message.reply_text(f'Available balance for {u.telegram_user}: {float(balances[1])} WOW ({float(balances[0])} WOW locked)') diff --git a/tipbot/commands/debug.py b/tipbot/commands/debug.py new file mode 100644 index 0000000..6bc9fe8 --- /dev/null +++ b/tipbot/commands/debug.py @@ -0,0 +1,11 @@ +from tipbot.helpers.decorators import wallet_rpc_required, log_event +from tipbot.helpers.utils import is_tg_admin + + +@wallet_rpc_required +@log_event +def debug(update, context): + if is_tg_admin(update.message.from_user['id']): + pass + else: + update.message.reply_text('you cant do that.') diff --git a/tipbot/commands/deposit.py b/tipbot/commands/deposit.py new file mode 100644 index 0000000..0e466a8 --- /dev/null +++ b/tipbot/commands/deposit.py @@ -0,0 +1,13 @@ +import logging +from tipbot import wownero +from tipbot import db +from tipbot.helpers.decorators import wallet_rpc_required, log_event, registration_required + + +@wallet_rpc_required +@registration_required +@log_event +def deposit(update, context): + u = db.User.get(telegram_id=update.message.from_user['id']) + address = wownero.Wallet().addresses(account=u.account_index)[0] + update.message.reply_text(f'Deposit address for {u.telegram_user}: {address}') diff --git a/tipbot/commands/help.py b/tipbot/commands/help.py new file mode 100644 index 0000000..7089c1f --- /dev/null +++ b/tipbot/commands/help.py @@ -0,0 +1,13 @@ +from tipbot import commands + + +def help(update, context): + cmds = list() + for i in commands.all_commands: + pk = commands.all_commands[i] + if not pk.get('admin', False): + cmds.append('{example} - {help}'.format( + example=pk['example'], + help=pk['help'] + )) + update.message.reply_text('Here are the available commands for this bot:\n\n' + '\n\n'.join(cmds)) diff --git a/tipbot/commands/register.py b/tipbot/commands/register.py new file mode 100644 index 0000000..eaa7a21 --- /dev/null +++ b/tipbot/commands/register.py @@ -0,0 +1,49 @@ +import logging +from tipbot import wownero +from tipbot import db +from tipbot.helpers.decorators import wallet_rpc_required, log_event + + +@wallet_rpc_required +@log_event +def register(update, context): + uid = update.message.from_user['id'] + un = update.message.from_user['first_name'] + + if db.User.filter(telegram_id=uid): + if db.User.filter(telegram_id=uid, telegram_user=un): + update.message.reply_text('You are already registered. Use /help to see available bot commands.') + else: + try: + u = db.User.get(telegram_id=uid) + u.telegram_user = un + u.save() + update.message.reply_text(f'You have been registered again as Telegram ID {uid} but with username {un}.') + except Exception as e: + logging.error(f'Unable to update user in DB: {e}. Debug: {update.message}') + update.message.reply_text('Unable to update your existing account. Ask for help.') + return False + else: + try: + wallet = wownero.Wallet() + account_index = wallet.new_account(label=un) + except Exception as e: + logging.error(f'Unable to create a new account in wallet RPC: {e}. Debug: {update.message}') + update.message.reply_text('Unable to create a new account for you. Ask for help.') + return False + try: + u = db.User( + telegram_id=uid, + telegram_user=un, + account_index=account_index, + ) + u.save() + reply_text = [ + f'You have been registered as Telegram ID {uid} and username {un} and can now send and receive tips.', + 'Ask for /help to see all available bot commands. Maybe start with /deposit to get your deposit address.' + ] + update.message.reply_text(' '.join(reply_text)) + except Exception as e: + logging.error(f'Unable to register user in DB: {e}. Debug: {update.message}') + update.message.reply_text('Unable to create a new account for you. Ask for help.') + return False diff --git a/tipbot/commands/tip.py b/tipbot/commands/tip.py new file mode 100644 index 0000000..b125bb8 --- /dev/null +++ b/tipbot/commands/tip.py @@ -0,0 +1,69 @@ +import logging +from decimal import Decimal +from tipbot import wownero +from tipbot import db +from tipbot.helpers.decorators import wallet_rpc_required, log_event, registration_required + + +@wallet_rpc_required +@registration_required +@log_event +def tip(update, context): + if len(context.args) < 2: + update.message.reply_text('Not enough arguments passed.') + return False + elif len(context.args) == 2: + message = "" + elif len(context.args) > 2: + message = context.args[2:] + + # validate target user + if context.args[0].startswith('@'): + target_un = context.args[0][1:] + else: + target_un = context.args[0] + + if target_un == update.message.from_user['first_name']: + update.message.reply_text('You cannot tip yourself!') + return False + + if not db.User.filter(telegram_user=target_un): + reply_text = [ + 'That user has not registered and cannot receive tips yet.', + 'If they would like to receive a tip, have them /register with the bot.' + ] + update.message.reply_text(' '.join(reply_text)) + return False + + # validate amount + try: + amount = Decimal(context.args[1]) + except: + update.message.reply_text(f'Bad Wownero amount specified; not a valid number.') + return False + + if amount < 1: + update.message.reply_text('Bad Wownero amount specified. Provide only positive integers or decimals greater than or equal to 1.') + return False + + tipper = db.User.get(telegram_id=update.message.from_user['id']) + tipper_balances = wownero.Wallet().balances(account=tipper.account_index) + if amount >= tipper_balances[1]: + update.message.reply_text(f'You do not have sufficient funds to send {amount} WOW. Check your /balance') + return False + + # get target user details + receiver = db.User.get(telegram_user=target_un) + address = wownero.Wallet().addresses(account=receiver.account_index)[0] + + # transfer funds to user + try: + tx = wownero.Wallet().transfer(dest_address=address, amount=wownero.as_wownero(amount), priority=2, account=tipper.account_index) + if 'tx_hash' in tx: + h = tx['tx_hash'] + update.message.reply_text(f'Tipped @{target_un} {amount} WOW! TX ID: [{h}](https://wownero.xmrauctions.com/transaction/{h})') + else: + update.message.reply_text('Failed to send a tip. Ask for help.') + except Exception as e: + logging.error(f'Unable to send transfer: {e}. Debug: {update.message}') + update.message.reply_text('Failed to send a tip. Ask for help.') diff --git a/tipbot/commands/withdraw.py b/tipbot/commands/withdraw.py new file mode 100644 index 0000000..7202afd --- /dev/null +++ b/tipbot/commands/withdraw.py @@ -0,0 +1,50 @@ +import logging +from decimal import Decimal +from tipbot import wownero +from tipbot import db +from tipbot.helpers.decorators import wallet_rpc_required, log_event, registration_required + + +@wallet_rpc_required +@registration_required +@log_event +def withdraw(update, context): + if len(context.args) < 2: + update.message.reply_text('Not enough arguments passed.') + return False + + # validate address + if len(context.args[0]) in [97, 108]: + address = context.args[0] + else: + update.message.reply_text('This does not look like a valid Wownero address. Try again.') + return False + + # validate amount + try: + amount = Decimal(context.args[1]) + except: + update.message.reply_text(f'Bad Wownero amount specified; not a valid number.') + return False + + if amount < 1: + update.message.reply_text('Bad Wownero amount specified. Provide only positive integers or decimals greater than or equal to 1.') + return False + + sender = db.User.get(telegram_id=update.message.from_user['id']) + sender_balances = wownero.Wallet().balances(account=sender.account_index) + if amount > sender_balances[1]: + update.message.reply_text(f'You do not have sufficient funds to send {amount} WOW. Check your /balance') + return False + + # transfer funds to given address + try: + tx = wownero.Wallet().transfer(dest_address=address, amount=wownero.as_wownero(amount), priority=2, account=sender.account_index) + if 'tx_hash' in tx: + h = tx['tx_hash'] + update.message.reply_text(f'Sent {amount} WOW! TX ID: [{h}](https://wownero.xmrauctions.com/transaction/{h})') + else: + update.message.reply_text('Failed to send Wownero. Ask for help.') + except Exception as e: + logging.error(f'Unable to send transfer: {e}. Debug: {update.message}') + update.message.reply_text('Failed to send Wownero. Ask for help.')