|
|
|
@ -3,6 +3,7 @@ import config
|
|
|
|
|
import logging
|
|
|
|
|
import db
|
|
|
|
|
import six
|
|
|
|
|
import re
|
|
|
|
|
from functools import wraps
|
|
|
|
|
from decimal import Decimal
|
|
|
|
|
|
|
|
|
@ -11,7 +12,7 @@ def log_event(f):
|
|
|
|
|
@wraps(f)
|
|
|
|
|
def decorated_function(*args, **kwargs):
|
|
|
|
|
msg = args[0].message
|
|
|
|
|
logging.info(f'"{f.__name__}" invoked from {msg.from_user["id"]} ({msg.from_user["first_name"]}) - Full command: "{msg.text}"')
|
|
|
|
|
logging.info(f'"{f.__name__}" invoked from {msg.from_user["username"]} - Full command: "{msg.text}"')
|
|
|
|
|
return f(*args, **kwargs)
|
|
|
|
|
return decorated_function
|
|
|
|
|
|
|
|
|
@ -52,26 +53,20 @@ def help(update, context):
|
|
|
|
|
@log_event
|
|
|
|
|
def register(update, context):
|
|
|
|
|
uid = update.message.from_user['id']
|
|
|
|
|
un = update.message.from_user['first_name']
|
|
|
|
|
un = update.message.from_user['username']
|
|
|
|
|
uidstr = str(uid)
|
|
|
|
|
|
|
|
|
|
if un == None:
|
|
|
|
|
logging.error(f'Unable to create a new account for users without username.')
|
|
|
|
|
update.message.reply_text('Unable to create a new account for users without username.')
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
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:
|
|
|
|
|
update.message.reply_text('Your ID exists in the database already but your `first_name` attribute has changed. Updating.')
|
|
|
|
|
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
|
|
|
|
|
update.message.reply_text('You are already registered.')
|
|
|
|
|
else:
|
|
|
|
|
wallet = wownero.Wallet()
|
|
|
|
|
try:
|
|
|
|
|
wallet = wownero.Wallet()
|
|
|
|
|
account_index = wallet.new_account(label=un)
|
|
|
|
|
account_index = wallet.new_account(label=uidstr) # i prefer using uid because it is permanent
|
|
|
|
|
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.')
|
|
|
|
@ -84,8 +79,8 @@ def register(update, context):
|
|
|
|
|
)
|
|
|
|
|
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.'
|
|
|
|
|
'You have been registered and can now send and receive tips.',
|
|
|
|
|
'Ask for /help to see all available bot commands.'
|
|
|
|
|
]
|
|
|
|
|
update.message.reply_text(' '.join(reply_text))
|
|
|
|
|
except Exception as e:
|
|
|
|
@ -111,11 +106,15 @@ def tip(update, context):
|
|
|
|
|
else:
|
|
|
|
|
target_un = context.args[0]
|
|
|
|
|
|
|
|
|
|
if target_un == update.message.from_user['first_name']:
|
|
|
|
|
target_uid = context.args[0]
|
|
|
|
|
|
|
|
|
|
if target_un == update.message.from_user['username']:
|
|
|
|
|
#if target_uid == update.message.from_user['id']:
|
|
|
|
|
update.message.reply_text('You cannot tip yourself!')
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
if not db.User.filter(telegram_user=target_un):
|
|
|
|
|
#if not db.User.filter(telegram_id=target_uid):
|
|
|
|
|
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.'
|
|
|
|
@ -136,21 +135,19 @@ def tip(update, context):
|
|
|
|
|
|
|
|
|
|
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]:
|
|
|
|
|
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]
|
|
|
|
|
u = db.User.get(telegram_user=target_un)
|
|
|
|
|
address = wownero.Wallet().addresses(account=u.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:
|
|
|
|
|
update.message.reply_text(f'Tipped @{target_un} {wownero.from_atomic(tx["amount"])} WOW! Here is the TX ID: {tx["tx_hash"]}')
|
|
|
|
|
else:
|
|
|
|
|
update.message.reply_text('Failed to send a tip. Ask for help.')
|
|
|
|
|
tx = wownero.Wallet().transfer(dest_address=address, amount=amount, priority=2, account=tipper.account_index)
|
|
|
|
|
txhash = tx['tx_hash']
|
|
|
|
|
update.message.reply_text(f'@{update.message.from_user["username"]} has tipped @{target_un} {amount} WOW!\ntx hash: {txhash}')
|
|
|
|
|
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.')
|
|
|
|
@ -160,13 +157,15 @@ def tip(update, context):
|
|
|
|
|
@wallet_rpc_required
|
|
|
|
|
@registration_required
|
|
|
|
|
@log_event
|
|
|
|
|
def send(update, context):
|
|
|
|
|
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, 107]:
|
|
|
|
|
#print(len(context.args[0]))
|
|
|
|
|
if (re.match(r"Sumo[on][1-9A-HJ-NP-Za-km-z]{94}", context.args[0])) or (re.match(r"Sumi[1-9A-HJ-NP-Za-km-z]{106}", context.args[0])) or (re.match(r"Subo[1-9A-HJ-NP-Za-km-z]{94}", context.args[0])):
|
|
|
|
|
#if len(context.args[0]) in [97, 107]:
|
|
|
|
|
address = context.args[0]
|
|
|
|
|
else:
|
|
|
|
|
update.message.reply_text('This does not look like a valid Wownero address. Try again.')
|
|
|
|
@ -191,22 +190,53 @@ def send(update, context):
|
|
|
|
|
|
|
|
|
|
# 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:
|
|
|
|
|
update.message.reply_text(f'Sent {wownero.from_atomic(tx["amount"])} WOW! Here is the TX ID: {tx["tx_hash"]}')
|
|
|
|
|
else:
|
|
|
|
|
update.message.reply_text('Failed to send Wownero. Ask for help.')
|
|
|
|
|
tx = wownero.Wallet().transfer(dest_address=address, amount=amount, priority=2, account=sender.account_index)
|
|
|
|
|
update.message.reply_text(f'Sent {amount} WOW! Tx: {tx}')
|
|
|
|
|
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.')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@wallet_rpc_required
|
|
|
|
|
@registration_required
|
|
|
|
|
@log_event
|
|
|
|
|
def sweepall(update, context):
|
|
|
|
|
if len(context.args) < 1:
|
|
|
|
|
update.message.reply_text('Not enough arguments passed.')
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
if (re.match(r"Sumo[on][1-9A-HJ-NP-Za-km-z]{94}", context.args[0])) or (re.match(r"Sumi[1-9A-HJ-NP-Za-km-z]{106}", context.args[0])) or (re.match(r"Subo[1-9A-HJ-NP-Za-km-z]{94}", context.args[0])):
|
|
|
|
|
address = context.args[0]
|
|
|
|
|
else:
|
|
|
|
|
update.message.reply_text('This does not look like a valid Wownero address. Try again.')
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
sender = db.User.get(telegram_id=update.message.from_user['id'])
|
|
|
|
|
|
|
|
|
|
# validate amount
|
|
|
|
|
|
|
|
|
|
sender_balances = wownero.Wallet().balances(account=sender.account_index)
|
|
|
|
|
print(sender_balances)
|
|
|
|
|
if sender_balances[1] < 1 :
|
|
|
|
|
update.message.reply_text(f'You do not have sufficient funds to empty your wallet. Check your /balance')
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
# transfer funds to given address
|
|
|
|
|
try:
|
|
|
|
|
tx = wownero.Wallet().sweepall(dest_address=address, priority=2, account=sender.account_index)
|
|
|
|
|
update.message.reply_text(f'Sent all unlocked WOW! Tx: {tx}')
|
|
|
|
|
except Exception as e:
|
|
|
|
|
logging.error(f'Unable to send sweepall: {e}. Debug: {update.message}')
|
|
|
|
|
update.message.reply_text('Failed to send Wownero. Ask for help.')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@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)')
|
|
|
|
|
update.message.reply_text(f'Available balance for {update.message.from_user["username"]}: {float(balances[1])} WOW ({float(balances[0])} WOW locked)')
|
|
|
|
|
|
|
|
|
|
@wallet_rpc_required
|
|
|
|
|
@registration_required
|
|
|
|
@ -214,13 +244,26 @@ def balance(update, context):
|
|
|
|
|
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}')
|
|
|
|
|
update.message.reply_text(f'Deposit address for {update.message.from_user["username"]}: {address}')
|
|
|
|
|
|
|
|
|
|
@wallet_rpc_required
|
|
|
|
|
@log_event
|
|
|
|
|
def debug(update, context):
|
|
|
|
|
if is_tg_admin(update.message.from_user['id']):
|
|
|
|
|
pass
|
|
|
|
|
# tx = wownero.Wallet().transfer(
|
|
|
|
|
# dest_address='WW2vmEGV68ZFeQWwPEJda3UcdWCPfWBnDK1Y6MB9Uojx9adBhCxfx9F51TomRjmD3z7Gyogie3mfVQEkRQjLxqbs1KMzaozDw',
|
|
|
|
|
# amount=Decimal(2),
|
|
|
|
|
# priority=2,
|
|
|
|
|
# account=0
|
|
|
|
|
# )
|
|
|
|
|
# update.message.reply_text(str(tx))
|
|
|
|
|
# balances = wownero.Wallet().balances(account=0)
|
|
|
|
|
# addresses = wownero.Wallet().addresses(account=0)
|
|
|
|
|
# accounts = wownero.Wallet().accounts()
|
|
|
|
|
# a = []
|
|
|
|
|
# for i in accounts:
|
|
|
|
|
# a.append(str(wownero.Wallet().balances(account=i)[1]))
|
|
|
|
|
update.message.reply_text('sup boss')
|
|
|
|
|
else:
|
|
|
|
|
update.message.reply_text('you cant do that.')
|
|
|
|
|
|
|
|
|
@ -236,10 +279,10 @@ all_commands = {
|
|
|
|
|
'example': '/tip <username> <amount> <message>',
|
|
|
|
|
'help': 'Tip a user in Wownero'
|
|
|
|
|
},
|
|
|
|
|
'send': {
|
|
|
|
|
'func': send,
|
|
|
|
|
'example': '/send <address> <amount>',
|
|
|
|
|
'help': 'Send Wownero to a specified Wownero address'
|
|
|
|
|
'withdraw': {
|
|
|
|
|
'func': withdraw,
|
|
|
|
|
'example': '/withdraw <address> <amount>',
|
|
|
|
|
'help': 'Withdraw to a specified Wownero address'
|
|
|
|
|
},
|
|
|
|
|
'balance': {
|
|
|
|
|
'func': balance,
|
|
|
|
@ -256,11 +299,21 @@ all_commands = {
|
|
|
|
|
'example': '/deposit',
|
|
|
|
|
'help': 'Show your Wownero wallet address for transferring funds to'
|
|
|
|
|
},
|
|
|
|
|
'empty': {
|
|
|
|
|
'func': sweepall,
|
|
|
|
|
'example': '/empty <address>',
|
|
|
|
|
'help': 'Withdraw all your coins to a specified Wownero address'
|
|
|
|
|
},
|
|
|
|
|
'help': {
|
|
|
|
|
'func': help,
|
|
|
|
|
'example': '/help',
|
|
|
|
|
'help': 'Show available commands for the bot',
|
|
|
|
|
},
|
|
|
|
|
'start': {
|
|
|
|
|
'func': help,
|
|
|
|
|
'example': '/start',
|
|
|
|
|
'help': 'Show available commands for the bot',
|
|
|
|
|
},
|
|
|
|
|
'debug': {
|
|
|
|
|
'func': debug,
|
|
|
|
|
'admin': True
|
|
|
|
|