revamp - bring the bot to life again

master
lza_menace 3 years ago
parent 594407c204
commit a6f858671e

1
.gitignore vendored

@ -132,4 +132,3 @@ dmypy.json
# Local data # Local data
data data
config.py

@ -0,0 +1,6 @@
setup:
python3 -m venv .venv
.venv/bin/pip install -r requirements.txt
up:
.venv/bin/python3 -m tipbot

@ -0,0 +1,32 @@
#!/bin/bash
export $(cat .env)
if [ ! -d "$WALLET_PATH" ]; then
# initialize new wow wallet and retain seed
mkdir -p $WALLET_PATH
docker run --rm -it --name tgbot-wallet-init \
-v $WALLET_PATH:/root \
lalanza808/wownero:latest \
wownero-wallet-cli \
--daemon-address $DAEMON_URI \
--generate-new-wallet /root/wow \
--password $WALLET_PASS \
--trusted-daemon
fi
# setup rpc process
docker run --rm -d --name tgbot-wallet \
-v $WALLET_PATH:/root \
-p 127.0.0.1:9999:9999 \
lalanza808/wownero:latest \
wownero-wallet-rpc \
--daemon-address $DAEMON_URI \
--wallet-file /root/wow \
--password $WALLET_PASS \
--rpc-bind-port 9999 \
--rpc-bind-ip 0.0.0.0 \
--confirm-external-bind \
--rpc-login "$WALLET_RPC_USER:$WALLET_RPC_PASS" \
--log-file /root/rpc.log \
--trusted-daemon

@ -0,0 +1,9 @@
WALLET_PATH=xxx
DAEMON_URI=xxx
WALLET_PASS=xxx
WALLET_RPC_USER=xxx
WALLET_RPC_PASS=xxx
TG_TOKEN=xxx
TG_ADMIN_ID=xxx
SQLITE_DB_PATH=xxx
DEBUG=xxx

@ -6,8 +6,11 @@ cryptography==2.9.2
decorator==4.4.2 decorator==4.4.2
idna==2.10 idna==2.10
peewee==3.13.3 peewee==3.13.3
Pillow==8.2.0
pycparser==2.20 pycparser==2.20
python-dotenv==0.17.1
python-telegram-bot==12.8 python-telegram-bot==12.8
qrcode==6.1
requests==2.24.0 requests==2.24.0
six==1.15.0 six==1.15.0
tornado==6.0.4 tornado==6.0.4

@ -5,7 +5,6 @@ from tipbot.commands.tip import tip
from tipbot.commands.withdraw import withdraw from tipbot.commands.withdraw import withdraw
from tipbot.commands.balance import balance from tipbot.commands.balance import balance
from tipbot.commands.deposit import deposit from tipbot.commands.deposit import deposit
from tipbot.commands.qr import qr
all_commands = { all_commands = {
@ -39,11 +38,6 @@ all_commands = {
'example': '/help', 'example': '/help',
'help': 'Show available commands for the bot', 'help': 'Show available commands for the bot',
}, },
'qr': {
'func': qr,
'example': '/qr <address>',
'help': 'Provides a helpful URL for generating QR code for a Wownero address'
},
'debug': { 'debug': {
'func': debug, 'func': debug,
'admin': True 'admin': True

@ -1,5 +1,6 @@
from tipbot.helpers.decorators import wallet_rpc_required, log_event, check_debug from tipbot.helpers.decorators import wallet_rpc_required, log_event, check_debug
from tipbot.helpers.utils import is_tg_admin from tipbot.helpers.utils import is_tg_admin
from tipbot.wownero import Wallet
@wallet_rpc_required @wallet_rpc_required
@ -7,6 +8,6 @@ from tipbot.helpers.utils import is_tg_admin
@check_debug @check_debug
def debug(update, context): def debug(update, context):
if is_tg_admin(update.message.from_user['id']): if is_tg_admin(update.message.from_user['id']):
pass update.message.reply_text('ohai')
else: else:
update.message.reply_text('you cant do that.') update.message.reply_text('you cant do that.')

@ -1,7 +1,9 @@
import logging import logging
from telegram import ParseMode
from tipbot import wownero from tipbot import wownero
from tipbot import db from tipbot import db
from tipbot.helpers.decorators import wallet_rpc_required, log_event, registration_required, check_debug from tipbot.helpers.decorators import wallet_rpc_required, log_event, registration_required, check_debug
from tipbot.helpers.utils import generate_qr
@wallet_rpc_required @wallet_rpc_required
@ -12,3 +14,8 @@ def deposit(update, context):
u = db.User.get(telegram_id=update.message.from_user['id']) u = db.User.get(telegram_id=update.message.from_user['id'])
address = wownero.Wallet().addresses(account=u.account_index)[0] 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 {u.telegram_user}: {address}')
update.message.reply_photo(
photo=generate_qr(address),
caption=f'{u.telegram_user} deposit address: {address}',
quote=False
)

@ -1,13 +0,0 @@
def qr(update, context):
if len(context.args) < 1:
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
update.message.reply_text(f'https://wownero.club/address/{address}')

@ -1,9 +0,0 @@
DEBUG = True
TG_TOKEN = 'tttttttttttt'
TG_ADMIN_ID = 0000000000
WALLET_PROTO = 'http'
WALLET_HOST = 'localhost'
WALLET_PORT = 8888
WALLET_USER = 'yyyy'
WALLET_PASS = 'xxxxxxxxx'
SQLITE_DB_PATH = '/tmp/db.sqlite'

@ -0,0 +1,19 @@
from dotenv import load_dotenv
from os import getenv
load_dotenv()
TG_TOKEN = getenv('TG_TOKEN')
TG_ADMIN_ID = int(getenv('TG_ADMIN_ID'))
WALLET_RPC_USER = getenv('WALLET_RPC_USER')
WALLET_RPC_PASS = getenv('WALLET_RPC_PASS')
SQLITE_DB_PATH = getenv('SQLITE_DB_PATH')
DAEMON_URI = getenv('DAEMON_URI')
_d = getenv('DEBUG', True)
if isinstance(_d, str):
print(_d)
if _d.lower() == 'false':
DEBUG = False
else:
DEBUG = True

@ -22,8 +22,11 @@ def check_debug(f):
def log_event(f): def log_event(f):
@wraps(f) @wraps(f)
def decorated_function(*args, **kwargs): def decorated_function(*args, **kwargs):
_d = ''
if config.DEBUG:
_d = ' (debug mode on)'
msg = args[0].message 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["id"]} ({msg.from_user["first_name"]}) - Full command: "{msg.text}"{_d}')
return f(*args, **kwargs) return f(*args, **kwargs)
return decorated_function return decorated_function

@ -1,3 +1,9 @@
from io import BytesIO
from PIL import Image
from base64 import b64encode
from qrcode import make as qrcode_make
from tipbot import config from tipbot import config
def is_tg_admin(chat_id): def is_tg_admin(chat_id):
@ -5,3 +11,9 @@ def is_tg_admin(chat_id):
return True return True
else: else:
return False return False
def generate_qr(s):
_address_qr = BytesIO()
qrcode_make(s).save(_address_qr, format="PNG")
_address_qr.seek(0)
return _address_qr

@ -10,16 +10,9 @@ PICOWOW = Decimal('0.00000000001')
class Wallet(object): class Wallet(object):
def __init__(self): def __init__(self):
self.host = config.WALLET_HOST self.endpoint = f'http://127.0.0.1:9999/json_rpc'
self.port = config.WALLET_PORT
self.proto = config.WALLET_PROTO
self.username = config.WALLET_USER
self.password = config.WALLET_PASS
self.endpoint = '{}://{}:{}/json_rpc'.format(
self.proto, self.host, self.port
)
self.auth = requests.auth.HTTPDigestAuth( self.auth = requests.auth.HTTPDigestAuth(
self.username, self.password config.WALLET_RPC_USER, config.WALLET_RPC_PASS
) )
try: try:
@ -35,7 +28,6 @@ class Wallet(object):
data=json.dumps({'method': method, 'params': params}), data=json.dumps({'method': method, 'params': params}),
auth=self.auth auth=self.auth
) )
# print(r.status_code)
if 'error' in r.json(): if 'error' in r.json():
return r.json()['error'] return r.json()['error']
else: else:
@ -54,15 +46,8 @@ class Wallet(object):
return self.make_wallet_rpc('query_key', {'key_type': 'mnemonic'})['key'] return self.make_wallet_rpc('query_key', {'key_type': 'mnemonic'})['key']
def accounts(self): def accounts(self):
accounts = []
_accounts = self.make_wallet_rpc('get_accounts') _accounts = self.make_wallet_rpc('get_accounts')
idx = 0 return [i['account_index'] for i in _accounts['subaddress_accounts']]
self.master_address = _accounts['subaddress_accounts'][0]['base_address']
for _acc in _accounts['subaddress_accounts']:
assert idx == _acc['account_index']
accounts.append(_acc['account_index'])
idx += 1
return accounts
def new_account(self, label=None): def new_account(self, label=None):
_account = self.make_wallet_rpc('create_account', {'label': label}) _account = self.make_wallet_rpc('create_account', {'label': label})